ConnMan - Arch Linux 中文维基

跳至內容

# ConnMan

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 ConnMan，最近一次同步於 2021-03-12，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- Network configuration
- Wireless network configuration

ConnMan 是一個命令行網絡管理器，為嵌入式設備和快速響應設計。ConnMan 通過插件擴展，但內置了 DHCP 與 NTP 支持。[1]

## 安裝

安裝 connman包 軟體包。 wpa_supplicant包、bluez包 與 openvpn包 是對應 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 都可以運行），參考 wiki。

  https://github.com/eurogiciel-oss/connman-json-client || connman-ncurses-gitAUR

- ConnMan-UI — GTK3 客戶端托盤程序。

  https://github.com/tbursztyka/connman-ui || connman-ui-gitAUR

- connman_dmenu — dmenu 客戶端/前端。

  https://github.com/taylorchu/connman_dmenu || connman_dmenu-gitAUR

- Econnman — Enlightenment 桌面托盤程序。

  https://www.enlightenment.org || econnmanAUR

- LXQt-Connman-Applet — LXQt 桌面托盤程序。

  https://github.com/lxqt/lxqt-connman-applet || lxqt-connman-appletAUR

- connman-gtk — GTK 客戶端。

  https://github.com/jgke/connman-gtk || connman-gtkAUR

- gnome-extension-connman — ConnMan 的 Gnome3 擴展；如果不安裝 connman-gtk，提供的功能很少。

  https://github.com/jgke/gnome-extension-connman || https://extensions.gnome.org/extension/981/connman-extension/

## 用法

ConnMan 自帶 `connmanctl` 命令行界面，參考 connmanctl(1)。 如果你不提供任何命令，直接運行 `connmanctl`，將會啟動一個交互式終端。

ConnMan 會自動處理有線連接。

### Wi-Fi

#### 啟用與禁用 wifi

執行 `connmanctl technologies` 來檢查 wifi 是否開啟，查看類似 `Powered: True/False` 的輸出。 執行 `connmanctl enable wifi` 來開啟 wifi，或者執行 `connmanctl disable wifi` 來禁用 wifi。 其他啟用 wifi 的方法包括使用筆記本電腦上的 `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 state` 或 `ip addr` 來檢查。

#### 連接到受保護的接入點

你需要提供更多的信息，起碼是密碼或者密碼短語，給 ConnMan 守護程序來連接受保護的接入點。

這一節的命令展示了如何在交互模式執行 `connmanctl`，只有交互模式下才能使用 `agent` 命令。要開啟交互模式，只需要輸入：

    $ connmanctl

接下來的操作和之前的類似，首先掃描所有的 Wi-Fi technologies：

    connmanctl> scan wifi

列出服務：

    connmanctl> services

現在你需要註冊一個 agent 來處理用戶請求，命令是：

    connmanctl> agent on

現在連接到受收保護的服務，使用 tab 補全來輸入 wifi_ 服務，比如要連接到上面例子中的 OtherNET， 輸入：

    connmanctl> connect wifi_dc85de828967_38303944616e69656c73_managed_psk

Agent 會向你詢問守護進程連接到網路需要的一切信息，這些信息會依據與你要連接的網絡類型的不同而變化。 Agent 也會像下面一樣顯示有關信息的額外數據：

    Agent RequestInput wifi_dc85de828967_38303944616e69656c73_managed_psk
      Passphrase = [ Type=psk, Requirement=mandatory ]
      Passphrase?

提供要求的信息，在這個例子裡是密碼短語，然後輸入：

    connmanctl> quit

如果你提供的信息正確，那麼你應該已經連接到受保護的接入點了。

#### 使用 iwd 代替 wpa_supplicant

ConnMan 可以使用 iwd包 連接無線網絡。Community 中提供的的軟體包已經支持使用 iwd包 來連接無線網絡。因為只要 connman包 找到 wpa_supplicant包 就會啟動它，這裡建議卸載 wpa_supplicant包。

目前 iwd包 的 `-i` 選項似乎會導致 connman包 無法找到 Wi-Fi 接口。

創建下面兩個服務文件，可以讓 connman包 無論是否安裝了wpa_supplicant包，都一律使用 iwd包 來連接無線網絡。

    /etc/systemd/system/iwd.service

    [Unit]
    Description=Internet Wireless Daemon (IWD)
    Before=network.target
    Wants=network.target

    [Service]
    ExecStart=/usr/lib/iwd/iwd

    [Install]
    Alias=multi-user.target.wants/iwd.service

    /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 時間似乎會更加一致，並且連接會更加可靠。

### 設置

對於用戶經常連接的網絡，ConnMan 會自動創建設置與配置文件。這些文件包括了密碼短語、essid 和其他信息。配置文件存放在 `/var/lib/connman/` 內，以服務為名的文件夾下。要查看所有的網絡配置文件，在 root shell 內執行：

    # cat /var/lib/connman/*/settings

注意：VPN 設置存放在 `/var/lib/connman-vpn/`。

### Technologies

ConnMan 將各種硬體接口稱為 Technologies。

要列出所有可用的 Technologies，執行：

    $ connmanctl technologies

只列出 Technologies 類型的名字，可以使用這一行命令：

    $ connmanctl technologies | awk '/Type/ { print $NF }'

注意：欄位 `Type = tech_name` 裡的「tech_name」，就是 `connmanctl` 命令所使用的 technology 類型

要與這些接口交互，必須使用 technology 的類型。要開啟或關閉 Technologies 可以用：

    $ connmanctl enable technology_type

與：

    $ connmanctl disable technology_type

比如要關閉 wifi：

    $ connmanctl disable wifi

警告：connman 會監聽 rfkill 事件。使用 connman 時，儘管硬體鎖可能可以正常工作，但基本無法使用 `rfkill` 或 `bluetoothctl` 來開關設備。 [2] 請使用 `connmanctl enable|disable`

## 提示與技巧

### 避免改變 hostname

ConnMan 默認會更改臨時 hostname。與 X authority 一起使用時會有問題：如果用舊的 hostname 生成了 xauth magic coookie 之後，ConnMan 改變了你的 hostname，那麼將無法創建新的窗口，會顯示諸如 `No protocol specified` 和 `Can't open display: :0.0` 的錯誤。手動重置 hostname 可以解決這個問題，但根本的解決辦法是從一開始就防止 ConnMan 改變你的 hostname。把下面的配置加入 `/etc/connman/main.conf` 即可：

    [General]
    AllowHostnameUpdates=false

改變這個文件後記得重啟 `connman.service`。

要測試的話，建議一邊觀察 systemd 日誌，一邊插拔幾次網線接口。

### 有線網絡與無線網絡共存時，優先使用有線網絡

ConnMan 默認不會優先使用有線網絡，這會導致 ConnMan 即使在可以使用有線網絡時，也只使用慢速的無線網絡。你可以將下面的配置加入 `/etc/connman/main.conf`，讓 ConnMan 優先使用有線網絡。

    [General]
    PreferredTechnologies=ethernet,wifi

### 互斥連接

ConnMan 允許你同時連接有線與無線網絡。這樣允許程序在通過 wifi 建立了連接後，再連接到有線網絡，通過 wifi 建立的連接也不會中斷。但有些人更喜歡同一時間只使用一種網絡，將下面的配置加入 `/etc/connman/main.conf` 可以實現這一點：

    [General]
    SingleConnectedTechnology=true

### 連接到 eduroam (802.1X)

在連接到諸如 eduroam 的 WPA2 企業模式網絡之前，需要建立單獨的配置文件。 比如，創建 `/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 代理也會嘗試綁定 53 埠。如果你看到了來自 BIND 或 dnsmasq 的日誌諸如：

    named[529]: could not listen on UDP socket: address in use

就是這個問題引起的。要確認是哪個應用占用了 53 埠，可以以 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

確保在新增此文件後 reload systemd 守護程序，並 restart `connman.service` 和你的 DNS 代理。

### /etc/resolv.conf

如果你既想知道從 DHCP 獲得的 DNS 伺服器地址，同時又想保留自定義的 `/etc/resolv.conf`，那麼就在上面的文件裡追加 `RuntimeDirectory=connman`（如果不需要 `ExecStart` ，就去掉 ExecStart 行）。這樣 connman 就會把從 DHCP 獲得的 DNS 伺服器地址寫入 `/var/run/connman/resolv.conf`。

記得在增加這個文件之後重載 systemd 守護程序，並重啟 `connman.service`和你的 DNS 代理。

### 屏蔽接口

如果有 Docker 之類的的程序創建了虛擬接口，當網絡連接中斷時，ConnMan 可能會嘗試連接這些虛擬接口，而不是真實的硬體接口。簡單的解決辦法是將你不想要 ConnMan 連接的接口加入黑名單。 ConnMan 默認會屏蔽以 `vmnet`、`vboxnet`、`virbr` 與 `ifb` 開頭的接口，所以配置新的黑名單時也要加入這些接口。

屏蔽接口還可以避免競態條件：在 systemd/udev 改變接口名稱到形如 `enp4s0` 的可預測的網絡接口名稱之前，connman 可能就會去連接接口。屏蔽慣用（且不可預測）的接口前綴可以讓 connman 在接口重命名之後再連接。

把下面的配置加入 `/etc/connman/main.conf`（如果不存在就創建這個文件）：

    [General]
    NetworkInterfaceBlacklist=vmnet,vboxnet,virbr,ifb,docker,veth,eth,wlan

重啟 `connman.service` 之後，在 Econnman 這樣的 GUI 工具中，所有形如 `veth#######` 的接口也都會被隱藏。

## 疑難雜症

### Error /net/connman/technology/wifi: Not supported

目前，connman 不支持用 iwd包 掃描 Wi-Fi 網絡，這個功能暫時只能由 `wpa_supplicant` 提供（參考 [4]）。要用 iwd連接 wifi，enable 並 start `iwd.service`，然後參考 Iwd 中的指示，或者使用#前端的其中之一。為了讓 connman 能掃描 Wi-Fi，安裝 wpa_supplicant包 軟體包，並在停用 `iwd.service` 之後重啟`connman.service`。

### Error /net/connman/technology/wifi: No carrier

在你使用這條命令啟用 wifi 後：

    $ connmanctl enable wifi

如果掃描無線網絡時產生了這條錯誤，這可能是因為一個未解決的 Bug。[5][失效連結 2022-09-17 ⓘ] 如果在滿足了這些條件後還未解決，請在禁用其他網絡管理器，並重啟系統之後再嘗試。

也可能僅僅是因為無線接口被 rfkill 關閉了，重啟 wpa_supplicant 時有可能會這樣。使用 `rfkill list` 來檢查。

### "Not registered", or "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

來自終端：

    # connmanctl connect service_id

    Error /net/connman/service/service_id: Not registered

這些錯誤是由於沒有運行 agent。在 `connmanctl` 提示符裡執行 `agent on` 來啟動 agent，然後再試一試。

### Error Failed to set hostname/domainname

Connman 可能會因沒有 `CAP_SYS_ADMIN` 而無法設置 hostanme 或 domainname。

你需要編輯 `connman.service`（以及其他類似的文件，如 `connman-vpn.service`）來修改 `CapabilityBoundingSet` 行，增加 `CAP_SYS_ADMIN`。

更多細節請參考 `EPERM` 下的 sethostname(2) § ERRORS 或 setdomainname(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 的連接，來測試網絡（在本例裡，`82.165.8.211` 就是 ipv4.connman.net 被解析後的 IP位址）。[6][失效連結 2022-09-17 ⓘ] 詳細信息，包括 ConnMan 為什麼要這麼做，以及 ConnMan 除了連接 IP 還傳遞了什麼信息，請參考 ConnMan README。

該行為可以通過在 `/etc/connman/main.conf` 中增加下面的配置來阻止：

    [General]
    EnableOnlineCheck=false

這項配置也會導致默認設備狀態不會從 READY 切換到 ONLINE。connman.conf(5) 但網絡連接是正常的。

也可以用防火牆規則阻止連接檢查，這不會影響正常的網絡連接（除非有 captive portal）：

    # ip6tables -A OUTPUT -d ipv6.connman.net -j REJECT
    # iptables -A OUTPUT -d ipv4.connman.net,ipv6.connman.net -j REJECT

### File /proc/net/pnp doesn't exist

如果你在錯誤日誌中看到了這個，這是由 connman 的 bug 引起的 [7]，可以無視。Bug Report[失效連結 2022-09-17 ⓘ]

## 另請參見

- Git 倉庫文檔——更多細節文檔

分類：​

- 網絡管理器
- 包含失效連結的頁面

ConnMan
新增話題