netctl
netctl 是一个基于配置文件的命令行网络管理器,也是一个 Arch 项目。
安装
netctl 用于自动化连接的 #特殊的 systemd 单元需要一些额外的依赖;请参阅该章节了解更多信息。
其他可选依赖项如下表所示。
| 特性 | 依赖项 |
|---|---|
| WPA | wpa_supplicant |
| DHCP | dhcpcd 或 dhclient |
| wifi-menu | dialog |
| PPPoE | ppp |
systemctl --type=service 确保没有其他网络服务正在运行。配置
netctl 使用配置文件来管理网络连接,并使用不同的操作模式来自动或手动按需启动配置。
netctl 配置文件存放在 /etc/netctl/ 中,示例配置文件位于 /etc/netctl/examples/ 中。
要使用示例配置,只需将其从 /etc/netctl/examples/ 复制到 /etc/netctl/ 并根据需要进行配置;请参阅下方的 #配置示例。创建配置所需的第一项参数是网络 Interface (接口),详情请参阅 网络配置#网络接口。
- 对于无线设置,您可以以 root 身份使用
wifi-menu在/etc/netctl/中生成配置文件。使用 wifi-menu 需要 dialog 软件包。 - 在您的配置中使用
SkipNoCarrier=yes,即可在有线接口上启用静态 IP 配置,无论网线是否连接。
有关配置选项的完整列表,请参阅 netctl.profile(5)。
用法
有关 netctl 命令的完整列表,请参阅 netctl(1)。
启动配置
创建配置文件后,尝试建立连接(其中 profile 仅指配置名称,而非完整路径):
# netctl start profile
如果上述命令导致失败,请以 root 身份运行 journalctl -xn 和 netctl status profile 以获取更详细的错误原因。
启用配置
可以通过以下方式启用配置,使其在开机时启动:
# netctl enable profile
这将创建并启用一个 systemd 服务,该服务会在计算机启动时运行。对配置文件的更改不会自动同步到服务文件。更改后,需要重新启用该配置。
# netctl reenable profile
启用配置后,它将在下次启动时运行。当然,这仅在有线连接已插上网线,或无线连接所用的接入点处于覆盖范围内时才能成功。
如果您需要频繁切换多个配置(例如使用笔记本电脑出行),请使用 #特殊的 systemd 单元,而不是启用配置。
特殊的 systemd 单元
netctl 提供了特殊的 systemd 服务,用于自动切换有线和无线连接配置。有关特殊 systemd 单元的完整列表,请参阅 netctl.special(7)。
有线
安装 ifplugd 软件包,并 启动/启用 netctl-ifplugd@interface.service systemd 单元。当网线插入/拔出时,DHCP 配置将自动启动/停止。
netctl-ifplugd@interface.service会优先选择使用 DHCP 的配置。- 若要自动启动静态 IP 配置,需要在其中设置
ExcludeAuto=no选项。 - 若要使静态 IP 配置优先于 DHCP 配置,可以将
Priority=2设置得高于 DHCP 配置默认的Priority=1。
无线
启动/启用 netctl-auto@interface.service systemd 单元。当您从一个网络覆盖范围移动到另一个网络范围时(漫游),netctl 配置将自动启动/停止。
- 配置必须使用
Security=wpa-configsection或Security=wpa才能与 netctl-auto 配合使用,而不是Security=wpa-config。 - 如果您希望某个无线配置不被
netctl-auto@interface.service自动启动,则必须显式在该配置中添加ExcludeAuto=yes。 - 您可以在 WPAConfigSection 中使用
priority=(参见/etc/netctl/examples/wireless-wpa-configsection)来设置当多个接入点可用时的连接优先级。数值越大,优先级越高。
注意,interface 不是字面意思,需要替换为您设备接口的名称,例如 netctl-auto@wlp4s0.service。详情请参阅 netctl.profile(5)。
- 如果任何配置包含错误(例如
Key=变量为空或引号引用错误),即使该配置未被使用,服务单元加载时也会显示"Failed to read or parse configuration '/run/network/wpa_supplicant_wlan0.conf'错误。 - 如果您之前通过 netctl 启用了配置,请运行
netctl disable profile以防止配置在启动时被重复加载。
您无需停止 netctl-auto.service 即可手动控制受 netctl-auto 管理的接口,方法是使用 netctl-auto 命令。有关可用操作的完整列表,请参阅 netctl-auto(1)。
技巧与提示
配置示例
有线
对于 DHCP 连接,在将 /etc/netctl/examples/ethernet-dhcp 示例配置复制到 /etc/netctl 后,只需配置 Interface。
例如:
/etc/netctl/my_dhcp_profile
Interface=enp1s0 Connection=ethernet IP=dhcp
对于静态 IP 配置,将 /etc/netctl/examples/ethernet-static 复制到 /etc/netctl,并按需修改 Interface、Address、Gateway 和 DNS。
例如:
/etc/netctl/my_static_profile
Interface=enp1s0
Connection=ethernet
IP=static
Address=('10.1.10.2/24')
Gateway='10.1.10.1'
DNS=('10.1.10.1')
注意必须包含子网掩码标记 /24(等同于 255.255.255.0),否则配置将无法启动。另请参阅 CIDR 表示法。要为单个 NIC 设置多个 IP 地址,请设为 Address=('10.1.10.2/24' '192.168.1.2/24')。要设置多个 DNS 服务器,请设为例如 DNS=('1.1.1.1' '1.0.0.1')。
无线连接 (WPA-PSK)
以下内容适用于使用预共享密钥 (WPA-PSK) 的标准无线连接。
/etc/netctl/wireless-wpa
Description='A simple WPA encrypted wireless connection using 256-bit PSK' Interface=wlp2s2 Connection=wireless Security=wpa IP=dhcp ESSID=your_essid Key=\"64cf3ced850ecef39197bb7b7b301fc39437a6aa6c6a599d0534b16af578e04a
- 请务必遵守 netctl.profile(5) § 特殊引用规则 中对
Key变量的特殊引用规则说明。 - 如果密码无法通过认证,请尝试移除
Key变量中的\"。 - 尽管进行了“加密”,但您放入配置中的密钥足以连接到 WPA-PSK 网络。因此,此过程仅用于隐藏明文密码。这并不能防止任何拥有该文件读取权限的人连接到网络。
混淆无线密码
您也可以执行以下步骤来混淆无线密码(使用 -o 标志时,wifi-menu 会自动执行此操作)。
如果不希望无线网络密码以 明文 形式存储,用户可以选择存储相应的 256 位预共享密钥 (PSK),该密钥是根据密码和 SSID 使用标准算法计算得出的。
使用 wpa_passphrase 计算您的 256 位 PSK。
$ wpa_passphrase your_essid
network={
ssid="your_essid"
#psk="passphrase"
psk=64cf3ced850ecef39197bb7b7b301fc39437a6aa6c6a599d0534b16af578e04a
}
现在需要用计算出的 预共享密钥 (psk) 替换配置文件中 Key 变量的明文密码。
使用实验性 GUI
如果您需要一个图形用户界面来管理 netctl 及您的连接,并且不介意使用高度实验性的非官方软件包,有一些选项可供选择。netctl-guiAUR 提供了基于 Qt 的图形界面、DBus 守护进程和 KDE 部件。netmenuAUR 使用 dmenu 作为图形界面。
还有一个应用程序可以显示配置更改的桌面通知并提供托盘图标:netctl-trayAUR。
绑定 (Bonding)
源自 内核文档
- Linux 绑定驱动程序提供了一种将多个网络接口聚合为单个逻辑“绑定”接口的方法。绑定接口的行为取决于其模式。通常,模式提供热备用或负载均衡服务。此外,还可以执行链路完整性监控。
负载均衡
将 /etc/netctl/examples/bonding 复制到 /etc/netctl/bond0 并根据需要编辑,例如:
/etc/netctl/bond0
Description='Bond Interface'
Interface='bond0'
Connection=bond
BindsToInterfaces=('eth0' 'eth1')
IP=dhcp
IP6=stateless
现在您可以禁用旧的配置并将 bond0 设置为自动启动。切换到新配置,例如:
# netctl switch-to bond0
bonding 驱动程序的默认策略。详情请参阅 官方文档。在 netctl 配置中设置 MODE 并不总是成功,可能需要在加载时直接将选项传递给 bonding 模块,如 此处 所述。这在需要使用 LACP / 模式 4 时可能是必要的。
$ cat /proc/net/bonding/bond0
有线到无线故障转移
此示例说明如何使用 bonding 在有线以太网断开时回落到无线连接。这在有线和无线接口连接到同一网络时非常有用。您的无线路由器/接入点必须配置为 桥接 (bridge) 模式。
您需要一个额外的软件包:wpa_supplicant。
首先,在启动时加载模块:
/etc/modules-load.d/bonding.conf
bonding
然后,配置 bonding 驱动选项以使用 active-backup,并将 primary 参数配置为您希望作为活动接口的设备(通常是有线接口)。同时,确保使用 ip link 返回的相同设备名称。
/etc/modprobe.d/bonding.conf
options bonding mode=active-backup miimon=100 primary=eth0 max_bonds=0
miimon 选项用于链路故障检测。max_bonds 选项可以避免 Interface bond0 already exists 错误。更多信息可以在 内核文档 中找到。
接下来,配置一个 netctl 配置文件来桥接这两个硬件接口。使用所有您希望绑定的设备名称。如果您有两个以上的有线或无线接口,可以将它们全部绑定到一个 bond 接口上。但大多数情况下,您只有两个设备:一个有线和一个无线。
/etc/netctl/failover
Description='A wired connection with failover to wireless'
Interface='bond0'
Connection=bond
BindsToInterfaces=('eth0' 'wlan0')
IP='dhcp'
禁用之前启用的任何其他配置文件(特别是原有的有线或无线配置),然后启用此故障转移配置文件。
# netctl enable failover
现在您需要配置 wpa_supplicant 以连接到任何您想要的已知网络。您应该为每个接口创建一个文件并在 systemd 上启用它。创建以下文件并填入内容:
/etc/wpa_supplicant/wpa_supplicant-wlan0.conf
ctrl_interface=/run/wpa_supplicant update_config=1
并在该文件末尾追加您想要连接的任何网络:
network={
ssid="SSID"
psk=PSK
}
要生成混淆的 PSK,可以按照 wpa_supplicant#Connecting with wpa_passphrase 页面运行 wpa_passphrase。
现在,在网络接口上 启用 wpa_supplicant@ 模板服务,例如 wpa_supplicant@wlan0。
现在您可以尝试重启机器,查看配置是否生效。
现在,您可以通过开始一次大文件下载来测试故障转移。拔掉网线,下载应该会自动通过无线接口继续。然后重新插上网线,它应该会切回并继续工作。您可以通过查看 journalctl 中 netctl@failover.service 和 wpa_supplicant@wlan0.service 单元的日志来进行调试。
使用任意接口
在某些情况下,可能希望允许配置使用系统上的任何接口。一个常见的用例是跨多台硬件不同的机器使用通用的磁盘映像(对于无头服务器尤其有用)。如果您使用内核的命名方案,且机器只有一个以太网接口,您可以推测 eth0 是正确的接口。然而,如果您使用 udev 的 可预测网络接口名称,名称将基于具体的硬件本身(例如 enp1s0)分配,而不是简单地按照检测顺序(如 eth0, eth1)。这意味着一个 netctl 配置在某台机器上工作,但在另一台机器上可能不行,因为它们的接口名称不同。
一个简单粗暴的解决方案是利用 /etc/netctl/interfaces/ 目录。为您的接口别名选择一个名称(本例中为 en-any),并将以下内容写入该名称的文件中(确保它是 可执行的)。
/etc/netctl/interfaces/en-any
#!/bin/sh
for interface in /sys/class/net/en*; do
break;
done
Interface=$(basename "$interface")
echo "en-any: using interface $Interface";
然后创建一个使用该接口的配置。特别注意 Interface 指令。其余部分仅作为示例提供。
/etc/netctl/wired
Description='Wired'
Interface=en-any
Connection=ethernet
IP=static
Address=('192.168.1.15/24')
Gateway='192.168.1.1'
DNS=('192.168.1.1')
当启动 wired 配置时,任何使用上述两个文件的机器都会自动启用并配置系统上发现的第一个以太网接口,无论 udev 分配给它什么名称。注意,这不是最稳健的配置方法。如果您使用多个接口,netctl 可能会尝试为它们分配同一个接口,这很可能会导致连接中断。如果您不介意更复杂的解决方案,netctl-auto 可能更可靠。
使用钩子 (Hooks)
netctl 支持 /etc/netctl/hooks/ 中的钩子,以及 /etc/netctl/interfaces/ 中每个接口的钩子。您可以在钩子/接口中设置配置文件中可以设置的任何选项。最重要的是包括 ExecUpPost 和 ExecDownPre。
当读取配置时,netctl 会先获取 hooks 中所有可执行脚本,然后读取连接的配置文件,最后从 interfaces 目录获取与配置中使用的接口名称匹配的可执行脚本。因此,接口脚本中的声明会覆盖配置文件中的声明,配置文件中的声明会覆盖钩子中的声明。
变量 $INTERFACE 和 $ACTION 仅在使用 netctl-auto 时在钩子/接口中可用。
示例
在建立连接时执行命令
/etc/netctl/hooks/myservices
#!/bin/sh ExecUpPost="systemctl start crashplan.service; systemctl start dropbox@<username>.service" ExecDownPre="systemctl stop crashplan.service; systemctl stop dropbox@<username>.service"
设置默认 DHCP 客户端
要为所有配置设置或更改 DHCP 客户端:
/etc/netctl/hooks/dhcp
#!/bin/sh DHCPClient='dhclient'
不要忘记使文件 可执行。
或者,也可以通过创建具有以下行的可执行文件 /etc/netctl/interfaces/<interface> 为特定网络接口指定:
DHCPClient='dhclient'
最小化 WPAConfigSection
正如 netctl.profile(5) § ‘WIRELESS’ 连接的选项 中所述,WPAConfigSection 变量是一个传递给 wpa_supplicant 的配置行数组。因此,最小化的 WPAConfigSection 包含:
Description='A wireless connection using a custom network block configuration'
Interface=wlan0
Connection=wireless
Security=wpa-configsection
IP=dhcp
WPAConfigSection=(
'ssid="University"'
'psk="very secret passphrase"'
)
ssid=F09F90BA 代表“🐺”。如果不确定十六进制编码,请运行 wifi-menu(注意去掉 \ 和 x 字符)。/etc/resolv.conf
如果您在配置中使用 DNS* 选项,netctl 将调用 resolvconf 来覆盖 resolv.conf。
故障排除
netctl@wlan(...).service 任务失败
有些人通过 netctl 连接网络时会遇到问题,例如:
# netctl start wlan0-ssid
Job for netctl@wlan0\x2ssid.service failed. See 'systemctl status netctl@wlan0\x2ssid.service' and 'journalctl -xn' for details.
以 root 身份运行 journalctl -xn 查看日志时,显示以下任一内容:
1. 如果您的设备(本例中为 wlan0)已启动:
network[2322]: The interface of network profile 'wlan0-ssid' is already up
关闭该接口应能解决此问题:
# ip link set wlan0 down
然后重试:
# netctl start wlan0-ssid
2. 如果错误依然存在,请在添加 ForceConnect 选项后重试:
/etc/netctl/wlan0-ssid
... ForceConnect=yes
保存并尝试连接该配置。
# netctl start wlan0-ssid
dhcpcd: ipv4_addroute: File exists
在某些系统上,dhcpcd 与 netctl 结合使用会导致恢复时出现超时问题,尤其是在切换网络之后。netctl 会报告连接成功,但您仍会遇到超时问题。在这种情况下,旧的默认路由依然存在且未更新。避免此问题的解决方法是切换到 dhclient 作为默认 DHCP 客户端。有关此问题的更多信息,请见 此处。
DHCP 超时问题
如果您在通过 DHCP 请求租约时遇到超时问题,可以将超时值设置得高于 netctl 默认的 30 秒。在 /etc/netctl/hooks/ 或 /etc/netctl/interfaces/ 中创建一个文件,添加 TimeoutDHCP=40(设置为 40 秒超时)并使其可执行。
dhcpcd 调试
如果 dhcpcd 无法获取地址,请将 -d 选项添加到 /usr/lib/netctl/dhcp,然后以 root 身份运行 journalctl -xe 查看调试信息。这可能显示例如服务器提供的 IP 地址在被检测到已在使用中后被客户端拒绝。
连接超时问题
如果您遇到与 DHCP 无关的超时问题(例如在静态以太网连接上),并且启动配置时遇到类似以下错误:
# journalctl _SYSTEMD_UNIT=netctl@profile.service
Starting network profile 'profile'... No connection found on interface 'eth0' (timeout) Failed to bring the network up for profile 'profile'
那么您应该通过在配置文件中添加 TimeoutUp= 和 TimeoutCarrier= 来增加载波和启动超时值:
/etc/netctl/profile
... TimeoutUp=300 TimeoutCarrier=300
不要忘记重新启用您的配置。
# netctl reenable profile
恢复时 netctl-auto 相关问题
有时 netctl-auto 在系统从挂起、休眠或混合睡眠恢复时无法重新连接。一个简单的解决方法是重启 netctl-auto 服务。这可以通过如下额外的服务来自动化:
/etc/systemd/system/netctl-auto-resume@.service
[Unit] Description=restart netctl-auto on resume. Requisite=netctl-auto@%i.service After=sleep.target [Service] Type=oneshot ExecStart=/usr/bin/systemctl restart netctl-auto@%i.service [Install] WantedBy=sleep.target
若要为您的无线网卡 启用 此服务,请以 root 身份启用 netctl-auto-resume@wlan0.service。将 wlan0 更改为所需的网络接口。
如果设备在恢复时尚未启动,该单元将失败。可以通过在 After 行中添加以下依赖项来修复:
/etc/systemd/system/netctl-auto-resume@.service
... After=sleep.target sys-subsystem-net-devices-%i.device ...
netctl-auto 不会自动解锁无线网卡以使用接口
许多笔记本电脑有硬件按钮(或开关)来关闭无线网卡,但网卡也可能被内核阻塞。这可以通过 rfkill 来处理。
如果您希望 netctl-auto 自动解锁无线网卡以连接到特定网络,请为该无线连接设置 RFKill=++auto++ 选项,如 netctl.profile(5) 中所述。
RTNETLINK answers: File exists (多网卡情况下)
这是一个非常有误导性的响应,它实际上意味着您在之前的 netctl 控制文件中分配了默认网关。当 netctl 启动第 n 个 NIC 并尝试设置其本地路由时,由于已经存在第 n-1 个 NIC 设置的默认路由,操作失败。
将其删除后一切正常,但您将不再拥有默认路由,因此无法访问互联网等资源。ExecUpPost 在此不起作用,因为它会对每张网卡各执行一次。
一种可能的解决方案是创建新服务。将 "FIRST_INTERFACE" 和 "SECOND_INTERFACE" 替换为您的接口名称,将 "192.168.xxx.yyy" 替换为您的默认网关。
/etc/systemd/system/defaultrouter.service
[Unit] Description="Configure default gateway" Requires=netctl@FIRST_INTERFACE.service netctl@SECOND_INTERFACE.service After=netctl@FIRST_INTERFACE.service netctl@SECOND_INTERFACE.service [Service] Type=oneshot ExecStart=/usr/bin/ip route add default via 192.168.xxx.yyy [Install] WantedBy=network-online.target
Eduroam 及其他 MSCHAPv2 连接问题
请参阅 wpa_supplicant#Problems with Eduroam。
使用 .include 指令的配置产生日志警告
仍然使用 systemd 旧版 .include 指令的配置文件会产生日志警告,例如:
systemd[1]: /etc/systemd/system/netctl@<profile>.service:1: .include directives are deprecated, and support for them will be removed in a future version of systemd. Please use drop-in files instead.
详情请参阅 FS#59494。
执行
netctl reenable profile
会将配置文件更新为新的 嵌入式单元文件 (drop-in unit file) 格式。
钩子 (Hooks) 不起作用
如果您在 /etc/netctl/hooks/ 中有多个钩子,像 ExecUpPost 和 ExecDownPre 这样的变量将只从一个文件中执行。要修复此问题,请按如下方式定义变量:
/etc/netctl/hooks/test
ExecUpPost="some command ; "$ExecUpPost ExecDownPre="some command ; "$ExecDownPre
这将把您的命令追加到已定义的命令之后执行。
关机时网络挂载超时
如果您将网络挂载与 netctl-ifplugd 或 netctl-auto 结合使用,可能需要在相关服务停止之前卸载它们。实现这一点的一种方法是为 netctl-ifplugd@.service 或 netctl-auto@.service 创建一个 嵌入式文件 (drop-in file),内容如下:
/etc/systemd/system/netctl-*@.service.d/unmount_on_shutdown.conf
[Unit] Wants=remote-fs-pre.target Before=remote-fs-pre.target
这将确保在自动网络服务停止之前断开网络挂载。