跳转至内容

ConnMan

来自 ArchWiki

ConnMan 是一款命令行网络管理器,专为嵌入式设备设计,具有快速的解析时间。它通过插件架构实现模块化,但原生支持 DHCPNTP[1]

安装

安装 connman 软件包。wpa_supplicantbluezopenvpn 是可选依赖项,分别用于 Wi-Fi、蓝牙和 VPN 功能。

启用 connman.service 之前,请确保所有现有的网络配置均已禁用。

ConnMan 附带 connmanctl(1) 命令行工具,此外还有多种#前端可用。

前端

  • cmst — ConnMan 的 Qt 图形界面。
https://github.com/andrew-bibb/cmst || cmstAUR
  • connman-ncurses — ConnMan 的简单 ncurses UI;虽然并未实现 ConnMan 的所有功能,但可用(在 X 环境中或终端下均可使用),详见 wiki
https://github.com/eurogiciel-oss/connman-json-client || connman-ncurses-gitAUR
  • ConnMan-UI — GTK3 客户端小程序。
https://github.com/tbursztyka/connman-ui || connman-ui-gitAUR
  • rofi-connman — 基于 rofi/dmenu 的前端
https://github.com/sourcemage/rofi-connman || rofi-connmanAUR
  • Econnman — Enlightenment 桌面面板小程序。
https://www.enlightenment.org || econnmanAUR

用法

本文章或章节需要扩充。

原因:仅描述了有线和 Wi-Fi 插件。(在 Talk:ConnMan 中讨论)

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
提示 网络名称可以使用 Tab 键补全。

现在您应该已连接到网络。请使用 connmanctl stateip 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

本文或本章节已过时。

原因:一种更简单的方法(针对滚动更新软件包)是使用 drop-in 文件。(在 Talk:ConnMan#connman_+_iwd_as_backend 中讨论)

请注意,对于 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

然后启用/启动 connman_iwd 服务。

使用 iwd 代替 wpa_supplicant 的优势在于,ping 时间似乎更加一致,连接也似乎更可靠。

设置

设置和配置文件会自动为用户经常连接的网络创建。它们包含密码、essid 和其他信息的字段。配置文件设置存储在 /var/lib/connman/ 下的目录中,目录名即为服务名称。要查看所有网络配置文件,请运行

# cat /var/lib/connman/*/settings
提示 此命令需要 root shell
注意 VPN 设置可在 /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
警告 connman 会接管 rfkill 事件。很可能无法使用 rfkillbluetoothctl 来锁定/解锁设备,但硬件按键可能仍然有效。[2] 请始终使用 connmanctl enable|disable

技巧与提示

避免更改主机名

默认情况下,ConnMan 会在每个网络的基础上更改临时主机名(参见 hostnamectl(1))。这可能会导致 X 授权问题:如果 ConnMan 将您的主机名更改为与生成 xauth 魔法 cookie 时所用的主机名不同,那么将无法创建新窗口。症状是出现诸如 No protocol specifiedCan'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.serviceconnman.service 以连接到新网络。

  • 选项区分大小写,例如使用 EAP = ttls 而不是 EAP = TTLS[3]
  • 请咨询托管 eduroam 网络的机构,获取用户名、密码、EAPPhase2output 和所需的证书等各种设置。

有关更多信息,请参阅 connman-service.config(5)Wireless network configuration#eduroam

避免与本地 DNS 服务器冲突

如果您正在运行本地 DNS 服务器,安装 Connman 后它可能会在绑定到 53 端口(TCP 和/或 UDP)时遇到问题。这是因为 Connman 包含自己的 DNS 代理,它也会尝试绑定到这些端口。如果您看到来自 BINDdnsmasq 的类似如下的日志消息

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.servicesystemd-resolved.service 以及(如果在使用的话)tailscale.service

黑名单接口

如果诸如 Docker 之类的程序创建了虚拟接口,当连接断开时,Connman 可能会尝试连接到其中一个接口而不是您的物理适配器。避免此问题的简单方法是列入黑名单您不想使用的接口。默认情况下,Connman 会将以 vmnetvboxnetvirbrifb 开头的接口列入黑名单,因此这些接口也需要包含在新的黑名单中。

将接口名称加入黑名单对于避免竞态条件也很有用,在该条件下,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) § ERRORSsetdomainname(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],可以忽略。错误报告

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.