Migrating Debian 13 to Systemd Networking
Part of the journey to a new Linux home server includes migrating from Docker to rootless Podman. After much smashing of head into wall, I found it’s a lot easier to make rootless containers do nice things1 if the network is being managed by systemd instead of the older ifupdown (/etc/network/interfaces) system.
The process breaks down to:
- Create systemd network config.
- Enable the new networking service / disable the old.
- Install systemd-resolved.
- Reboot.
Configuration files
This is what my /etc/network/interfaces file looked like:
allow-hotplug enxa1b2c3d4e5f6
iface enxa1b2c3d4e5f6 inet dhcp
post-up ip link property add dev enxa1b2c3d4e5f6 altname homelan
down ip link property del dev enxa1b2c3d4e5f6 altname homelan
post-up ip addr add 10.1.1.3/32 dev enxa1b2c3d4e5f6
down ip addr del 10.1.1.3/32 dev enxa1b2c3d4e5f6
post-up ip addr add 10.1.1.4/32 dev enxa1b2c3d4e5f6
down ip addr del 10.1.1.4/32 dev enxa1b2c3d4e5f6
The ip link commands became a .link file and everything else went into a .network file. They can be named however, though the docs recommend prefixing the files with a number less than 70 (and explain why) and its convention to put the interface name in the filename (as a kindness to human maintainers).
In /etc/systemd/network/10-usb-enxa1b2c3d4e5f6.link went something like:
[Match]
MACAddress=a1:b2:c3:d4:e5:f6
[Link]
AlternativeName=homelan
In /etc/systemd/network/20-usb-enxa1b2c3d4e5f6.network went something like:
[Match]
MACAddress=a1:b2:c3:d4:e5:f6
[Network]
Description=USB-C 2.5g Ethernet
DHCP=yes
UseDomains=yes
Address=10.1.1.3/32
Address=10.1.1.4/32
I was pretty happy with how clear and straightforward these files were. Much better than all the pre/post commands added to interfaces.
Enabling the new, disabling the old
With that in place, it was time to turn on the systemd networking and disable ifupdown:
sudo systemctl enable --now systemd-networkd
sudo systemctl disable --now networking
Additionally, in order for /etc/resolv.conf to get properly populated we need systemd-resolved:
sudo apt install systemd-resolved
sudo systemctl enable --now systemd-resolved
Finally, I moved the old /etc/network/interfaces file to /root to remove any confusion as to which system was doing the network config (and keep it around … in case).
At this point, I reboot (and got in front of the console in case of failure).
Results
Things worked! The only surprise was the interface was now named “eth0” instead of the longer “enx” one. You can modify the config to make the name the same, I didn’t bother. This isn’t a multi-NIC server where I need to worry about the order of the NIC assignment. This is fine.
Helpful commands
Here are a couple of new tools I ran into along the journey.
To see information about your network interfaces, use use networkctl:
networkctl list— shows all your links and their statusnetworkctl status eth0— shows an exhaustive amount of information about the network interface that I normally would need multiple tools to see.
To see information about how DNS resolution is configured, use resolvectl:
resolvectl status eth0— shows servers, domains, and protocols configuredsudo resolvectl statistics— shows cache hits/misses
Hit me up on the fediverse if you run into any issues.
-
Fancy, like automatically updating container images (❗️), and basic, like restarting the container when the system boots. ↩︎