admin管理员组

文章数量:1576354

本文介绍了在linux操作系统上编译、运行、调试wpa_supplicant程序的详细步骤,对希望研究wifi连接过程的开发者有一定帮助

前提:安装ubuntu虚拟机

本文使用的linux发行版本:Ubuntu 20.04.6 LTS

1 编译wpa_supplicant软件

1.1 下载wpa_supplicant

wpa_supplicant各版本下载页面:Index of /releases

在页面中,不同前缀开头的表示不同的程序,后面的数字代表版本号

  • - Prism2
  • - hostap
  • - hostap-driver
  • - hostap-utils
  • - hostapd
  • - wpa_supplican
  • - wpa_supplicant-cygwin-bin
  • - wpa_supplicant-windows-bin

本文只需下载wpa_supplican前缀的包即可,在Linux系统中下载命令如下:

mkdir -p ~/Documents
cd ~/Documents
wget https://w1.fi/releases/wpa_supplicant-2.10.tar.gz
tar -xzvf wpa_supplicant-2.10.tar.gz
cd wpa_supplicant-2.10

进入wpa_supplicant-2.10文件夹,查看wpa_supplicant/README

vim wpa_supplicant/README

搜索关键字www.openssl,可以看到如下内容:

Optional libraries for EAP-TLS, EAP-PEAP, and EAP-TTLS:
 
- OpenSSL (tested with 1.0.1 and 1.0.2 versions; assumed to
  work with most relatively recent versions; this is likely to be
  available with most distributions, http://www.openssl/)
- GnuTLS
- internal TLSv1 implementation

说明该wpa_supplicant版本依赖openssl 1.0.1或1.0.2版本,因此还需要安装openssl

1.2 下载openssl

OpenSSL是一个开源的密码学库和SSL/TLS协议实现,下载页面:[ Downloads ] - /source/index.html

1.0.1是较老的版本,下载页面:[ 1.0.1 ] - /source/old/1.0.1/index.html

只需下载第一个链接即可,在Linux系统中下载命令如下:

cd ~/Documents
wget https://www.openssl/source/old/1.0.1/openssl-1.0.1u.tar.gz
tar -zxvf openssl-1.0.1u.tar.gz
cd openssl-1.0.1u

1.3 编译安装openssl

进入openssl-1.0.1u文件夹,执行以下命令安装openssl

cd ~/Documents
cd openssl-1.0.1u
./config --openssldir=/usr/local/bin/openssl-1.0.1u shared
sudo make
sudo make install
ls -l /usr/bin/openssl
openssl version -a
sudo mv /usr/bin/openssl /usr/bin/openssl_old
 
sudo ln -s /usr/local/bin/openssl-1.0.1u/bin/openssl /usr/bin/openssl
ls -l /usr/bin/openssl
openssl_old version -a
openssl version -a

注意:./config --openssldir命令中指定了openssl的安装路径

因为本文使用的系统已经安装过openssl,所以将已安装的openssl软链接改为openssl_old,再创建了一个新的openssl软链接

最后输出结果如下:

OpenSSL 1.0.1u  22 Sep 2016
built on: Tue Sep 12 11:14:06 2023
platform: linux-x86_64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx) 
compiler: gcc -I. -I.. -I../include  -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/usr/local/bin/openssl-1.0.1u"

1.4 安装libnl、libssl和libdbus

安装wpa_supplicant还需要libnl、libssl和libdbus库的支持

sudo apt-get update
sudo apt-get install libdbus-1-dev
sudo apt-get install libssl-dev
sudo apt-get install libnl-3-dev libnl-3-200 libnl-genl-3-dev libnl-route-3-dev

注意,上述命令中的几个libnl包,只要有一个能安装成功即可,测试libnl-genl-3-dev在Ubuntu 20.04.6 LTS上可以正常安装

安装成功后,使用命令查看libnl包

sudo apt list libnl*

结果如下:

ibnl-3-200-dbg
libnl-3-200
libnl-3-dev
libnl-cli-3-200
libnl-cli-3-dev
libnl-genl-3-200
libnl-genl-3-dev
libnl-idiag-3-200
libnl-idiag-3-dev
libnl-nf-3-200
libnl-nf-3-dev
libnl-route-3-200
libnl-route-3-dev
libnl-utils
libnl-xfrm-3-200
libnl-xfrm-3-dev
libnlopt-cxx-dev
libnlopt-cxx0
libnlopt-dev
libnlopt-guile0
libnlopt0

对照以上包,缺少哪一个就再安装那一个包

1.5 编译安装wpa_supplicant

最后,编译并安装wpa_supplicant,执行以下命令

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant
cp defconfig .config
ls -l .config
sudo ln -s /usr/local/bin/openssl-1.0.1u/lib/libcrypto.so /usr/lib/libcrypto.so
sudo make
sudo make install
wpa_supplicant -v

最后输出结果如下:

wpa_supplicant v2.10
Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi> and contributors

1.6 编译结果

在wpa_supplicant文件下可以看到编译后的可执行文件

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant
file * | grep "ELF"

结果如下

wpa_cli:                      ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=1ecc67063a6d45d7432f9d946a7ae3f2642cb47d, for GNU/Linux 3.2.0, with debug_info, not stripped
wpa_passphrase:               ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=e6a666c4d5153295dbb1dc6c148bdac707a1dd82, for GNU/Linux 3.2.0, with debug_info, not stripped
wpa_supplicant:               ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=49e7bf7c341bc72ceac844ef90f5ba3ad30fefd1, for GNU/Linux 3.2.0, with debug_info, not stripped

编译结果中有3个软件,wpa_supplicant、wpa_cli、wpa_passphrase

1、wpa_passphrase:用于向conf配置文件中添加网络配置信息,例如

sudo wpa_passphrase ssid passphrase | sudo tee wpa_supplicant.conf`

2、wpa_supplicant:用于启动wpa_supplicant应用程序,例如 

sudo wpa_supplicant -D nl80211 -i wlan0 -c wpa_supplicant.conf

3、wpa_cli:用于与 wpa_supplicant控制接口进行交互的命令行工具,例如

(1)扫描

wpa_cli -i wlan0 scan

 (2)查看扫描结果

wpa_cli -i wlan0 scan_results

安装之前,查看文件位置

whereis wpa_cli wpa_supplicant wpa_passphrase

结果如下:

wpa_cli: /usr/sbin/wpa_cli /usr/share/man/man8/wpa_cli.8.gz
wpa_supplicant: /usr/sbin/wpa_supplicant /etc/wpa_supplicant /usr/share/man/man8/wpa_supplicant.8.gz
wpa_passphrase: /usr/bin/wpa_passphrase /usr/share/man/man8/wpa_passphrase.8.gz

安装之后,再使用whereis 命令查看位置

结果如下:

wpa_cli: /usr/sbin/wpa_cli /usr/local/sbin/wpa_cli /usr/share/man/man8/wpa_cli.8.gz
wpa_supplicant: /usr/sbin/wpa_supplicant /etc/wpa_supplicant /usr/local/sbin/wpa_supplicant /usr/share/man/man8/wpa_supplicant.8.gz
wpa_passphrase: /usr/bin/wpa_passphrase /usr/local/sbin/wpa_passphrase /usr/share/man/man8/wpa_passphrase.8.gz

说明本次编译这3个软件安装的位置在/usr/local/sbin,具体路径如下:

wpa_cli: /usr/local/sbin/wpa_cli
wpa_supplicant: /usr/local/sbin/wpa_supplicant
wpa_passphrase: /usr/local/sbin/wpa_passphrase

2 运行wpa_supplicant

2.1 编辑wpa_supplicant.conf文件

在运行wpa_supplicant时需要先设置conf文件

关于conf文件中各参数配置的详细解释,可以查看示例文件

wpa_supplicant-2.10/wpa_supplicant/wpa_supplicant.conf

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant
vim wpa_supplicant.conf

新建wpa_supplicant.conf文件如下:

sudo vim /etc/wpa_supplicant.conf

在文件中输入以下内容

ctrl_interface=/var/run/wpa_supplicant
update_config=1
country=CN
ap_scan=1
 
network={
        ssid="xxxxxx"
        psk="password"
}

然后插入一个免驱的usb无线网卡,虽然免驱,其实是Linux系统已经自带了该类型网卡的驱动

插入网卡后,点击VirtualBox虚拟机上方窗口菜单的:设备->USB,选择对应的网卡设备

网卡名称前打勾后就表示生效,可以进行下一步操作

输入ifconfig查看网卡信息,结果如下:

wlan0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 52:b0:60:45:0a:bc  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

注意:插入网卡后,系统会自动启动自带的wpa_supplicant进程,此时通过ps命令可以看到wpa_supplicant已经启动

ps aux | grep wpa_supplicant

可以切换到root用户,使用airmon-ng工具关闭系统自带的wpa_supplicant进程,再切换回普通用户

sudo apt-get install aircrack-ng
su root
airmon-ng check kill

此时再输入ifconfig已经看不到wlan的网卡了,但是输入iw dev或ip link可以看到wlan0网卡

iw dev命令结果如下:

phy#0
	Interface wlan0
		ifindex 4
		wdev 0x1
		addr c0:1c:30:2f:ef:5d
		type managed
		txpower 20.00 dBm

ip link命令结果如下:

3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
    link/ether c0:1c:30:2f:ef:5d brd ff:ff:ff:ff:ff:ff

2.2 启动wpa_supplicant程序

启动本文编译的wpa_supplicant即可

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant
sudo ./wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf

上述命令中,各参数说明如下:

- 参数-D表示指定驱动,上述命令指定了nl80211驱动
- 参数-i表示指定网卡接口,上述命令指定了wlan0
- 参数-c表示指定conf文件路径,上述命令指定为/etc/wpa_supplicant.conf

还可以输出日志到指定文件,如下

sudo ./wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -dd > ./wpa_supplicant.log

若提示已经运行了wpa_supplicant,初始化wpa_supplicant失败,如下

ctrl_iface exists and seems to be in use - cannot override it
Delete '/var/run/wpa_supplicant/wlan0' manually if it is not used anymore
Failed to initialize control interface '/var/run/wpa_supplicant'.
You may have another wpa_supplicant process already running or the file was
left by an unclean termination of wpa_supplicant in which case you will need
to manually remove this file before starting wpa_supplicant again.
 
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
nl80211: deinit ifname=wlan0 disabled_11b_rates=0

则运行以下命令,删除已经存在的socket文件wlan0,并杀死所有的wpa_supplicant进程

sudo rm /var/run/wpa_supplicant/wlan0
sudo killall wpa_supplicant

也可以切换到root用户,使用airmon-ng工具关闭wpa_supplicant进程,再切换回普通用户

sudo apt-get install aircrack-ng
su root
airmon-ng check kill

然后再次启动wpa_supplicant

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant/
sudo ./wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf

运行完成后,新建终端,使用以下命令查看刚才启动的wpa_supplicant是否已经运行

ps aux | grep wpa_supplicant

如果conf文件中配置了有效的无线网络,则可以看到类似以下输出

Successfully initialized wpa_supplicant
wlan0: CTRL-EVENT-REGDOM-CHANGE init=BEACON_HINT type=UNKNOWN
wlan0: CTRL-EVENT-REGDOM-CHANGE init=USER type=COUNTRY alpha2=CN
wlan0: SME: Trying to authenticate with 9c:8c:d8:00:a8:e0 (SSID='xxxxxx' freq=2412 MHz)
wlan0: Trying to associate with 9c:8c:d8:00:a8:e0 (SSID='xxxxxx' freq=2412 MHz)
wlan0: Associated with 9c:8c:d8:00:a8:e0
wlan0: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
wlan0: WPA: Key negotiation completed with 9c:8c:d8:00:a8:e0 [PTK=CCMP GTK=CCMP]
wlan0: CTRL-EVENT-CONNECTED - Connection to 9c:8c:d8:00:a8:e0 completed [id=0 id_str=]

在另一个终端中使用DHCP获取ip地址

sudo dhclient wlan0

此时输入ifconfig可以看到已经获取到了ip地址

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.98.70.196  netmask 255.255.252.0  broadcast 10.98.71.255
        ether 2e:d0:00:6c:31:e4  txqueuelen 1000  (Ethernet)
        RX packets 39  bytes 6772 (6.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 94  bytes 13072 (12.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2.3 启动wpa_cli程序

新建终端,运行wpa_cli程序

wpa_cli操作命令示例

wpa_cli -i wlan0 scan          //扫描
wpa_cli -i wlan0 scan_result   //显示扫描结果
wpa_cli -i wlan0 status        //查看状态
wpa_cli -i wlan0 mib          //获取设备的mib信息
wpa_cli -i wlan0 ping           //pings wpa_supplicant,wpa_supplicant收到后回复PONG
 
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> key_mgmt NONE  //无密码的网络
wpa_cli -i wlan0 save_config   //保存网络信息到配置文件
 
wpa_cli -i wlan0 list_network  //列出网络
wpa_cli -i wlan0 select_network  <network id>  //选择网络
wpa_cli -i wlan0 enable_network  <network id>  //使能网络,也就是连接网络
wpa_cli -i wlan0 disable_network <network id>  //断开网络

更多详细命令,输入以下命令查看

wpa_cli -h

例如要连接test网络,密码为password,网卡接口为wlan0,命令如下

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant/
sudo ./wpa_cli -i wlan0 add_network
sudo ./wpa_cli set_network 0 ssid "test"
sudo ./wpa_cli set_network 0 psk "password"
sudo ./wpa_cli -i wlan0 list_network
sudo ./wpa_cli -i wlan0 select_network 0
sudo ./wpa_cli -i wlan0 enable_network 0

最后使用DHCP获取ip地址

sudo dhclient wlan0

3 运行wpa_gui

3.1 直接安装wpagui

wpa_gui是图形化的管理工具,需要单独安装,安装命令如下

sudo apt-get install wpagui

启动wpa_gui

sudo wpa_gui

3.2 编译安装wpa_gui-qt4

wpa_supplicant项目中也提供了一个wpa_gui-qt4程序

如果直接从wpa_supplicant项目中编译安装也是可以的,如下:

安装qmake

sudo apt-get install qt5-qmake

查询安装路径

qmake -query | grep bin

结果如下

QT_INSTALL_BINS:/usr/lib/qt5/bin
QT_HOST_BINS:/usr/lib/qt5/bin

添加bin文件的路径到环境变量

export PATH=/usr/lib/qt5/bin:$PATH

然后安装qt5-default

sudo apt install qt5-default
sudo apt install libpcap-dev libncurses5-dev libprocps-dev libxtst-dev libxcb-util0-dev qttools5-dev-tools libdtkwidget-dev libdtkwm-dev pkg-config

如果安装失败,尝试安装qtbase5-dev

sudo apt-get install qtbase5-dev
sudo apt install libpcap-dev libncurses5-dev libxtst-dev libxcb-util0-dev qttools5-dev-tools libdtkwidget-dev pkg-config

然后进入wpa_supplicant文件目录,编译安装wpa_gui-qt4

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant
sudo make wpa_gui-qt4
sudo make install wpa_gui-qt4

结果如下:

make -C ../src install
for d in ap common crypto drivers eapol_auth eapol_supp eap_common eap_peer eap_server l2_packet p2p pae radius rsn_supp tls utils wps fst; do [ -d $d ] && make -C $d install; done
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
Nothing to be made.
if ls eap_*.so >/dev/null 2>&1; then \
        install -d /usr/local/lib/wpa_supplicant && \
        cp *.so /usr/local/lib/wpa_supplicant \
; fi
make: 'wpa_gui-qt4' is up to date.

进入目录执行wpa_gui

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant/wpa_gui-qt4
sudo ./wpa_gui

4 修改代码后重新编译wpa_supplicant

应用程序wpa_cli就是通过创建的socket文件/var/run/wpa_supplicant/wlan0与wpa_supplicant程序进行交互

在文件src\utils\wpa_debug.h中可以看到wpa_supplicant的日志级别共有6种,如下:

enum {
    MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR
};

查看当前的日志调试级别

sudo ./wpa_cli -p/var/run/wpa_supplicant -iwlan0 log_level

结果如下

Current level: INFO
Timestamp: 0

默认输出的级别为INFO,即EXCESSIVE、MSGDUMP、DEBUG级别的日志将不会输出

修改级别为DEBUG

sudo ./wpa_cli -p/var/run/wpa_supplicant -iwlan0 log_level DEBUG

若要在代码中修改调试级别,需要修改wpa_supplicant\main.c文件下的main()函数,找到对应位置

params.wpa_debug_level = MSG_INFO;

修改为

params.wpa_debug_level = MSG_DEBUG;

修改wpa_supplicant的源码后,重新编译的命令如下

cd ~/Documents
cd wpa_supplicant-2.10/wpa_supplicant
sudo make clean
sudo make
sudo make install

5 参考

wpa_supplicant - ArchWiki

https://www.linuxfromscratch/blfs/view/svn/basicnet/wpa_supplicant.html

本文标签: 操作系统Linuxwpasupplicant