100% systemd network configuration with Debian GNU/Linux

100% systemd network configuration with Debian GNU/Linux

This article will show you how to set up a network configuration completely controlled by systemd.
systemd©

Here we want to use a network configuration completely controlled by systemd.

The objective is to benefit from a modern configuration that is totally unified and independent of the Lunux distribution used.

This evolution of the network configuration concerns 3 parts:

  • The management of the network interface
  • The resolution of domain names with the DNS (Domain Name System) protocol
  • Clock synchronization with the NTP (Network Time Protocol) protocol

Setting up Systemd-Networkd

If you are doing this remotely, please ensure that you can get to the physical machine in order to fix things should something go wrong. You can’t work remotely on a machine whose networking isn’t.

If you currently have a network running using /etc/network/, move the interfaces file there to another name so that it won’t be used after systemd-networkd is set up:

mv /etc/network/interfaces /etc/network/interfaces.save

You may also need to move /etc/network/network.d if you nave anything defined there:

mv /etc/network/interfaces.d /etc/network/interfaces.d.save

Name of the network interface

Liste des interfaces avec la commande ip

ip addr ls
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 2c:cf:67:27:2f:97 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.42/24 metric 1024 brd 172.16.0.255 scope global dynamic noprefixroute eth0
       valid_lft 80275sec preferred_lft 80275sec
    inet6 fe80::2d0f:ed2a:43f9:cbea/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

La commande udevadm donne le résultat de la traduction du nom des périphériques réseau en parcourant le dossier /sys/class/net/

udevadm info --path /sys/class/net/eth0
P: /devices/platform/axi/1000120000.pcie/1f00100000.ethernet/net/eth0
M: eth0
R: 0
U: net
I: 2

What is the status of the systemd-networkd service?

The systemd initialization manager provides a specific service for controlling network interfaces: systemd-networkd.

We check the status of the service and see that it is disabled.

systemctl status systemd-networkd
○ systemd-networkd.service - Network Configuration
     Loaded: loaded (/lib/systemd/system/systemd-networkd.service; disabled; preset: enabled)
     Active: inactive (dead)
TriggeredBy: ○ systemd-networkd.socket
       Docs: man:systemd-networkd.service(8)
             man:org.freedesktop.network1(5)
   FD Store: 0 (limit: 512)

It is line 3 which indicates the status of the service: inactive

What are the new network configuration instructions to put in place?

All configuration files are generally stored in /etc/systemd/network. Note that in the configuration files, case is important. Match is not the same as match.

A new configuration file must be created for each interface to be supported.

  • lo local loop interface

The configuration file is named /etc/systemd/network/01-lo.network.

cat << EOF | sudo tee /etc/systemd/network/01-lo.network
[Match]
Name=lo

[Network]
LinkLocalAddressing=ipv6
Address=127.0.0.1/8
EOF
  • Ethernet interface eth0

The configuration file is named /etc/systemd/network/20-wired.network.

cat << EOF | sudo tee /etc/systemd/network/20-wired.network
[Match]
Name=eth0

[Network]
DHCP=ipv4

[DHCP]
UseDNS=no
EOF

put UseDNS=no in DHCP section if you don’t want to used DNS configuration of DHCP server.

Connecting to WiFi network using systemd and wpa-supplicant

In order to connect to the WiFi network a proper configuration needs to be provided. This part shows how to do this using the wpa_supplicant tool and the systemd service manager.

  • First, create the /etc/wpa_supplicant directory and the /etc/wpa_supplicant/wpa_supplicant-wlan0.conf file with the following configuration:
#file: "/etc/wpa_supplicant/wpa_supplicant-wlan0.conf"
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1

network={
  ssid="<NETWORK_SSID>"
  psk="<NETWORK_PASSWORD>"
  key_mgmt=WPA-PSK
  proto=WPA2
  pairwise=CCMP TKIP
  group=CCMP TKIP
  scan_ssid=1
}

The network in the example is protected with the WPA2 standard and requires a password. The and fields need to be changed according to the existing network configuration.

  • Create the /etc/systemd/network/30-wlan.network file:
cat << EOF | sudo tee /etc/systemd/network/30-wlan.network
[Match]
Name=wlan0
Type=wlan
WLANInterfaceType=station

[Network]
DHCP=ipv4

[DHCP]
UseDNS=no
EOF
  • Enable the wpa_service for the wlan0 interface:
systemctl enable wpa_supplicant@wlan0.service
  • Restart the systemd-networkd and wpa_supplicant services:
systemctl restart systemd-networkd.service
systemctl restart wpa_supplicant@wlan0.service
  • And check the interface status:
ip a

The wireless network (wlan0) should now be enabled and configured after each system boot:

3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 2c:cf:67:27:2f:98 brd ff:ff:ff:ff:ff:ff
    inet 10.0.1.108/24 metric 1024 brd 10.0.1.255 scope global dynamic wlan0
       valid_lft 77448sec preferred_lft 77448sec
    inet6 fd38:6e5a:d9c:3748:2ecf:67ff:fe27:2f98/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 1702sec preferred_lft 1702sec
    inet6 fe80::2ecf:67ff:fe27:2f98/64 scope link 
       valid_lft forever preferred_lft forever

Enable the systemd-networkd service

As it is a systemd service, we call the systemctl command.

sudo systemctl enable systemd-networkd

Finalize the new management of network interfaces

The previous step of activating the systemd-networkd service is not enough to make configuration management of network interfaces effective.

To finalize the piloting change, we must remove the ifupdown package to avoid conflicts in interface support.

sudo apt purge ifupdown

Finally, we can restart the server and verify that the network interface configuration directives have been executed.

view network configuration status

The ip command is certainly the most immediate way to access network configuration information.

We start with the list of addresses which shows that the eth0 interface has obtained the IPv4 and IPv6 network layer addresses.

ip addr ls
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 2c:cf:67:27:2f:97 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.42/24 brd 172.16.0.255 scope global dynamic noprefixroute eth0
       valid_lft 83718sec preferred_lft 83718sec
    inet6 fe80::2d0f:ed2a:43f9:cbea/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

We complete with the routing tables which show that a default gateway address is in place for IPv4 and for IPv6.

In both cases it is the default keyword that must be searched for.

ip route ls
default via 172.16.0.1 dev eth0 proto dhcp src 172.16.0.42 metric 100 
default via 172.16.0.1 dev eth0 proto dhcp src 172.16.0.42 metric 1024 
ip -6 route ls
fd04:651f:6241::/64 via fe80::14a2:4487:9b64:9e15 dev wlan0 proto ra metric 1024 expires 1704sec pref medium
fd38:6e5a:d9c:3748::/64 dev wlan0 proto ra metric 1024 expires 1704sec pref medium
fe80::/64 dev wlan0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 1024 pref medium

As we have activated a service driven by systemd, it makes sense to be interested in the state of this service.

systemctl status systemd-networkd
● systemd-networkd.service - Network Configuration
     Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-05-24 11:54:53 CEST; 23h ago
TriggeredBy: ● systemd-networkd.socket
       Docs: man:systemd-networkd.service(8)
             man:org.freedesktop.network1(5)
   Main PID: 368 (systemd-network)
     Status: "Processing requests..."
      Tasks: 1 (limit: 9252)
     Memory: 4.5M
        CPU: 932ms
     CGroup: /system.slice/systemd-networkd.service
             └─368 /lib/systemd/systemd-networkd

Finally, systemd provides a command line management tool called networkctl which allows, among other things, to consult the status of the network configuration.

networkctl
IDX LINK            TYPE      OPERATIONAL SETUP     
  1 lo              loopback  carrier     configured
  2 eth0            ether     routable    configured

Domain Name resolution

Now that we know that IPv4 and IPv6 packets are routable from the network interface, we must take care of the correspondence between domain names and IP addresses.

Again, systemd provides a service called systemd-resolved which is used to define the IPv4 and/or IPv6 addresses of hosts that support DNS service queries based on the various suggestions made by auto-configuration tools such as DHCP for IPv4 or SLAAC for IPv6.

Systemd-resolved service status

If we take the same approach as for the network interface, we fail…

systemctl status systemd-resolved
Unit systemd-resolved.service could not be found.

In fact, this service is provided by a package that is not installed on our system. We therefore proceed with its installation to move forward with the configuration.

  • Install systemd-resolved Debian package
sudo apt install systemd-resolved

We are recommended to restart the system so that the combination of the two services systemd-networkd and systemd-resolved produces a coherent configuration.

We come to the subject of the question: the state of the service.

systemctl status systemd-resolved.service
● systemd-resolved.service - Network Name Resolution
     Loaded: loaded (/lib/systemd/system/systemd-resolved.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-05-24 11:54:54 CEST; 1 day 1h ago
       Docs: man:systemd-resolved.service(8)
             man:org.freedesktop.resolve1(5)
             https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
             https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
   Main PID: 614 (systemd-resolve)
     Status: "Processing requests..."
      Tasks: 1 (limit: 9252)
     Memory: 8.3M
        CPU: 994ms
     CGroup: /system.slice/systemd-resolved.service
             └─614 /lib/systemd/systemd-resolved

May 24 11:54:54 tars systemd[1]: Starting systemd-resolved.service - Network Name Resolution..

Line 3 shows the service is up and running.

  • Create the folder /etc/systemd/resolved.conf.d/
mkdir /etc/systemd/resolved.conf.d
  • Create the dns_servers.conf file in /etc/systemd/resolved.conf.d/ folder
cat << EOF | sudo tee /etc/systemd/resolved.conf.d/dns_servers.conf
[Resolve]
DNS=9.9.9.9
FallbackDNS=149.112.112.112
#DNSSEC=yes
#DNSOverTLS=allow-downgrade
Domains=~.
EOF
  • Create the link below (resolv.conf will be updated by systemd-resolved)
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
  • Restart systemd-resolved service
    systemctl restart systemd-resolved.service
    

Just as with the configuration of the network interface, we have a specific tool for managing the resolution of domain names: resolvectl.

resolvectl
Global
          Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
   resolv.conf mode: stub
 Current DNS Server: 9.9.9.9
         DNS Servers 9.9.9.9
Fallback DNS Servers 149.112.112.112
          DNS Domain ~.

Link 2 (eth0)
Current Scopes: LLMNR/IPv4 LLMNR/IPv6
     Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

Link 3 (wlan0)
Current Scopes: LLMNR/IPv4 LLMNR/IPv6
     Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

The contents of my /etc/resolv.conf now

# file: "/etc/resolv.conf"
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
#
# This file might be symlinked as /etc/resolv.conf. If you're looking at
# /etc/resolv.conf and seeing this text, you have followed the symlink.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0 trust-ad
search .

Test DNS resolution

We use the host command followed by a host name to display the results.

host quad9.net
quad9.net has address 216.21.3.77
quad9.net has IPv6 address 2620:0:871:9000::77
quad9.net mail is handled by 5 mx1.quad9.net.
quad9.net mail is handled by 10 mx4.quad9.net.
quad9.net mail is handled by 20 mx2.quad9.net.

We obtain the IPv4 and IPv6 addresses corresponding to the name quad9.net as well as the list of email servers in the domain.

This step can be completed by displaying the address of the resolver used.

host -v quad9.net
Trying "quad9.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15499
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;quad9.net.			IN	A

;; ANSWER SECTION:
quad9.net.		960	IN	A	216.21.3.77

Received 43 bytes from 127.0.0.53#53 in 0 ms
Trying "quad9.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36098
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;quad9.net.			IN	AAAA

;; ANSWER SECTION:
quad9.net.		1018	IN	AAAA	2620:0:871:9000::77

Received 55 bytes from 127.0.0.53#53 in 0 ms
Trying "quad9.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25116
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;quad9.net.			IN	MX

;; ANSWER SECTION:
quad9.net.		118	IN	MX	5 mx1.quad9.net.
quad9.net.		118	IN	MX	10 mx4.quad9.net.
quad9.net.		118	IN	MX	20 mx2.quad9.net.

Received 87 bytes from 127.0.0.53#53 in 0 ms

The results of this last command show that the address used to relay DNS requests is: 127.0.0.53.

This address is defined in the DNS resolver IP address designation history file.

grep -Ev '(^$|^#)' /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search .

Time synchronization

The systemd boot manager provides a dedicated service called: systemd-timesyncd

Systemd-timesyncd service status

systemctl status systemd-timesyncd
● systemd-timesyncd.service - Network Time Synchronization
     Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-05-24 11:54:54 CEST; 1 day 1h ago
       Docs: man:systemd-timesyncd.service(8)
   Main PID: 616 (systemd-timesyn)
     Status: "Contacted time server 82.223.114.98:123 (0.debian.pool.ntp.org)."
      Tasks: 2 (limit: 9252)
     Memory: 2.7M
        CPU: 307ms
     CGroup: /system.slice/systemd-timesyncd.service
             └─616 /lib/systemd/systemd-timesyncd

We see from the information given on line 3 that the service is active.

The following lines give the IPv4 address of the reference NTP server used to synchronize the server clock.

View time at system level

Just as for configuring network interfaces and resolving names, we have an ad hoc command: timedatectl.

timedatectl
               Local time: Sat 2024-05-25 13:22:25 CEST
           Universal time: Sat 2024-05-25 11:22:25 UTC
                 RTC time: Sat 2024-05-25 11:22:25
                Time zone: Europe/Paris (CEST, +0200)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Line 6 shows that the NTP protocol is used to set the system time.

Conclusion

Once we have verified that all three services are up and running and have been able to test how they work, we have a properly configured system with systemd.

References

This part of systemd is documented in those various manual pages:

Share it :