Setting up Systemd-Networkd

basic configuration

NOTE: If you are doing this remotely, please ensure that you can get to the physical machine in order to fix things should something go wrong. You can't work remotely on a machine whose networking isn't.

If you currently have a network running using /etc/network/, move the interfaces file there to another name so that it won't be used after systemd-networkd is set up:

  mv /etc/network/interfaces /etc/network/interfaces.save

Next enable systemd-networkd. You don't need to start the service yet because your old network is still running and there is currently no systemd-networkd defined.

  systemctl enable systemd-networkd

All configuration files are generally stored in /etc/systemd/network. Note that in the configuration files, case is important. Match is not the same as match.

Next you need to define a network. In the simplest case, this is just a single file in /etc/systemd/network. Let's use lan0.network and put in the following information:

  [Match]
  Name=eth0

  [Network]
  DHCP=ipv4

This tells systemd-networkd to use eth0 (which was set up by udev) and assign it an address using DHCP.

For a static IP, lan0.network could be:

  [Match]
  Name=enp8s0

  [Network]
  Address=192.168.1.20/24
  Gateway=192.168.1.1
  DNS=192.168.1.1

I recommend a reboot at this point to remove the currently running network and to ensure that your network comes up properly.

This is all it takes for a simple case.

beyond the basics

setting up a bond between 2 network interfaces

This is covered in https://wiki.debian.org/Bonding#Using_systemd-networkd

setting up a network bridge

If you are running virtual machines, you probably have set up a bridge in your interfaces file. Since that is no longer used, you need to set up a bridge using systemd-networkd. Fortunately this is very easy.

First you need to define the virtual network device using a .netdev file (in /etc/systemd/network of course). Let's call this br0.netdev. It should look like:

  [NetDev]
  Name=br0
  Kind=bridge

Hint: in Debian Buster (probably also previous versions) systemd-networkd may assign a different MAC-Address to the bridge than your physical interface has. This may cause connection issues if your service provider uses some kind of MAC-filterng when routing your traffic. To circumvent such problems you may assign a MAC-address to your bridge (probably tha same as your physical device, replace the 'xx' with valid MAC):

  [NetDev]
  Name=br0
  Kind=bridge
  MACAddress=xx:xx:xx:xx:xx:xx

Then you link it to the real network device using br0.network:

  [Match]
  Name=eth0

  [Network]
  Bridge=br0

Finally modify lan0.network to refer to br0 instead of eth0:

  [Match]
  Name=br0

  [Network]
  DHCP=ipv4

Restart systemd-networkd and your bridge should be up.

  systemctl restart systemd-networkd

bridging over a bond

bridging over a bond is simply a matter of referring the bond device in your br0.network file instead of referring to a physical device. From the above bridge example, change br0.network to read:

  [Match]
  Name=bond0

  [Network]
  Bridge=br0

assuming your bond virtual device is called bond0.

Configuring the physical layer

In general you don't need a .link file since udev already identifies the device. However you can configure multiple options here that can't be set elsewhere. The most basic of these is the name.

uDev these days does a good job of consistently handling the naming of network devices. Unless you have legacy names like eth0 (which are now set up using uDev naming rules to override the way uDev would normally handle it), wired interfaces are usually something like "enp5s0". This is derived from its PCI address.

Issuing lspci will show you the addresses of all the PCI devices on your system. You should see a line describing your network interface like

  05:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 06)

where the 05 part becomes the 5 in enp5s0 and the 00.0 part becomes the 0.

enp5s0 isn't very descriptive if you've got multiple NICs in your system, such as if you were bonding the NICs together for greater bandwidth on a server. To give the interface a more descriptive name. Simply create a .network file (say onboardnic.network) as

  [Match]
  Path=pci-0000:05:00.0

  [Network]
  Bond=bond0

and refer to onboardnic instead of enp5s0 in your bond0.network file.

You can also create a .link file to give it a more descriptive name.

manpage: https://manpages.debian.org/stretch/udev/systemd.link.5.en.html

Link level configuration files need to end in .link

So in order to configure the onboardnic you can create the file /etc/systemd/network/onboardnic.link such as:

  [Match]
  OriginalName=enp5s0

or more directly

  [Match]
  Path=pci-0000:05:00.0

Unfortunately outside of your systemd-networkd configuration, tools use the name given by udev.

Setting an IP-Address

Static

IP addresses are configured in .network files.

In order to give an IP address to eth0 one can create the following file

/etc/systemd/network/eth0.network

With this content

  [Match]
  Name=eth0

  [Network]
  Address=10.20.30.2/24
  Gateway=10.20.30.1

This will give the device with the name 'eth0' the ip 10.20.30.2 with netmask 255.255.255.0 and set a default route to 10.20.30.1

DHCP

Create a file like /etc/systemd/network/eth0.network with this content

  [Match]
  Name=eth0

  [Network]
  Address=DHCP

References

This part of systemd is documented in those various manpages:


CategoryNetwork