【翻译 Meike Chabowski 的《Creating Virtual WLAN Interfaces》】

概述

当涉及到用于测试目的的测试和虚拟设备时,Linux 内核始终是一个令人惊讶的丰富来源。我目前正在为wpa_supplicant设置一个openQA测试,这可能是最广泛的受保护WiFi访问程序。wpa_supplicant也用于Android,是提供大多数更高级别的WiFi功能的部分。为了验证wpa_supplicant是否继续工作,我创建了一个自动测试,用于检查每个更新是否仍然有效。我使用了虚拟 WLAN 接口和网络命名空间分离,因此测试是自包含的(即它在单个虚拟机上运行)和可移植的。

因此,在本指南中,我们将执行以下操作:

  • 设置两个虚拟 WLAN 接口(WLAN0 和 WLAN1)
  • 将 WLAN0 和 WLAN1 隔离到两个网络命名空间中
  • 使用 hostapd
    和 dnsmasq 创建虚拟接入点
  • 将 WiFi 客户端连接到网络
  • 运行基本网络 ping 测试

您将需要以下内容:

  • 运行 openSUSE Leap/Tumbleweed 的物理机或虚拟机(但它也应该适用于其他发行版)
  • 对该计算机的根访问权限

要求

首先安装本指南的要求:

leap-15_1:~ # zypper in hostapd dnsmasq wpa_supplicant iw

设置无线局域网接口

Linux 内核已经通过 mac80211_hwsim 模块提供了我们需要的一切。它是由Jouni Malinen编写的IEEE 802.11无线网络(通常称为WLAN网络)的软件模拟器。这个内核模块是一件艺术品 - 它创建了任意数量的虚拟WiFi接口,如果将它们调谐到同一信道,则可以相互通信。像这样,可以模拟各种任意复杂的场景,从简单的双设备网络(如我们将使用的那样)到多个客户端连接到在不同通道上运行的各种热点的复杂设置。

按如下方式设置 WiFi 接口:

leap-15_1:~ # modprobe mac80211_hwsim radios=2

参数 radios=2 定义将创建多少个虚拟接口,默认为两个设备。成功加载内核模块后,出现WLAN0和WLAN1,如下图所示(执行ip链路)。弹出的第三个接口是 hwsim1。如前所述,WLAN接口可以调谐到信道,并且只能在该特定信道上发送和接收无线电帧。hwsim0 是用于调试目的的虚拟接口,您可以在其中收听所有通道上的所有无线电帧。本指南不需要它。


mac80211_hwsim模块已加载并显示两个 WLAN 接口

将接口隔离到命名空间中

设置接口后,所有接口都可见,可从系统访问。我们需要将两个WiFi接口分开,以便我们能够测试它们之间的连接性。假设 WLAN0 的 IP 地址为 192.168.200.1,WLAN1 的 IP 地址为 102.168.200.101。如果您现在对两个地址之一执行简单的 ping,系统将直接在该接口上执行 ping。在此配置中,我们无法测试数据包是否会通过虚拟WiFi。

幸运的是,网络命名空间分离允许我们将接口彼此分开。更具体地说,它允许我们运行一个单独的外壳,其中一个 WLAN 接口将在其中。在该配置中,系统除了通过 WLAN 接口路由数据包以到达另一个数据包外,没有其他可能性。有关分离的说明,请参见下图:


如果没有网络命名空间分离,两个接口都可见


不同网络命名空间中的接口看不到彼此。在此配置中,数据包需要通过虚拟 wifi 才能相互访问

我们将为 WLAN0 接口创建一个名为 wifi_master 的网络命名空间,并在该命名空间中运行单独的 shell。这样,我们最终有两个shell:一个用于WiFi热点(wifi_master),一个用于WiFi客户端。两个外壳都只能看到它们对应的 WLAN 接口,并不知道另一个接口的存在。

首先创建网络命名空间:

leap-15_1:~ # ip netns add wifi_master
leap-15_1:~ # ip netns list
wifi_master

分配网络命名空间的最方便方法之一是通过 IP link set。不幸的是,这不适用于虚拟接口,因此我们需要为此使用 iw 实用程序。

leap-15_1:~ # ip link set dev wlan1 netns wifi_master
RTNETLINK answers: Invalid argument

使用 iw 实用程序分配 WLAN 接口基于进程 ID 工作。因此,我们首先将在新的网络命名空间中启动我们的WiFi Master shell:

# Run this in a separate shell.
leap-15_1:~ # ip netns exec wifi_master bash
leap-15_1:~ # echo $BASHPID
3282

这将是我们的WiFi热点,称为wifi_master,具有pid 3282。现在,从我们的第一个shell开始,WLAN0 仍然可见,我们将 WLAN0 分配给 wifi_master 命名空间(将 3282 替换为wifi_master shell的 pid):

leap-15_1:~ # iw phy phy0 set netns 3282


WiFi master shell


WiFi client shell
结果应该是这两个shell:具有WLAN0接口的WiFi Master和具有WLAN1接口的WiFi Client。

配置接入点

在WiFi Master shell中,我们现在配置接入点。接口获得一个静态IP,dnsmasq将作为DHCP服务器运行,并为WiFi设置托管。首先,我们将静态 IP 设置并将 dnsmasq 设置为 DHCP 服务器(并将其作为后台作业运行):

leap-15_1:~ # ip addr add 192.168.200.1/24 dev wlan0

接下来,我们将 dnsmasq 设置为 DHCP 服务器并将其作为后台作业运行:

leap-15_1:~ # dnsmasq -i wlan0 --dhcp-range=192.168.200.128,192.168.200.200 &

对于hostapd,我们使用以下非常简单的配置文件hostapd.conf:

# hostapd.conf
interface=wlan0
driver=nl80211
country_code=DE
ssid=Virtual Wifi
channel=0
hw_mode=b
wpa=3
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
wpa_passphrase=TopSecretWifiPassphrase
auth_algs=3
beacon_int=100

然后我们使用以下命令运行 hostapd:

leap-15_1:~ # hostapd hostapd.conf

您应该看到类似于以下屏幕的内容:


无线网络接入点已启动

祝贺!接入点已启动并正在运行。下一步是配置 WiFi 客户端。

连接无线网络客户端

我们使用wpa_supplicant连接到WiFi接入点。在 Wifi 客户端 shell 中,我们首先创建以下非常简单的 wpa_supplicant.conf 文件:

# wpa_supplicant.conf
network={
  ssid="Virtual Wifi"
  key_mgmt=WPA-PSK
  psk="TopSecretWifiPassphrase"
}

并通过以下命令连接到接入点:

# Run those commands in the wifi-client shell!

# Note: -B is for run in background
leap-15_1:~ # wpa_supplicant -B -i wlan1 -c wpa_supplicant.conf

您现在应该在 WiFi 主终端中看到身份验证:


WPA 握手在 WiFi 接入点上完成

DHCP客户端使用Wicked

为 wicked 创建以下非常基本的配置文件:

# /etc/sysconfig/network/ifcfg-wlan1
BOOTPROTO='dhcp'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR=''
MTU=''
NAME=''
NETMASK=''
NETWORK=''
REMOTE_IPADDR=''
STARTMODE='auto'

然后重新启动 wicked 以获取新的 IP 地址:

leap-15_1:~ # systemctl restart wicked
leap-15_1:~ # ip addr show dev wlan1
4: wlan1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN 
group default qlen 1000
    link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::ff:fe00:100/64 scope link 
       valid_lft forever preferred_lft forever

最后 ping 接入点:

leap-15_1:~ # ping -c 4 192.168.200.1


Ping 在 WiFi 客户端shell中成功工作

祝贺!您已成功设置虚拟 WLAN 网络!

译者补充

这篇文章代码我在Arch上测试了一遍,总体不差的能在虚拟机上模拟wlan

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐