systemd-networkd

systemd-networkd is a system daemon that manages network configurations. It detects and configures network devices as they appear; it can also create virtual network devices. This service can be especially useful to set up complex network configurations for a container managed by systemd-nspawn or for virtual machines. It also works fine on simple connections.

Basic usage

The systemd package is part of the default Arch installation and contains all needed files to operate a wired network. Wireless adapters, covered later in this article, can be set up by services, such as wpa_supplicant or iwd.

Wireless adapter

In order to connect to a wireless network with systemd-networkd, a wireless adapter configured with another application such as WPA supplicant or Iwd is required.

/etc/systemd/network/25-wireless.network

[Match]
Name=wlp2s0
[Network]
DHCP=ipv4

If the wireless adapter has a static IP address, the configuration is the same (except for the interface name) as in a wired adapter.

Wired and wireless adapters on the same machine

This setup will enable a DHCP IP for both a wired and wireless connection making use of the metric directive to allow the kernel to decide on-the-fly which one to use. This way, no connection downtime is observed when the wired connection is unplugged.

The kernel's route metric (same as configured with ip) decides which route to use for outgoing packets, in cases when several match. This will be the case when both wireless and wired devices on the system have active connections. To break the tie, the kernel uses the metric. If one of the connections is terminated, the other automatically wins without there being a gap with nothing configured (ongoing transfers may still not deal with this nicely but that is at a different OSI layer).

Note: The Metric option is for static routes while the RouteMetric option is for setups not using static routes. See systemd.network(5) for more details.

/etc/systemd/network/20-wired.network

[Match]
Name=enp1s0
[Network]
DHCP=ipv4
[DHCP]
RouteMetric=10

/etc/systemd/network/25-wireless.network

[Match]
Name=wlp2s0
[Network]
DHCP=ipv4
[DHCP]
RouteMetric=20

Renaming an interface

Instead of editing udev rules, a .link file can be used to rename an interface. A useful example is to set a predictable interface name for a USB-to-Ethernet adapter based on its MAC address, as those adapters are usually given different names depending on which USB port they are plugged into.

Note: Any user-supplied .linkmust have a lexically earlier file name than the default config 99-default.link in order to be considered at all. For example, name the file 10-ethusb0.link and not ethusb0.link.

Configuration files

Configuration files are located in /usr/lib/systemd/network, the volatile runtime network directory /run/systemd/network and the local administration network directory /etc/systemd/network. Files in /etc/systemd/network have the highest priority.

There are three types of configuration files. They all use a format similar to systemd unit files.

.network files. They will apply a network configuration for a matching device

.netdev files. They will create a virtual network device for a matching environment

.link files. When a network device appears, udev will look for the first matching.link file

They all follow the same rules:

If all conditions in the [Match] section are matched, the profile will be activated

an empty [Match] section means the profile will apply in any case (can be compared to the * wildcard)

all configuration files are collectively sorted and processed in lexical order, regardless of the directory in which they live

files with identical name replace each other

Tip:

To override a system-supplied file in /usr/lib/systemd/network in a permanent manner (i.e even after upgrade), place a file with same name in /etc/systemd/network and symlink it to /dev/null

The * wildcard can be used in VALUE (e.g en* will match any Ethernet device), a boolean can be simple written as yes or no.

Following this Arch-general thread, the best practice is to setup specific container network settings inside the container with networkd configuration files.

network files

These files are aimed at setting network configuration variables, especially for servers and containers.

.network files have the following sections: [Match], [Link], [Network], [Address], [Route], and [DHCP]. Below are commonly configured keys for each section. See systemd.network(5) for more information and examples.

[Match]

MACAddress= a whitespace-separated list of hardware addresses

Name= a white-space separated list of device names, which may contain globs (e.g. en*). By prefixing with !, the list can be inverted.

Host= the machine hostname

Virtualization= check whether the system is executed in a virtualized environment or not. A Virtualization=no key will only apply on your host machine, while Virtualization=yes apply to any container or VM.

IPv6PrivacyExtensions= configures use of stateless temporary addresses that change over time, takes a boolean argument, prefer-public or kernel

[Address]

Address= this option is mandatory unless DHCP is used

[Route]

Gateway= this option is mandatory unless DHCP is used

Destination= the destination prefix of the route, possibly followed by a slash and the prefix length

If Destination is not present in [Route] section this section is treated as a default route.

Tip: You can put the Address= and Gateway= keys in the [Network] section as a short-hand if [Address] section contains only an Address key and [Route] section contains only a Gateway key.

[DHCP]

Anonymize= when true, the options sent to the DHCP server will follow the RFC7844 (Anonymity Profiles for DHCP Clients) to minimize disclosure of identifying information (default = false)

UseDNS= controls whether the DNS servers advertised by the DHCP server are used (default = true)

UseDomains= controls whether the domain name received from the DHCP server will be used as DNS search domain. If set to route, the domain name received from the DHCP server will be used for routing DNS queries only, but not for searching. This option can sometimes fix local name resolving when using systemd-resolved (default = false)

netdev files

These files will create virtual network devices. They have two sections: [Match] and [NetDev]. Below are commonly configured keys for each section. See systemd.netdev(5) for more information and examples.

[Match] section

Host= the hostname

Virtualization= check if running in a VM

[NetDev] section

Most common keys are:

Name= the interface name. mandatory

Kind= e.g. bridge, bond, vlan, veth, sit, etc. mandatory

link files

These files are an alternative to custom udev rules and will be applied by udev as the device appears. They have two sections: [Match] and [Link]. Below are commonly configured keys for each section. See systemd.link(5) for more information and examples.

If you are using systemd-nspawn, you may need to modify the systemd-nspawn@.service and append boot options to the ExecStart line. Please refer to systemd-nspawn(1) for an exhaustive list of options.

Note that if you want to take advantage of automatic DNS configuration from DHCP, you need to enable systemd-resolved and symlink /run/systemd/resolve/resolv.conf to /etc/resolv.conf. See systemd-resolved.service(8) for more details.

Before you start to configure your container network, it is useful to:

make sure packet forwarding is enabled if you want to let containers access the internet. Make sure that your .network file does not accidentally turn off forwarding because if you do not have a IPForward=1 setting in it, systemd-networkd will turn off forwarding on this interface, even if you have it enabled globally.

By default, hostname received from the DHCP server will be used as the transient hostname.

To change it add UseHostname=false in section [DHCPv4]

/etc/systemd/network/MyDhcp.network

[DHCPv4]
UseHostname=false

If you did not want to configure a DNS in /etc/resolv.conf and want to rely on DHCP for setting it up, you need to enablesystemd-resolved.service and symlink /run/systemd/resolve/resolv.conf to /etc/resolv.conf

Note: Users accessing a system partition via /usr/bin/arch-chroot from arch-install-scripts, will need to create the symlink outside of the chroot, on the mounted partition. This is due to arch-chroot linking the file to the live environment.

DHCP with two distinct IP

Bridge interface

First, create a virtual bridge interface. We tell systemd to create a device named br0 that functions as an ethernet bridge.

Note that the interface br0 is listed but is still DOWN at this stage.

Bind ethernet to bridge

The next step is to add to the newly created bridge a network interface. In the example below, we add any interface that matches the name en* into the bridge br0.

/etc/systemd/network/bind.network

[Match]
Name=en*
[Network]
Bridge=br0

The ethernet interface must not have DHCP or an IP address associated as the bridge requires an interface to bind to with no IP: modify the corresponding /etc/systemd/network/MyEth.network accordingly to remove the addressing.

Bridge network

Now that the bridge has been created and has been bound to an existing network interface, the IP configuration of the bridge interface must be specified. This is defined in a third .network file, the example below uses DHCP.

/etc/systemd/network/mybridge.network

[Match]
Name=br0
[Network]
DHCP=ipv4

Add option to boot the container

As we want to give a separate IP for host and container, we need to Disconnect networking of the container from the host. To do this, add this option --network-bridge=br0 to your container boot command.

Notice

we have now one IP address for br0 on the host, and one for host0 in the container

two new interfaces have appeared: vb-MyContainer in the host and host0 in the container. This comes as a result of the --network-bridge=br0 option. This option implies another option, --network-veth. This means a virtual Ethernet link has been created between host and container.

the DHCP address on host0 comes from the system /usr/lib/systemd/network/80-container-host0.network file.

the above command outputs confirm we have activated br0 and host0 interfaces with an IP address and Gateway 192.168.1.254. The gateway address has been automatically grabbed by systemd-networkd

$ cat /run/systemd/resolve/resolv.conf

nameserver 192.168.1.254

Static IP network

Setting a static IP for each device can be helpful in case of deployed web services (e.g FTP, http, SSH). Each device will keep the same MAC address across reboots if your system /usr/lib/systemd/network/99-default.link file has the MACAddressPolicy=persistent option (it has by default). Thus, you will easily route any service on your Gateway to the desired device.

The following configuration needs to be done for this setup:

on host

The configuration is very similar to that of #DHCP with two distinct IP. First, a virtual bridge interface needs to be created and the main physical interface needs to be bound to it. This task can be accomplished with the following two files, with contents equal to those available at the DHCP section.

First, we shall get rid of the system /usr/lib/systemd/network/80-container-host0.network file, which provides a DHCP configuration for the default network interface of the container. To do it in a permanent way (e.g. even after systemd upgrades), do the following on the container. This will mask the file /usr/lib/systemd/network/80-container-host0.network since files of the same name in /etc/systemd/network take priority over /usr/lib/systemd/network. Keep in mind that this file can be kept if you only want a static IP on the host, and want the IP address of your containers to be assigned via DHCP.

# ln -sf /dev/null /etc/systemd/network/80-container-host0.network

Then, configure an static IP for the default host0 network interface and enable and startsystemd-networkd.service on your container. An example configuration is provided below:

Interface and desktop integration

systemd-networkd does not have a proper interactive management interface neither via command-line nor graphical.
Still, some tools are available to either display the current state of the network, receive notifications or interact with the wireless configuration:

When networkd is configured with wpa_supplicant, both wpa_cli and wpa_gui offer the ability to associate and configure WLAN interfaces dynamically.

networkd-notify-gitAUR can generate simple notifications in response to network interface state changes (such as connection/disconnection and re-association).

The networkd-dispatcherAUR daemon allows executing scripts in response to network interface state changes, similar to NetworkManager-dispatcher.

As for the DNS resolver systemd-resolved, information about current DNS servers can be visualized with resolvectl status.

Troubleshooting

Mount services at boot fail

If running services like Samba/NFS which fail if they are started before the network is up, you may want to enable the systemd-networkd-wait-online.service. This is, however, rarely necessary because most networked daemons start up okay, even if the network has not been configured yet.

systemd-resolve not searching the local domain

systemd-resolved may not search the local domain when given just the hostname, even when UseDomains=yes or Domains=[domain-list] is present in the appropriate .network file, and that file produces the expected search [domain-list] in resolv.conf. You can run networkctl status or resolvectl status to check if the search domains are actually being picked up.