18

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?

Ingo
  • 42,107
  • 20
  • 85
  • 197

2 Answers2

41

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.


♦ Abstract

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.


♦ Quick Step

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.


♦ Create interface file for a wired connection

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.


♦ Create interface file for a WiFi connection

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.


♦ Details to enable systemd-networkd

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

♦ Details to enable systemd-resolved

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

Check D-Bus software interface

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

Configure NSS software interface

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

Configure DNS stub listener interface

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.

Check name resolution

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


♦ Quirks and troubleshooting

Problem with DNSSEC

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.

DNS-name domain search trouble

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

Ingo
  • 42,107
  • 20
  • 85
  • 197
  • 1
    This is a very good "how-to" for systemd-networkd. Reading your answer again has reminded me that it should be mentioned as an alternative to dhcpcd in some situations. In other words, dhcpcd would be for most users, and systemd-networkd for those with use-cases described in your abstract. Do you agree? – Seamus Sep 03 '20 at 03:49
  • 1
    @Seamus Yes, I completely agree. Except with mobile using you have much more possibilities to do sophisticated things out of the box by just configuring it, or well integrated like VPN with wireguard, also just configurable by systemd-networkd. All this is well structured and straight forward without the need to fit different helpers together and without possible problems on its (different?) APis. – Ingo Sep 03 '20 at 09:08
  • I think this would make an excellent page on your github site :) – Seamus Sep 03 '20 at 21:31
  • I also needed to enable:
     systemctl enable systemd-networkd-wait-online.service
    
    

    which is needed to wait for a DHCP address before mounting nfs shares.

    – lbt Dec 20 '20 at 18:16
  • @lbt Just do it. What's the problem? – Ingo Dec 20 '20 at 18:22
  • Additionally, before systemd v243, any 'search' options in resolv.conf are kinda broken and need a Domains= entry in the [Network] section. See https://superuser.com/questions/1490670/does-systemd-networkd-systemd-resolved-add-search-domains-specified-in-dhcp No problem at all @Ingo - just adding this info as it may help others - you may even want to include it in your excellent guide. – lbt Dec 20 '20 at 18:53
  • @lbt I noticed with older systemd versions some times ago that there was a problem, but it doesn't hurt me, because I had found a solution. I have documented it in my answer at the end in section DNS-name domain search trouble. – Ingo Dec 20 '20 at 23:49
  • The only thing missing is IPv6 configuration – Jaromanda X Feb 06 '21 at 02:12
  • 1
    @JaromandaX Yes, you are right. Haven't thought of it but will make it next time now. – Ingo Feb 06 '21 at 20:34
  • @JaromandaX By the way, you will find a testing, more for my own documentation, at How to use IPv6 internet addresses on Linux with systemd-networkd. – Ingo Feb 07 '21 at 22:00
  • 1
    thanks @Ingo - lots of good info there – Jaromanda X Feb 07 '21 at 22:17
  • 1
    Hi - name resolution broke, and apt install libnss-resolve failed. My hack fix was to add a couple of addresses to hosts. But I think it needs to be pre-downloaded for this to work well – mksteve Apr 07 '21 at 08:37
  • @Ingo this is a fantastic guide, and it works beautifully on a RPi0W! One question thoug: you strongly linked ap@wlan0 and wlan0, such that we cannot put down the hostap without taking the wlan0 down with it. Would it be possible to have a version where both can cohabit? This is useful if you want the AP to be UP for initial config (and loss of STA wifi if you move the device), but then tear it down when the RPI is configured. – Gui13 May 01 '21 at 11:39
  • 1
    But why remove rsyslog?! – ankostis Jun 02 '21 at 12:40
  • 1
    @ankostis rsyslog 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
  • In the quick setup, how do you not loose your SSH connection when running: "systemctl disable --now...."? – MethodMan Aug 01 '21 at 05:28
  • 1
    @MatthewRedmond Seems I forgot to support the headless installation over time :-/ I will have a look at it. Thanks for the hint. – Ingo Aug 07 '21 at 19:10
  • On quick guide, the step apt install libnss-resolve fails because at this point the system can no longer resolve dns – Narshe Feb 06 '22 at 09:19
2

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.

Seamus
  • 21,900
  • 3
  • 33
  • 70
Barbudor
  • 41
  • 4
  • Good comment - Do you know if this issue is triggered by the RPi's rather imprecise SNTP time-keeping mechanism - or is it something else? – Seamus Mar 16 '21 at 21:30
  • @Seamus No idea. But the fact that the issue have been opened for 2.5 years and Ubuntu decided to package systemd-resoved with 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