Network mit Systemd

Zu den neuen Möglichkeiten von systemd zählt auch einiges, was den Bereich Netzwerk betrifft.

Hostname setzen

Gewöhnlich setzen wir bei Distributionen ohne Systemd den Full Qualified Domain Name (FQDN) eines Hosts so:

hostname myHost
hostname > /etc/hostname
echo "127.0.1.1  myHost.dom1.test  myHost" >>  /etc/hosts

Mit Systemd steht darüberhinaus das Kommando hostnamectl zur Verfügung, mit dem u.a. auch der FQDN gesetzt werden kann:

root@ubu20:~# hostnamectl set-hostname u20lts.domX.abc
root@ubu20:~#
root@ubu20:~# hostnamectl
Static hostname: u20lts.domX.abc
        Icon name: computer-vm
        Chassis: vm
        Machine ID: 027963d558754fefb9521769340c4d60
        Boot ID: 05625a14ad744f78a8b8e6e64431832b
    Virtualization: oracle
Operating System: Ubuntu 20.04.1 LTS
            Kernel: Linux 5.4.0-42-generic
    Architecture: x86-64
root@ubu20:~#
root@ubu20:~# hostname -f
u20lts.domX.abc
root@ubu20:~#
root@ubu20:~# ping -c3 u20lts.domX.abc
PING u20lts.domX.abc (10.0.2.15) 56(84) Bytes Daten.
64 Bytes von u20lts.domX.abc (10.0.2.15): icmp_seq=1 ttl=64 Zeit=0.232 ms
64 Bytes von u20lts.domX.abc (10.0.2.15): icmp_seq=2 ttl=64 Zeit=0.051 ms
64 Bytes von u20lts.domX.abc (10.0.2.15): icmp_seq=3 ttl=64 Zeit=0.098 ms

--- u20lts.domX.abc ping statistics ---
3 Pakete übertragen, 3 empfangen, 0% Paketverlust, Zeit 2029ms
rtt min/avg/max/mdev = 0.051/0.127/0.232/0.076 ms
root@ubu20:~#

Damit das funktioniert, müssen allerdings Services laufen:

root@ubu20:~# systemctl list-unit-files | grep host
dbus-org.freedesktop.hostname1.service     static          enabled
systemd-hostnamed.service                  static          enabled
root@ubu20:~#

Dazu ein paar Hinweise:

  • Der neue Hostname wird mitsamt FQDN in die Datei /etc/hostname geschrieben, die Datei /etc/hosts wird hierbei nicht verwaltet! So verblieb bei Ubuntu 10.04 der bei der Erstinstallation vergebene Name „ubu20“ in der Datei /etc/hosts (127.0.1.1    ubu20), was eine fehlerhafte Doppelbenennung bedeutet. Diese Zeile muss entfernt werden.

  • Die lokale Namensauflösung des neu gesetzten Hostnames geschieht gegen die IP-Adresse der Ethernet-Schnittstelle, nicht mehr gegen 127.0.1.1 oder 127.0.0.1.

  • Der Dienst hostname.service ist bei Debian 10 „masked“ und lässt sich auch nicht ohne weiteres aktivieren, weshalb dann auch der FQDN nicht auf diese Art gesetzt werden kann.

IP-Adressierung und Routing

Distribution: Debian 10, Codename Buster

Um die Adressierung und das Definieren von Weiterleitungsregeln kümmert sich systemd-networkd, um die Namensauflösung dann ein zweiter Daemon systemd-resolved. Hier geht es erst einmal nur um die die grundsätzliche Adressierung und das Routing.

Konfigurationsdatei anlegen

Unterhalb /etc/systemd/network/ werden Konfigurationsdateien erwartet, die auf .network enden, im Beispiel heißt unsere Datei nic1.network. Die Configs sind wie die bekannten init-Dateien aufgebaut.

Im Abschnitt [Match] muss der übereinstimmende Name der Netzwerkkarte, so wie er bei ip link auftaucht, hinterlegt werden. Als robustere Alternative kann die Netzwerkkarte auch über die MAC-Adresse spezifiziert werden.

Im Abschnitt [Network] wird dann die eigentliche Konfiguration vorgenommen. Siehe dazu diese Datei /etc/systemd/network/nic1.network:

[Match]
Name=enp0s3
# Alternativ:
#MACAddress=1a:2b:3c:4d:5e:6f

[Network]
# Für statische Adressierung:
Address=10.21.21.235/24
Gateway=10.21.21.1
# Alternativ bei dynamischer Adressierung:
#DHCP=ipv4

In Sachen Namensauflösung könnten wir in dieser schnittstellenspezifischen Konfiguration zugleich auch die DNS-Clienteinstellungen vornehmen (typischerweise DNS=8.8.8.8 und Domains=dom1.test), was dann als zusätzlich laufenden Daemon systemd-resolved erforderlich macht. Siehe dazu unter https://www.freedesktop.org/software/systemd/man/systemd.network.html#DNS=

Wir aber wollen DNS weiter unten im Zusammenhang mit der globalen Konfigurationsdatei /etc/systemd/resolved.conf einrichten.

Alte Konfigurationsdatei schrumpfen

Damit nun nicht zwei Systeme versuchen, die Adressierung vorzunehmen, ist es wichtig, die neuerdings vom Systemd verwalteten Schnittstellen aus der Debian-Konfigurationsdatei /etc/network/interfaces herauszunehmen, so dass nur ‚lo‘ erhalten bleibt:

root@dsrv ~# ifdown enp0s3
root@dsrv ~#
root@dsrv ~# vi /etc/network/interfaces
root@dsrv ~# grep -Ev '^\s*#|^$' /etc/network/interfaces
auto lo
iface lo inet loopback
root@dsrv ~#

Service aktivieren und starten/testen

Fehlt nur noch das Aktivieren und Starten des Daemons, dann ist der erste Teil geschafft:

root@dsrv ~# systemctl enable systemd-networkd
Created symlink /etc/systemd/system/dbus-org.freedesktop.network1.service → /lib/systemd/system/systemd-networkd.service.
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.
Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.
Created symlink /etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service → /lib/systemd/system/systemd  networkd-wait-online.service.
root@dsrv ~#
root@dsrv ~# systemctl start systemd-networkd

Mit ip addr und ìp route können wir nachschauen, ob die neue Adressierung vorhanden ist.

Namensauflösung mit Systemd

Wie oben erwähnt, dient hierzu ein zweiter Daemon namens systemd-resolved.

Wir editieren am besten die globale, bereits vorhandene Datei /etc/systemd/resolved.conf, so dass im Endeffekt folgende Zeilen aktiviert sind:

[Resolve]
DNS=194.25.2.129 8.8.8.8
Domains=dom1.test
Cache=yes

Noch liegt aber eine normale resolv.conf vor, die wir entfernen bzw. umbenennen müssen. Danach kann der Daemon gestartet und ein Symlink auf die neue, unter /run/systemd/resolve/ liegende Datei erzeugt werden:

root@dsrv ~# ls -l /etc/resolv.conf
-rw-r--r-- 1 root root 23 Aug 12 15:23 /etc/resolv.conf
root@dsrv ~#
root@dsrv ~# mv /etc/resolv.conf /etc/resolv.conf.old
root@dsrv ~#
root@dsrv ~# systemctl enable systemd-resolved
Created symlink /etc/systemd/system/dbus-org.freedesktop.resolve1.service → /lib/systemd/system/systemd-resolved.service.
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-resolved.service → /lib/systemd/system/systemd-resolved.service.
root@dsrv ~#
root@dsrv ~# systemctl restart systemd-resolved
root@dsrv ~#
root@dsrv ~# ln -s /run/systemd/resolve/resolv.conf /etc
root@dsrv ~#
root@dsrv ~# ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 32 Aug 19 12:01 /etc/resolv.conf -> /run/systemd/resolve/resolv.conf
root@dsrv ~#
root@dsrv ~# cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must 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 194.25.2.129
nameserver 8.8.8.8
search dom1.test
root@dsrv ~#

Und schon läuft auch die Namensauflösung, mit dem Parameter Cache=yes wird systemd zu einem Cache-only Nameserver:

root@dsrv ~# ping -c3 y0o.de
PING y0o.de (173.212.216.166) 56(84) bytes of data.
64 bytes from 88it.de (173.212.216.166): icmp_seq=1 ttl=56 time=20.1 ms
64 bytes from 88it.de (173.212.216.166): icmp_seq=2 ttl=56 time=18.2 ms
64 bytes from 88it.de (173.212.216.166): icmp_seq=3 ttl=56 time=18.7 ms

--- y0o.de ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 6ms
rtt min/avg/max/mdev = 18.218/19.002/20.069/0.789 ms
root@dsrv ~#
root@dsrv ~#
root@dsrv ~# lsof -i:53 -Pn
COMMAND    PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
dnsmasq   1051         dnsmasq    6u  IPv4  26382      0t0  UDP 10.11.22.1:53
dnsmasq   1051         dnsmasq    7u  IPv4  26383      0t0  TCP 10.11.22.1:53 (LISTEN)
systemd-r 2602 systemd-resolve   17u  IPv4  36782      0t0  UDP 127.0.0.53:53
systemd-r 2602 systemd-resolve   18u  IPv4  36783      0t0  TCP 127.0.0.53:53 (LISTEN)
root@dsrv ~#

Troubleshooting

Üblicherweise schleichen sich Syntaxfehler in die Konfigurationsdateien ein (z.B. Leerzeichen anstelle von „=“). Welche es sind, kann dem Logbuch entnommen werden: journalctl -xe | grep -E 'systemd-networkd|systemd-resolved'

Weiterhin kann man sich mittels systemctl --stat=failed einen Überblick verschaffen, welche Systemd-Units Ärger machen.

Außerdem kann es auch Probleme mit anderen Netzwerkverwaltern wie NetworkManager oder connman geben, wenn sie ebenfalls versuchen, diese Schnittstelle zu konfigurieren. Abhilfe schafft die rigerose Deinstallation dieser Netzwerkmanager. Wenn dies aber nicht möglich ist, weil noch andere Schnittstellen damit behandelt werden müssen, bleibt nur dem jeweiligen Manager mitzuteilen, dass er sich hier heraushalten soll. Nach diesem Tutorial gelingt es via udev ganz einfach, dem NetworkManager die Verwaltung der NIC „enp0s3“ zu untersagen. Dazu ist lediglich diese Regeldatei 00-unmanaged-nic.rules anzulegen:

### FILE: /etc/udev/rules.d/00-unmanaged-nic.rules
#
# Interfaces that shouldn't be managed by NetworkManager
#
ACTION=="add", SUBSYSTEM=="net", KERNEL=="enp0s3", ENV{NM_UNMANAGED}="1"

Danach muss udevadm control --reload-rules && udevadm trigger oder ein Reboot ausgeführt werden.