Fork me on GitHub
0%

Wpa_supplicant & Hostapd

WIFI基础

OSI七层模型

请不要把暗号告诉任何人(Please Do Not Tell the Secret Password to Anyone)。

  • Application Layer(应用层)。应用层能与应用程序界面沟通以达到向用户展示的目的。常见的协议有HTTP、HTTPS、FTP、SMTP等。其数据单位为APDU(Application Protocol Data Unit)。
  • Presentation Layer(表示层)。表示层能为不同客户端提供数据和信息的语法转换,使系统能解读成正确的数据,同时它还能提供压缩解压、加密解密等服务。例如不同格式图像(如GIF、JPEG、TIFF等)的显示就是由位于表示层的协议来支持的。其数据单位为PPDU(Presentation Protocol Data Unit)。
  • Session Layer(会话层)。会话层用于为通信双方制定通信方式,创建和注销会话(双方通信)等。其数据单位为-SPDU(Session Protocol Data Unit)。常见的协议有ZIP、AppleTalk、SCP等。
  • Transport Layer(传输层)。传输层用于控制数据流量,同时能进行调试及错误处理,以确保通信顺利。发送端的传输层会为数据分组加上序号,以方便接收端把分组重组为有用的数据或文件。传输层的常见协议有TCP、UDP等。于 TCP 而言,数据单元是数据包。对于 UDP 而言,包被称为数据报(datagram)
  • Network Layer(网络层)。网络层为数据传送的目的地寻址,然后再选择一个传送数据的最佳路线。网络层数据的单位为Packet或Datagram。常见的设备有路由器等。常见协议有IP、IPv6。第三层的数据单元是 数据包(data packet)/负载(payload)。通常,每个数据包都包含一个帧 加上 一个 IP 地址信息的包装。换句话说,帧被第三层的地址信息封装了。
  • Data Link Layer(数据链路层)。在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路。通过差错控制提供数据帧(Frame)在信道上无差错的传输。数据链路层在不可靠的物理介质上提供可靠的传输。该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。数据链路层数据的单位为Frame(帧)。常见的设备有二层交换机、网桥等。
    • 介质访问控制(MAC,Media Access Control)。MAC 子层负责分配硬件标识号,这个标识号被称为 MAC 地址,它能够唯一标识网络上的各个设备。两个设备不应该有相同的 MAC 地址。MAC 地址在硬件制造时就分配好了,位于网卡当中,大多数网络都会自动对其进行识别。交换机会跟踪网络上所有的 MAC 地址。在这里这里了解更多有关 MAC 地址的信息,在这里进一步了解网络交换机。
    • 逻辑链路控制(LLC,Logical Link Control)。 LLC 子层处理帧的寻址以及流量控制。速度取决于两个节点之间的链路,例如以太网或 Wifi。
  • Physical Layer(物理层)。物理层定义了通信设备机械、电气、功能和过程等方面的特性,用以建立、维护和拆除物理链路连接。物理层数据的单位为bit

STA模式

STA客户端模式用到了wpa_supplicant和轻量级的udhcpd客户端

wpa_supplicant介绍

wpa_supplicant - ArchWiki

wpa_supplicant: Developers’ documentation for wpa_supplicant

WPA代表Wi-Fi Protected Access(Wi-Fi受保护访问),是一种用于无线网络的安全协议。它的目的是提供比WEP(Wired Equivalent Privacy,有线等效隐私)更强大的安全性,以保护无线网络免受未经授权的访问和数据截取。

wpa_supplicant是一个用于实现 WPA(Wi-Fi Protected Access)和 WPA2(Wi-Fi Protected Access 2)协议的开源软件客户端。它的主要功能是处理 Wi-Fi 网络的扫描、关联、认证和加密等任务,使得计算机或设备能够安全地连接到受保护的 Wi-Fi 网络。

wpa_supplicant是一个 独立运行的 守护进程,其核心是一个消息循环,在消息循环中处理WPA状态机、控制命令、驱动事件、配置信息等。经过编译后 的 wpa_supplicant源程序可以看到两个主要的可执行工具:wpa_supplicant 和 wpa_cli。wpa_supplicant是核心程序,它和wpa_cli的关系就是服务和客户端的关系:后台运行wpa_supplicant,使用 wpa_cli来搜索、设置、和连接网络。

WPA命令行参数

使用WPAS和WPSC的命令之前,可以通过ifconfig命令查看wlan驱动是否成功加载,wlan成功加载是必要的前提

  1. 启动WPAS

    1
    2
    3
    4
    5
    6
    7
    /usr/sbin/wpa_supplicant -Dnl80211 -iwlan0 -c/usr/resource/wpa_supplicant.conf -B -d

    # -D : driver 可选指定的驱动程序,nl80211是当前的标准,但并非所有无线芯片的模块都支持它;
    # -i :interface 网络接口名称 wlan0
    # -c : configure files 读取配置文件/etc/wpa_supplicant.conf
    # -B : background 后台执行
    # -d : debug 调试信息
  2. wpa_cli常用参数含义

    1
    2
    3
    4
    5
    # -p:  path, Change the path where control sockets should be found,更改应找到控制套接字的路径。
    # -i: ifname, Specify the interface that is being configured. By default, choose the first interface found with a control socket in the socket path
    # 指定正在配置的接口。 默认情况下,选择在套接字路径中找到的第一个带有控制套接字的接口
    # -B: Run as a daemon in the background,在后台作为守护进程运行。
    # command :运行命令,包括:status、scan、scan_result等等命令
  3. 搜索附近网络(显示OK/NO)

    1
    2
    3
    4
    # 使用默认参数
    $ wpa_cli scan
    # 指定参数
    $ wpa_cli scan -i wlan0 -p /var/run/wpa_supplicant
  4. 搜索附近网络,并列出结果

    1
    $ wpa_cli scan_results
  5. 查看当前设备已连接的网络配置列表

    1
    $ wpa_cli list_networks
  6. 连接网络(wpa_supplicant.conf配置文件没有配置,即首次连接)

    1
    2
    3
    4
    5
    6
    7
    8
    # 获取一个存储wifi结构的ID (基于wpa_supplicant.conf配置递增),ID值将以返回值或者打印的形式显示
    $ wpa_cli -i wlan0 add_network
    # 设置ID=2的热点的SSID
    $ wpa_cli -i wlan0 set_network 2 ssid '"Jz_Staff"'
    # 设置ID=2的热点的PSK
    $ wpa_cli -i wlan0 set_network 2 psk '"mAkEZnZWPk"'
    # 启动ID=2的网络
    $ wpa_cli -i wlan0 enable_network 2
  7. 设置网络信息(选填项)

    1
    2
    3
    4
    5
    # 基于以上连接信息,设置ID=2的热点的加密方式
    $ wpa_cli -i wlan0 set_network 2 key_mgmt WPA2-PSK
    $ wpa_cli -i wlan0 set_network 0 key_mgmt SAE
    #设置ID=2的网络优先级,默认为2
    wpa_cli -i wlan0 set_network 2 priority 2
  8. 获取当前网络状态

    1
    $ wpa_cli status
  9. 保存刚刚填写的wifi账号密码

    1
    $ wpa_cli -i wlan0 save_config
  10. 将ID=2的网络断开

    1
    $ wpa_cli -i wlan0 disable_network 2
  11. 将ID=2的网络移除,移除的前提一定是该网络需要断开(DISABLE)

    1
    $ wpa_cli -i wlan0 remove_network 2
  12. 切换使用ID=2的网络

    1
    $ wpa_cli -i wlan0 select_network 2
  13. 断开/重启网络连接

    1
    2
    $ wpa_cli -i wlan0 disconnect
    $ wpa_cli -i wlan0 reconnect

WPA配置文件

文件名称:wpa_supplicant.conf
该配置文件用于指定 Wi-Fi 网络的连接参数、安全设置和其他相关配置。同时包含了连接到一个或多个 Wi-Fi 网络所需的信息,wpa_supplicant 在启动时会读取这个文件,并根据其中的配置信息进行相应的连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 指定本地socket路径,用于wpa_cli与wpas的通信
ctrl_interface=/var/run/wpa_supplicant
# 这个配置项通常用于确定是否要将成功连接到的网络的配置信息写入到配置文件中。如果网络连接成功,会把信息写入该文件
update_config=1

network={
# ssid : 指定无线网络的服务集标识符(SSID),是网络的名称。
ssid="xiaomiCivi"
# 表示允许扫描隐藏的网络。当设置为1时,wpa_supplicant 会尝试主动发起对隐藏网络的扫描,并连接到匹配的隐藏网络
scan_ssid=1
# 密码
psk="12345678"
# 通过配置网络块的优先级,影响最终要连接的网络
priority=1
# 指定使用的密钥管理方式,例如 WPA-PSK(预共享密钥)或 WPA-EAP(扩展认证协议)。
key_mgmt=WPA-PSK
}

AP模式

AP热点模式使用到了hostapd和轻量级的udhcpd服务端

Hostapd介绍

en:users:documentation:hostapd [Linux Wireless]

hostapd: IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator

  1. hostapd 是一种用于无线局域网(WLAN)访问点的软件,可通过 Linux 系统将一台计算机转化为 WLAN 的访问点。
  2. 特点
    1. WLAN访问点(WLAN Access Point):hostapd 允许将一台计算机配置为无线局域网访问点,以便允许其他无线设备(如手机、笔记本电脑)连接到计算机并访问网络资源。
    2. 支持多种认证协议: hostapd 支持多种认证协议,包括WPA(Wi-Fi Protected Access)和WPA2,以提供更高级别的无线网络安全性。
    3. 支持多种加密算法: 它支持多种加密算法,如WEP(Wired Equivalent Privacy)、TKIP(Temporal Key Integrity Protocol)和CCMP(Counter Cipher Mode with Block Chaining Message Authentication Code Protocol),提供灵活的加密选项。
    4. 支持802.1X认证: hostapd 支持使用IEEE 802.1X认证协议,这是一种提供对网络用户进行身份验证的标准化方法。
    5. 灵活的配置选项: 用户可以通过配置文件对 hostapd 进行灵活的设置,以满足特定网络环境和需求。
    6. 实时监控和日志记录: hostapd 提供实时监控功能,可以记录无线客户端的连接和断开情况,同时生成详细的系统日志以便故障排查和性能监测

配置文件

配置说明

en:users:documentation:hostapd [Linux Wireless]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 告诉hostapd 使用什么无线接口
interface=wlan0
# 使用hostapd_cli的命令需要指定这个控制接口
ctrl_interface=/var/run/hostapd
# 驱动程序的选择,始终是nl80211
driver=nl80211
# 设置网络接口名称(SSID = service set identifier)
ssid=MyNetwork
# 设置接口的工作模式和允许的通道。有效值取决于硬件,但始终是 a(5G频段)、b(2.4G)、g(2.4G) 的子集。
hw_mode=g
# 设置hostapd 操作的通道。必须是 hw_mode 中设置的模式支持的通道,以及您所在国家/地区的无线监管规则允许的通道。
channel=1
# 控制 MAC 地址过滤。MAC 地址很容易被欺骗,因此仅考虑使用它来增强您现有的其他安全措施。
macaddr_acl=0
# 身份验证算法,位字段。1=用于开放身份验证,2=用于共享密钥身份验证 (WEP),3=两者
auth_algs=1
# 是否广播,0 广播SSID,1 不广播SSID(发送空SSID,即长度为0的SSID),2 忽略广播 SSID 的探测请求,跟1类似,但是兼容某些不支持空SSID的设备
ignore_broadcast_ssid=0
# 类似于auth_algs。1 wpa,2 wpa2, 3 两者。 新的设备可以设置为2,仅使用wpa2版本。
wpa=3
# 确定用于 WPA 身份验证的预共享密钥
wpa_passphrase=YourPassPhrase
# 控制客户端可以使用哪些密钥管理算法进行身份验证
wpa_key_mgmt=WPA-PSK
# 设置加密算法,CCMP就是AES,不推荐使用TKIP,除非设备不支持。wpa控制 WPA 的数据加密,rsn控制 WPA2 的数据加密。
wpa_pairwise=TKIP
rsn_pairwise=CCMP

命令行使用

  1. 启动hostapd server

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ hostapd /etc/hostapd.conf -B -d

    -h 显示帮助信息
    -d 显示更多的debug信息 (-dd 获取更多)
    -B 将hostapd程序运行在后台
    -g 全局控制接口路径,这个工hostapd_cli使用,一般为/var/run/hostapd
    -G 控制接口组
    -P PID 文件
    -K 调试信息中包含关键数据
    -t 调试信息中包含时间戳
    -v 显示hostapd的版本
  2. 修改无线热点的名称

    1
    2
    3
    $ hostapd_cli set ssid myNetWorkAP

    # 对端没有连接成功,reload不生效,新的SSID不显示; 对端连接成功,reload断开连接,但无法连接。
  3. 修改无线热点密码(reload生效)

    1
    $ hostapd_cli set wpa_passphrase 87654321
  4. 设置无线热点信道(reload不生效)

    1
    $ hostapd_cli set channel 11
  5. 隐藏无线热点(reload不生效)

    1
    $ hostapd_cli set ignore_broadcast_ssid 1
  6. 显示接口状态信息,包括接入点命令,当前连接客户端数量

    1
    $ hostapd_cli status
  7. 显示当前配置信息

    1
    $ hostapd_cli get_config

**注意事项**

  1. 使用 set 命令进行修改时,修改的内容是对应的内存里变量的内容,并不是修改 hostapd 配置文件的内容,因此在使用 set 命令完成所有的配置修改后,需要使用 reload 命令将这些配置重新加载。

    1
    $ hostapd_cli reload
  2. 有些配置内容即使按照 set 、reload 配置后,也是无法更新的。此时需要再 set 命令配置完成后,先使用 disable 命令,再使用 enable ,从而实现配置更新。

    1
    2
    3
    4
    # 禁用hostapd
    $ hostapd_cli disable
    #启用hostapd
    $ hostapd_cli enable

启动AP流程

  1. 启动hostapd server

  2. 为wlan0分配IP地址,默认为网关地址(可省略,直接使用udhcpd加 -I 参数)

    1
    ifconfig wlan0 192.168.1.1
  3. 启动udhcpd服务

    1
    udhcpd /etc/udhcpd.conf &

其它命令

udhcp

官网

udhcp Server/Client Package

u 可能是 “micro” 的缩写,表示 “微型”。udhcp 是一个小型 DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)客户端和服务器的工具集。这个工具集包括 udhcpc 客户端和 udhcpd 服务器(d 通常表示 “daemon”,指的是守护进程)。udhcpc是用来获取IP地址的,而udhcpd则是用来为设备分配IP地址的。如果使用的是静态IP则不需DHCP服务的。

udhcpd

  • 配置文件:udhcpd.conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # IP租用块的开始和结束
    start 192.168.0.150 #default: 192.168.0.20
    end 192.168.0.240 #default: 192.168.0.254

    # udhcpd使用的接口
    interface wlan0 #default: eth0

    # 最大租约数(包括 OFFER、DECLINE 和 ARP 冲突保留的地址)
    max_leases 21 #default: 254

    # 其它DHCP选项
    opt dns 116.116.116.116
    option subnet 255.255.255.0
    opt router 192.168.0.1
  • 功能:

    • IP地址分配: 提供动态分配 IP 地址的功能。当设备首次连接到网络时,udhcpd 可以为其分配一个可用的IP地址。
    • 子网掩码分配: 配置子网掩码,定义设备在网络上的地址范围。
    • 默认网关分配: 分配默认网关的IP地址,允许设备访问其他网络。
    • DNS服务器分配: 提供DNS服务器的IP地址,用于域名解析。
    • 租约管理: 管理IP地址的租约,包括租约的分配、更新和释放。
  • 启动udhcpd进程

    1
    2
    3
    4
    5
    6
    7
    # 执行下面命令自动在对应的目录下生成一个内容为该进程pid的文件,默认/var/run/udhcpd.pid
    udhcpd /etc/udhcpd.conf -I [addr]

    # -f 在前台运行
    # -S 也记录到系统日志
    # -I 本地地址,如果已经使用ifconfig工具配置了addrsess,就不需要这个悬念
    # -a ARP ping 的 MSEC 超时 (默认 2000)

udhcpc

udhcpc 是一个用于从 DHCP 服务器获取 IP 地址的小型 DHCP 客户端程序。通常,udhcpc 用于嵌入式系统或资源受限的环境,因为它相对轻量且占用资源少。

1
2
3
4
5
6
7
8
9
10
# 获取DHCP地址
$ udhcpc -i <interface>

#-b: 在后台运行udhcpc,以守护进程的方式工作。
#-i 指定接口,默认eth0
#-t 设置 DHCP 超时时间,即等待 DHCP 服务器响应的最长时间。单位是秒。(默认3)
#-T 设置 DHCP 重试时间,即在未收到 DHCP 服务器响应时,客户端将尝试重新发送 DHCP 请求的时间间隔。单位是秒。(默认3)
#-R: 在关闭udhcpc时,可以向dhcpserver发送release取消租约。
#-H 选项用于指定客户端主机名(Hostname)。主机名是在网络中用于标识设备的名称。

  • -b: 后台执行udhcpc命令
  • -s: 指定脚本文件,在DHCP成功获取地址后执行该脚本文件
  • -H: 指定客户端主机名,会在DHCP消息中发送
  • -p: 指定pid文件,记录udhcpc进程的id
  • -t: 指定超时时间,单位为秒

netd

Netd是Android系统中专门负责网络管理和控制的后台daemon程序。Netd位于Framework层和Kernel层之间,它是Android系统中网络相关消息和命令转发及处理的中枢模块。

  1. 异步非阻塞:netd采用异步非阻塞的编程模型,这意味着它可以同时处理多个并发的网络连接,而无需为每个连接创建一个线程。这种模型可以极大地减少线程切换和资源消耗,提高应用程序的性能和可扩展性。
  2. Reactor模式:netd使用Reactor模式来处理并发网络操作。它通过一个主事件循环来监听所有的网络事件,一旦有事件发生,就会通知相应的处理程序进行处理。这种事件驱动的模式可以更有效地管理并发连接和事件处理。
  3. 内存池:netd使用内存池来管理网络连接的内存分配和释放。通过预先分配一块连续的内存空间,可以避免频繁的内存申请和释放,提高内存的利用率和性能。
  4. 可扩展性:netd具有良好的可扩展性,可以根据应用程序的需求进行灵活的配置。它支持多线程的并发处理,可以通过增加线程数来提高处理能力。同时,它还支持基于事件的任务调度,可以将复杂的任务拆分为多个小任务,并根据情况动态地调整和分配资源。

ifconfig

ifconfig(接口配置)是一个网络管理工具,它用于配置和查看 Linux 操作系统中网络接口的状态,使用ifconfig,您可以分配 IP 地址、启用或禁用接口、管理 ARP 缓存、路由等。自从 Linux 内核版本 2.2 开始,推荐使用 ip 命令来替代 **ifconfig**,因为ip 命令提供了更强大和灵活的网络管理功能。

使用该ifconfig命令设置的配置不是持久的。系统重新启动后,所有更改都将丢失。要使更改永久生效,您需要编辑特定于发行版的配置文件或将命令添加到启动脚本。

  1. 显示网络接口信息

    1
    2
    # 输出包括有关所有活动和非活动网络接口的信息
    $ ifconfig -a
  2. 启用/禁用网络接口

    1
    2
    3
    4
    # 启用接口,interface: eth0、wlan0等
    $ ifconfig <interface> up
    # 禁用接口
    $ ifconfig <interface> down
  3. 设置IP地址和掩码

    1
    2
    # 例:ifconfig eth0 192.168.0.101 netmask 255.255.0.0
    $ ifconfig <interface> [ip-address] netmask [subnet-mask]
  4. 更改网络接口的MTU

    1
    2
    # MTU “最大传输单元”允许您限制在接口上传输的数据包的大小。
    $ ifconfig <interface> mtu [mtu-value]

ip

ip 命令是一个强大的网络工具,用于配置网络接口、路由表、策略路由等。

  1. 查看网络接口信息

    1
    2
    $ ip address show
    $ ip a
  2. 启用/禁用网络接口

    1
    2
    $ ip link set <interface> up    # 启用接口
    $ ip link set <interface> down # 禁用接口
  3. 配置/删除IP地址

    1
    2
    $ ip address add    <ip_address/mask> dev <interface>  # 添加 IP 地址
    $ ip address delete <ip_address/mask> dev <interface> # 删除 IP 地址
  4. 使用详情:click

iw

iw 是一个全新的基于 nl80211 的用于配置无线设备的命令行界面(CLI)实用程序。它支持最近添加到内核中的所有新驱动程序。与已废弃的 iwconfig 工具相比,采用无线扩展接口的 iw 更为先进和强大。因此,我们强烈建议您切换到 iw 和 nl80211,以便更好地配置和管理您的无线设备。

1
2
3
4
5
6
7
8
9
10
11
12
# iw help    # 帮助
# iw list # 获得所有设备的功能,如带宽信息(2.4GHz,和5GHz),和802.11n的信息
# iw dev wlan0 scan # 扫描
# iw event # 监听事件
# iw dev wlan0 link # 获得链路状态
# iw wlan0 connect foo # 连接到已禁用加密的AP,这里它的SSID是foo
# iw wlan0 connect foo 2432 # 假设你有两个AP SSID 都是 foo ,你知道你要连接的是在 2432 频道
# iw wlan0 connect foo keys 0:abcde d:1:0011223344 # 连接到使用WEP的AP
# iw dev wlan1 station dump # 获取station 的统计信息
# iw dev wlan1 station get # 获得station对应的peer统计信息
# iw dev wlan0 set power_save on #设置省电模式
# iw dev wlan0 get power_save #查询当前的节电设定

Q&A

  1. 使用wpa_cli执行scan命令出现 Failed to connect to non-global ctrl_ifname: wlan0 error: No such file or directory错误?
    可能是-p的参数指定socket的路径的时候出现错误,此时需要查看在wpa_supplicant.conf文件中ctrl_interface指定的socket路径是哪里

  2. 直接使用udhcpd可能出现一些错误,错误log以及解决方案如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # error, max_leases value (254) not sane, setting to 234 instead
    max_leases 字段的值设置不正确,改成234或者更小即可

    # error, Unable to open /var/lib/misc/udhcpd.leases for reading
    系统中没有这个路径和文件。使用以下命令:***mkdir -p /var/lib/misc/; touch /var/lib/misc/udhcpd.leases***

    # error, SIOCGIFADDR failed, is the interface up and configured?: No such device
    interface接口没有启动或者名称错误。可以使用ifconfig查看是否存在,不存在启动(ifconfig wlan0 up),并检查名字拼写

    # udhcpd: is interface wlan0 up and configured?: Cannot assign requested address
    没有指定的地址,使用 ***udhcpd -I [addr]*** 或者 ***ifconfig wlan0 addr*** 命令指定

参考资料

第4章 深入理解wpa_supplicant · 深入理解Android:Wi-Fi、NFC和GPS卷(完整版) · 看云

linux下wifi的sta和ap操作 - 良知犹存 - 博客园

【转】wpa_supplicant和hostapd的定义和区别 - 陈晓涛 - 博客园