Saturday, November 9, 2019

Ubuntu 19.10 and Namespaces vs Netplan

I am using OpenVPN and namespaces to isolate access to the VPN connection. Originally, I wrote small scripts to bring up the connection and setup the necessary network interfaces.

I used a bridged ethernet inside the namespace as gateway to outside. For this purpose, normally I use brctl to edit bridge configurations. But now that Ubuntu is using netplan, things have changed a little bit.

Some namespace related operations are unclear and not documented at all.

Setting Up Namespace

First action is to edit /etc/systemd/network/25-veth.netdev and define 2 virtual ethernets.

[NetDev]
Name=veth0
Kind=veth
[Peer]
Name=veth1

Next action is to edit the /etc/netplan/50-cloud-init.yaml and assign one of the ethernets into bridge with main ethernet.

# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    version: 2
    ethernets:
        enp5s0:
            addresses: []
            dhcp4: false
        veth0: {}
        veth1: {}

    bridges:
      br0:
        dhcp4: yes
        interfaces:
          - enp5s0
          - veth0


So after this I still had to configure few setting using a script. If you know how to convert this to use netplan, please write to comments.
  ip netns add vpn
  ip netns exec vpn ip link set dev lo up
  ip link set veth1 netns vpn
  ip netns exec vpn ifconfig veth1 inet 192.168.1.252 netmask 255.255.255.0 up
  ip netns exec vpn route add default gw 192.168.1.1 dev veth1
  ip netns exec vpn route add -net 10.8.0.0 netmask 255.255.255.0 gw 192.168.1.1 dev veth1

You probably do not need the last line. I needed to add it so that packets for 10.8.0.0/24 network would not go out through VPN.

Name Resolution

One other problem is that Ubuntu 19.10 seem to be using systemd-resolved and therefore /etc/resolv.conf looks like this:

# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0
search lan

Now the fun part is that it is extremely difficult to route localhost addresses from namespace. So I had to use external resolv.conf and hosts files. These files are put to /etc/netns/vpn/ (here "vpn" is my namespace).

resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4


hosts
127.0.0.1       localhost.localdomain   localhost ubuntu
::1             localhost6.localdomain6 localhost6 ubuntu

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Now the reason for using some outside DNS IP addresses is so that the DNS traffic is routed over VPN once it is established. I was not super paranoid about this. But somebody might want to use up/down scripts with openvpn to edit the nameservers.

I had to setup hosts file because sudo command was giving dns resolving errors for the hostname ubuntu

No comments:

Post a Comment