Have a Plan for Netplan
Ubuntu changed networking. Embrace the YAML.
If I'm being completely honest, I still dislike the switch from eth0,
eth1, eth2
to names like, enp3s0, enp4s0, enp5s0
. I've learned to accept
it and mutter to myself while I type in unfamiliar interface names. Then I
installed the new LTS version of Ubuntu and typed vi
/etc/network/interfaces
. Yikes. After a technological lifetime of entering
my server's IP information in a simple text file, that's no longer how
things are done. Sigh. The good news is that while figuring out Netplan for
both desktop and server environments, I fixed a nagging DNS issue I've had
for years (more on that later).
The old way of configuring Debian-based network interfaces was based on the
ifupdown
package. The new default is called Netplan, and
although it's not
terribly difficult to use, it's drastically different. Netplan is sort of
the interface used to configure the back-end dæmons that actually
configure the interfaces. Right now, the back ends supported are
NetworkManager and networkd
.
If you tell Netplan to use NetworkManager, all interface configuration control is handed off to the GUI interface on the desktop. The NetworkManager program itself hasn't changed; it's the same GUI-based interface configuration system you've likely used for years.
If you tell Netplan to use networkd
, systemd itself handles the interface
configurations. Configuration is still done with Netplan files, but once
"applied", Netplan creates the back-end configurations systemd requires. The
Netplan files are vastly different from the old /etc/network/interfaces
file, but it uses YAML syntax, and it's pretty easy to figure out.
If you install a GUI version of Ubuntu, Netplan is configured with
NetworkManager as the back end by default. Your system should get IP
information via DHCP or static entries you add via GUI. This is usually not
an issue, but I've had a terrible time with my split-DNS setup and
systemd-resolved
. I'm sure there is a magical combination of configuration
files that will make things work, but I've spent a lot of time, and it
always behaves a little oddly. With my internal DNS server resolving domain
names differently from external DNS servers (that is, split-DNS), I get random
lookup failures. Sometimes ping
will resolve, but
dig
will not. Sometimes
the internal A record will resolve, but a CNAME
will not. Sometimes I get
resolution from an external DNS server (from the internet), even though I
never configure anything other than the internal DNS!
I decided to disable systemd-resolved
. That has the potential to break DNS
lookups in a VPN, but I haven't had an issue with that. With
resolved
handling DNS information, the /etc/resolv.conf file points to 127.0.0.53 as
the nameserver. Disabling systemd-resolved
will stop the automatic creation
of the file. Thankfully, NetworkManager itself can handle the creation and
modification of /etc/resolv.conf. Once I make that change, I no longer have
an issue with split-DNS resolution. It's a three-step process:
-
Do
sudo systemctl disable systemd-resolved.service
. -
Then
sudo rm /etc/resolv.conf
(get rid of the symlink). -
Edit the /etc/NetworkManager/NetworkManager.conf file, and in the
[main]
section, add a line that readsDNS=default
.
Once those steps are complete, NetworkManager itself will create the
/etc/resolv.conf file, and the DNS server supplied via DHCP or static entry
will be used instead of a 127.0.0.53 entry. I'm not sure why the
resolved
dæmon incorrectly resolves internal addresses for me, but the above method
has been foolproof, even when switching between networks with my
laptop.
If Ubuntu is installed in server mode, it is almost certainly configured to
use networkd
as the back end. To check, have a look at the
/etc/netplan/config.yaml file. The renderer
should be set to
networkd
in order to use the systemd-networkd
back end. The file should look
something like this:
network:
version: 2
renderer: networkd
ethernets:
enp2s0:
dhcp4: true
Important note: remember that with
YAML files, whitespace matters, so the indentation is important. It's also
very important to remember that after making any changes, you need to
run sudo netplan apply
so the back-end configuration files are
populated.
The default renderer is networkd
, so it's possible you won't have that line
in your configuration file. It's also possible your configuration file will
be named something different in the /etc/netplan folder. All .conf files
are read, so it doesn't matter what it's called as long as it ends with
.conf. Static configurations are fairly simple to set up:
network:
version: 2
renderer: networkd
ethernets:
enp2s0:
dhcp4: no
addresses:
- 192.168.1.10/24
- 10.10.10.10/16
gateway4: 192.168.1.1
nameservers:
addresses: [192.168.1.1, 8.8.8.8]
Notice I've assigned multiple IP addresses to the interface. Netplan does
not support virtual interfaces like enp3s0:0
, rather multiple IP
addresses can be assigned to a single interface.
Unfortunately, networkd
doesn't create an /etc/resolv.conf file if you
disable the resolved
dæmon. If you have problems with split-DNS on a
headless computer, the best solution I've come up with is to disable
systemd-resolved
and then manually create an /etc/resolv.conf file. Since
headless computers don't usually move around as much as laptops, it's likely
the /etc/resolv.conf file won't need to be changed. Still, I wish
networkd
had an option to manage the resolv.conf file the same way
NetworkManager
does.
The configuration formats are different, but it's still possible to do more advanced network configurations with Netplan:
Bonding:
network:
version: 2
renderer: networkd
bonds:
bond0:
dhcp4: yes
interfaces:
- enp2s0
- enp3s0
parameters:
mode: active-backup
primary: enp2s0
The various bonding modes (balance-rr
,
active-backup
, balance-xor
,
broadcast
, 802.3ad
, balance-tlb
and
balance-alb
) are supported.
Bridging:
network:
version: 2
renderer: networkd
bridges:
br0:
dhcp4: yes
interfaces:
- enp4s0
- enp3s0
Bridging is even simpler to set up. This configuration creates a bridge
device using the two interfaces listed. The device (br0
) gets address
information via DHCP.
If you're a crusty old sysadmin like me, you likely type
ifconfig
to see
IP information without even thinking. Unfortunately, those tools are not
usually installed by default. This isn't actually the fault of Ubuntu and
Netplan; the old ifconfig
toolset has been deprecated. If you want to use
the old ifconfig
tool, you can install the package:
sudo apt install net-tools
But, if you want to do it the "correct" way, the new "ip" tool is the proper
way to do it. Here are some equivalents of things I commonly do with
ifconfig
:
Show network interface information.
Old way:
ifconfig
New way:
ip address show
(Or you can just do ip a
, which is actually less typing than
ifconfig
.)
Bring interface up.
Old way:
ifconfig enp3s0 up
New way:
ip link set enp3s0 up
Assign IP address.
Old way:
ifconfig enp3s0 192.168.1.22
New way:
ip address add 192.168.1.22 dev enp3s0
Assign complete IP information.
Old way:
ifconfig enp3s0 192.168.1.22 net mask 255.255.255.0 broadcast
↪192.168.1.255
New way:
ip address add 192.168.1.22/24 broadcast 192.168.1.255
↪dev enp3s0
Add alias interface.
Old way:
ifconfig enp3s0:0 192.168.100.100/24
New way:
ip address add 192.168.100.100/24 dev enp3s0 label enp3s0:0
Show the routing table.
Old way:
route
New way:
ip route show
Add route.
Old way:
route add -net 192.168.55.0/24 dev enp4s0
New way:
ip route add 192.168.55.0/24 dev enp4s0
Old Dogs and New Tricks
I hated Netplan when I first installed Ubuntu 18.04. In fact, on the
particular server I was installing, I actually started over and installed
16.04 because it was "comfortable". After a while, curiosity got the better
of me, and I investigated the changes. I'm still more comfortable with the
old /etc/network/interfaces file, but I have to admit, Netplan makes a
little more sense. There is a single "front end" for configuring networks,
and it uses different back ends for the heavy lifting. Right now, the only
back ends are the GUI NetworkManager and the systemd-networkd
dæmon. With
the modular system, however, that could change someday without the need to
learn a new way of configuring interfaces. A simple change to the
renderer
line would send the configuration information to a new back end.
With regard to the new command-line networking tool (ip
vs.
ifconfig
),
it really behaves more like other network devices (routers and so on), so that's
probably a good change as well. As technologists, we need to be ready and
eager to learn new things. If we weren't always trying the next best thing,
we'd all be configuring Trumpet Winsock to dial in to the internet on our
Windows 95 machines. I'm glad I tried that new Linux thing, and while it
wasn't quite as dramatic, I'm glad I tried Netplan as well!