wpa_supplicant
wpa_supplicant 是一个跨平台 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 terminate
此时运行:
# wpa_cli
这将显示一个交互式提示符(>),该提示符具有选项卡自动完成功能和已完成命令的描述。还有一个 help 命令。
- 控制套接字的默认位置是
/var/run/wpa_supplicant/。可以使用-p选项手动设置自定义路径,以匹配 wpa_supplicant 的配置。 - 可以使用
-i选项指定要配置的接口;否则,将使用由 wpa_supplicant 管理的第一个找到的无线接口。
使用 scan 和 scan_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 将从引用的“passphrase”字符串计算得出。或者,您可以使用 wpa_passphrase 命令,通过将 PSK 直接传递给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_cli 对 example.conf 所做的更改可以保存。请注意,如果启用此功能,属于 ctrl_interface_group 组的任何用户都可以对该文件进行更改。
fast_reauth=1 和 ap_scan=1 是撰写本文时全局有效的 wpa_supplicant 选项。您是否需要它们,或需要其他全局选项,取决于要连接的网络类型。如果您需要其他全局选项,只需从 /usr/share/doc/wpa_supplicant/wpa_supplicant.conf 中将它们复制到文件中即可。
或者,可以使用 wpa_cli set 查看选项状态或设置新选项。可以将多个网络块附加到此配置中:supplicant 将处理与所有网络的关联和漫游。通常会默认连接到具有最强信号的网络块,可以定义 priority= 来影响行为。例如,以最低优先级自动连接到任何不安全的网络作为备用:
network={
key_mgmt=NONE
priority=-999
}
完成配置文件后,可以根据 #开机时(systemd) 中列出的路径,将其用作系统范围或每个接口的默认配置。如果使用其他网络管理器工具,这也适用,这些工具可能依赖于这些路径(例如 Dhcpcd#10-wpa_supplicant)。
scan_ssid=1 选项。连接
手动
首先启动 wpa_supplicant 命令,其最常用的参数是:
-B- 派生到后台。-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 有一个钩子可以隐式启动 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 unit。
现在选择并启用某个服务的实例,以便为特定接口获取 IP 地址,如 #概述 中所示。例如,启用 dhcpcd@interface systemd unit。
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 服务之前,请确保将设备设置为关闭状态:
# ip link set adapter down
dhcpcd@adapter.service 来请求地址。wpa_cli 动作脚本
wpa_cli 可以以守护进程模式运行,并根据 wpa_supplicant 的事件执行指定的脚本。支持两个事件:CONNECTED 和 DISCONNECTED。一些 环境变量 可供脚本使用,有关详细信息,请参阅 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)中信号强度(RSSI)更近的接入点(BSSID),它将重新关联到更近的接入点。
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 来获取调试消息,等待几秒钟,然后查找列出 SSIDs 及其未连接原因的行。例如:
# 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 unit 并相应地修改 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 尝试卸载共享(们)之前。一个 bug 报告建议通过编辑 wpa_supplicant@.service 作为一种变通方法,如下所示:
/etc/systemd/system/wpa_supplicant.service.d/override.conf
[Unit] After=dbus.service
密码相关问题
wpa_supplicant 在通过 stdin 直接传递长密码或包含特殊字符的复杂密码时可能无法正常工作。这可能导致诸如 failed 4-way WPA handshake, PSK may be wrong 之类的错误,当启动 wpa_supplicant 时。
为了解决这个问题,请尝试使用 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_supplicant 还是 iwd)将拒绝进一步建立连接。幸运的是,对于 OpenSSL 的 TLS 1.0 和 1.1 弃用存在一个简单的变通方法,而不会使客户端计算机的整个 Wi-Fi 连接堆栈全局容易受到攻击,尽管它只适用于 NetworkManager。
请查阅 NetworkManager#WPA Enterprise 连接使用 OpenSSL "unsupported protocol" 错误进行身份验证失败 以获取解决方案。
Connman 用户可以访问 ConnMan#连接到 eduroam (802.1X) 文章以获取他们版本的修复方案。
连接到纯 WPA3-SAE 接入点
请确保在配置的 network 块中定义以下内容以启用连接到纯 WPA3 接入点:
ssid="network SSID" key_mgmt=SAE sae_password="the.literal.wifi.password" ieee80211w=2
此外,Intel Wi-Fi 6 网卡可能需要在配置文件的主(非 network)部分中添加 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 相关)或旧的硬件。
wpa_cli scan_result 中的非 ASCII 字符
/etc/wpa_supplicant/wpa_supplicant.conf 使用 UTF-8 编码的标准访问点名称。如果在 wpa_cli scan_result 中看到类似 KEBAP\xc3\x87I HAL\xc4\xb0L 的内容,我们需要将转义的十六进制序列转换为实际字符:
$ echo -e 'KEBAP\xc3\x87I HAL\xc4\xb0L'
将把 KEBAPÇI HALİL 插入配置文件。
有关 -e 选项的详细信息,请参阅 echo(1) man 页。
技巧与提示
抑制 journal 中的过多日志条目
使用默认配置,wpa_supplicant 有时会向 journal 过度记录信息,例如每秒一次:
Aug 23 15:11:15 mainpc wpa_supplicant[1206]: wlp12s0: CTRL-EVENT-SIGNAL-CHANGE above=1 signal=-60 noise=9999 txrate=154800
无法通过将 wpa_supplicant 的日志级别设置为 WARNING 或更高来消除这些日志条目。最简单的方法是添加一个 systemd 配置文件:
/etc/systemd/system/wpa_supplicant.service.d/quieter_logs.conf
[Service] LogLevelMax=4
然后,daemon-reload systemd 并重启 wpa_supplicant.service。
参见
- wpa_supplicant 主页
- wpa_supplicant README - 包含项目完整文档,包括 manpage 中未列出的 wpa_cli 命令。
- wpa_cli 用法示例
- wpa_supplicant(8)
- wpa_supplicant.conf(5)
- wpa_cli(8)
- Kernel.org wpa_supplicant 文档