wpa_supplicant
是 Linux 中支持 WPA 和 WPA2 (IEEE 802.11i)协议的客户端,适用于台式机/笔记本和嵌入式系统,常用来管理 Wifi 链接
介绍
- Wi-Fi 是一种无线网络技术,可用于将计算机(笔记本电脑和台式机)、移动设备(智能手机和可穿戴设备)以及其他设备(打印机和摄像头)连接到互联网
- Wi-Fi 的设置至少需要一个
接入点(Access Point,AP)
和一个或一个以上的客户端用户(client) - 无线 AP 每 100ms 都会将
SSID(Service Set Identifier)
经由 beacons(信号台)
数据包广播一次,beacons 数据包的传输速率是 1 Mbit/s,并且长度相当的短,所以这个广播动作对网络性能的影响不大 - 因此 Wi-Fi 规定其最低传输速率为 1 Mbit/s,以确保所有的 Wi-Fi client 端都能收到这个 SSID 广播数据包,client 可以借此决定是否要和这一个 SSID 的 AP 连线
wpa_supplicant
管理无线网卡驱动- 它是 Linux BSD, Mac OSX 和 Windows 的 WPA 的服务,支持 WPA 和
WPA2(IEEE 802.11i/RSN)
,它适用于台式机/笔记本和嵌入式系统,配置可参考
- 组成
- 守护进程:
systemctl start wpa_supplicant.service
- 客户端 cli:
wpa_cli
- 被NetworkManager 介绍替代
安装
apt install -y wpasupplicant
进程
- 配置
/etc/wpa_supplicant/wpa_supplicant.conf
update_config=1
用来更新配置文件ctrl_interface
用来指定 wpa_cli
的控制接口priority
为优先级,值越大,优先级越高- 更多配置参考
ctrl_interface=/var/run/wpa_supplicant
update_config=1
# AP scanning
ap_scan=1
# ISO/IEC alpha2 country code in which the device is operating
country=CN
network={
scan_ssid=1
ssid="xxxx"
psk="xxxx"
bssid="xxx"
priority=2
}
network={
ssid="example"
scan_ssid=1
key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
pairwise=CCMP TKIP
group=CCMP TKIP WEP104 WEP40
psk="very secret passphrase"
eap=TTLS PEAP TLS
identity="user@example.com"
password="foobar"
ca_cert="/etc/cert/ca.pem"
client_cert="/etc/cert/user.pem"
private_key="/etc/cert/user.prv"
private_key_passwd="password"
phase1="peaplabel=0"
}
wpa_supplicant -B -i $interface -c /etc/wpa_supplicant/wpa_supplicant.conf
dhcpcd <interface>
$ /etc/systemd/system/dhclient.service
[Unit]
Description= DHCP Client
Before=network.target
[Service]
Type=simple
ExecStart=/sbin/dhclient wlp3s0 -v
ExecStop=/sbin/dhclient wlp3s0 -r
[Install]
WantedBy=multi-user.target
/sbin/wpa_action
wpa_action
是一个脚本,用于在 wpa_supplicant
事件发生时执行操作wpa_cli
可以从 wpa supplicant daemon 中获取无线网卡的状态信息事件(CONNECTED 或者 DISCONNECTED event),然后会调用 wpa_action
进行相应的处理
man wpa_action
查看帮助信息
wpa_cli 使用
- wpa_cli 可以在守护进程模式下运行,并根据来自 wpa_supplicant 的事件执行指定的脚本。支持两个事件:CONNECTED 和 DISCONNECTED
wpa_supplicant
和 wpa_cli
一起使用,wpa_cli
可以查询和设置 wpa_supplicant
里面的参数,其是通过 sock
来通讯的,wpa_supplicant
运行的时候还在 /var/run/wpa_supplicant
下创建一个文件,wpa_cli
利用该文件还和 wpa_supplicant
通讯
help
$ wpa_cli -h
wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] [-a<action file>] \
[-P<pid file>] [-g<global ctrl>] [-G<ping interval>] \
[-s<wpa_client_socket_file_path>] [command..]
-h = help (show this usage text)
-v = shown version information
-a = run in daemon mode executing the action file based on events from
wpa_supplicant
-B = run a daemon in the background
default path: /var/run/wpa_supplicant
default interface: first interface found in socket path
commands:
status [verbose] = get current WPA/EAPOL/EAP status
ifname = get current interface name
ping = pings wpa_supplicant
relog = re-open log-file (allow rolling logs)
note <text> = add a note to wpa_supplicant debug log
mib = get MIB variables (dot1x, dot11)
help [command] = show usage help
interface [ifname] = show interfaces/select interface
level <debug level> = change debug level
license = show full wpa_cli license
quit = exit wpa_cli
set = set variables (shows list of variables when run without arguments)
dump = dump config variables
get <name> = get information
driver_flags = list driver flags
logon = IEEE 802.1X EAPOL state machine logon
logoff = IEEE 802.1X EAPOL state machine logoff
pmksa = show PMKSA cache
pmksa_flush = flush PMKSA cache entries
pmksa_get <network_id> = fetch all stored PMKSA cache entries
pmksa_add <network_id> <BSSID> <PMKID> <PMK> <reauth_time in seconds> <expiration in seconds> <akmp> <opportunistic> = store PMKSA cache entry from external storage
reassociate = force reassociation
reattach = force reassociation back to the same BSS
preauthenticate <BSSID> = force preauthentication
identity <network id> <identity> = configure identity for an SSID
password <network id> <password> = configure password for an SSID
new_password <network id> <password> = change password for an SSID
pin <network id> <pin> = configure pin for an SSID
otp <network id> <password> = configure one-time-password for an SSID
psk_passphrase <network id> <PSK/passphrase> = configure PSK/passphrase for an SSID
passphrase <network id> <passphrase> = configure private key passphrase
for an SSID
sim <network id> <pin> = report SIM operation result
bssid <network id> <BSSID> = set preferred BSSID for an SSID
blacklist <BSSID> = add a BSSID to the blacklist
blacklist clear = clear the blacklist
blacklist = display the blacklist
log_level <level> [<timestamp>] = update the log level/timestamp
log_level = display the current log level and log options
list_networks = list configured networks
select_network <network id> = select a network (disable others)
enable_network <network id> = enable a network
disable_network <network id> = disable a network
add_network = add a network
remove_network <network id> = remove a network
set_network <network id> <variable> <value> = set network variables (shows
list of variables when run without arguments)
get_network <network id> <variable> = get network variables
dup_network <src network id> <dst network id> <variable> = duplicate network variables
list_creds = list configured credentials
add_cred = add a credential
remove_cred <cred id> = remove a credential
set_cred <cred id> <variable> <value> = set credential variables
get_cred <cred id> <variable> = get credential variables
save_config = save the current configuration
disconnect = disconnect and wait for reassociate/reconnect command before
connecting
reconnect = like reassociate, but only takes effect if already disconnected
scan = request new BSS scan
scan_results = get latest scan results
abort_scan = request ongoing scan to be aborted
bss <<idx> | <bssid>> = get detailed scan result info
get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> = get capabilities
reconfigure = force wpa_supplicant to re-read its configuration file
terminate = terminate wpa_supplicant
interface_add <ifname> <confname> <driver> <ctrl_interface> <driver_param>
<bridge_name> <create> <type> = adds new interface, all parameters but
<ifname> are optional. Supported types are station ('sta') and AP ('ap')
interface_remove <ifname> = removes the interface
interface_list = list available interfaces
ap_scan <value> = set ap_scan parameter
scan_interval <value> = set scan_interval parameter (in seconds)
bss_expire_age <value> = set BSS expiration age parameter
bss_expire_count <value> = set BSS expiration scan count parameter
bss_flush <value> = set BSS flush age (0 by default)
ft_ds <addr> = request over-the-DS FT with <addr>
wps_pbc [BSSID] = start Wi-Fi Protected Setup: Push Button Configuration
wps_pin <BSSID> [PIN] = start WPS PIN method (returns PIN, if not hardcoded)
wps_check_pin <PIN> = verify PIN checksum
wps_cancel Cancels the pending WPS operation
wps_nfc [BSSID] = start Wi-Fi Protected Setup: NFC
wps_nfc_config_token <WPS|NDEF> = build configuration token
wps_nfc_token <WPS|NDEF> = create password token
wps_nfc_tag_read <hexdump of payload> = report read NFC tag with WPS data
nfc_get_handover_req <NDEF> <WPS> = create NFC handover request
nfc_get_handover_sel <NDEF> <WPS> = create NFC handover select
nfc_report_handover <role> <type> <hexdump of req> <hexdump of sel> = report completed NFC handover
wps_reg <BSSID> <AP PIN> = start WPS Registrar to configure an AP
wps_ap_pin [params..] = enable/disable AP PIN
wps_er_start [IP address] = start Wi-Fi Protected Setup External Registrar
wps_er_stop = stop Wi-Fi Protected Setup External Registrar
wps_er_pin <UUID> <PIN> = add an Enrollee PIN to External Registrar
wps_er_pbc <UUID> = accept an Enrollee PBC using External Registrar
wps_er_learn <UUID> <PIN> = learn AP configuration
wps_er_set_config <UUID> <network id> = set AP configuration for enrolling
wps_er_config <UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP
wps_er_nfc_config_token <WPS/NDEF> <UUID> = build NFC configuration token
ibss_rsn <addr> = request RSN authentication with <addr> in IBSS
sta <addr> = get information about an associated station (AP)
all_sta = get information about all associated stations (AP)
list_sta = list all stations (AP)
deauthenticate <addr> = deauthenticate a station
disassociate <addr> = disassociate a station
chan_switch <cs_count> <freq> [sec_channel_offset=] [center_freq1=] [center_freq2=] [bandwidth=] [blocktx] [ht|vht] = CSA parameters
suspend = notification of suspend/hibernate
resume = notification of resume/thaw
roam <addr> = roam to the specified BSS
p2p_find [timeout] [type=*] = find P2P Devices for up-to timeout seconds
p2p_stop_find = stop P2P Devices search
p2p_asp_provision <addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device
p2p_asp_provision_resp <addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device
p2p_connect <addr> <"pbc"|PIN> [ht40] = connect to a P2P Device
p2p_listen [timeout] = listen for P2P Devices for up-to timeout seconds
p2p_group_remove <ifname> = remove P2P group interface (terminate group if GO)
p2p_group_add [ht40] = add a new P2P group (local end as GO)
p2p_group_member <dev_addr> = Get peer interface address on local GO using peer Device Address
p2p_prov_disc <addr> <method> = request provisioning discovery
p2p_get_passphrase = get the passphrase for a group (GO only)
p2p_serv_disc_req <addr> <TLVs> = schedule service discovery request
p2p_serv_disc_cancel_req <id> = cancel pending service discovery request
p2p_serv_disc_resp <freq> <addr> <dialog token> <TLVs> = service discovery response
p2p_service_update = indicate change in local services
p2p_serv_disc_external <external> = set external processing of service discovery
p2p_service_flush = remove all stored service entries
p2p_service_add <bonjour|upnp|asp> <query|version> <response|service> = add a local service
p2p_service_rep asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace local ASP service
p2p_service_del <bonjour|upnp> <query|version> [|service] = remove a local service
p2p_reject <addr> = reject connection attempts from a specific peer
p2p_invite <cmd> [peer=addr] = invite peer
p2p_peers [discovered] = list known (optionally, only fully discovered) P2P peers
p2p_peer <address> = show information about known P2P peer
p2p_set <field> <value> = set a P2P parameter
p2p_flush = flush P2P state
p2p_cancel = cancel P2P group formation
p2p_unauthorize <address> = unauthorize a peer
p2p_presence_req [<duration> <interval>] [<duration> <interval>] = request GO presence
p2p_ext_listen [<period> <interval>] = set extended listen timing
p2p_remove_client <address|iface=address> = remove a peer from all groups
vendor_elem_add <frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)
0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), 3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, 7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, 11: Assoc Req (P2P), 12: Assoc Resp (P2P)
vendor_elem_get <frame id> = get vendor specific IE(s) to frame(s)
0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), 3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, 7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, 11: Assoc Req (P2P), 12: Assoc Resp (P2P)
vendor_elem_remove <frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)
0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), 3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, 7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, 11: Assoc Req (P2P), 12: Assoc Resp (P2P)
wfd_subelem_set <subelem> [contents] = set Wi-Fi Display subelement
wfd_subelem_get <subelem> = get Wi-Fi Display subelement
fetch_anqp = fetch ANQP information for all APs
stop_fetch_anqp = stop fetch_anqp operation
interworking_select [auto] = perform Interworking network selection
interworking_connect <BSSID> = connect using Interworking credentials
interworking_add_network <BSSID> = connect using Interworking credentials
anqp_get <addr> <info id>[,<info id>]... = request ANQP information
gas_request <addr> <AdvProtoID> [QueryReq] = GAS request
gas_response_get <addr> <dialog token> [start,len] = Fetch last GAS response
hs20_anqp_get <addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information
nai_home_realm_list <addr> <home realm> = get HS20 nai home realm list
hs20_icon_request <addr> <icon name> = get Hotspot 2.0 OSU icon
fetch_osu = fetch OSU provider information from all APs
cancel_fetch_osu = cancel fetch_osu command
sta_autoconnect <0/1> = disable/enable automatic reconnection
tdls_discover <addr> = request TDLS discovery with <addr>
tdls_setup <addr> = request TDLS setup with <addr>
tdls_teardown <addr> = tear down TDLS with <addr>
tdls_link_status <addr> = TDLS link status with <addr>
wmm_ac_addts <uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] [mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] = add WMM-AC traffic stream
wmm_ac_delts <tsid> = delete WMM-AC traffic stream
wmm_ac_status = show status for Wireless Multi-Media Admission-Control
tdls_chan_switch <addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] [center_freq2=] [bandwidth=] [ht|vht] = enable channel switching with TDLS peer
tdls_cancel_chan_switch <addr> = disable channel switching with TDLS peer <addr>
signal_poll = get signal parameters
signal_monitor = set signal monitor parameters
pktcnt_poll = get TX/RX packet counters
reauthenticate = trigger IEEE 802.1X/EAPOL reauthentication
autoscan [params] = Set or unset (if none) autoscan parameters
raw <params..> = Sent unprocessed command
flush = flush wpa_supplicant state
radio_work = radio_work <show/add/done>
vendor <vendor id> <command id> [<hex formatted command argument>] = Send vendor command
neighbor_rep_request [ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)
erp_flush = flush ERP keys
mac_rand_scan <scan|sched|pno|all> enable=<0/1> [addr=mac-address mask=mac-address-mask] = scan MAC randomization
get_pref_freq_list <interface type> = retrieve preferred freq list for the specified interface type
p2p_lo_start <freq> <period> <interval> <count> = start P2P listen offload
p2p_lo_stop = stop P2P listen offload
dpp_qr_code report a scanned DPP URI from a QR Code
dpp_bootstrap_gen type=<qrcode> [chan=..] [mac=..] [info=..] [curve=..] [key=..] = generate DPP bootstrap information
dpp_bootstrap_remove *|<id> = remove DPP bootstrap information
dpp_bootstrap_get_uri <id> = get DPP bootstrap URI
dpp_bootstrap_info <id> = show DPP bootstrap information
dpp_auth_init peer=<id> [own=<id>] = initiate DPP bootstrapping
dpp_listen <freq in MHz> = start DPP listen
dpp_stop_listen = stop DPP listen
dpp_configurator_add [curve=..] [key=..] = add DPP configurator
dpp_configurator_remove *|<id> = remove DPP configurator
dpp_configurator_get_key <id> = Get DPP configurator's private key
dpp_configurator_sign conf=<role> configurator=<id> = generate self DPP configuration
dpp_pkex_add add PKEX code
dpp_pkex_remove *|<id> = remove DPP pkex information
命令行示例
wpa_cli status
// 搜索附件wifi热点
wpa_cli -i wlan0 scan
wpa_cli -i wlan0 scan_result
wpa_cli -i wlan0 status
wpa_cli -i wlan0 ping
// 添加新的连接
wpa_cli -i wlan0 add_network // 返回<network id>
wpa_cli set_network <network id> ssid '"name"'
wpa_cli set_network <network id> psk '"psk"' // 密码
wpa_cli set_network <network id> scan_ssid 1
wpa_cli set_network <network id> priority 1
// 保存连接 /etc/wpa_supplicant
wpa_cli -i wlan0 save_config
// 断开连接
wpa_cli -i wlan0 disable_network <network id>
// 连接已有连接
wpa_cli -i wlan0 list_network
wpa_cli -i wlan0 select_network <network id>
wpa_cli -i wlan0 enable_network <network id>
iwconfig wlan0 essid <name>
# or
iwconfig wlan0 essid <name> key <password>
守护进程示例
#!/bin/sh
# IFNAME=$1
# ACTION=$2
case "$2" in
CONNECTED)
notify-send "WPA supplicant: connection established";
;;
DISCONNECTED)
notify-send "WPA supplicant: connection lost";
;;
esac
启动服务,当 wifi 网卡 CONNECTED、DISCONNECTED event 时,可以自定义相关的处理:
wpa_cli -a /path/to/wpa_action.sh -B
wpa_passphrase 生成加密密码
# 生成的 psk 是加密的
wpa_passphrase <ssid> <password> > /etc/wpa_supplicant/wpa_supplicant.conf
漫游 Roaming
- WLAN 漫游是指 client 在不同的 AP 覆盖范围之间移动,且保持用户业务不中断的行为。
- 漫游的分类
- 配置示例:
bgscan="simple:30:-70:3600"
- bgscan 参数用于配置后台扫描,格式为
<algorithm>:<interval>:<rssi_threshold>:<max_age>
<algorithm>
是背景扫描算法,可以是 simple
、apscan
或 mesh
<interval>
是扫描间隔,单位为秒<rssi_threshold>
是信号强度阈值,单位为 dBm<max_age>
是信号强度最大年龄,单位为秒
其他
- 服务启动区别,参考
wpa_supplicant.service
一般在 D-Bus
类型的系统重,与 NetworkManager
一起使用wpa_supplicant@interface.service
通过 接口名称
启动 wpa_supplicant
守护进程- 默认加载
/etc/wpa_supplicant/wpa_supplicant-<interface>.conf
配置文件 - 一般与
systemd-networkd
配合使用
$ systemctl cat wpa_supplicant
# /lib/systemd/system/wpa_supplicant.service
[Unit]
Description=WPA supplicant
Before=network.target
After=dbus.service
Wants=network.target
[Service]
Type=dbus
BusName=fi.w1.wpa_supplicant1
ExecStart=/sbin/wpa_supplicant -u -s -O /run/wpa_supplicant
[Install]
WantedBy=multi-user.target
Alias=dbus-fi.w1.wpa_supplicant1.service
$ systemctl cat wpa_supplicant@
# /lib/systemd/system/wpa_supplicant@.service
[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Before=network.target
Wants=network.target
# NetworkManager users will probably want the dbus version instead.
[Service]
Type=simple
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I
[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service
- 更多配置示例参考
- /usr/share/doc/wpasupplicant/README.modes.gz
- /usr/share/doc/wpasupplicant/examples/wpa_supplicant.conf.gz
- /usr/share/doc/wpasupplicant/examples/wpa-roam.conf