ConnMan
ConnMan 是一款命令行网络管理器,专为嵌入式设备设计,具有快速的解析时间。它通过插件架构实现模块化,但原生支持 DHCP 和 NTP。[1]
安装
安装 connman 软件包。wpa_supplicant、bluez 和 openvpn 是可选依赖项,分别用于 Wi-Fi、蓝牙和 VPN 功能。
在启用 connman.service 之前,请确保所有现有的网络配置均已禁用。
ConnMan 附带 connmanctl(1) 命令行工具,此外还有多种#前端可用。
前端
- cmst — ConnMan 的 Qt 图形界面。
- connman-ncurses — ConnMan 的简单 ncurses UI;虽然并未实现 ConnMan 的所有功能,但可用(在 X 环境中或终端下均可使用),详见 wiki。
- ConnMan-UI — GTK3 客户端小程序。
- rofi-connman — 基于 rofi/dmenu 的前端
- Econnman — Enlightenment 桌面面板小程序。
用法
ConnMan 附带了 connmanctl 命令行界面,参见 connmanctl(1)。如果不提供任何命令,connmanctl 将以交互式 shell 启动。
ConnMan 会自动处理有线连接。
Wi-Fi
启用和禁用 Wi-Fi
要检查 Wi-Fi 是否已启用,您可以运行 connmanctl technologies 并查看显示 Powered: True/False 的行。要开启 Wi-Fi,可以运行 connmanctl enable wifi,如果需要禁用,可以运行 connmanctl disable wifi。启用 Wi-Fi 的其他方法包括使用笔记本电脑上的 Fn 键开启,或运行 ip link set interface up。
连接到开放接入点
要扫描网络,connmanctl 接受称为技术 (technologies) 的简单名称。要扫描附近的 Wi-Fi 网络
$ connmanctl scan wifi
要列出扫描后找到的可用网络,请运行(输出示例)
$ connmanctl services
*AO MyNetwork wifi_dc85de828967_68756773616d_managed_psk
OtherNET wifi_dc85de828967_38303944616e69656c73_managed_psk
AnotherOne wifi_dc85de828967_3257495245363836_managed_wep
FourthNetwork wifi_dc85de828967_4d7572706879_managed_wep
AnOpenNetwork wifi_dc85de828967_4d6568657272696e_managed_none
要连接到开放网络,请使用以 wifi_ 开头的第二个字段
$ connmanctl connect wifi_dc85de828967_4d6568657272696e_managed_none
现在您应该已连接到网络。请使用 connmanctl state 或 ip addr 进行检查。
连接到受保护的接入点
对于受保护的接入点,您需要向 ConnMan 守护进程提供一些信息,至少是密码或口令。
本节中的命令展示了如何以交互模式运行 connmanctl,运行 agent 命令时需要此模式。要启动交互模式,只需输入
$ connmanctl
然后按照上述步骤操作,首先扫描 Wi-Fi 技术
connmanctl> scan wifi
列出服务
connmanctl> services
现在您需要注册代理 (agent) 来处理用户请求。命令是
connmanctl> agent on
现在您需要连接到受保护的服务之一。为了方便起见,直接对 wifi_ 服务使用 Tab 键补全即可。如果您要连接到上述示例中的 OtherNET,您可以输入
connmanctl> connect wifi_dc85de828967_38303944616e69656c73_managed_psk
代理随后会要求您提供守护进程完成连接所需的信息。请求的信息取决于您正在连接的网络类型。代理还会打印关于所需信息的额外数据,如下例所示。
Agent RequestInput wifi_dc85de828967_38303944616e69656c73_managed_psk Passphrase = [ Type=psk, Requirement=mandatory ] Passphrase?
提供请求的信息(在本例中为密码),然后输入
connmanctl> quit
如果您提供的信息正确,现在应该已成功连接到受保护的接入点。
使用 iwd 代替 wpa_supplicant
ConnMan 可以使用 iwd 连接到无线网络。由于 connman 在发现 wpa_supplicant 时会启动它,因此建议卸载 wpa_supplicant。
请注意,对于 IWD 用户来说 ConnMan 可能是不必要的,因为 IWD 可以处理其自身的网络配置,在这种情况下应停止 connmand。
目前,iwd 的 -i 选项似乎会导致 Wi-Fi 接口对 connman 隐藏。
创建以下服务文件,它应该会使 connman 使用 iwd 连接到无线网络,无论是否安装了 wpa_supplicant。
/etc/systemd/system/connman_iwd.service
[Unit] Description=Connection service DefaultDependencies=false Conflicts=shutdown.target RequiresMountsFor=/var/lib/connman After=dbus.service network-pre.target systemd-sysusers.service iwd.service Before=network.target multi-user.target shutdown.target Wants=network.target Requires=iwd.service [Service] Type=dbus BusName=net.connman Restart=on-failure ExecStart=/usr/bin/connmand --wifi=iwd_agent -n StandardOutput=null CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SYS_TIME CAP_SYS_MODULE ProtectHome=true ProtectSystem=true [Install] WantedBy=multi-user.target
使用 iwd 代替 wpa_supplicant 的优势在于,ping 时间似乎更加一致,连接也似乎更可靠。
设置
设置和配置文件会自动为用户经常连接的网络创建。它们包含密码、essid 和其他信息的字段。配置文件设置存储在 /var/lib/connman/ 下的目录中,目录名即为服务名称。要查看所有网络配置文件,请运行
# cat /var/lib/connman/*/settings
/var/lib/connman-vpn/ 中找到。技术 (Technologies)
各种硬件接口在 ConnMan 中被称为技术。
要列出可用的技术,请运行
$ connmanctl technologies
若要仅获取名称对应的类型,可以使用以下单行命令
$ connmanctl technologies | awk '/Type/ { print $NF }'
Type = tech_name 字段提供了与 connmanctl 命令一起使用的技术类型要与之交互,必须按类型引用该技术。技术可以通过以下命令开启/关闭
$ connmanctl enable technology_type
和
$ connmanctl disable technology_type
例如,要关闭 Wi-Fi
$ connmanctl disable wifi
rfkill 或 bluetoothctl 来锁定/解锁设备,但硬件按键可能仍然有效。[2] 请始终使用 connmanctl enable|disable技巧与提示
避免更改主机名
默认情况下,ConnMan 会在每个网络的基础上更改临时主机名(参见 hostnamectl(1))。这可能会导致 X 授权问题:如果 ConnMan 将您的主机名更改为与生成 xauth 魔法 cookie 时所用的主机名不同,那么将无法创建新窗口。症状是出现诸如 No protocol specified 和 Can't open display: :0.0 之类的错误消息。手动重置主机名可以解决此问题,但永久的解决方案是防止 ConnMan 从一开始就更改您的主机名。这可以通过向 /etc/connman/main.conf 添加以下内容来实现
[General] AllowHostnameUpdates=false
更改此文件后,请务必重启 connman.service。
为了进行测试,建议观察 systemd 日志 并插拔网线几次以查看执行结果。
优先使用以太网而非无线
默认情况下,ConnMan 不会优先选择以太网而非无线,这可能导致它在有以太网可用时仍然停留在缓慢的无线网络上。您可以通过向 /etc/connman/main.conf 添加以下内容来告知 connman 优先使用以太网
[General] PreferredTechnologies=ethernet,wifi
独占连接
ConnMan 允许您同时连接到以太网和无线网络。这很有用,因为它允许通过 Wi-Fi 建立连接的程序在您连接到以太网后仍能保持连接。但有些人更喜欢一次只保持一个明确的连接。该行为可以通过向 /etc/connman/main.conf 添加以下内容来激活
[General] SingleConnectedTechnology=true
连接到 eduroam (802.1X)
WPA2 Enterprise 网络(如 eduroam)在连接到网络之前需要单独的配置文件。例如,创建 /var/lib/connman/eduroam.config
eduroam.config
[service_eduroam] Type=wifi Name=eduroam EAP=peap CACertFile=/etc/ssl/certs/certificate.cer Phase2=MSCHAPV2 Identity=user@foo.edu AnonymousIdentity=anonymous@foo.edu Passphrase=password
重启 wpa_supplicant.service 和 connman.service 以连接到新网络。
- 选项区分大小写,例如使用
EAP = ttls而不是EAP = TTLS。[3] - 请咨询托管 eduroam 网络的机构,获取用户名、密码、
EAP、Phase2output和所需的证书等各种设置。
有关更多信息,请参阅 connman-service.config(5) 和 Wireless network configuration#eduroam。
避免与本地 DNS 服务器冲突
如果您正在运行本地 DNS 服务器,安装 Connman 后它可能会在绑定到 53 端口(TCP 和/或 UDP)时遇到问题。这是因为 Connman 包含自己的 DNS 代理,它也会尝试绑定到这些端口。如果您看到来自 BIND 或 dnsmasq 的类似如下的日志消息
named[529]: could not listen on UDP socket: address in use
这可能是问题所在。要验证哪个应用程序正在监听这些端口,您可以以 root 身份执行 ss -tulpn。
要解决此问题,可以通过覆盖 systemd 服务文件,将 -r 或 --nodnsproxy 选项传递给 connmand。创建目录 /etc/systemd/system/connman.service.d/ 并添加文件 disable_dns_proxy.conf
/etc/systemd/system/connman.service.d/disable_dns_proxy.conf
[Service] ExecStart= ExecStart=/usr/bin/connmand -n --nodnsproxy
添加此文件后,请务必重载 systemd 守护进程并重启 connman.service 以及您的 DNS 代理。
DNS 管理
/etc/resolv.conf
如果您想在保持自定义 /etc/resolv.conf 的同时了解通过 DHCP 接收到的 DNS 服务器,请将 RuntimeDirectory=connman 追加到上述文件中(如果不需要,请清除 ExecStart 行)。现在 connman 将把它们写入 /var/run/connman/resolv.conf。
使用 systemd-resolved
ConnMan 支持 systemd-resolved,它用一个模块替换其内部 DNS 代理,每当连接到网络时,该模块会使用正确的 DNS 服务器和搜索域配置 systemd-resolved。已知使用 systemd-resolved 可以改善与 Tailscale 的兼容性,因为 ConnMan 的内部代理和 Tailscale 可能会争夺 /etc/resolv.conf 的控制权,而双方都与 resolved 通信则可以更好地协调。
要使用此支持,需要重新构建 ConnMan:使用 Arch 构建系统检出软件包,设置配置标志 --with-dns-backend=systemd-resolved,重新构建软件包并安装修改后的版本。安装修改后的软件包后,将 存根解析器设置为 /etc/resolv.conf,然后重启 connman.service、systemd-resolved.service 以及(如果在使用的话)tailscale.service。
黑名单接口
如果诸如 Docker 之类的程序创建了虚拟接口,当连接断开时,Connman 可能会尝试连接到其中一个接口而不是您的物理适配器。避免此问题的简单方法是列入黑名单您不想使用的接口。默认情况下,Connman 会将以 vmnet、vboxnet、virbr 和 ifb 开头的接口列入黑名单,因此这些接口也需要包含在新的黑名单中。
将接口名称加入黑名单对于避免竞态条件也很有用,在该条件下,Connman 可能会在 systemd/udev 能够将其重命名为使用 可预测网络接口名称(如 enp4s0)之前访问 eth# 或 wlan#。将常规(且不可预测的)接口前缀加入黑名单会使 connman 等待它们重命名。
如果不存在,请创建 /etc/connman/main.conf
[General] NetworkInterfaceBlacklist=vmnet,vboxnet,virbr,ifb,docker,veth,eth,wlan
一旦 connman.service 被重启,这也会从 Econnman 等 GUI 工具中隐藏所有 veth####### 接口。
故障排除
错误 /net/connman/technology/wifi: Not supported
目前,connman 不支持使用 iwd 扫描 Wi-Fi 网络,此时该功能仅适用于 wpa_supplicant(参见 [4])。要使用 iwd 连接到 Wi-Fi,请启用/启动 iwd.service,然后按照 Iwd 中的说明连接到 Wi-Fi,或者也可以使用任何#前端。为了在 connman 内部获得 Wi-Fi 扫描支持,请安装 wpa_supplicant,然后在停止 iwd.service 后重启 connman.service。
错误 /net/connman/technology/wifi: No carrier
您已通过以下方式启用了 Wi-Fi
$ connmanctl enable wifi
如果无线扫描导致上述错误,这可能是由于一个未解决的错误。如果即使满足无线前提条件问题仍未解决,请尝试在禁用冲突的网络管理器并重启后重试。
这也可能仅仅是由无线接口被 rfkill 锁定引起的,这可能在重启 wpa_supplicant 后发生。请使用 rfkill list 进行检查。
"Not registered", 或 "Method "Connect" with signature ... doesn't exist"
执行命令时,您可能会看到如下错误
在 connmanctl 提示符下
connmanctl> connect service_id
Error /net/connman/service/SSID: Method "Connect" with signature "" on interface "net.connman.Service" doesn't exist
在 shell 中
# connmanctl connect service_id
Error /net/connman/service/service_id: Not registered
这些错误是因为代理未运行。在 connmanctl 提示符下使用 agent on 启动代理,然后再试一次。
错误 Failed to set hostname/domainname
由于缺乏 CAP_SYS_ADMIN,connman 可能会设置主机名或域名失败。
您需要编辑 connman.service(以及其他类似 connman-vpn.service 等),以修改 CapabilityBoundingSet 行并添加 CAP_SYS_ADMIN。
有关更多详细信息,请参阅 sethostname(2) § ERRORS 或 setdomainname(2) § ERRORS 下的 EPERM。
连接时出现未知路由
每次进行连接时都会出现未知路由的日志条目。例如
...
connmand[473]: wlp2s0 {add} route 82.165.8.211 gw 10.20.30.4 scope 0 <UNIVERSE>
connmand[473]: wlp2s0 {del} route 82.165.8.211 gw 10.20.30.4 scope 0 <UNIVERSE>
...
这很可能是 Connman 对 ipv4.connman.net 主机(当前解析为 IP 地址 82.165.8.211)执行连接检查。[5] 有关它为何以及除连接 IP 外还传输了什么内容的更多信息,请参见 Connman README。此行为可以通过向 /etc/connman/main.conf 添加以下内容来防止
[General] EnableOnlineCheck=false
此设置将导致默认设备不会切换到 ONLINE,而是保持在 READY 状态。connman.conf(5) 但是,连接仍然可以使用。
如果检查被防火墙规则阻止,连接本身仍然可以使用(除非在强制网络门户之后)
# ip6tables -A OUTPUT -d ipv6.connman.net -j REJECT # iptables -A OUTPUT -d ipv4.connman.net,ipv6.connman.net -j REJECT
文件 /proc/net/pnp 不存在
如果您在错误日志中看到此信息,这是由 connman 中的错误引起的 [6],可以忽略。错误报告
参见
- Git 仓库文档 — 获取更多详细文档