Systemd/networkd: Difference between revisions
imported>Mweinelt →Examples: Static network configuration |
imported from old wiki |
||
(51 intermediate revisions by 12 users not shown) | |||
Line 1: | Line 1: | ||
{{Systemd/breadcrumb}} | |||
{{DISPLAYTITLE:systemd-networkd}} | |||
[https://www.freedesktop.org/software/systemd/man/systemd-networkd.html systemd-networkd] is the network configuration component of the [[systemd]][[Category:systemd]] software suite. It is well integrated into NixOS below {{Nixos:option|systemd.network}} and should be preferred over {{Nixos:option|networking.interfaces}} options for most use cases, since it receives far superior maintenance. | |||
Configuration for networkd is split into three sections. | Configuration for networkd is split into three sections. | ||
* | * {{Nixos:option|systemd.network.links}} reconfigures existing network devices | ||
** https://www.freedesktop.org/software/systemd/man/systemd.link.html | ** https://www.freedesktop.org/software/systemd/man/systemd.link.html | ||
** actually implemented by udev, not networkd | ** actually implemented by udev, not networkd | ||
* | * {{Nixos:option|systemd.network.netdevs}} creates virtual network devices | ||
** https://www.freedesktop.org/software/systemd/man/systemd.netdev.html | ** https://www.freedesktop.org/software/systemd/man/systemd.netdev.html | ||
* | * {{Nixos:option|systemd.network.networks}} configures network devices | ||
** https://www.freedesktop.org/software/systemd/man/systemd.network.html | ** https://www.freedesktop.org/software/systemd/man/systemd.network.html | ||
In most simple scenarios configuring existing network devices is what you want to do. | In most simple scenarios configuring existing network devices is what you want to do. | ||
== Basics == | |||
=== When to use === | |||
Use systemd-networkd for setups that rely on static configuration, that doesn't change much during its lifetime, that does not require varying profiles for a single interface. Common examples are: | |||
* Servers/Routers | |||
* Always-On VPN Tunnels | |||
Following that logic, it is less suitable to | |||
* Varying WLAN profiles | |||
* Selectively used VPN tunnels | |||
These use cases are better served by [[NetworkManager]] and its various frontends, that provides a better integrated user experience for various desktop systems. | |||
{{Note|Both systemd-networkd and NetworkManager can exist in parallel on the same machine, when they manage a distinct set of interfaces. If upstream connectivity is managed by NetworkManager (for example, NM handles wifi and networkd does VM networking), set {{Nixos:option|systemd.network.wait-online.enable}} to false so that boot isn't blocked on connectivity that networkd will never provide.}} | |||
=== Enabling === | === Enabling === | ||
To be able to use networkd configuration it needs to be enabled first. | To be able to use networkd configuration, it needs to be enabled first. | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
Line 21: | Line 39: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Some guides will mention the | Some guides will mention the {{Nixos:option|networking.useNetworkd}} option, which | ||
offers translation of some | in addition to enabling systemd-networkd, also offers translation of some | ||
can write your complete network setup in native networkd configuration, you should | {{Nixos:option|networking.interfaces}} and {{Nixos:option|networking.useDHCP}} options | ||
stay away from that option. | into networkd. | ||
If you can write your complete network setup in native networkd configuration, you | |||
should stay away from that option. | |||
=== Configuring === | |||
The configuration of networkd happens through one or multiple configuration files per | |||
interface stored in <code>/etc/systemd/network</code>. | |||
The following declaration in your NixOS configuration | |||
<syntaxhighlight lang="nix"> | |||
systemd.network.networks."10-lan" = { | |||
matchConfig.Name = "lan"; | |||
networkConfig.DHCP = "ipv4"; | |||
}; | |||
</syntaxhighlight> | |||
renders the following network configuration: | |||
{{file|/etc/systemd/network/10-lan.network|ini|<nowiki> | |||
[Match] | |||
Name=lan | |||
[Network] | |||
DHCP=ipv4 | |||
</nowiki>}} | |||
Note that we usually prefix the configuration file with a number. This can be important, because networkd collects all available configuration files, then sorts them alphanumerically, and uses the first match for each interface as its configuration. This happens separately for <code>.link</code>, <code>.netdev</code> and <code>.network</code> files, so that you can have one configuration of each type per interface. | |||
=== Debugging === | |||
When things don't work as expected, the journal for <code>systemd-networkd.service</code> should be consulted. Unfortunately, by default the log is not very useful in its default loglevel. Increasing the loglevel can be done using the <code>SYSTEMD_LOG_LEVEL</code> environment variable. | |||
<syntaxhighlight lang="nix"> | |||
systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug"; | |||
</syntaxhighlight> | |||
=== Limitations === | === Limitations === | ||
* | Some limitations might be surprising, so it is probably helpful to get them out of the way early. | ||
* | |||
** https://github.com/systemd/systemd/issues/9627 | * {{Nixos:option|systemd.network.links}} | ||
** Executed by udev and only applied on boot | |||
* {{Nixos:option|systemd.network.netdevs}} | |||
** Does not modify properties (e.g., MTU, VLAN ID, VXLAN ID, Wireguard Peers) of existing netdevs | |||
*** https://github.com/systemd/systemd/issues/9627 | |||
=== network-online.target === | === network-online.target === | ||
Line 61: | Line 117: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
systemd.network."50-enp3s0" = { | systemd.network.networks."50-enp3s0" = { | ||
matchConfig.Name = "enp3s0"; | matchConfig.Name = "enp3s0"; | ||
# acquire a DHCP lease on link up | # acquire a DHCP lease on link up | ||
Line 77: | Line 133: | ||
entirely, because a working <code>network-online.target</code> is required for some | entirely, because a working <code>network-online.target</code> is required for some | ||
services to properly start without race conditions. | services to properly start without race conditions. | ||
Also consider enabling the <code>systemd.network.wait-online.anyInterface</code> option, | |||
which makes networkd consider the network online when any interface is online, | |||
as opposed to all that have a positive value for <code>linkConfig.RequiredForOnline</code>. | |||
This is useful on portable machines with a wired and a wireless interface, for example. | |||
Recommended documentation: | Recommended documentation: | ||
Line 87: | Line 148: | ||
Examples should be concise and give proper hints on how to achieve a reliably working <code>network-online.target</code>. | Examples should be concise and give proper hints on how to achieve a reliably working <code>network-online.target</code>. | ||
=== DHCP === | === DHCP/RA === | ||
Common scenario for dynamic configuration, DHCP for IPv4 and router advertisements for IPv6 connectivity. Make <code>network-online.target</code> wait until addresses and routes are configured. | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
systemd.network.networks."10 | systemd.network.networks."10-wan" = { | ||
matchConfig.Name = "enp1s0"; | matchConfig.Name = "enp1s0"; | ||
networkConfig | networkConfig = { | ||
# make | # start a DHCP Client for IPv4 Addressing/Routing | ||
linkConfig.RequiredForOnline = | DHCP = "ipv4"; | ||
# accept Router Advertisements for Stateless IPv6 Autoconfiguraton (SLAAC) | |||
IPv6AcceptRA = true; | |||
}; | |||
# make routing on this interface a dependency for network-online.target | |||
linkConfig.RequiredForOnline = "routable"; | |||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 102: | Line 168: | ||
=== Static === | === Static === | ||
Apply a static address and routing configuration onto <code>enp1s0</code>. When the gateway is not on the same prefix as the address configured, you usually also need to set <code>GatewayOnLink</code>, to indicate the gateway is directly reachable on the interface. | Apply a static address and routing configuration onto <code>enp1s0</code>. | ||
When the gateway is not on the same prefix as the address configured, as is customary on some cloud providers, you usually also need to set <code>GatewayOnLink</code>, to indicate the gateway is directly reachable on the interface. | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
Line 109: | Line 177: | ||
matchConfig.Name = "enp1s0"; | matchConfig.Name = "enp1s0"; | ||
address = [ | address = [ | ||
# configure addresses including subnet mask | |||
"192.0.2.100/24" | |||
"2001:DB8::2/64" | |||
]; | ]; | ||
routes = [ | routes = [ | ||
# create default routes for both IPv6 and IPv4 | # create default routes for both IPv6 and IPv4 | ||
{ | { Gateway = "fe80::1"; } | ||
{ | { Gateway = "192.0.2.1"; } | ||
# or when the gateway is not on the same network | # or when the gateway is not on the same network | ||
{ | |||
Gateway = "172.31.1.1"; | Gateway = "172.31.1.1"; | ||
GatewayOnLink = true; | GatewayOnLink = true; | ||
Line 125: | Line 193: | ||
# make the routes on this interface a dependency for network-online.target | # make the routes on this interface a dependency for network-online.target | ||
linkConfig.RequiredForOnline = "routable"; | linkConfig.RequiredForOnline = "routable"; | ||
}; | |||
</syntaxhighlight> | |||
=== VLAN === | |||
VLANs can be configured on top of hardlinks as well as virtual links, like bonding interfaces. They provide separate logical networks over physical links. | |||
In this example we tag two VLANs with Ids 10 and 20 on a physical link <code>enp1s0</code>. The VLAN interfaces become available as <code>vlan10</code> and <code>vlan20</code> and can receive additional configuration. | |||
<syntaxhighlight lang="nix"> | |||
systemd.network = { | |||
netdevs = { | |||
"20-vlan10" = { | |||
netdevConfig = { | |||
Kind = "vlan"; | |||
Name = "vlan10"; | |||
}; | |||
vlanConfig.Id = 10; | |||
}; | |||
"20-vlan20" = { | |||
netdevConfig = { | |||
Kind = "vlan"; | |||
Name = "vlan20"; | |||
}; | |||
vlanConfig.Id = 20; | |||
}; | |||
}; | |||
networks = { | |||
"30-enp1s0" = { | |||
matchConfig.Name = "enp1s0"; | |||
# tag vlan on this link | |||
vlan = [ | |||
"vlan10" | |||
"vlan20" | |||
]; | |||
networkConfig.LinkLocalAddressing = "no"; | |||
linkConfig.RequiredForOnline = "carrier"; | |||
}; | |||
"40-vlan10" = { | |||
matchConfig.Name = "vlan10"; | |||
# add relevant configuration here | |||
}; | |||
"40-vlan20" = { | |||
matchConfig.Name = "vlan20"; | |||
# add relevant configuration here | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
=== Bridge === | |||
Given multiple interfaces, that are connected into a bridge will act like a common switch and forward Ethernet frames between all connected bridge ports. The Linux bridge supports various features, like spanning tree, bridge port isolation or acting as a multicast router. | |||
The configuration on top of the bridge interface depends on the desired functionality, e.g., configuring an IP address would make the bridge host reachable on the Ethernet segment. | |||
Recommended documentation: | |||
* [https://www.freedesktop.org/software/systemd/man/systemd.network.html#%5BBridge%5D%20Section%20Options <nowiki>[Bridge]</nowiki> configuration reference] | |||
<syntaxhighlight lang="nix"> | |||
systemd.network = { | |||
netdevs = { | |||
# Create the bridge interface | |||
"20-br0" = { | |||
netdevConfig = { | |||
Kind = "bridge"; | |||
Name = "br0"; | |||
}; | |||
}; | |||
}; | |||
networks = { | |||
# Connect the bridge ports to the bridge | |||
"30-enp1s0" = { | |||
matchConfig.Name = "enp1s0"; | |||
networkConfig.Bridge = "br0"; | |||
linkConfig.RequiredForOnline = "enslaved"; | |||
}; | |||
"30-enp2s0" = { | |||
matchConfig.Name = "enp2s0"; | |||
networkConfig.Bridge = "br0"; | |||
linkConfig.RequiredForOnline = "enslaved"; | |||
}; | |||
# Configure the bridge for its desired function | |||
"40-br0" = { | |||
matchConfig.Name = "br0"; | |||
bridgeConfig = {}; | |||
# Disable address autoconfig when no IP configuration is required | |||
#networkConfig.LinkLocalAddressing = "no"; | |||
linkConfig = { | |||
# or "routable" with IP addresses configured | |||
RequiredForOnline = "carrier"; | |||
}; | |||
}; | |||
}; | |||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 130: | Line 293: | ||
=== Bonding === | === Bonding === | ||
Given two hardlinks <code>enp2s0</code> and <code>enp3s0</code> create a virtual <code>bond0</code> interface using Dynamic LACP (802.3ad), hashing outgoing packets using a packet's | Given two hardlinks <code>enp2s0</code> and <code>enp3s0</code> create a virtual <code>bond0</code> interface using Dynamic LACP (802.3ad), hashing outgoing packets using a packet's layer 3/4 (network/transport layer in the OSI model) information. | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
Line 166: | Line 329: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[Category: Networking]] | === Router Advertisement === | ||
Router advertisements are way to allow clients to achieve stateless autoconfiguration (SLAAC). The most prominent setup is where the router announces a prefix onto a LAN segment, which the receiving client can use to set up an address on that prefix, and configure the sender as its default gateway. | |||
In this example the router will announce a static IPv6 prefix on the <code>lan</code> interface from it's automatically configured link local address on that link. The router does not generally require a unique local or globally reachable address on the link, unless you also want to host services like DNS and NTP on that LAN segment. | |||
Recommended documentation: | |||
* [https://www.freedesktop.org/software/systemd/man/systemd.network.html#%5BIPv6SendRA%5D%20Section%20Options <nowiki>[IPv6SendRa]</nowiki> configuration reference] | |||
<syntaxhighlight lang="nix"> | |||
systemd.network = { | |||
networks = { | |||
"30-lan" = { | |||
matchConfig.Name = "lan"; | |||
address = [ "2001:db8:1122:3344::1/64" ]; | |||
networkConfig = { | |||
IPv6SendRA = true; | |||
}; | |||
ipv6Prefixes = [ | |||
{ | |||
# Announce a static prefix | |||
ipv6PrefixConfig.Prefix = "2001:db8:1122:3344::/64"; | |||
} | |||
]; | |||
ipv6SendRAConfig = { | |||
# Provide a DNS resolver | |||
EmitDNS = true; | |||
DNS = "2001:db8:1122:3344::1"; | |||
}; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
An extended form of this setup uses DHCPv6 prefix delegation to acquire a dynamic prefix over a WAN link, which then gets distributed onto designated LAN segments. | |||
=== WireGuard === | |||
WireGuard can also be set up using <code>systemd.network.netdevs</code>. More details can be found at [[WireGuard#Setting up WireGuard with systemd-networkd]]. | |||
== User configurations == | |||
This section allows references to actual user configurations. They show how individual configuration snippets | |||
get integrated as a whole and serve as real world examples. | |||
''When adding new links, please describe the primary features of your setup and against which NixOS version it was last updated.'' | |||
* [https://gist.github.com/mweinelt/b78f7046145dbaeab4e42bf55663ef44 NixOS 22.11 VDSL Router (VLANs on top of Bonding, IPv6 Prefix-Delegation, pppd Integration)] by [https://github.com/mweinelt mweinelt] | |||
[[Category:systemd]] | |||
[[Category:Networking]] |