wpa_supplicant

出自 ArchWiki
(重定向自 WPA supplicant)

wpa_supplicant 是一个跨平台的 请求者,支持 WPA、WPA2 和 WPA3 (IEEE 802.11i)。它适用于桌面、笔记本电脑和嵌入式系统。它是客户端工作站中使用的 IEEE 802.1X/WPA 组件。它实现了与 WPA 认证器的密钥协商,并控制无线驱动程序的漫游和 IEEE 802.11 身份验证/关联。

安装

安装 wpa_supplicant 软件包,其中包含主程序 wpa_supplicant、密码工具 wpa_passphrase 和文本前端 wpa_cli

可选地,也可以安装官方的 wpa_supplicant_guiAUR,它提供了 wpa_gui,一个 wpa_supplicant 的图形前端,或者 wpa-cuteAUR,它是 wpa_gui 早期版本的一个分支,包含一些修复和改进。

概述

连接到加密无线网络的第一步是让 wpa_supplicant 从 WPA 认证器获取身份验证。为了做到这一点,必须配置 wpa_supplicant,以便它能够向认证器提交正确的凭据。

一旦通过身份验证,您需要分配一个 IP 地址,请参阅 网络配置#IP 地址

使用 wpa_cli 连接

这种连接方法允许扫描可用网络,利用 wpa_cli,这是一个命令行工具,可用于配置 wpa_supplicant。有关详细信息,请参阅 wpa_cli(8)

为了使用 wpa_cli,必须为 wpa_supplicant 指定一个控制接口,并且必须赋予它更新配置的权限。通过创建一个最小的配置文件来做到这一点

/etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/run/wpa_supplicant
update_config=1
警告:update_config 设置为 1 允许 wpa_supplicant 覆盖配置文件。当覆盖时,wpa_supplicant 将根据您的默认 umask 重置文件权限。如果您的系统是多用户系统,这可能会意外地使文件对所有人可读,从而暴露您的密码。

现在使用以下命令启动 wpa_supplicant

# wpa_supplicant -B -i interface -c /etc/wpa_supplicant/wpa_supplicant.conf
提示: 要发现您的无线网络接口名称,请参阅 网络配置#列出网络接口

此时运行

# wpa_cli

这将呈现一个交互式提示符 (>),它具有制表符补全和已完成命令的描述。还有一个 help 命令。

提示
  • 控制套接字的默认位置是 /var/run/wpa_supplicant/。可以使用 -p 选项手动设置自定义路径,以匹配 wpa_supplicant 配置。
  • 可以使用 -i 选项指定要配置的接口;否则,将使用 wpa_supplicant 管理的第一个找到的无线接口。

使用 scanscan_results 命令查看可用网络

> scan
OK
<3>CTRL-EVENT-SCAN-RESULTS
> scan_results
bssid / frequency / signal level / flags / ssid
00:00:00:00:00:00 2462 -49 [WPA2-PSK-CCMP][ESS] MYSSID
11:11:11:11:11:11 2437 -64 [WPA2-PSK-CCMP][ESS] ANOTHERSSID

要与 MYSSID 关联,请添加网络,设置凭据并启用它

> add_network
0
> set_network 0 ssid "MYSSID"
> set_network 0 psk "passphrase"
> enable_network 0
<2>CTRL-EVENT-CONNECTED - Connection to 00:00:00:00:00:00 completed (reauth) [id=0 id_str=]

如果 SSID 没有密码验证,您必须通过将命令 set_network 0 psk "passphrase" 替换为 set_network 0 key_mgmt NONE 来显式地将网络配置为无密钥。

注意
  • 可以添加多个网络配置。每个网络都以数字方式索引,因此第一个网络的索引为 0。
  • 如果无法建立连接,将打印一些信息,并且将定期进行尝试。作为定期尝试的一部分,还将定期给出用户提示。发出 disable_network 0 命令将停止定期尝试并返回到稳定的用户提示符。
  • 如果将密码短语提供给 set_network,则将从 带引号的 “密码短语”字符串计算 PSK。或者,您可以使用 wpa_passphrase 命令并直接输入 PSK,方法是将其传递给 psk不带 引号。

最后,将此网络保存在配置文件中并退出 wpa_cli

> save_config
OK
> quit

关联完成后,您必须获取 IP 地址。有关详细信息,请参阅 网络配置#网络管理

使用 wpa_passphrase 连接

这种连接方法允许快速连接到 SSID 已知的网络,利用 wpa_passphrase,这是一个命令行工具,它生成 wpa_supplicant 所需的最小配置。例如

$ wpa_passphrase MYSSID passphrase
network={
    ssid="MYSSID"
    #psk="passphrase"
    psk=59e0d07fa4c7741797a4e394f38a5c321e3bed51d54ad5fcbd3f84bc7415d73d
}

这意味着 wpa_supplicant 可以与 wpa_passphrase 关联,并使用以下命令启动

# wpa_supplicant -B -i interface -c <(wpa_passphrase MYSSID passphrase)
提示
  • 之前的命令需要 root shell
  • 如果输入包含空格,请使用引号。例如:"secret passphrase"
  • 要发现您的无线网络接口名称,请参阅 网络配置#列出网络接口
  • 一些异常复杂的密码短语可能需要从文件输入,例如 wpa_passphrase MYSSID < passphrase.txt,或者 here strings,例如 wpa_passphrase MYSSID <<< "passphrase"
  • 或者,当在密码短语中使用特殊字符时,与其转义它们,不如直接调用 wpa_passphrase 而不指定密码短语。然后它将提示在标准输入中输入密码短语,用户可以在其中粘贴密码短语,即使它包含特殊字符。

最后,您应该获取 IP 地址,请参阅 网络配置#IP 地址

高级用法

对于各种复杂性的网络,可能广泛使用 EAP,维护自定义配置文件将很有用。有关配置概述和示例,请参阅 wpa_supplicant.conf(5);有关所有受支持的配置参数的详细信息,请参阅示例文件 /usr/share/doc/wpa_supplicant/wpa_supplicant.conf[1]

配置

#使用 wpa_passphrase 连接 中所述,可以使用以下命令生成基本配置文件

# wpa_passphrase MYSSID passphrase > /etc/wpa_supplicant/example.conf

这只会创建一个 network 部分。具有 #使用 wpa_cli 连接 的能力和一些其他常见选项的配置文件可能如下所示

/etc/wpa_supplicant/example.conf
# Giving configuration update rights to wpa_cli
ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1

# AP scanning
ap_scan=1

# ISO/IEC alpha2 country code in which the device is operating
country=US

# network section generated by wpa_passphrase
network={
    ssid="MYSSID"
    psk=59e0d07fa4c7741797a4e394f38a5c321e3bed51d54ad5fcbd3f84bc7415d73d
}

如果安全不是问题,密码短语也可以在 network 部分中以明文形式定义,方法是用引号括起来

psk="passphrase"

如果网络没有密码短语,例如公共 Wi-Fi

network={
   ssid="MYSSID"
   key_mgmt=NONE
}

要连接到 WPA-Enterprise 网络,请参阅 #802.1x/radius

可以手动添加更多 network 块,或者使用 wpa_cli,如 #使用 wpa_cli 连接 中所示。为了使用 wpa_cli,必须使用 ctrl_interface 选项设置控制接口。设置 ctrl_interface_group=wheel 允许属于该组的用户执行 wpa_cli。此设置可用于允许没有 root 访问权限(或通过 sudo 等效权限)的用户连接到无线网络。还要添加 update_config=1,以便可以将使用 wpa_cliexample.conf 所做的更改保存下来。请注意,如果启用此选项,则 ctrl_interface_group 组的任何成员都能够更改该文件。

fast_reauth=1ap_scan=1 是编写本文时全局激活的 wpa_supplicant 选项。您是否需要它们,或者是否需要其他全局选项,取决于要连接的网络类型。如果您需要其他全局选项,只需将它们从 /usr/share/doc/wpa_supplicant/wpa_supplicant.conf 复制到文件中即可。

或者,可以使用 wpa_cli set 查看选项的状态或设置新选项。可以将多个网络块附加到此配置:请求者将处理所有网络块之间的关联和漫游。默认情况下,通常连接到网络块中定义的信号最强的网络,可以定义 priority= 来影响行为。例如,要自动连接到任何不安全的网络作为优先级最低的后备方案

network={
   key_mgmt=NONE
   priority=-999
}

完成配置文件后,您可以选择根据 #启动时 (systemd) 中列出的路径命名该文件,将其用作系统范围或每个接口的默认配置。如果您使用其他网络管理器工具,这也适用,这些工具可能依赖于这些路径(例如 Dhcpcd#10-wpa_supplicant)。

提示: 要将网络块配置为隐藏的无线 SSID,根据定义,它不会在常规扫描中出现,则必须在网络块中定义选项 scan_ssid=1

连接

手动

首先启动 wpa_supplicant 命令,其最常用的参数是

  • -B - Fork 到后台。
  • -c filename - 配置文件的路径。
  • -i interface - 要监听的接口。
  • -D driver - 可选地指定要使用的驱动程序。有关受支持驱动程序的列表,请参阅 wpa_supplicant -h 的输出。
    • nl80211 是当前标准,但并非所有无线芯片的模块都支持它。
    • wext 当前已弃用,但仍被广泛支持。

有关完整的参数列表,请参阅 wpa_supplicant(8)。例如

# wpa_supplicant -B -i interface -c /etc/wpa_supplicant/example.conf

然后按照 #概述 中指示的手动获取 ip 地址的方法,例如

# dhcpcd interface
提示
  • dhcpcd 有一个 hook 可以隐式启动 wpa_supplicant,请参阅 dhcpcd#10-wpa_supplicant
  • 在测试参数/配置时,在前台启动 wpa_supplicant(即不带 -B 选项)可能有助于获得更好的调试消息。

启动时 (systemd)

wpa_supplicant 软件包提供多个 systemd 服务文件

  • wpa_supplicant.service - 使用 D-Bus,推荐给 NetworkManager 用户。
  • wpa_supplicant@interface.service - 接受接口名称作为参数,并为此接口启动 wpa_supplicant 守护程序。它读取 /etc/wpa_supplicant/wpa_supplicant-interface.conf 配置文件。在使用 systemd-networkd 时很有用。
  • wpa_supplicant-nl80211@interface.service - 也是特定于接口的,但显式强制使用 nl80211 驱动程序(见下文)。配置文件路径为 /etc/wpa_supplicant/wpa_supplicant-nl80211-interface.conf
  • wpa_supplicant-wired@interface.service - 也是特定于接口的,使用 wired 驱动程序。配置文件路径为 /etc/wpa_supplicant/wpa_supplicant-wired-interface.conf

要在启动时启用无线,请在特定的无线接口上启用上述服务之一的实例。例如,启用 wpa_supplicant@interface systemd 单元。

现在选择并启用一个服务实例,以获取特定 interface 的 ip 地址,如 #概述 中所示。例如,启用 dhcpcd@interface systemd 单元。

提示: dhcpcd 有一个 hook 可以隐式启动 wpa_supplicant,请参阅 dhcpcd#10-wpa_supplicant
802.1x/radius

要使用 802.1x/radius 连接有线适配器,您需要指定一些配置并为适配器启用必要的服务。这对于使用 systemd-networkd 的无头服务器非常有用。

如果默认驱动程序不支持您的适配器,您可能需要使用 -D wired 命令行选项指定 wired 驱动程序(请参阅 #手动)。

adapter 替换为您要连接的有线适配器,并调整设置以符合您的 802.1x/radius 要求。

/etc/wpa_supplicant/wpa_supplicant-wired-adapter.conf
ctrl_interface=/run/wpa_supplicant
ap_scan=0
network={
  key_mgmt=IEEE8021X
  eap=PEAP
  identity="user_name"
  password="user_password"
  phase2="autheap=MSCHAPV2"
}
提示: 相同的配置,但对于无线适配器,将需要将 IEEE8021X 更改为 WPA-EAP 并删除 ap_scan=0

由于此文件存储的是纯文本密码,请使用 chown 将其所有者更改为 root:root,并使用 chmod 将其权限更改为 600

要使用哈希而不是纯文本密码,您可以使用 hash 关键字

password=hash:hash_of_plaintext_password

要哈希您的密码

$ iconv -t utf16le | openssl dgst -md4 -provider legacy

在调用上述命令后,提供您的明文密码,然后按 Ctrl+d

注意: 哈希密码并不能提高安全性,也不能避免泄露机密的风险。

在运行 wpa_supplicant-wired@adapter.service 服务之前,请确保将设备设置为 down

# ip link set adapter down
提示: 此设置也可用于系统安装期间,尽管您可能希望使用 dhcpcd@adapter.service 运行以请求地址。

wpa_cli 操作脚本

wpa_cli 可以在守护程序模式下运行,并根据来自 wpa_supplicant 的事件执行指定的脚本。支持两个事件:CONNECTEDDISCONNECTED。脚本可以使用一些 环境变量,有关详细信息,请参阅 wpa_cli(8)

以下示例将使用 notify-send 来通知用户有关事件

#!/bin/sh

case "$2" in
    CONNECTED)
        notify-send "WPA supplicant: connection established";
        ;;
    DISCONNECTED)
        notify-send "WPA supplicant: connection lost";
        ;;
esac

记住使脚本 可执行,然后使用 -a 标志将脚本路径传递给 wpa_cli

$ wpa_cli -a /path/to/script

漫游

当连接到具有多个接入点的无线网络时,wpa_supplicant 通常负责在接入点之间漫游。选择新的接入点需要 wpa_supplicant 执行可用网络的扫描,这会导致与当前接入点的连接短暂中断,同时无线电扫描其他频率。扫描后,如果 wpa_supplicant 检测到当前网络 (SSID) 中更近的接入点 (BSSID)(就信号强度 (RSSI) 而言),它将重新关联到更近的接入点。

wpa_supplicant 的默认配置具有相对保守的漫游:它仅在与当前接入点的关联丢失时才重新扫描。这意味着,如果客户端远离其当前接入点,但没有远到完全失去信号,则客户端将继续使用弱信号,而不是漫游到更近的接入点。

为了使 wpa_supplicant 在漫游方面更积极,请在配置文件中设置 bgscan 参数,例如

bgscan="simple:30:-70:3600"

上面的示例将导致 wpa_supplicant 在信号弱(低于 -70)时每 30 秒扫描一次,否则每 3600 秒扫描一次。bgscan 可以在特定的 network 块中指定,也可以全局为所有网络指定。

故障排除

注意: 确保您没有基于完整文档示例 /usr/share/doc/wpa_supplicant/wpa_supplicant.conf 的残留配置文件。它充满了未注释的网络示例,这些示例实际上可能会导致随机错误 (FS#40661)。

调试连接失败

为了确定您无法连接到接入点的原因,您可以运行带有 -d 标志的 wpa_supplicant 以获取调试消息,等待几秒钟,然后查找列出 SSID 以及未连接到它们的原因的行。例如

# wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/example.conf -d
wlan0: Selecting BSS from priority group 0
wlan0: 0: d2:93:5b:b7:5d:d2 ssid= wpa_ie_len=26 rsn_ie_len=24 caps=0x511 level=-54 freq=5180
wlan0:    skip - SSID not known
wlan0: 1: f2:93:5b:b7:5d:d2 ssid= wpa_ie_len=26 rsn_ie_len=24 caps=0x511 level=-54 freq=5180
wlan0:    skip - SSID not known
wlan0: 2: b2:93:5b:b7:5d:d2 ssid= wpa_ie_len=26 rsn_ie_len=24 caps=0x511 level=-54 freq=5180
wlan0:    skip - SSID not known
wlan0: 3: b0:93:5b:b7:5d:d2 ssid='Access Point 1' wpa_ie_len=0 rsn_ie_len=20 caps=0x511 level=-55 freq=5180  wps
wlan0:    skip - SSID mismatch
wlan0: 4: c4:13:e2:33:42:20 ssid='\x00\x00\x00\x00' wpa_ie_len=22 rsn_ie_len=0 caps=0x111 level=-69 freq=5260
wlan0:    skip - SSID mismatch
wlan0: 5: c4:13:e2:33:42:24 ssid='Home' wpa_ie_len=0 rsn_ie_len=26 caps=0x1111 level=-69 freq=5260
wlan0:    skip RSN IE - no mgmt frame protection enabled but AP requires it
wlan0:    reject due to mismatch with WPA/WPA2
...

在本例中,我们尝试连接到 SSID 为 home 的接入点。连接失败的原因是 skip RSN IE - no mgmt frame protection enabled but AP requires it,因此我们需要将 ieee80211w=2 添加到我们的配置文件中。

某些硬件不支持 nl80211 驱动

在某些(尤其是旧的)硬件上,wpa_supplicant 可能会失败,并出现以下错误

Successfully initialized wpa_supplicant
nl80211: Driver does not support authentication/association or connect commands
wlan0: Failed to initialize driver interface

这表明标准 nl80211 驱动程序不支持给定的硬件。已弃用的 wext 驱动程序可能仍然支持该设备

# wpa_supplicant -B -i wlan0 -D wext -c /etc/wpa_supplicant/example.conf

如果该命令可以连接,并且用户希望使用 systemd 管理无线连接,则需要 编辑 软件包提供的 wpa_supplicant@.service 单元,并相应地修改 ExecStart

/etc/systemd/system/wpa_supplicant@.service.d/wext.conf
[Service]
ExecStart=
ExecStart=/usr/bin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I -Dnl80211,wext
注意: 选项 -Dnl80211,wext 中以逗号分隔的多个驱动程序包装器使 wpa_supplicant 使用能够初始化接口的第一个驱动程序包装器(请参阅 wpa_supplicant(8) § EXAMPLES)。当使用多个或可移动(例如 USB)无线设备(它们使用不同的驱动程序)时,这非常有用。

已挂载网络共享 (cifs) 和关机问题

当您使用无线连接到网络共享时,您可能会遇到关机需要很长时间的问题。这是因为 systemd 运行时间超过了 3 分钟的超时时间。原因是 WPA supplicant 关闭得太早,即在 systemd 尝试卸载共享之前。错误报告 建议通过 编辑 wpa_supplicant@.service 来解决此问题,如下所示

/etc/systemd/system/wpa_supplicant.service.d/override.conf
[Unit]
After=dbus.service

密码相关问题

如果通过 stdin 直接传递特别长或复杂的密码短语(包括特殊字符),wpa_supplicant 可能无法正常工作。这可能会导致启动 wpa_supplicant 时出现诸如 failed 4-way WPA handshake, PSK may be wrong 之类的错误。

为了解决这个问题,请尝试使用 here strings wpa_passphrase <MYSSID> <<< "<passphrase>" 或将文件传递给 -c 标志

# wpa_supplicant -i <interface> -c /etc/wpa_supplicant/example.conf

在某些情况下,人们发现将密码短语以明文形式存储在 wpa_supplicant.conf network 块的 psk 密钥中会产生积极的结果(请参阅 [2])。但是,这种方法相当不安全。使用 wpa_cli 创建此文件而不是手动编写它在大多数情况下都能获得最佳结果,因此是推荐的步骤。

Eduroam 问题

如果用户学习或工作的机构尚未将其网络隧道的加密升级到至少 TLS 1.2,并且仍然在其 Eduroam Wi-Fi 基础设施中使用 TLS 1.0 或 1.1 进行网络流量加密,则 OpenSSL 3.x 会抛出“unsupported protocol”错误,并且客户端机器的 Wi-Fi 后端(wpa_supplicantiwd)拒绝进一步建立连接。幸运的是,对于 OpenSSL 的 TLS 1.0 和 1.1 弃用,存在一个简单的解决方法,而不会使客户端计算机的整个 Wi-Fi 连接堆栈在全球范围内容易受到攻击,尽管它仅适用于 NetworkManager

有关解决方案,请查阅 NetworkManager#WPA 企业连接无法使用 OpenSSL “unsupported protocol” 错误进行身份验证

Connman 用户可以访问 ConnMan#连接到 eduroam (802.1X) 文章以获取其自己版本的修复程序。

连接到纯 WPA3-SAE 接入点

确保在配置的网络块中定义以下内容,以启用与纯 WPA3 接入点的连接

ssid="network SSID"
key_mgmt=SAE
sae_password="the.literal.wifi.password"
ieee80211w=2

此外,Intel Wi-Fi 6 卡可能需要在配置文件的主(非网络)部分中添加 sae_pwe=1

连接到混合 WPA2-PSK/WPA3-SAE 接入点

混合 WPA2-PSK/WPA3-SAE 接入点将需要 key_mgmt 的替代设置,如下所示

ssid="network SSID"
key_mgmt=WPA-PSK-SHA256
psk=xxx
ieee80211w=2

硬件 802.11w 支持

您可以通过运行以下命令来检查接口客户端上 MFP/PMF(Management Frame Protection / Protected Management Frames)的硬件支持

$ iw phy phy0 info | grep 00-0f-ac:6

大多数 Wi-Fi 设备都支持 2009 年引入的此标准,但某些有限的(又名非 x86_64 相关的)或旧硬件除外。

参见