Systemd Network Configuration

Unless you’ve been living in a very Linux-free environment for a while, you’ll know about systemd – the collection of daemons intended to replace the System V init system commonly found on Linux, with something more complicated. I’m not a fan of System V startup, but they might have done better by going for the Research Unix or BSD /etc/rc approach for robustness, simplicity and compatibility. But Linux, to many, is a launcher stub for graphical desktops running LibreOffice and games, and these probably work better with systemd syntax when controlled by a simple GUI.

Systemd is more than an init system – in fact it has daemons from everything from the keyboard to DNS resolution – and network interface configuration (networkd)

This nightmare came out of Red Hat, and Linux distributions like Debian, Ubuntu, openSUSE, Arch, and their derivatives have started using it. One result, amongst other things, is that it’s suddenly not possible to configure networks the way you used to using ifconfig and /etc/resolv.conf.

You can install the missing ifconfig and suchlike using a package called net-tools, which is present on most major Linux distributions and is installed in the appropriate way (dnf, apt, yum etc). This may be the best way to keep scripts working.

Otherwise, you might be hoping systemd-networkd has simplified things, with less to type. But I’m afraid not.

So for those who are struggling, here’s a cheat sheet.

Names

The first think you’ll have to remember is that systemd-networkd doesn’t call your Ethernet interfaces eth0:, eth1. It doesn’t even call them by their driver name+enum BSD style. Instead it mungs a name from indices provided by the firmware, PCIe slot number and even the MAC address. Look out for some very strange interface names.

The idea is that the NIC/port has a predictable name, which is great in theory. I can see two problems: Firstly this doesn’t really help you find the RJ45 any better unless you have a schematic. Secondly, if you pull the system from one host and put it in another it all goes to hell in a handcart anyway. On the plus side I guess it means that adding or removing a NIC isn’t going to change the name of the existing ports.

For what it’s worth, eno# is an onboard device, ens# is a PCI slot index, enp#s# is port number on NIC and PCI slot index. enx1122334455667788 is the MAC address but this behaviour seems to be turned off on most systems. If it can’t determine anything it will fall back to eth#.

There are ways of selecting the old behaviour using kernel parameters or knobbling the /etc/systemd/network/… something “default” depending on system but you should check that out in the man page. Oh, hang on, this is Linux there probably no man pages.

Cheat Sheet

OldNew
ifconfig eth0 192.168.1.2/24ip addr add 192.168.1.2/24 dev eth0
ifconfig eth0 192.168.1.2 deleteip addr del 192.168.1.2/24 dev eth0
ifconfig eth0 netmask 255.255.255.0? Set address and netmask together ?
ifconfig eth0 mtu 5000ip link set eht0 mtu 5000
ifconfig eth0 down (or up)ip link set eth0 down (or up)
ifconfigip a
netstatss
netstat -rip route show
routeip r
route add default 192.168.1.254ip route add default via 192.168.1.254
arp -aip n
ifconfig eht0 name wan1? Not possible from command line ?

The last entry in the table is about renaming an interface, which given the user-hostile names now generated is even more useful. I haven’t figured out how to do this from the command line, but the assumption is that all interface configuration is done in configuration files by default, which brings us neatly on to these.

Configuring at startup

At one time you could just edit /etc/network/interfaces, and it might still work (it does int he latest Debian, for example). In BSD stick simple definitions in rc.conf, but that’s too easy. Anyway, /etc/network/interfaces could look something like this:

auto eth0
iface eth0 inet static
address 192.168.1.2
netmask 255.255.255.0
gateway 192.168.1.253

auto eth1
iface eth1 inet dhcp

After editing the configuration files(s) you could restart:

/etc/init.d/networking [start | stop | restart]

But some systemd Linux distributions are different. Systemd-networkd has a directory tree full of configuration stuff and I can only scratch the surface here.

Basically a load of *.network stored in /etc/systemd/network/ get run in sort order. It’s normal to prefix each file with two digits and a dash to set this order. I don’t think there’s any reason not to use a single file, but in the Linux world people don’t, often choosing to make the rest of the filename the NIC name, such as “04-enp0s5.network“, although the name you choose is only for your reference (or that of some GUI configuration tool).

To force every NIC to configure using dhcp create a file 02-dhcpall.network:

[Match]
Name=en*
[Network]
DHCP=yes

Note the wildcard on the NIC Name=*

On the other hand if you want to make one specific card static, have a file which you might want to call 01-enp5s2.network:

[Match]
Name=enp5s2
 
[Network]
Address=192.168.1.2/24
Gateway=192.168.1.254
DNS=192.168.1.254 8.8.8.8
Domains=example.com test.example.com

This should be fairly self-explanatory. You can specify multiple Address= lines (aliases) but for some reason DNS servers tend to be listed on one line, although multiple lines do work in my experience. I’ve used IPv4 in the examples but IPv6 works too.

Domains=example.com test.example.com is basically the DNS search domains (as normally found in resolv.conf). As systemd has its own resolver, systemd-resolved, it’s not just a matter of edit one file any longer, and is also less flexible.

You can restart systemd-networkd with:

systemctl restart systemd-networkd

If you haven’t made any mistakes you might still be connected to your server.

Leave a Reply

Your email address will not be published. Required fields are marked *