systemd-networkd

来自 Arch Linux 中文维基

systemd-networkd 是一个管理网络配置的系统守护进程。它会在网络设备出现时检测和配置它们;它还可以创建虚拟网络设备。这个服务非常适合于为 systemd-nspawn 管理的容器或者虚拟机创建复杂的网络配置。如果只是简单网络的配置,它也同样能胜任。

基本用法[编辑 | 编辑源代码]

systemd 是默认 Arch 安装的一部分,包含操作有线网络所需的所有文件。无线适配器可以通过其他服务(比如 wpa_supplicant 或者 iwd)来配置,本文后面的部分也会介绍相关内容。

必需的服务和设置[编辑 | 编辑源代码]

start/enable systemd-networkd.service 以使用 systemd-networkd

注意: 必须确认没有其他服务正在管理网络。不同的网络管理服务会互相冲突。通过 systemctl --type=service 可以得到正在运行的服务的列表,请 停止 其他网络管理服务。

配置 systemd-resolved 是可选的,它是一个为本地应用程序提供网络名称(DNS)解析服务。是否使用它可以考虑下面几条:

  • 如果 .network 文件中指定了 DNS 条目,则 systemd-resolved 服务是必需的
  • 想自动从DHCP服务器或IPv6路由器推荐获取 DNS 服务器地址(通过在[Network]中设置(DHCP=和/或IPv6AcceptRA=,并在对应的[DHCPv4][DHCPv6][IPv6AcceptRA]中设置UseDNS=yes(默认值)来实现,参见systemd.network(5)
  • 请搞明白 resolv.confsystemd-resolved 如何互相影响,以便正确配置要使用的 DNS 服务器。更多相关信息可以参见 systemd-resolved
  • 注意:即使没有启用 systemd-networkdsystemd-resolved 也能够提供服务。

配置样例[编辑 | 编辑源代码]

在本节中,所有配置都存储为在 /etc/systemd/network/ 目录下 形如 foo.network 的文件。有关选项的完整列表和处理顺序可以参考 #配置文件systemd.network(5)

Systemd/udev 会自动为所有本地以太网、WLAN 和 WWAN 接口分配可预测且稳定的网络接口名。使用 networkctl list 以列出系统上所有设备。

在修改了配置文件之后,restart systemd-networkd.service 以使得它们生效。

注意:
  • 配置文件中指定的选项区分大小写。
  • 在下面的示例中,enp1s0 是有线适配器,wlp2s0 是无线适配器。他们的名字在不同系统上可能会有不同的名字。也可以使用通配符,例如,Name=en*
  • 如果想要禁用 IPv6 的话,参考 IPv6#systemd-networkd
  • [Network] 段设置 DHCP=yes 来同时接收 IPv4 IPv6 DHCP 请求。

使用 DHCP 的有线适配器[编辑 | 编辑源代码]

/etc/systemd/network/20-wired.network
[Match]
Name=enp1s0

[Network]
DHCP=yes

使用静态 IP 的有线适配器[编辑 | 编辑源代码]

/etc/systemd/network/20-wired.network
[Match]
Name=enp1s0

[Network]
Address=10.1.10.9/24
Gateway=10.1.10.1
DNS=10.1.10.1
#DNS=8.8.8.8

Address= 能够被使用多次来指定多个 IPv4 或者 IPv6 地址。 参见 #network 文件或者 systemd.network(5) 了解更多配置项。

无线适配器[编辑 | 编辑源代码]

为了能够使用 systemd-networkd 连接一个无线网络,需要一个被其他应用,比如 wpa_supplicantIwd,配置好的无线适配器。

/etc/systemd/network/25-wireless.network
[Match]
Name=wlp2s0

[Network]
DHCP=yes
IgnoreCarrierLoss=3s

如果无线适配器有一个静态地址,它的配置(除了接口的名字)跟有线适配器是一样的。

同一台机器上的有线和无线适配器[编辑 | 编辑源代码]

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).

注意: 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=yes

[DHCPv4]
RouteMetric=100

[IPv6AcceptRA]
RouteMetric=100
/etc/systemd/network/25-wireless.network
[Match]
Name=wlp2s0

[Network]
DHCP=yes

[DHCPv4]
RouteMetric=600

[IPv6AcceptRA]
RouteMetric=600

网络接口重命名[编辑 | 编辑源代码]

作为更改设备名称的替代方案,systemd 使用.link文件用于接口重命名。常见的例子是基于 MAC 地址给一个 USB 接口以太网适配器设置一个可预见的接口名称。这类设备依其连接到不同 USB 接口而具有不同的接口名称。

/etc/systemd/network/10-ethusb0.link
[Match]
MACAddress=12:34:56:78:90:ab

[Link]
Description=USB to Ethernet Adapter
Name=ethusb0
注意: 任何由用户提供的.link文件名必须是依字典顺序先于默认配置文件名99-default.link才能生效。例如,必须是10-ethusb0.link而不能是 ethusb0.link

配置文件[编辑 | 编辑源代码]

配置文件位于 /usr/lib/systemd/network,非持久化的运行时网络配置目录位于 /run/systemd/network ,本地管理网络配置位于 /etc/systemd/network/etc/systemd/network 中的配置文件具有最高优先级。

配置文件有三类。它们均使用类似于 systemd 单元文件的格式。

  • .network 文件,为匹配的设备提供一个网络配置
  • .netdev 文件,为匹配的环境创建一个虚拟网络设备
  • .link 文件,当网络设备出现时,udev 将查找第一个匹配.link文件

它们均遵循下列规则:

  • 如果位于[Match]小节的全部条件相匹配,配置项将被激活
  • 一个空的[Match]小节意味着配置项适用任何情况(相当于*通配符)
  • 所有配置文件将按字典顺序集中保存和处理,不管它们在目录中的实际顺序如何。
  • 同名文件将彼此替换
提示:
  • 要永久覆盖 /usr/lib/systemd/network 中系统提供的文件(即升级之后仍覆盖),请在 /etc/systemd/network 中放置一个具有相同名称的文件并将其符号链接到 /dev/null
  • 星号(*)通配符可以在 VALUE 中使用(例如 en* 将匹配任何以太网设备), 布尔值可以简单地写为 yesno
  • 根据这个线索的讨论,最佳实践是 to setup specific container network settings inside the container with networkd configuration files.
  • Systemd 使用1, true, yes, on作为逻辑“真”值,0, false, no, off作为逻辑“假”值

network 文件[编辑 | 编辑源代码]

这类文件用于设置网络配置变量,尤其适用于服务器和容器。

.network文件含有下列小节:[Match][Link][Network][Address][Route]以及[DHCP]。下列为每小节的通用配置。详情及范例请参阅systemd.network(5)

[Match] 小节[编辑 | 编辑源代码]

  • MACAddress= 由空白字符分割的网卡硬件地址列表
  • Name= 由空白字符分割的设备名列表,可以包含集合字符(如:en*)。使用前缀字符!禁用列表中的名字。
  • Host= 机器的主机名
  • Virtualization= 检查系统是否运行于虚拟化环境。Virtualization=no选项值表示仅应用于物理主机,Virtualization=yes选项值表示应用于任何容器或虚拟机。

[Link] 小节[编辑 | 编辑源代码]

  • 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
  • Multicast allow the usage of multicast on interface(s)

[Network] 小节[编辑 | 编辑源代码]

参数 说明 值类型 默认值
DHCP= Controls DHCPv4 and/or DHCPv6 client support. boolean, ipv4, ipv6 false
DHCPServer= If enabled, a DHCPv4 server will be started. boolean false
MulticastDNS= Enables multicast DNS support. When set to resolve, only resolution is enabled, but not host or service registration and announcement. boolean, resolve false
DNSSEC= Controls DNSSEC DNS validation support on the link. When set to allow-downgrade, compatibility with non-DNSSEC capable networks is increased, by automatically turning off DNSSEC in this case. boolean, allow-downgrade false
DNS= Configure static DNS addresses. May be specified more than once. inet_pton
Domains= A list of domains which should be resolved using the DNS servers on this link. more information domain name, optionally prefixed with a tilde (~)
IPForward= If enabled, incoming packets on any network interface will be forwarded to any other interfaces according to the routing table. boolean, ipv4, ipv6 false
IPv6PrivacyExtensions= Configures use of stateless temporary addresses that change over time (see RFC 4941). When prefer-public, enables the privacy extensions, but prefers public addresses over temporary addresses. When kernel, the kernel's default setting will be left in place. boolean, prefer-public, kernel false

[Address] 小节[编辑 | 编辑源代码]

  • Address= 这个选项必选,除非使用了 DHCP。

[Route] 小节[编辑 | 编辑源代码]

  • Gateway= 这个选项必选,除非使用了 DHCP
  • Destination= 路由的目的地前缀,可能后接一个斜线字符和前缀长度

如果Destination选项没有出现在[Route]小节,本节将视为默认路由。

提示:如果[Address]小节仅包含 Address 选项值并且[Route]小节仅包含 Gateway 选项值,可以把这两项放在[Network]小节中以简化配置。

[DHCP] 小节[编辑 | 编辑源代码]

参数 说明 值类型 默认值
UseDNS= controls whether the DNS servers advertised by the DHCP server are used 布尔值 true
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 布尔值 false
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 布尔值,route false

netdev 文件[编辑 | 编辑源代码]

这类文件将创建虚拟网络设备。包含两个小节:[Match][NetDev]。下列为每小节的通用配置。详情及范例请参阅systemd.netdev(5)

[Match] 小节[编辑 | 编辑源代码]

  • Host= 主机名
  • Virtualization= 检查是否运行于虚拟机中

[NetDev] 小节[编辑 | 编辑源代码]

最通用的配置为:

  • Name= 接口名称。必须提供
  • Kind= 例如:bridge, bond, vlan, veth, sit,等等。必须提供

link 文件[编辑 | 编辑源代码]

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.

提示:Use # udevadm test-builtin net_setup_link /sys/path/to/network/device to diagnose problems with .link files.

[Match] 小节[编辑 | 编辑源代码]

  • MACAddress= the MAC address
  • Host= the host name
  • Virtualization=
  • Type= the device type e.g. vlan

[Link] 小节[编辑 | 编辑源代码]

  • MACAddressPolicy= persistent or random addresses, or
  • MACAddress= a specific address
注意: the system /usr/lib/systemd/network/99-default.link is generally sufficient for most of the basic cases.

容器下的应用[编辑 | 编辑源代码]

The service is available with systemd. You will want to enable and start the systemd-networkd.service unit on the host and container.

For debugging purposes, it is strongly advised to 安装 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 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:

  • 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=1 setting in it, systemd-networkd will 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 networkctl command displays the status of network interfaces.

For the set-up described below,

  • we will limit the output of the ip a command 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

基本 DHCP 网络[编辑 | 编辑源代码]

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 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 /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.

注意: 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 用于两个独立 IP[编辑 | 编辑源代码]

桥接端口[编辑 | 编辑源代码]

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

/etc/systemd/network/MyBridge.netdev
[NetDev]
Name=br0
Kind=bridge

Restart 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.

绑定以太网到桥接端口[编辑 | 编辑源代码]

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.

桥接网络[编辑 | 编辑源代码]

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

添加选项以引导容器[编辑 | 编辑源代码]

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

成果[编辑 | 编辑源代码]

  • 在宿主机上
$ 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
  • 在容器中
$ 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 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.
  • 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.

  • 在宿主机上
$ 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
  • 在容器中
$ 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

静态 IP 网络[编辑 | 编辑源代码]

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 用于两个独立 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.

/etc/systemd/network/MyBridge.netdev
/etc/systemd/network/MyEth.network

Next, you need to configure the IP and DNS of the newly created virtual bridge interface. The following MyBridge.network provides an example configuration:

/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

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 start systemd-networkd.service on your container. An example configuration is provided below:

/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

交互界面及桌面集成[编辑 | 编辑源代码]

无论是命令行或是图形桌面,systemd-networkd都没有相应的交互式管理界面。但某些工具可以显示当前网络状态、接收通知或提供无线网络配置界面的功能:

  • networkctl (命令行)提供简单的网络接口状态展示。
  • 如果networkd配置了wpa_supplicant,那么wpa_cliwpa_gui 都提供了动态关联和配置 WLAN 接口的功能。
  • networkd-notify-gitAUR 可以生成简单的接口状态改变的通知消息(如:连接/断开以及重新关联等)。
  • networkd-dispatcherAUR 后台进程允许执行一个脚本以响应网络接口状态变化事件,类似于NetworkManager-dispatcher
  • systemd-resolved作为 DNS 解析器,resolvectl status命令可以将当前 DNS 服务器的信息做可视化呈现。

排错[编辑 | 编辑源代码]

引导时的“挂载”服务失败[编辑 | 编辑源代码]

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 不搜索本地域[编辑 | 编辑源代码]

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.

Possible workarounds:

  • Disable LLMNR to let systemd-resolved immediately continue with appending the DNS suffixes
  • Trim /etc/nsswitch.conf's hosts database (e.g., by removing [!UNAVAIL=return] option after resolve service)
  • Switch to using fully-qualified domain names
  • Use /etc/hosts to resolve hostnames
  • Fall back to using glibc's dns instead of using systemd's resolve

Connected second PC unable to use bridged LAN[编辑 | 编辑源代码]

First PC have two LAN. Second PC have one LAN and connected to first PC. Lets go second PC to give all access to LAN after bridged interface:

# sysctl net.bridge.bridge-nf-filter-pppoe-tagged=0
# sysctl net.bridge.bridge-nf-filter-vlan-tagged=0
# sysctl net.bridge.bridge-nf-call-ip6tables=0
# sysctl net.bridge.bridge-nf-call-iptables=0
# sysctl net.bridge.bridge-nf-call-arptables=0

参阅[编辑 | 编辑源代码]