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.
- 1 Basic usage
- 2 Configuration files
- 3 Usage with containers
- 4 Interface and desktop integration
- 5 Troubleshooting
- 6 See also
Required services and setup
To use systemd-networkd, start/enable
It is optional to also start/enable
systemd-resolved.service, which is a network name resolution service to local applications, considering the following points:
- The systemd-resolved service is required if DNS entries are specified in .network files,
- It can be used to automatically obtain DNS addresses from the network DHCP client,
- It is important to understand how resolv.conf and systemd-resolved interact to properly configure the DNS that will be used, some explanations are provided in systemd-resolved.
- Note that systemd-resolved can also be used without systemd-networkd.
All configurations in this section are stored as
/etc/systemd/network/. For a full listing of options and processing order, see #Configuration files and .
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, restart
- The options specified in the configuration files are case sensitive.
- In the examples below,
enp1s0is the wired adapter and
wlp2s0is the wireless adapter. These names can be different on different systems. It is also possible to use a wildcard, e.g.
- If you want to disable IPv6, see IPv6#systemd-networkd.
DHCP=yesto accept an IPv4 and IPv6 DHCP request to the
Wired adapter using DHCP
[Match] Name=enp1s0 [Network] DHCP=ipv4
Wired adapter using a static IP
[Match] Name=enp1s0 [Network] Address=10.1.10.9/24 Gateway=10.1.10.1 DNS=10.1.10.1 #DNS=188.8.131.52
Address= can be used more than once to configure multiple IPv4 or IPv6 addresses. See #network files or for more options.
[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).
Metricoption is for static routes while the
RouteMetricoption is for setups not using static routes.
[Match] Name=enp1s0 [Network] DHCP=ipv4 [DHCP] RouteMetric=10
[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.
[Match] MACAddress=12:34:56:78:90:ab [Link] Description=USB to Ethernet Adapter Name=ethusb0
99-default.linkin order to be considered at all. For example, name the file
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
- 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
- To override a system-supplied file in
/usr/lib/systemd/networkin a permanent manner (i.e even after upgrade), place a file with same name in
/etc/systemd/networkand symlink it to
*wildcard can be used in
en*will match any Ethernet device), a boolean can be simple written as
- Following this Arch-general thread, the best practice is to setup specific container network settings inside the container with networkd configuration files.
These files are aimed at setting network configuration variables, especially for servers and containers.
.network files have the following sections:
[DHCP]. Below are commonly configured keys for each section. See for more information and examples.
MACAddress=a whitespace-separated list of hardware addresses
Name=the device name
Host=the machine hostname
Virtualization=check whether the system is executed in a virtualized environment or not. A
Virtualization=nokey will only apply on your host machine, while
Virtualization=yesapply to any container or VM.
MACAddress=useful for MAC address spoofing
MTUBytes=setting a larger MTU value (e.g. when using jumbo frames) can significantly speed up your network transfers
Multicastallow the usage of multicast on interface(s)
DHCP=enables the DHCP client, accepts
DHCPServer=enables the DHCP server
MulticastDNS=accepts a boolean or
resolve, enables multicast DNS support
DNSSEC=a boolean or
DNS=to configure static DNS addresses, may be specified more than once
Domains=a list of domains to be resolved on this link
IPForward=configures IP packet forwarding, takes either a boolean argument,
Address=this option is mandatory unless DHCP is used
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
Destination is not present in
[Route] section this section is treated as a default route.
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.
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
UseDomains=can sometimes fix local name resolving when using systemd-resolved
These files will create virtual network devices. They have two sections:
[NetDev]. Below are commonly configured keys for each section. See for more information and examples.
Virtualization=check if running in a VM
Most common keys are:
Name=the interface name. mandatory
Kind=e.g. bridge, bond, vlan, veth, sit, etc. mandatory
These files are an alternative to custom udev rules and will be applied by udev as the device appears. They have two sections:
[Link]. Below are commonly configured keys for each section. See for more information and examples.
udevadm test-builtin net_setup_link /sys/path/to/network/deviceto diagnose problems with .link files.
MACAddress=the MAC address
Host=the host name
Type=the device type e.g. vlan
MACAddressPolicy=persistent or random addresses, or
MACAddress=a specific address
/usr/lib/systemd/network/99-default.linkis generally sufficient for most of the basic cases.
Usage with containers
For debugging purposes, it is strongly advised to install the , , and 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 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
/etc/resolv.conf. See for more details.
Before you start to configure your container network, it is useful to:
- disable all your netctl (host and container), dhcpcd (host and container), systemd-networkd (container only) and
systemd-nspawn@.service(host only) services to avoid potential conflicts and to ease debugging
- 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=1setting in it,
systemd-networkdwill turn off forwarding on this interface, even if you have it enabled globally.
- make sure you do not have any iptables rules which can block traffic
- when the daemon is started the systemd
networkctlcommand displays the status of network interfaces.
For the set-up described below,
- we will limit the output of the
ip acommand to the concerned interfaces
- we assume the host is your main OS you are booting to and the container is your guest virtual machine
- all interface names and IP addresses are only examples
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.
[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
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 enable
systemd-resolved.service and symlink
# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
Seefor more details.
/usr/bin/arch-chrootfrom , 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
First, create a virtual bridge interface. We tell systemd to create a device named br0 that functions as an ethernet bridge.
[NetDev] Name=br0 Kind=bridge
systemd-networkd.service to have systemd create the 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 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.
[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.
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.
[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
- 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
- we have now one IP address for
br0on the host, and one for
host0in the container
- two new interfaces have appeared:
vb-MyContainerin the host and
host0in 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
- 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
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
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.
Next, you need to configure the IP and DNS of the newly created virtual bridge interface. The following MyBridge.network provides an example configuration:
[Match] Name=br0 [Network] DNS=192.168.1.254 Address=192.168.1.87/24 Gateway=192.168.1.254
- on container
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 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 start
systemd-networkd.service on your container. An example configuration is provided below:
[Match] Name=host0 [Network] DNS=192.168.1.254 Address=192.168.1.94/24 Gateway=192.168.1.254
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:
- networkctl (via CLI) offers a simple dump of the network interface states.
- When networkd is configured with wpa_supplicant, both wpa_cli and wpa_gui offer the ability to associate and configure WLAN interfaces dynamically.
- AUR can generate simple notifications in response to network interface state changes (such as connection/disconnection and re-association).
- The AUR 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
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
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.
hostsdatabase (e.g., by removing
- Switch to using fully-qualified domain names
/etc/hoststo resolve hostnames
- Fall back to using glibc's
dnsinstead of using systemd's
- 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)