ConnMan

出自 ArchWiki

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

安装

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

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

ConnMan 自带 connmanctl(1) 命令行界面,还有各种可用的 #前端

前端

  • cmst — ConnMan 的 Qt GUI。
https://github.com/andrew-bibb/cmst || cmstAUR
  • connman-ncurses — ConnMan 的简单 ncurses UI;并非所有 connman 功能都已实现,但可用(带 X 或不带 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
  • connman-gtk — GTK 客户端,自 2021-10-25 起已弃用。
https://github.com/jgke/connman-gtk || connman-gtkAUR

用法

本文或章节需要扩充。

原因: 仅描述了有线和 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 接受称为技术的简单名称。要扫描附近的 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 stateip addr 检查。

连接到受保护的接入点

对于受保护的接入点,您需要向 ConnMan 守护程序提供一些信息,至少是密码或密码短语。

本节中的命令演示了如何在交互模式下运行 connmanctl,这是运行 agent 命令所必需的。要启动交互模式,只需键入

$ connmanctl

然后,您几乎可以像上面一样继续操作,首先扫描任何 Wi-Fi 技术

connmanctl> scan wifi

列出服务

connmanctl> services

现在您需要注册代理以处理用户请求。命令是

connmanctl> agent on

现在您需要连接到其中一项受保护的服务。为了轻松地做到这一点,只需使用制表符补全 wifi_ 服务。如果您要连接到上面示例中的 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/ 中找到。

技术

各种硬件接口在 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 magic cookie 的主机名不同的名称,则将无法创建新窗口。症状是错误消息,例如 No protocol specifiedCan't open display: :0.0。手动重置主机名可以解决此问题,但永久的解决方案是首先阻止 ConnMan 更改您的主机名。这可以通过将以下内容添加到 /etc/connman/main.conf 来实现

[General]
AllowHostnameUpdates=false

在更改此文件后,请确保重启 connman.service

为了测试目的,建议观看 systemd 日志 并多次插入网线以查看操作。

优先使用以太网而非无线网络

默认情况下,ConnMan 不会优先选择以太网而不是无线网络,这可能会导致它决定坚持使用缓慢的无线网络,即使以太网可用。您可以告诉 connman 优先使用以太网,方法是将以下内容添加到 /etc/connman/main.conf

[General]
PreferredTechnologies=ethernet,wifi

独占连接

ConnMan 允许您同时连接到以太网和无线网络。这可能很有用,因为它允许通过 Wi-Fi 建立连接的程序在您连接到以太网后仍保持连接。但有些人更喜欢一次只激活一个明确的连接。可以通过将以下内容添加到 /etc/connman/main.conf 来激活该行为

[General]
SingleConnectedTechnology=true

连接到 eduroam (802.1X)

WPA2 企业级网络(如 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)无线网络配置#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

如果您想知道从 DHCP 接收的 DNS 服务器,同时保留自定义的 /etc/resolv.conf,则将 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,重新构建软件包,然后安装修改后的版本。安装修改后的软件包后,设置 stub 解析器 作为 /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重启,这还将从 GUI 工具(如 Econnman)中隐藏所有 veth####### 接口。

故障排除

错误 /net/connman/technology/wifi: 不支持

目前,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: 无载波

您已使用以下命令启用了 Wi-Fi

$ connmanctl enable wifi

如果无线扫描导致上述错误,则可能是由于 未解决的错误 造成的。如果即使满足无线 先决条件[死链接 2023-09-16 ⓘ] 仍然无法解决,请在禁用竞争网络管理器并重启后重试。

这也可能仅仅是由 rfkill 阻止无线接口引起的,这可能会在重启 wpa_supplicant 后发生。使用 rfkill list 进行检查。

“未注册”,或“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

connman 可能由于缺少 CAP_SYS_ADMIN 而无法设置主机名或域名。

您需要编辑 connman.service(以及其他类似 connman-vpn.service 等)以修改 CapabilityBoundingSet 行以添加 CAP_SYS_ADMIN

有关更多详细信息,请参阅 sethostname(2) § ERRORSsetdomainname(2) § ERRORS

连接上出现未知路由

每次完成连接时,都会出现未知路由的日志条目。例如

...
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] 引起的,可以忽略它。错误报告

参见