实验 01:mac80211_hwsim 虚拟无线建链与状态观测¶
实验目标¶
在无需任何真实 Wi-Fi 射频网卡与屏蔽箱的环境下,利用 Linux 内核的 mac80211_hwsim 驱动创建两个虚拟无线节点(一个作为 AP,一个作为 STA),完成从扫描、WPA2 握手、关联到 IP 通信的全流程,并实时观测内核与用户态的状态机事件流。
实验准备与避坑说明¶
- 系统要求:Ubuntu 20.04/22.04/24.04 或 Debian (内核已内置
CONFIG_MAC80211_HWSIM=m)。 - 工具安装:
- 避坑警告 (NetworkManager 干扰): 桌面发行版默认开启的 NetworkManager 会自动抢占虚拟无线网卡,导致 AP 启动失败或 STA 握手被打断。实验前务必将虚拟网卡设为未托管:
步骤 1:加载虚拟无线驱动并核验接口¶
加载包含 2 个虚拟 Radio 的模块:
预期输出类似:步骤 2:启动 AP 端 (hostapd)¶
创建最小 AP 配置文件 /tmp/hwsim-hostapd.conf:
interface=wlan0
driver=nl80211
ssid=Hwsim-Lab-AP
hw_mode=g
channel=6
wpa=2
wpa_passphrase=password123
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
在默认命名空间中启动 hostapd(记录 PID 便于清理):
步骤 3:动态识别 STA 无线 PHY 并隔离至 Network Namespace¶
为什么必须按 wiphy 隔离网络命名空间?
- 避免本地回环短路:若将两个属于同一子网的 IP(如
192.168.99.1和192.168.99.2)直接配置在同一个 Linux 网络命名空间,内核本地路由表(table local)会直接由lo回环短路交付,根本不流经虚拟无线介质。 - cfg80211 的命名空间规则:Linux 内核规定无线网卡(
net_device)必须与其所属的无线物理层实体(struct wiphy)一同迁移,不能使用常规的ip link set <dev> netns <ns>。必须动态识别其绑定的wiphy名称,再调用iw phy <phyname> set netns name <ns>。
# 1. 动态查询与 wlan1 绑定的 wiphy 名称 (如 phy1,避免硬编码)
STA_PHY=$(iw dev wlan1 info | awk '/wiphy/ {print "phy"$2}')
# 2. 创建独立的网络命名空间
sudo ip netns add sta_ns
# 3. 将 STA 对应的整个 wiphy 迁移进命名空间
sudo iw phy "$STA_PHY" set netns name sta_ns
# 4. 验证无线物理接口已在命名空间内可见
sudo ip netns exec sta_ns iw dev
步骤 4:在命名空间内启动 STA 并完成建链¶
创建 STA 配置文件 /tmp/hwsim-wpa.conf:
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="Hwsim-Lab-AP"
psk="password123"
key_mgmt=WPA-PSK
proto=RSN
pairwise=CCMP
}
在 sta_ns 命名空间中启动 wpa_supplicant:
检查连接状态:
预期看到:Connected to 02:00:00:00:00:00, SSID: Hwsim-Lab-AP, rx bitrate: 54.0 MBit/s。
步骤 5:跨命名空间配置 IP 并进行真无线链路 Ping 测试¶
# 1. 为 AP 分配 IP (默认命名空间)
sudo ip addr add 192.168.99.1/24 dev wlan0
sudo ip link set wlan0 up
# 2. 为 STA 分配 IP (sta_ns 命名空间)
sudo ip netns exec sta_ns ip addr add 192.168.99.2/24 dev wlan1
sudo ip netns exec sta_ns ip link set wlan1 up
# 3. 在终端中实时监听 AP 接口的数据包
# 若看到 ARP 请求与 ICMP 报文,证明流量切实穿过了 mac80211_hwsim 虚拟无线介质
sudo tcpdump -i wlan0 -nn -e icmp &
TCPDUMP_PID=$!
# 4. 从 sta_ns 命名空间向 AP 发起 Ping
sudo ip netns exec sta_ns ping -c 4 192.168.99.1
kill $TCPDUMP_PID 2>/dev/null || true
步骤 6:安全清理实验环境¶
使用记录的 PID 文件安全终止实验进程,避免使用危险的 killall 误杀系统其他无线服务:
# 终止实验进程
[ -f /tmp/hwsim-hostapd.pid ] && sudo kill $(cat /tmp/hwsim-hostapd.pid) 2>/dev/null || true
[ -f /tmp/hwsim-wpa.pid ] && sudo kill $(cat /tmp/hwsim-wpa.pid) 2>/dev/null || true
# 删除测试命名空间并卸载驱动
sudo ip netns del sta_ns 2>/dev/null || true
sudo modprobe -r mac80211_hwsim 2>/dev/null || true
rm -f /tmp/hwsim-*.conf /tmp/hwsim-*.pid
进阶挑战¶
- 错误密码实验:将
/tmp/hwsim-wpa.conf中的密码改为wrongpass,再次运行,观察wpa_supplicant日志:在 Association 成功后,四次握手因 MIC 校验失败被 AP 踢下线并抛出Deauth (reason 2: PREV_AUTH_NOT_VALID)。 - 虚拟 Monitor 抓包:在加载驱动后,通过
sudo iw phy phy0 interface add mon0 type monitor创建专用的虚拟监听接口,利用 Wireshark 捕获无损的 802.11 原始管理帧。