systemd-networkd
Related articles
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 can be setup by other services, such as wpa_supplicant, which are covered later in this article.
Required services and setup
To use systemd-networkd, start the following two services and enable them to run on system boot:
-
systemd-networkd.service -
systemd-resolved.service
For compatibility with resolv.conf, delete or rename the existing file and create the following symbolic link:
# ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
Additionally, in order to use the local DNS stub resolver of systemd-resolved (and thus use LLMNR and DNS merging per interface), replace dns with resolve in /etc/nsswitch.conf:
hosts: files resolve myhostname
See man systemd-resolved and man resolved.conf and Systemd README.
Configuration examples
All configurations in this section are stored as foo.network in /etc/systemd/network. For a full listing of options and processing order, see #Configuration files and the systemd.network man page.
Systemd/udev automatically assigns predictable, stable network interface names for all local Ethernet, WLAN, and WWAN interfaces. Use networkctl list to list the devices on the system.
After making changes to a configuration file, reload the networkd daemon.
# systemctl restart systemd-networkd
Wired adapter using DHCP
/etc/systemd/network/wired.network
[Match] Name=enp1s0 [Network] DHCP=ipv4
Wired adapter using a static IP
/etc/systemd/network/wired.network
[Match] Name=enp1s0 [Network] DNS=10.1.10.1 [Address] Address=10.1.10.9/24 [Route] Gateway=10.1.10.1
Wireless adapter
In order to connect to a wireless network with systemd-networkd, a wireless adapter configured with another service such as wpa_supplicant is required. In this example, the corresponding systemd service file that needs to be enabled is wpa_supplicant@wlp2s0.service.
/etc/systemd/network/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 the 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).
/etc/systemd/network/wired.network
[Match] Name=enp1s0 [Network] DHCP=ipv4 [DHCP] RouteMetric=10
/etc/systemd/network/wireless.network
[Match] Name=wlp2s0 [Network] DHCP=ipv4 [DHCP] RouteMetric=20
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.
- .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*joker) - each entry is a key with the
NAME=VALUEsyntax - 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
network files
These files are aimed at setting network configuration variables, especially for servers and containers.
Below is a basic structure of a MyProfile.network file:
/etc/systemd/network/MyProfile.network
[Match] a vertical list of keys [Network] a vertical list of keys [Address] a vertical list of keys [Route] a vertical list of keys
[Match] section
Most common keys are:
-
Name=the device name (e.g Br0, enp4s0) -
Host=the machine hostname -
Virtualization=check whether the system is executed in a virtualized environment or not. AVirtualization=nokey will only apply on your host machine, whileVirtualization=yesapply to any container or VM.
[Network] section
Most common keys are:
-
DHCP=enables DHCPv4 and/or DHCPv6 support. Acceptsyes,no,ipv4oripv6 -
DNS=is a DNS server address. You can specify this option more than once -
Bridge=is the name of the bridge to add the link to -
IPForward=enables IP forwarding, performing the forwarding according to the routing table, and is required for setting up Internet sharing. Acceptsyes,no,ipv4,ipv6orkernel.
[Address] section
Most common key in the [Address] section is:
-
Address=is a static IPv4 or IPv6 address and its prefix length, separated by a/character (e.g192.168.1.90/24). This option is mandatory unless DHCP is used.
[Route] section
Most common key in the [Route] section is:
-
Gateway=is the address of your machine gateway. This option is mandatory unless DHCP is used.
For an exhaustive key list, please refer to systemd.network(5)
netdev files
These files will create virtual network devices.
Below is a basic structure of a Mydevice.netdev file:
/etc/systemd/network/MyDevice.netdev
[Match] a vertical list of keys [Netdev] a vertical list of keys
[Match] section
Most common keys are Host= and Virtualization=
[Netdev] section
Most common keys are:
-
Name=is the interface name used when creating the netdev. This option is compulsory -
Kind=is the netdev kind. For example, bridge, bond, vlan, veth, sit, etc. are supported. This option is compulsory
For an exhaustive key list, please refer to systemd.netdev(5)
link files
These files are an alternative to custom udev rules and will be applied by udev as the device appears.
Below is a basic structure of a Mydevice.link file:
/etc/systemd/network/MyDevice.link
[Match] a vertical list of keys [Link] a vertical list of keys
The [Match] section will determine if a given link file may be applied to a given device, when the [Link] section specifies the device configuration.
[Match] section
Most common keys are MACAddress=, Host= and Virtualization=.
Type= is the device type (e.g. vlan)
[Link] section
Most common keys are:
MACAddressPolicy= is either persistent when the hardware has a persistent MAC address (as most hardware should) or random , which allows to give a random MAC address when the device appears.
MACAddress= shall be used when no MACAddressPolicy= is specified.
Usage with containers
The service is available with systemd >= 210. You will want to enable and start the systemd-networkd.service on the host and container.
For debugging purposes, it is strongly advised to install the bridge-utils, net-tools and iproute2 packages.
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 man 1 systemd-nspawn 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.
Basic DHCP network
This setup will enable a DHCP IP for host and container. In this case, both systems will share the same IP as they share the same interfaces.
/etc/systemd/network/MyDhcp.network
[Match] Name=en* [Network] DHCP=ipv4
Then, enable and start systemd-networkd.service on your container.
You can of course replace en* by the full name of your ethernet device given by the output of the ip link command.
- on host and container:
$ ip a
2: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 14:da:e9:b5:7a:88 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.72/24 brd 192.168.1.255 scope global enp7s0
valid_lft forever preferred_lft forever
inet6 fe80::16da:e9ff:feb5:7a88/64 scope link
valid_lft forever preferred_lft forever
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 configure a DNS in /etc/resolv.conf and want to rely on DHCP for setting it up, you need to enable systemd-resolved.service and symlink /run/systemd/resolve/resolv.conf to /etc/resolv.conf
# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
See systemd-resolved.service(8) for more details.
DHCP with two distinct IP
Bridge interface
Create a virtual bridge interface
/etc/systemd/network/MyBridge.netdev
[NetDev] Name=br0 Kind=bridge
On host and container:
$ ip a
3: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
link/ether ae:bd:35:ea:0c:c9 brd ff:ff:ff:ff:ff:ff
Note that the interface br0 is listed but is DOWN.
Bind ethernet to bridge
Modify the /etc/systemd/network/MyDhcp.network to remove the DHCP, as the bridge requires an interface to bind to with no IP, and add a key to bind this device to br0. Let us change its name to a more relevant one.
/etc/systemd/network/MyEth.network
[Match] Name=en* [Network] Bridge=br0
Bridge network
Create a network profile for the Bridge
/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.
# systemd-nspawn --network-bridge=br0 -bD /path_to/my_container
Result
- on host
$ ip a
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 14:da:e9:b5:7a:88 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.87/24 brd 192.168.1.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::16da:e9ff:feb5:7a88/64 scope link
valid_lft forever preferred_lft forever
6: vb-MyContainer: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether d2:7c:97:97:37:25 brd ff:ff:ff:ff:ff:ff
inet6 fe80::d07c:97ff:fe97:3725/64 scope link
valid_lft forever preferred_lft forever
- on container
$ ip a
2: host0: <BROADCAST,MULTICAST,ALLMULTI,AUTOMEDIA,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 5e:96:85:83:a8:5d brd ff:ff:ff:ff:ff:ff
inet 192.168.1.73/24 brd 192.168.1.255 scope global host0
valid_lft forever preferred_lft forever
inet6 fe80::5c96:85ff:fe83:a85d/64 scope link
valid_lft forever preferred_lft forever
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-MyContainerin the host andhost0in the container. This comes as a result of the--network-bridge=br0option. This option implies another option,--network-veth. This means a virtual Ethernet link has been created between host and container. - the DHCP address on
host0comes from the system/usr/lib/systemd/network/80-container-host0.networkfile. - on host
$ brctl show
bridge name bridge id STP enabled interfaces br0 8000.14dae9b57a88 no enp7s0 vb-MyContainer
the above command output confirms we have a bridge with two interfaces binded to.
- on host
$ ip route
default via 192.168.1.254 dev br0 192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.87
- on container
$ ip route
default via 192.168.1.254 dev host0 192.168.1.0/24 dev host0 proto kernel scope link src 192.168.1.73
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.
First, we shall get rid of the system /usr/lib/systemd/network/80-container-host0.network file. To do it in a permanent way (e.g even after upgrades), do the following on 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.
# ln -sf /dev/null /etc/systemd/network/80-container-host0.network
Then, enable and start systemd-networkd on your container.
The needed configuration files:
- on host
/etc/systemd/network/MyBridge.netdev /etc/systemd/network/MyEth.network
A modified MyBridge.network
/etc/systemd/network/MyBridge.network
[Match] Name=br0 [Network] DNS=192.168.1.254 Address=192.168.1.87/24 Gateway=192.168.1.254
- on container
/etc/systemd/network/MyVeth.network
[Match] Name=host0 [Network] DNS=192.168.1.254 Address=192.168.1.94/24 Gateway=192.168.1.254
See also
- systemd.networkd man page
- Tom Gundersen, main systemd-networkd developer, G+ home page
- Tom Gundersen posts on Core OS blog
- How to set up systemd-networkd with wpa_supplicant (WonderWoofy's walkthrough on Arch forums)