跳转至内容

systemd-networkd

来自 ArchWiki

systemd-networkd 是一个系统守护进程,用于管理网络配置。它会检测并配置出现的网络设备;它还可以创建虚拟网络设备。此服务对于为由 systemd-nspawn 管理的容器或虚拟机设置复杂的网络配置特别有用。它在简单的连接上也能很好地工作。

安装

systemd 是 Arch 默认安装的一部分,并包含运行有线网络所需的所有文件。无线适配器,将在本文后面介绍,可以通过 wpa_supplicantiwd 等服务进行设置。

所需服务和设置

要使用 systemd-networkd,请 启动/启用 systemd-networkd.service

注意 每个网络接口应仅由一个 DHCP 客户端或网络管理器 管理,因此建议系统上只运行一个 DHCP 客户端或网络管理器。使用 systemctl --type=service 查找当前运行的服务列表,然后 停止 或重新配置有冲突的服务。

您还可以选择配置 systemd-resolved,这是一个为本地应用程序提供网络名称解析的服务,请考虑以下几点:

  • 要正确配置将使用的 DNS,理解 resolv.confsystemd-resolved 的交互方式非常重要,一些解释在 systemd-resolved 中提供。
  • 如果在 .network 文件中指定了 DNS 条目,则需要 systemd-resolved
  • 从 DHCP 服务器或 IPv6 路由器通告获取 DNS 地址也需要 systemd-resolved
    (通过在 [Network] 部分设置 (DHCP= 和/或 IPv6AcceptRA=),以及在相应的 [DHCPv4][DHCPv6][IPv6AcceptRA] 部分设置 UseDNS=yes(默认值),参见 systemd.network(5))。
  • 请注意,systemd-resolved 也可以在没有 systemd-networkd 的情况下使用。

systemd-networkd-wait-online

启用 systemd-networkd.service 也会启用 systemd-networkd-wait-online.service,这是一个一次性系统服务,它会等待网络配置完成。后者具有 WantedBy=network-online.target,因此只有当 network-online.target 本身被启用或被其他单元拉入时才会启动。另请参阅 systemd#Running services after the network is up

默认情况下,systemd-networkd-wait-online.service 会等待由 systemd-networkd 管理的所有链路完全配置或失败,并至少有一个链路在线。

有关详细信息,请参阅 systemd-networkd-wait-online(8)

配置

systemd 示例网络文件

启用网络接口的快速方法是使用位于 /usr/lib/systemd/network/ 的提供的 .example 文件之一。例如,要启用 Wi-Fi 和以太网,可以创建指向示例文件的符号链接:

# ln -s /usr/lib/systemd/network/80-wifi-station.network.example /etc/systemd/network/80-wifi-station.network
# ln -s /usr/lib/systemd/network/89-ethernet.network.example /etc/systemd/network/89-ethernet.network

您可以使用 networkctl 添加任何额外的自定义配置。参见 #networkctl 部分。

多个不总是连接的接口

对于具有多个不总是连接的网络接口的系统(例如,双端口以太网卡,但只连接一根网线),启动 systemd-networkd-wait-online.service 将在默认的 2 分钟超时后失败。这可能会导致启动过程出现不必要的延迟。要将行为更改为等待 *任何* 接口在线而非 *所有* 接口在线,请 编辑 服务并在 ExecStart 行添加 --any 参数:

/etc/systemd/system/systemd-networkd-wait-online.service.d/wait-for-only-one-interface.conf
[Service]
ExecStart=
ExecStart=/usr/lib/systemd/systemd-networkd-wait-online --any

或者,使用 systemd-networkd-wait-online@.service 来等待特定接口。例如,要等待 enp1s0,请 禁用 systemd-networkd-wait-online.service启用 systemd-networkd-wait-online@enp1s0.service

提示 如果您知道哪个接口可能不总是启动,您可以在 .network 配置文件中的 [Link] 部分使用 RequiredForOnline=no 来代替。参见 systemd.network(5) § [LINK] SECTION OPTIONS

等待网络接口拥有可路由地址

根据 systemd-networkd-wait-online.service(8),“在线意味着链路的操作状态等于或高于‘降级’。”(有关‘降级’和其他操作状态的定义,请参阅 networkctl(1))。

为防止 systemd-networkd-wait-online.service 在网络接口拥有可路由 IP 地址之前退出(从而导致其他需要正常运行的网络连接的服务过早启动),请在 .network 文件的 [Link] 部分添加 RequiredForOnline=routable

[Link]
RequiredForOnline=routable

等待 DNS 服务器可达

systemd-networkd-wait-online.service(8) 可以在所有配置的接口都能连接到其 DNS 服务器之前延迟退出。这可以提高在达到 network-online.target 且其后排序的单元开始启动时 DNS 可用的可能性。

要启用此功能,请 编辑 systemd-networkd-wait-online.service 并在 ExecStart 行添加 --dns 选项:

/etc/systemd/system/systemd-networkd-wait-online.service.d/wait-for-dns.conf
[Service]
ExecStart=
ExecStart=/usr/lib/systemd/systemd-networkd-wait-online --dns

用法

本条目或章节是合并至 #配置 的候选对象。

注意: 解释配置文件的工作原理属于配置部分。(请在 Talk:Systemd-networkd 中讨论)

本文章或章节需要扩充。

原因: 添加 networkctl 命令并简化从以前的“配置文件”部分合并的内容。(请在 Talk:Systemd-networkd 中讨论)

全局配置文件 /etc/systemd/networkd.conf 只能用于覆盖某些默认设置。主要配置是针对每个网络设备进行的。配置文件位于 /usr/lib/systemd/network/、易失性运行时网络目录 /run/systemd/network/ 和本地管理网络目录 /etc/systemd/network//etc/systemd/network/ 中的文件具有最高优先级。

有三种类型的配置文件。它们都使用与 systemd 单元文件 类似的格式。

.network 文件
它们将对 *匹配* 的设备应用网络配置。参见 systemd.network(5) man 页。
.netdev 文件
它们将为 *匹配* 的环境创建一个 *虚拟网络设备*。参见 systemd.netdev(5) man 页。
.link 文件
当网络设备出现时,udev 会查找第一个 *匹配* 的 .link 文件。参见 systemd.link(5) man 页。

它们都遵循相同的规则:

  • 如果 [Match] 部分中的 *所有* 条件都匹配,则该配置文件将被激活。
  • 一个空的 [Match] 部分意味着该配置文件将应用在任何情况下(可以与 * 通配符进行比较)。
  • 所有配置文件都会被集体排序并按词汇顺序处理,无论它们位于哪个目录。
  • 具有相同名称的文件会相互替换。

在更改配置文件后,请 重启 systemd-networkd.service

  • 配置文件中指定的选项区分大小写。
  • 在下面的示例中,enp1s0 是有线适配器,wlp2s0 是无线适配器。这些名称在不同系统上可能不同。请参阅 网络配置#网络接口网络配置#更改接口名称
  • 也可以使用通配符,例如 Name=en*Name=wl*
  • 设备也可以按类型匹配。例如,Type=ether 表示以太网,Type=wlan 表示 Wi-Fi,Type=wwan 表示 WWAN。
  • 请注意,Type=ether 也会匹配虚拟以太网接口。要排除它们,请将 Type=etherKind=!* 结合使用。
提示
  • /etc/systemd/network/ 中的文件会覆盖 /usr/lib/systemd/network/ 中相应的系统提供的文件。您可以选择使用指向 /dev/null 的符号链接来“屏蔽”一个系统文件。
  • systemd 接受 1trueyeson 作为真布尔值,以及 0falsenooff 作为假布尔值。参见 systemd.syntax(7)
  • systemd-networkd 还会为其他网络软件修改路由表。如果不需要这样做,请相应地在 networkd.conf(5) 中配置 ManageForeignRoutingPolicyRules=。例如,参见 WireGuard#Connection lost after sleep using systemd-networkd

networkctl

您可以使用 networkctl 查询或修改网络链路的状态。

$ networkctl
IDX LINK        TYPE     OPERATIONAL SETUP    
  1 lo          loopback carrier     unmanaged
  2 wlo1        wlan     routable    unmanaged
  3 tailscale0  none     routable    unmanaged
  4 enp0s20f0u1 ether    routable    unmanaged

例如,为 Wi-Fi 接口启用多播 DNS。

# networkctl edit @wlan0 --drop-in mdns
[Network]
MulticastDNS=true

wlan0 替换为您的稳定接口名称,或指定完整路径。参见 networkctl(1)

使用 DHCP 的有线适配器

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

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes

使用静态 IP 的有线适配器

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

[Network]
Address=10.1.10.9/24
Address=2001:db8:1234:5678::1/64
Gateway=10.1.10.1
Gateway=fe80::1
DNS=10.1.10.1
DNS=2001:db8:1122::3344:1

Address= 可以使用多次来配置多个 IPv4 或 IPv6 地址。参见 systemd.network(5) 以了解更多选项。

无线适配器

要使用 systemd-networkd 连接到无线网络,需要一个使用其他应用程序(如 wpa_supplicantiwd)配置的无线适配器。

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

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes
IgnoreCarrierLoss=3s

如果无线适配器具有静态 IP 地址,配置与 有线适配器 中的配置相同(除了接口名称)。

提示 IgnoreCarrierLoss=3s 可确保在无线接口漫游到同一无线网络(SSID)内的另一个接入点时,systemd-networkd 不会在短时间内(此处为 3 秒)重新配置接口(例如,释放并重新获取 DHCP 租约),从而缩短漫游时的停机时间。

要对无线网络进行身份验证,请使用例如 wpa_supplicantiwd

同一台机器上的有线和无线适配器

此设置将为有线和无线连接启用 DHCP IP,利用 metric 指令使内核能够动态决定使用哪个连接。这样,当有线连接断开时,不会出现连接中断。

内核的路由度量(与使用 ip 配置的相同)决定了在有多个匹配路由时使用哪个路由来转发出站数据包。当系统上的无线和有线设备都有活动连接时就会出现这种情况。为了打破僵局,内核会使用度量。如果其中一个连接终止,另一个连接会自动获胜,而不会出现未配置的间隙(持续传输可能仍然无法很好地处理这种情况,但这发生在不同的 OSI 层)。

systemd-networkd 不会为每种接口类型设置默认路由度量,因此需要手动配置。

注意 Metric 选项用于静态路由,而 RouteMetric 选项用于不使用静态路由的设置。有关更多详细信息,请参见 systemd.network(5)
/etc/systemd/network/20-wired.network
[Match]
Name=enp1s0

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes

[DHCPv4]
RouteMetric=100

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

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes

[DHCPv4]
RouteMetric=600

[IPv6AcceptRA]
RouteMetric=600

DHCP 服务器

这是一个 DHCP 服务器配置示例,它与 hostapd 配合良好,用于创建无线热点。IPMasquerade 添加了用于 NAT 的防火墙规则,并隐含 IPv4Forwarding=yes 以启用 数据包转发

本文或本章节的准确性存在争议。

原因: IPMasquerade=ipv4 不会添加 filter 表的规则,必须手动添加。参见 systemd-nspawn#Use a virtual Ethernet link。(请在 Talk:Systemd-networkd 中讨论)
/etc/systemd/network/wlan0.network
[Match]
Name=wlan0

[Network]
Address=10.1.1.1/24
DHCPServer=true
IPMasquerade=ipv4

[DHCPServer]
PoolOffset=100
PoolSize=20
EmitDNS=yes
DNS=9.9.9.9

有关所有可用选项,请参见 systemd.network(5) § [DHCPSERVER] SECTION OPTIONS

与容器一起使用

systemd-networkd 可以为 systemd-nspawn 容器提供完全自动化的网络配置,使用私有网络,当它在宿主系统上以及在容器内部使用时。参见 systemd-nspawn#Networking 以获得全面的概述。

提示 在宿主系统上,启动 systemd-networkd.service 是*所有需要*的操作,以提供所描述的网络自动配置给使用默认 虚拟以太网链路 设置的容器。以下内容仅用于其他私有网络场景。

对于下面的示例,

  • 我们将 ip a 命令的输出限制在相关接口,
  • 我们假设*宿主*是运行在真实硬件上的主操作系统,*容器*是客户系统,
  • 所有接口名称和 IP 地址仅为示例。

带 DHCP 的网络桥接

桥接接口

首先,创建一个虚拟 桥接 接口,使用一个 .netdev 单元文件,它告诉 systemd-networkd 创建一个名为 br0 的设备,该设备充当以太网桥。

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

您也可以选择在桥接的 NetDev 部分添加 MACAddress=none 来让桥接继承其中一个桥接接口的 MAC 地址。这还需要创建一个 25-br0.link 文件。

提示 systemd-networkd 分配一个基于接口名称和机器 ID 生成的 MAC 地址给桥接。这可能会导致连接问题,例如在基于 MAC 过滤的路由情况下。为避免此类问题,请为您的桥接分配一个 MAC 地址,最好是与您的物理设备相同,在上面的 NetDev 部分添加 MACAddress=xx:xx:xx:xx:xx:xx 行。

重启 systemd-networkd.service 以让 systemd-networkd 创建桥接。

要查看宿主和容器中新创建的桥接,请键入:

$ 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

请注意,此时接口 br0 已列出但仍处于 DOWN 状态。

将以太网绑定到桥接

下一步是将网络接口添加到新创建的桥接。桥接的配置文件必须在桥接接口的配置文件之前加载,因此其配置文件在字母数字上应该优先于后者。在下面的示例中,我们将名称匹配 en* 的任何接口添加到桥接 br0

/etc/systemd/network/25-br0-en.network
[Match]
Name=en*

[Network]
Bridge=br0

以太网接口不得关联 DHCP 或 IP 地址,因为桥接需要一个不带 IP 地址的接口来绑定。

注意 确保没有其他 .network 文件尝试通过 Name=en* 匹配接口。只有第一个匹配接口的文件才会被应用。

桥接网络

现在桥接已创建并已绑定到现有网络接口,必须指定桥接接口的 IP 配置。这在第三个 .network 文件中定义,下面的示例使用 DHCP。

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

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes

继承 MAC 地址(可选)

要使桥接继承其中一个桥接接口的 MAC 地址,请设置 MACAddress=noneMACAddressPolicy=none

/etc/systemd/network/25-br0.netdev
[NetDev]
Name=br0
Kind=bridge
MACAddress=none
/etc/systemd/network/25-br0.link
[Match]
OriginalName=br0

[Link]
MACAddressPolicy=none

配置容器

启动容器时使用 --network-bridge=br0 选项。有关详细信息,请参见 systemd-nspawn#Use a network bridge

结果

  • 在宿主系统上
$ 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

Notice

  • 现在我们在宿主系统上有一个 br0 的 IP 地址,在容器中有一个 host0 的 IP 地址。
  • 出现了两个新接口:宿主系统中的 vb-MyContainer 和容器中的 host0。这是由于 --network-bridge=br0 选项,正如在 systemd-nspawn#Use a network bridge 中解释的那样。
  • host0 上的 DHCP 地址来自系统 /usr/lib/systemd/network/80-container-host0.network 文件。
  • 在宿主系统上

本文或本章节已过时。

原因: brctl 已弃用,请使用 bridge link。参见 网络桥接#With iproute2。(请在 Talk:Systemd-networkd 中讨论)
$ brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.14dae9b57a88	no		enp7s0
							vb-MyContainer

上面的命令输出证实我们有一个桥接,并且有两个接口绑定到它。

  • 在宿主系统上
$ 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

上面的命令输出证实我们已经启用了 br0host0 接口,并带有 IP 地址和网关 192.168.1.254。网关地址已由 systemd-networkd 自动获取。

带静态 IP 地址的网络桥接

为每个设备设置静态 IP 地址对于部署 Web 服务(例如 FTP、HTTP、SSH)很有帮助。如果您的系统 /usr/lib/systemd/network/99-default.link 文件具有 MACAddressPolicy=persistent 选项(默认情况下具有),则每个设备在重启后将保留相同的 MAC 地址。此设置会将网关上的任何服务路由到所需的设备。

需要为此设置进行以下配置:

  • 在宿主系统上

配置非常类似于 #Network bridge with DHCP 部分。首先,需要创建一个虚拟桥接接口,并将主物理接口绑定到它。可以使用以下两个文件来完成此任务,其内容与 DHCP 部分中的内容相同。

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

接下来,您需要配置新创建的虚拟桥接接口的 IP 和 DNS。例如:

/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
  • 在容器中

要为容器配置静态 IP 地址,我们需要覆盖系统 /usr/lib/systemd/network/80-container-host0.network 文件,该文件为容器的 host0 网络接口提供 DHCP 配置。这可以通过将配置放在 /etc/systemd/network/80-container-host0.network 中来完成。例如:

/etc/systemd/network/80-container-host0.network
[Match]
Name=host0

[Network]
DNS=192.168.1.254
Address=192.168.1.94/24
Gateway=192.168.1.254

请确保 systemd-networkd.service 在容器中已 启用

MACVLAN 桥接

为了让宿主能够访问通过 MACVLAN 连接的容器,宿主本身也需要通过 MACVLAN 连接,而不是直接连接到底层以太网网络接口。

在宿主系统上,将底层以太网网络接口附加到 MACVLAN,并确保它不会被分配 IP 地址。例如,使用 mv-0 作为 MACVLAN 接口名称,并使用 enp1s0 作为宿主的以太网接口:

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

[Link]
RequiredForOnline=carrier

[Network]
MACVLAN=mv-0
DHCP=no
IPv6AcceptRA=false
LinkLocalAddressing=no
MulticastDNS=false
LLMNR=false
提示
  • RequiredForOnline=carrier 防止 systemd-networkd-wait-online.service 等待(并最终失败)连接获取 IP 地址,而这永远不会发生。
  • 底层网络接口不一定非得是物理以太网接口。例如,MACVLAN 桥接可以附加到 bond。

创建 MACVLAN 桥接 mv-0

/etc/systemd/network/25-mv-0.netdev
[NetDev]
Name=mv-0
Kind=macvlan

[MACVLAN]
Mode=bridge

配置宿主系统在 MACVLAN 桥接 (mv-0) 上的网络连接。以下示例使用 DHCP,请根据需要替换选项。

/etc/systemd/network/35-mv-0.network
[Match]
Name=mv-0

[Link]
RequiredForOnline=routable

[Network]
BindCarrier=enp1s0
DHCP=yes

对于容器,将 MACVLAN 附加到*底层以太网网络接口*(上述示例中的 enp1s0)。例如,在 /etc/systemd/nspawn/container_name.nspawn 中指定:

[Network]
MACVLAN=enp1s0

对于从命令行启动的容器,请传递 --network-macvlan=enp1s0 选项。

在容器中,MACVLAN 接口的名称将是 mv-underlying_interface_name(例如 mv-enp1s0)。根据需要配置网络连接(与宿主系统中的一样),通过匹配接口名称。例如,使用 DHCP:

/etc/systemd/network/30-mv-enp1s0.network
[Match]
Name=mv-enp1s0

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes

技巧与提示

接口和桌面集成

systemd-networkd 没有一个完善的交互式图形管理界面。尽管如此,还是有一些工具可用于显示或修改网络的当前状态、接收通知或与无线配置进行交互。

  • networkctl 提供了一个 命令行 shell 接口来查询或修改网络接口状态。值得注意的是,要仅更改接口行为的某些方面,需要先 编辑 /etc/systemd/network/ 中的一个或多个配置文件。
  • networkd 配置了 wpa_supplicant 时,wpa_cliwpa_gui 都提供了动态关联和配置 WLAN 接口的能力。
  • networkd-dispatcherAUR 守护进程允许响应网络接口状态变化执行脚本,类似于 NetworkManager-dispatcher
  • networkd-notify-gitAUR 在接口变化时创建简单的通知消息。
  • 至于 DNS 解析器 systemd-resolved,可以使用 resolvectl status 可视化当前 DNS 服务器的信息。

基于 SSID(位置)配置静态 IP 或 DHCP

通常会遇到家庭无线网络使用 DHCP,而办公室无线网络使用静态 IP 的情况。这种混合设置可以如下配置:

注意 文件名中的数字决定了文件处理的顺序。用户可以基于 SSID 或 BSSID(或两者)进行 [Match]
/etc/systemd/network/24-wireless-office.network
# special configuration for office Wi-Fi network
[Match]
Name=wlp2s0
SSID=office_ap_name
#BSSID=aa:bb:cc:dd:ee:ff

[Network]
Address=10.1.10.9/24
Gateway=10.1.10.1
DNS=10.1.10.1
#DNS=8.8.8.8
/etc/systemd/network/25-wireless-dhcp.network
# use DHCP for any other Wi-Fi network
[Match]
Name=wlp2s0

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes

绑定有线和无线接口

另请参阅 无线绑定

绑定允许通过多个接口共享连接,因此如果例如有线接口断开连接,无线接口仍然连接,并且网络连接会无缝保持。

创建绑定接口。在这种情况下,模式为 active-backup,这意味着如果主接口出现故障,数据包将通过辅助接口路由。

/etc/systemd/network/30-bond0.netdev
[NetDev]
Name=bond0
Kind=bond

[Bond]
Mode=active-backup
PrimaryReselectPolicy=always
MIIMonitorSec=1s

将有线接口设置为主接口。

/etc/systemd/network/30-ethernet-bond0.network
[Match]
Name=enp0s25

[Network]
Bond=bond0
PrimarySlave=true

将无线接口设置为辅助接口。

/etc/systemd/network/30-wifi-bond0.network
[Match]
Name=wlan0

[Network]
Bond=bond0
注意[Match] 部分使用 MAC 地址时,建议使用 PermanentMACAddress 而非 MACAddress,参见 此上游讨论

像普通接口一样配置绑定接口。

/etc/systemd/network/30-bond0.network
[Match]
Name=bond0

[Link]
RequiredForOnline=routable

[Network]
BindCarrier=enp0s25 wlan0
DHCP=yes

现在,如果拔掉了有线网络连接,连接应继续通过无线接口保持。

$ networkctl
IDX LINK    TYPE     OPERATIONAL      SETUP     
  1 lo      loopback carrier          unmanaged 
  2 enp0s25 ether    no-carrier       configured
  3 bond0   bond     degraded-carrier configured
  5 wlan0   wlan     enslaved         configured

4 links listed.

加速 TCP 慢启动

在具有中等延迟的高带宽链路上(通常是 10 Mbit/s 以上的家庭互联网连接),TCP 慢启动算法的默认设置有些保守。这个问题表现为下载开始缓慢,需要几秒钟才能加速到连接的全部带宽。这在 pacman 升级时尤其明显,每个下载的包都开始缓慢,并且在达到连接的全部速度之前就经常完成。

可以通过调整这些设置,使 TCP 连接以比默认值更大的窗口大小开始,从而避免它们在每个新 TCP 连接上自动增加所需的时间[1]。虽然这通常会因需要重新传输大量丢失的数据包而降低慢速连接的性能(或当值设置过高时),但可以显著提高具有足够带宽的连接的性能。

在更改这些值之前和之后进行基准测试很重要,以确保它正在提高网络速度而不是降低。如果您没有看到下载开始缓慢然后逐渐加速,那么就没有必要更改这些值,因为它们对您的连接速度来说已经是最优的了。进行基准测试时,请务必针对高速和低速远程服务器进行测试,以确保您不是通过加快对快速机器的访问来牺牲对慢速服务器的访问速度,使其变得更慢。

要调整这些值,请编辑连接的 .network 文件:

/etc/systemd/network/eth0.network
[Match]
Name=eth0

#[Network]
#Gateway=...  <-- Remove this if you have it, and put it in the Gateway= line below

[Route]
# This will apply to the gateway supplied via DHCP.  If you manually specify
# your gateway, put it here instead.
Gateway=_dhcp4

# The defaults for these values is 10.  They are a multiple of the MSS (1460 bytes).
InitialCongestionWindow=10
InitialAdvertisedReceiveWindow=10

对于慢于 10 Mbit/s 的连接,默认值 10 可以正常工作。对于 100 Mbit/s 的连接,值 30 可以正常工作。man 页 systemd.network(5) § [ROUTE] SECTION OPTIONS 表示值 100 被认为是过高的。

如果启用了 sysctl 设置 net.ipv4.tcp_slow_start_after_idle,那么在连接空闲一段时间后(通常是很短的时间),连接将恢复到这些初始设置。如果禁用此设置,则在协商了更大的窗口后,连接将保持较高的窗口。无论设置如何,每个新的 TCP 连接都将以上面设置的 Initial* 设置开始。

sysctl 设置 net.ipv4.tcp_congestion_control 与这些值没有直接关系,因为它控制 TCP 链路激活期间拥塞和接收窗口如何调整,特别是当两个主机之间的路径拥塞且吞吐量必须降低时。上面的 Initial* 值仅设置每个新连接选择的默认窗口值,然后任何拥塞算法开始接管并根据需要进行调整。设置更高的初始值只是绕过了一些协商过程,而拥塞算法则试图找到最佳值(反之亦然,设置不正确的初始值会增加额外的协商时间,而拥塞算法则会努力纠正它们,从而使每个新建立的 TCP 连接额外慢几秒钟)。

防止多个默认路由

systemd-networkd 不会为每种接口类型设置默认路由度量,即在使用多个网络设备时需要手动配置。例如,以下 ip route 显示了多个默认路由:

ip route
default via 10.30.1.1 dev eno2 proto dhcp src 10.30.1.15 metric 1024
default via 192.168.1.254 dev eno1 proto dhcp src 172.18.105.104 metric 1024

由于分配了相同的默认 metric1024,因此存在一个竞争条件,即两者中的哪个被选为默认路由。由于 eno2 设备先启动,它被优先考虑,因此通过 eno1 可用的访问可能会被忽略。

为防止此竞争条件,请为设备分配不同的 RouteMetric= 值。有关相应示例,请参见 #Wired and wireless adapters on the same machine

如果相反,一个设备不应提供默认路由,则可以在 [DHCPv4][IPv6AcceptRA] 部分中使用 UseGateway=false 选项来省略创建 DHCP/RA 服务器提供的默认路由,同时保留其他无类别静态路由。例如,当设备提供到单个其他机器的连接时,这可能很有用。

在一个现有接口上配置第二个具有自己 MAC 地址的静态 IP

要让您的计算机在路由器看来像是两个完全独立的设备,您可以创建一个虚拟接口,它不仅具有不同的 IP 地址,还具有不同的 MAC 地址。

要实现这一点,请在您的物理接口之上创建一个具有唯一 MAC 地址的虚拟接口(macvlan

/etc/systemd/network/25-eth210.netdev
[NetDev]
Name=eth210
Kind=macvlan
MACAddress=00:11:22:33:44:55

[MACVLAN]
Mode=bridge

然后像往常一样添加一个网络文件,使用相同的子网和网关,如果您配置的是静态 IP,请避免使用 DHCP 地址池中的 IP 号段。例如

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

[Network]
Address=192.168.132.210/24
Gateway=192.168.132.1

[Route]
Destination=192.168.132.0/24
Metric=2

macvlan 接口路由的度量值为 2。这确保了流量会优先通过主接口(因为主接口(隐式地)具有度量值为 1 的默认路由),除非明确指示使用 macvlan 接口。

最后,在您主接口的 .network 文件的 [Network] 部分添加 MACVLAN=eth210

此时,一种快速让您的路由器感知新 MAC(并配置它接受该 MAC)的方法是,您可以例如以 root 身份运行 arping -I eth210 192.168.132.1。在为“新设备”配置好路由器后,您可以测试新接口是否具有互联网访问权限,例如运行 curl --interface 192.168.132.210 ifconfig.me,它应该会显示您的公共 IP 地址。

参见