systemd-networkd
can be used to replace the existing networking system on Raspbian.
How can I use it for general purposes for networking like DHCP server, name resolution, link-local addresses, mDNS and so on?
systemd-networkd
can be used to replace the existing networking system on Raspbian.
How can I use it for general purposes for networking like DHCP server, name resolution, link-local addresses, mDNS and so on?
Tested on a Raspberry Pi 4B with
Raspbian Buster Lite 2020-02-13 updated on 2020-05-05.
For reference I use a fresh flashed SD Card with the tested version. Updates done with sudo apt update && sudo apt full-upgrade && sudo reboot
.
Here you will find the last tested revision for Raspbian Stretch Lite.
Using systemd-networkd
instead of default dhcpcd
it is not meaningful in all cases.
networkd is a small and lean service to configure network interfaces, designed mostly for server use cases in a world with hotplugged and virtualized networking. Its configuration is similar in spirit and abstraction level to ifupdown, but you don't need any extra packages to configure bridges, bonds, vlan etc. It is not very suitable for managing WLANs yet; NetworkManager is still much more appropriate for such Desktop use cases. (5)
But for a RasPi laying near by a TV or amplifier and doing its work 24/7 for streaming audio or video or for a camera etc., systemd-networkd
is a good choice.
But you have to do a complete switch. There is no way to mix up with Debian networking
and/or dhcpcd
.
For this tutorial I assume you have setup an installation from the image with a network connection either wired (works out of the box) or using a wireless connection so you can connect to it with ssh
but haven't done any further configuration.
Those who have already read the details and know how it works and only want to quick enable systemd-networkd will just do this here. But don't forget to configure the network interfaces with files in /etc/systemd/network/
.
Please read at least the "♦ Abstract" section above and make a backup of your running system if you modify it!
# deinstall classic networking
pi@raspberrypi:~ $ sudo -Es # if not already done
root@raspberrypi:~ # systemctl daemon-reload
root@raspberrypi:~ # systemctl disable --now ifupdown dhcpcd dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog
root@raspberrypi:~ # apt --autoremove purge ifupdown dhcpcd dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog
root@raspberrypi:~ # rm -r /etc/network /etc/dhcp
setup/enable systemd-resolved and systemd-networkd
root@raspberrypi:~ # systemctl disable --now avahi-daemon libnss-mdns
root@raspberrypi:~ # apt --autoremove purge avahi-daemon
root@raspberrypi:~ # apt install libnss-resolve
root@raspberrypi:~ # ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
root@raspberrypi:~ # apt-mark hold avahi-daemon dhcpcd dhcpcd5 ifupdown isc-dhcp-client isc-dhcp-common libnss-mdns openresolv raspberrypi-net-mods rsyslog
root@raspberrypi:~ # systemctl enable systemd-networkd.service systemd-resolved.service
root@raspberrypi:~ # exit
pi@raspberrypi:~ $
Return to your setup.
I will have attention to a headless installation only with ssh
. If you are also headless, double check typos or so otherwise you are lost with a broken connection. Deinstalling services does not effect the current network connection as long as you don't restart or reboot the network. So only do it if you are sure to have finished all needed configuration to have a working network.
First enable systemd-networkd by following section "♦ Quick Step". Then come back here.
If you are connected wired then create this interface file but with only one option enabled (uncommented). Most common is to use DHCP.
pi@raspberrypi:~ $ sudo -Es # if not already done
root@raspberrypi:~ # cat > /etc/systemd/network/04-wired.network <<EOF
[Match]
Name=e*
[Network]
Uncomment only one option block
Option: using a DHCP server and multicast DNS
LLMNR=no
LinkLocalAddressing=no
MulticastDNS=yes
DHCP=ipv4
Option: using link-local ip addresses and multicast DNS
#LLMNR=no
#LinkLocalAddressing=yes
#MulticastDNS=yes
Option: using static ip address and multicast DNS
(example, use your settings)
#Address=192.168.50.60/24
#Gateway=192.168.50.1
#DNS=84.200.69.80 1.1.1.1
#MulticastDNS=yes
EOF
Reboot.
If you connect using the ip address it is possible that this has also changed so you have to search for the new ip address.
I will have attention to a headless installation only with ssh
. If you are also headless, double check typos or so otherwise you are lost with a broken connection. Deinstalling services does not effect the current network connection as long as you don't restart or reboot the network. So only do it if you are sure to have finished all needed configuration to have a working network.
First enable systemd-networkd by following section ♦ Quick Step. Then come back here.
Create this file for wpa_supplicant with your settings for country=
, ssid=
and psk=
:
pi@raspberrypi:~ $ sudo -Es # if not already done
root@raspberrypi:~ # cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
country=DE
ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev
update_config=1
p2p_disabled=1
network={
ssid="TestNet"
psk="testingPassword"
}
EOF
root@raspberrypi: ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
root@raspberrypi: ~# systemctl disable wpa_supplicant.service
root@raspberrypi: ~# systemctl enable wpa_supplicant@wlan0.service
root@raspberrypi: ~# rfkill unblock wlan
Create an interface file with only one option enabled (uncommented). Most common is to use DHCP.
root@raspberrypi:~ # cat > /etc/systemd/network/08-wifi.network <<EOF
[Match]
Name=wl*
[Network]
Uncomment only one option block
Option: using a DHCP server and multicast DNS
LLMNR=no
LinkLocalAddressing=no
MulticastDNS=yes
DHCP=ipv4
Option: using link-local ip addresses and multicast DNS
#LLMNR=no
#LinkLocalAddressing=yes
#MulticastDNS=yes
Option: using static ip address and multicast DNS
(example, use your settings)
#Address=192.168.50.61/24
#Gateway=192.168.50.1
#DNS=84.200.69.80 1.1.1.1
#MulticastDNS=yes
EOF
Reboot.
If you connect using the ip address it is possible that this has also changed so you have to search for the new ip address.
This is a detailed setup that you also have in short in section "♦ Quick Step".
To simplify commands we will work as root:
pi@raspberrypi:~ $ sudo -Es # if not already done
Deinstall classic Debian networking that is managed with file /etc/network/interfaces
and deinstall default Raspbian dhcpcd
network management.
root@raspberrypi:~ # apt --autoremove purge ifupdown
root@raspberrypi:~ # rm -r /etc/network
root@raspberrypi:~ # apt --autoremove purge dhcpcd5
root@raspberrypi:~ # apt --autoremove purge isc-dhcp-client isc-dhcp-common
root@raspberrypi:~ # rm -r /etc/dhcp
root@raspberrypi:~ # apt --autoremove purge rsyslog
We will set this programs to hold so they are not authomatically installed with other programs later and conflict with systemd-networkd.
root@raspberrypi:~ # apt-mark hold ifupdown dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog raspberrypi-net-mods openresolv
And enable systemd-networkd:
root@raspberrypi:~ # systemctl enable systemd-networkd.service
This is a detailed setup that you also have in short in section "♦ Quick Step".
An important part of systemd networking is its network name resolution. systemd-resolved provides name services by Domain Name System (DNS) (including DNSSEC and DNS over TLS), Multicast DNS (mDNS) and Link-Local Multicast Name Resolution (LLMNR).(1)
systemd-resolved provides this to local applications via a D-Bus interface, the resolve NSS service (libnss-resolve
), and a local DNS stub listener on 127.0.0.53 (1), (2). For all three software interfaces there are also traditional services installed which may conflict with systemd-resolved. On my tests I have seen problems in the order of name resolution: long response time depending on the amount of DNS server to use, queries for the .local
domain going to DNS server, no responses to local host names if the internet connection was down and so on. So I will deinstall not needed services instead of only disable them. This should ensure that entries in common used static config files like /etc/nsswitch.conf
will also cleaned up.
At first please follow section ♦ Details to enable systemd-networkd.
Then enable systemd-resolved and configure its three interfaces:
pi@raspberrypi:~ $ sudo -Es # if not already done
root@raspberrypi:~ # systemctl enable systemd-resolved.service
I haven't found any conflicting issues. The D-Bus should be installed by default and running. Check with:
root@raspberrypi:~ # systemctl status dbus.service
There is the avahi service together with the mdns service definitely conflicting, so we have to deinstall them. This will also clean up /etc/nsswitch.conf
:
root@raspberrypi:~ # apt --autoremove purge avahi-daemon
root@raspberrypi:~ # apt-mark hold avahi-daemon
Now install the systemd-resolved software interface:
root@raspberrypi:~ # apt install libnss-resolve
For troubleshooting you may have a look at /etc/nsswitch.conf
. It should contain a line like this:
hosts: files resolve [!UNAVAIL=return] dns
Here we have to symlink /etc/resolv.conf
to the stub listener:
root@raspberrypi:~ # ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Don't Reboot! Before doing that you must have created an interface file for a wired or WiFi connection.
Now you can check the status of name resolution. Depending on your settings it could look similar to this with a wireless connection:
pi@raspberrypi:~ $ resolvectl status
Global
LLMNR setting: yes
MulticastDNS setting: yes
DNSOverTLS setting: no
DNSSEC setting: allow-downgrade
DNSSEC supported: yes
--- snip ---
Link 3 (wlan0)
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
DefaultRoute setting: yes
LLMNR setting: yes
MulticastDNS setting: no
DNSOverTLS setting: no
DNSSEC setting: allow-downgrade
DNSSEC supported: yes
Current DNS Server: 84.200.69.80
DNS Servers: 84.200.69.80
1.1.1.1
Link 2 (eth0)
Current Scopes: none
DefaultRoute setting: no
LLMNR setting: yes
MulticastDNS setting: no
DNSOverTLS setting: no
DNSSEC setting: allow-downgrade
DNSSEC supported: yes
It should be said that there is a known bug. If you get error messages like:
DNSSEC validation failed for question google.com IN A: no-signature
then you hit Sporadic "DNSSEC validation failed" — "no-signature" #12388. You can workaround this with adding option DNSSEC=no
to /etc/systemd/resolved.conf
and reboot to disable DNS record signing.
According to a comment from @lbt there was a bug with the name search option given by the DHCP server. This option completes not full qualified DNS names. For example if you
rpi ~$ ping harley
PING harley.home.hoeft-online.de (192.168.30.121) 56(84) bytes of data.
64 bytes from harley.home.hoeft-online.de (192.168.30.121): icmp_seq=1 ttl=64 time=0.932 ms
--- snip ---
the domain search will complete the DNS name harley
to harley.home.hoeft-online.de
to get the ip address, where the domain home.hoeft-online.de
is given by the DHCP-server (received together with the dynamic ip address). According to https://superuser.com/questions/1490670/does-systemd-networkd-systemd-resolved-add-search-domains-specified-in-dhcp there was a problem which was fixed with systemd v243. I have noticed that there was a problem with older systemd versions but was able to find a solution, because I have full access to my own powerful isc-dhcp-server. Here are the settings on a test client to get domain search working as you can see with the ping above:
rpi ~$ systemd --version
systemd 241 (241)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid
rpi ~$ cat /etc/systemd/network/04-wired.network
[Match]
Name=e*
[Network]
LLMNR=no
MulticastDNS=yes
LinkLocalAddressing=no
DHCP=ipv4
[DHCP]
UseDomains=true
rpi ~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 37 2020-12-18 16:52 /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
rpi ~$ cat /etc/resolv.conf
--- snip ---
nameserver 127.0.0.53
options edns0
search home.hoeft-online.de
The search line is received from the DHCP server. The essential is the setting on the ISC DHDP-server. Here the subnet setting from its /etc/dhcp/dhcpd.conf
:
# My settings
subnet 192.168.30.0 netmask 255.255.255.0 {
range 192.168.30.65 192.168.30.126;
option routers 192.168.30.1;
option domain-name "home.hoeft-online.de";
# option domain-search "home.hoeft-online.de";
}
As you can see there are two options available. option domain-search
doesn't work but I successful use option domain-name
. The only restriction is, that you can only give one domain name. It is not possible to search for e.g. home.hoeft-online.de
and hoeft-online.de
.
references:
(1) - archlinux - systemd-resolved
(2) - freedesktop - systemd-resolved — Network Name Resolution manager
(3) - freedesktop - What is D-Bus?
(4) - archlinux - Domain name resolution
(5) - /usr/share/doc/systemd/README.Debian
Thanks @ingo for this guide and the other one to add the AP on the same wifi. Incredibly well written and useful.
I would like to emphase the DNSSEC=allow-downgrade
issue as it took me a week and 3 complete re-install of my PI before I finally understood why I was getting more and more DNS errors, hour after hour to the point I was unable to do an apt update
or apt install
. On my x86 Ubuntu 20.04, resolved.conf
come with DSSEC=no
by default.
This bug seems to be present for quite some time in resolved
: https://github.com/systemd/systemd/issues/10579.
DNSSEC=no
by default even on x86 may be a clue that this is a deep problem not easy to solve what ever the platform is. Probably not related to PI time management.
– Barbudor
Mar 17 '21 at 22:45
systemd-networkd
. Reading your answer again has reminded me that it should be mentioned as an alternative todhcpcd
in some situations. In other words,dhcpcd
would be for most users, andsystemd-networkd
for those with use-cases described in your abstract. Do you agree? – Seamus Sep 03 '20 at 03:49which is needed to wait for a DHCP address before mounting nfs shares.
– lbt Dec 20 '20 at 18:16rsyslog
?! – ankostis Jun 02 '21 at 12:40rsyslog
is redundant information to the systemd journal and waste of storage. This is the reason why Debian suggested at/usr/share/doc/systemd/README.Debian.gz
to remove it: If you enable persistent logging, consider uninstalling rsyslog or any other system-log-daemon, to avoid logging everything twice. – Ingo Jun 21 '21 at 09:00