6

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?

11

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:~ # apt --autoremove purge ifupdown dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog
root@raspberrypi:~ # apt-mark hold ifupdown dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog raspberrypi-net-mods openresolv
root@raspberrypi:~ # rm -r /etc/network /etc/dhcp

# setup/enable systemd-resolved and systemd-networkd
root@raspberrypi:~ # apt --autoremove purge avahi-daemon
root@raspberrypi:~ # apt-mark hold avahi-daemon libnss-mdns
root@raspberrypi:~ # apt install libnss-resolve
root@raspberrypi:~ # ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
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

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.


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

| improve this answer | |
  • 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 3 at 3:49
  • @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 3 at 9:08
  • I think this would make an excellent page on your github site :) – Seamus Sep 3 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.