Systemd — Network Configuration

Linux
Network
Systemd
Published

January 24, 2016

Modified

September 26, 2025

hostnamectl

hostnamectl status                  # view hostname
hostnamectl set-hostname <fqdn>     # set hostname
hostnamectl set-hostname ""         # clear hostname
/etc/hostname                       # hostname configuration file
/etc/hosts                          # may contain FQDN of host (to be resolved without DNS)
dnsdomainname                       # display DNS domain name
domainname                          # (aka. nisdomainname) display NIS domain name
hostname                            # print hostname returned by the gethostname(2) function
hostname -s                         # print hostname cut at the first dot
hostname -f                         # print host FQDN
hostname -d                         # print host domain name

systemd-networkd

Systemd service that manages network configurations:

  • Detects and configures network devices as they appear
ls -l {/etc,/run,/lib}/systemd/network/*.network # network configuration 
networkctl list                                  # list network connections
networkctl status                                # show IP addresses for interfaces

Persistently enable the service:

# eventually prevent NetworkManager [1] from controlling the network interface:
systemctl disable --now NetworkManager
systemctl mask NetworkManager
# enable systemd-networkd
systemctl enable --now systemd-networkd

Debugging:

# execute with debugging in foreground
SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd   
# Permanent by drop-in configuration
mkdir /etc/systemd/system/systemd-networkd.service.d/
echo -e "[Service]\nEnvironment=SYSTEMD_LOG_LEVEL=debug" \
        > /etc/systemd/system/systemd-networkd.service.d/10-debug.conf 
systemctl daemon-reload && systemctl restart systemd-networkd

Predictable interface names

Prefix en Ethernet wl WLAN with following types:

o<index>                                                         on-board device index number
s<slot>[f<function>][d<dev_id>]                                  hotplug slot index number
x<MAC>                                                           MAC address
p<bus>s<slot>[f<function>][d<dev_id>]                            PCI geographical location
p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>] USB port number chain

Cf. /lib/udev/rules.d/80-net-setup-link.rules, cf. systemd.link

udevadm info -e | grep -A 9 ^P.*en[sop]          # dump udev database and grep for ethernet
udevadm test /sys/class/net/* 2>&- | grep ID_NET_NAME_
## -- .link file are used to rename an interface -- ##
ls -l {/etc,/run,/lib}/systemd/network/*.link    # list link configuration files
ip -o -4 link                                    # show link state

Network Interfaces

Configure the network, cf. systemd.network

Skeleton for a dynamic IP-address

[Match]
Name=                              # device name (e.g en*)

[Network]
DHCP={yes,no,ipv4,ipv6}            # enable DHCP

Skeleton for a static IP-address

[Match]
Name=              # device name (e.g en*)

[Network]
Address=           # IP address, CIDR notation
Gateway=           # IP address
DNS=               # is a DNS server address (multiples possibel)
Domains=           # a list of the domains used for DNS host name resolution

Wired & Wireless in Parallel

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

[Network]
DHCP=ipv4

[DHCP]
RouteMetric=10
EOF 
cat <<EOF | sudo tee /etc/systemd/network/25-wireless.network
[Match]
Name=wl*

[Network]
DHCP=ipv4

[DHCP]
RouteMetric=20
EOF

Note that the wireless interface needs to be connected by another service like iwd.

systemd-resolved service is required if DNS entries are specified in .network files

VLANs

File Purpose
10-vlan101.netdev Creates the VLAN device
10-eth4.network Attaches VLAN to physical NIC
20-vlan101.network Configures IP/DHCP on VLAN
cat > /etc/systemd/network/10-vlan101.netdev <<EOF
[NetDev]
Name=vlan101
Kind=vlan

[VLAN]
Id=100
EOF

cat > /etc/systemd/network/20-vlan101.network <<EOF
[Match]
Name=vlan101

[Network]
Address=10.10.65.80/26
Gateway=10.10.65.65
EOF

cat > /etc/systemd/network/10-eth0.network <<EOF
[Match]
Name=eth0

[Network]
VLAN=vlan101
EOF
# re-configure the network after changes in /etc/systemd/network
systemctl restart systemd-networkd

# check interface and IP
networkctl status vlan101

systemd-resolved

Provides network name resolution…

  • …supports DNSSEC and DNS over TLS
  • glibc NSS interface plugin nss-resolve
systemctl enable --now systemd-resolved # start the service daemon
systemd-resolve --status
/etc/systemd/resolved.conf              # conf. file
/etc/systemd/resolved.conf.d/*.conf     # drop-in conf. files

Fallback DNS addresses ensure DNS resolution in case no config is present

Provides a local DNS stub listener on IP address 127.0.0.53 on the local loopback interface:

rm /etc/resolv.conf
# redirect glibc NSS conf. file to local stub DNS resolver 
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# operations mode detected automatically depending on existence of this link

Configuration

Temporarily change the DNS server configuration:

  • LINK specifies the network interface, get the name from resolvectl status or ip addr
  • SERVER specifies the IP address of a DNS server i.e. 1.1.1.1
systemd-resolve -i LINK --set-dns=SERVER
# or
sudo resolvectl dns LINK SERVER

Configure a custom list of DNS resolvers, and enable DNSSEC

mkdir /etc/systemd/resolved.conf.d
# use a drop in .conf file for the Quad9 primary DNS resolvers 
cat > /etc/systemd/resolved.conf.d/dns.conf <<EOF
[Resolve]
DNS=9.9.9.9 149.112.112.112
EOF
# if supported by the DNS resolvers, enforce DNSSEC validation
cat > /etc/systemd/resolved.conf.d/dnssec.conf <<EOF
[Resolve]
DNSSEC=true
EOF
# if supported by the DNS resolver, attempt to use DNS over TLS
cat > /etc/systemd/resolved.conf.d/dot.conf <<EOF
[Resolve]
DNSOverTLS=opportunistic
EOF

systemd-resolved currently only supports opportunistic DNS over TLS resolution

  • Resolver tries resolution using DoT before fall back to traditional DNS (allowing for downgrade attacks)
  • Eventually another option will be added strict to prevent fallback

DNS server certificates are not checked making systemd-resolved vulnerable to man-in-the-middle attacks

resolvectl

resolvectl status                       # check service status
resolvectl query <ip|name>              # query DNS records
resolvectl statistics                   # show DNS cache stats

Enable debugging and follow the logs:

resolvectl log-level debug             
journalctl -fu systemd-resolved
# disable debugging
resolvectl log-level info

systemd-timesyncd

Types of clocks:

  • RTC (Real-Time Clock) aka hardware clock runs on battery when the machine is powered off (unplugged)
    • Uses local time (in current time zone)
    • Or UTC (Coordinated Universal Time) with an time zone dependent offset
  • SC (Software Clock) aka system clock
    • Maintained by the OS kernel during run-time driven by a timer interrupt
    • Initialized on boot using RTC as reference.
timedatectl                                 # show time and time zone configuration
timedatectl set-time YYYY-MM-DD             # change the current date
timedatectl set-time HH:MM:SS               # change the current time
timedatectl list-timezones                  # list available time zones
timedatectl set-timezone <zone>             # set a given time zone, e.g. Europe/Berlin
grep ^Servers /etc/systemd/timesyncd.conf   # list time servers 
timedatectl set-ntp true                    # enable NTP
timedatectl set-local-rtc 0                 # RTC in UTC mode
timedatectl set-local-rtc 1                 # RTC in locel time mode
systemctl start systemd-timesyncd           # start the time sync daemon 
systemctl enable systemd-timesyncd          # make the time sync daemon boot persistant 

Low-level administration tool

locale                                      # print locale settings
hwclock                                     # manipulate the hardware clock
/etc/adjtime                                # state file for hwclock
/usr/share/zoneinfo                         # time zone database