最近想搞个无线路由,linux下的无线路由/无线AP的实现就是 hostapd 这个软件了。
网上有很多关于 hostapd 的介绍,百度一下就能得到很多相关的信息,这里只是整理我自己配置hostapd的一步骤,过程中也遇到大大小小的坑,方便以后查询避免。
AP的工作模式我们只需要一块无线网卡和一块有线网卡。无线网卡PCI接口或者USB接口的都可以,有线网卡通常集成在主板上或插在主板上百兆/千兆的速率,市面上也很常见。
一般linux系统内核默认就已经支持绝大多数的硬件型号并且工作良好,如果遇到内核无法识别的网卡型号,就需要自己手动安装驱动模块或者手动编译。搞定驱动的方法及相关步骤并不在本文的讨论范围之内。
要使用AP模式无线网卡首先要支持AP模式才行。如何检测无线网卡是否支持AP模式,可以通过下面命令查看:
iw list
[root@server ~]# iw list Wiphy phy0 ……省略…… Supported interface modes: * IBSS * managed * AP #说明无线网卡支持AP模式 * AP/VLAN * monitor ……省略……
我的Intel Corporation Centrino Wireless-N 105 无线网卡支持5种,AP模式也在受支持的范围。
我用的是 CentOS 7 的系统,目前已经更新至 CentOS 7.1, 官方实际上并没有提供hostapd的软件包,要使用hostapd这个软件的第一步就是要启用EPEL的源。
关于EPEL源的介绍请自行百度或看看《CentOS 7 安装EPEL源》。
yum update #先更新系统
yum install epel-release #安装EPEL源
我们可能不知道系统提供哪些有关hostapd的软件包,可以先搜索一下有哪些包含hostapd的软件包。
当然如果没有安装并启用EPEL源的话将无法通过 yum search <软件包名字符串> 命令搜索到任何结果。安装并启用EPEL源后使用下面命令搜索。
yum search hostapd
[root@server ~]# yum search hostapd 已加载插件:fastestmirror, remove-with-leaves Loading mirror speeds from cached hostfile ============================ N/S matched: hostapd ============================ hostapd-logwatch.x86_64 : Logwatch scripts for hostapd hostapd.x86_64 : IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
从上面可以看到hostapd.x86_64就是我们想要的软件包,使用 yum 进行安装。
yum install hostapd
那么接下来配置使用 hostapd 就是从他的软件包中的文件入手。因此要先查看hostapd软件包所提供文件列表,使用 rpm -ql <软件包名>进行查询。
rpm -ql hostapd
[root@server ~]# rpm -ql hostapd /etc/hostapd /etc/hostapd/hostapd.conf #最主要的配置文件 /etc/sysconfig/hostapd /usr/lib/systemd/system/hostapd.service #服务脚本 /usr/sbin/hostapd #主要的命令 /usr/sbin/hostapd_cli ……省略…… /usr/share/doc/hostapd-2.4/hostapd.conf #该文件夹下包含相关配置示例一定要看 ……省略…… /usr/share/man/man1/hostapd_cli.1.gz #man手册 /usr/share/man/man8/hostapd.8.gz
在安装好无线网卡后,如果没有连接过任何无线接入点(如无线路由器、其他wifi等)可以直接看下一步。
坑提示:如果是 NetworkManager 管理的无线网卡,是无法启动 hostapd 服务的。我们可能想要无线网卡既能连接其他无线接入点(如无线路由器、其他wifi等)又能供其它手机等客户端连接,需要在 hostapd.conf 配置文件中设置。
未连接过任何无线接入点(如无线路由器、其他wifi等)的情况下 NetworkManager 中显示的无线网卡的状态默认是“不可用”的。通过 nmcli device show 命令就可以查看到,只要确保无线网卡的状态为“不可用”或“未管理”就可以,就像下面这样。
nmcli device show
[root@server ~]# nmcli device show ……省略…… GENERAL.设备: wlp2s0 GENERAL.类型: wifi GENERAL.硬盘: 80:5B:22:D0:7C:64 GENERAL.MTU: 1500 GENERAL.状态: 20 (不可用) GENERAL.CONNECTION: -- GENERAL.CON-PATH: --
那如果有连接过其他的无线接入点(如无线路由器、其他wifi等),那有两种方法可以用。
先用 nmcli connection show 查看系统已存在的连接配置。
nmcli connection show
[root@server ~]# nmcli connection show 名称 UUID 类型 设备 wifi-wlp2s0 f921eace-fe96-446e-a70c-7f707c3370af 802-11-wireless wlp2s0 p2p1 54fec36f-6103-4342-aca1-4aabd42ee999 802-3-ethernet p2p1
删除无线网卡对应的连接配置 wifi-wlp2s0,注意这里对应的无线网卡接口为:wlp2s0。
nmcli connection delete wifi-wlp2s0
通过修改配置文件使 NetworkManager 取消自动接管无线网卡,配置文件通常位于 /etc/NetworkManager/NetworkManager.conf。
vi /etc/NetworkManager/NetworkManager.conf
[root@server ~]# vi /etc/NetworkManager/NetworkManager.conf [main] plugins=ifcfg-rh #这行系统默认就有如果不清楚就不要修改 #添加下面两行指定排除的MAC地址,MAC地址可以有多个 [keyfile] #这里是排除了两个MAC地址的示例。 unmanaged-devices=mac:E0:05:CC:77:DF:B0;mac:80:5B:22:D0:7C:64
修改保存之后重启 NetworkManager.service
systemctl restart NetworkManager.service
重启服务后再次查看接口状态:
nmcli device show
[root@server ~]# nmcli device show ……省略…… GENERAL.设备: wlp2s0 GENERAL.类型: wifi GENERAL.硬盘: 80:5B:22:D0:7C:64 GENERAL.MTU: 1500 GENERAL.状态: 10 (未管理) GENERAL.CONNECTION: -- GENERAL.CON-PATH: --
如果需要开机自动启动 hostapd 服务
systemctl enable hostapd.service
手动启动
systemctl start hostapd.service
重启
systemctl restart hostapd.service
停止
systemctl stop hostapd.service
禁止开机自动启动
systemctl disable hostapd.service
首先要说明的是:默认安装的 hostapd 是没有配置的并且无法启动。
通过上面 rpm -ql hostapd 命令可以看到,hostapd 软件包已经提供了 hostapd.conf 的最全最详细的说明,也就是上面软件包文件列表中的 /usr/share/doc/hostapd-<版本号>/hostapd.conf 这个文件,只不过里面全是英文的。有关 hostapd.conf 的中文说明可以看看《CentOS 7 之 hostapd.conf 配置说明》。
按照我们要求 hostapd 正常启动并工作且满足下面几点:
工作在AP模式
连接时要求输入密码
工作在AP模式就需要有线网卡和无线网卡进行桥接,这就要求我们首先要建立一个桥接接口。
首先使用 ip link 命令就可以看到哪些本机已经识别是网卡名称:
ip link
[root@server ~]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: p2p1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 00:14:78:66:2e:a7 brd ff:ff:ff:ff:ff:ff 3: wlp2s0: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000 link/ether 90:94:e4:78:49:b5 brd ff:ff:ff:ff:ff:ff
使用 nmcli 建立一个桥接接口 br0 并设置开机自动连接,“br0”可以自由设定,只要保证上下配置一致就可以。为了方便通用,一般桥接接口都是用这种方式命名。
nmcli connection add type bridge autoconnect yes save yes ifname br0
将有线接口 p2p1 加入到桥接接口 br0 中,CentOS 7 中的网络接口默认不再像以前 eth0 eth1 等这种方式命名,而是会加上总线顺序等来进行命名,我这里是的PCI 千兆网卡为 p2p1 有些主板上会类似 enp2s0 这种。
nmcli connection add type bridge-slave autoconnect yes save yes ifname p2p1 master br0
查看接口
[root@server ~]# nmcli connection show NAME UUID TYPE DEVICE bridge-br0 bc7e63a4-7fee-4419-8f09-e316a78f42e7 bridge br0 bridge-slave-p2p1 59fc1f91-4e60-4388-ad41-1a4937c8ff25 802-3-ethernet p2p1
坑提示:实际上到这一步就可以了,这里我们只建立了一个只有一个有线接口的桥,并没有包含无线接口。而事实上 nmcli 命令也并不支持将将无线接口加入网桥接口 br0 无线接口加入网桥就只能通过 hostapd.conf 来进行。
虽然将无线网卡接口加入网桥的命令可以正常执行。
nmcli connection add type bridge-slave autoconnect yes save yes ifname wlp2s0 master br0
但显示网络连接时注意 DEVICE 字段,新添加的无线网卡的桥接的 DEVICE 字段为“--”空。
nmcli connection show
[root@server ~]# nmcli connection show NAME UUID TYPE DEVICE bridge-br0 bc7e63a4-7fee-4419-8f09-e316a78f42e7 bridge br0 bridge-slave-p2p1 59fc1f91-4e60-4388-ad41-1a4937c8ff25 802-3-ethernet p2p1 bridge-slave-wlp2s0 18880002-44c1-4a84-968a-66670c00322f 802-3-ethernet --
当激活连接时会提示未找到设备。
nmcli connection up bridge-slave-wlp2s0
[root@server ~]# nmcli connection up bridge-slave-wlp2s0 Error: no device found for connection 'bridge-slave-wlp2s0'.
好吧……删掉没有用的无线桥接连接。
nmcli connection delete bridge-slave-wlp2s0
下面继续:
之前有提到过有关 hostapd.conf 的中文说明可以看看《CentOS 7 之 hostapd.conf 配置说明》。
这里只是一个最小化的配置:
# /etc/hostapd/hostapd.conf 最小化配置 interface=wlp2s0 bridge=br0 #无线网卡桥接到 br0 就是通过这个参数来完成 driver=nl80211 ssid=test hw_mode=g channel=1 auth_algs=3 ignore_broadcast_ssid=0 # 是否广播,0 广播 wpa=3 wpa_passphrase=12345678 # 无线连接密码
坑提示:我在上面的提示中提到过,之前我们只建立了一个只有一个有线接口的桥。请注意上面 bridge=br0 选项,这个非常重要,如果要运行AP模式就一定要指定要桥接的网桥接口。bridge=br0 选项说明将无线网卡接口 wlp2s0 加入到网桥 br0 ,无线网卡接口由第一行 interface=wlp2s0 选项指定。这样 br0 才是一个包含有线接口 p2p1 和一个无线接口 wlp2s0 的网桥。
虽然还有其他方式建立网桥的命令,但是如果是在 CentOS 7 下面,最简单的还是使用 nmcli 命令,因为 CentOS 7 默认提供 NeteorkManager 这个软件,使用 nmcli 命令配置好连接后一直有效。但 nmcli 也并不是万能的,前面有提到过,我目前遇到了两个问题:1. nmcli 不支持将无线网卡加入到网桥;2. 到目前为止 nmcli 不支持设置无线网卡静态IP地址(这个在 hostapd 配置路由模式会遇到)。
关于 CentOS 7 桥接网络配置可以看看《<<<<<<这篇文章>>>>>>>》。
到此我们已经配置了网桥,网桥将自动从路由器获取IP地址、网关及DNS等设置,也就是本机将自动就能上网。hostapd 也配置好了,SSID为test,密码12345678。因为是桥接接口,所以当无线客户端连接成功后也将自动从路由器那获取IP地址、网关及DNS等设置。
现在是时候启动 hostapd 服务了。
systemctl start hostapd.service
而结果确实启动失败,查看服务状态:
systemctl status hostapd.service
[root@server ~]# systemctl status hostapd ● hostapd.service - Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator Loaded: loaded (/etc/systemd/system/hostapd.service; enabled) Active: failed (Result: exit-code) since 一 2015-09-21 20:19:49 CST; 3s ago Process: 6897 ExecStart=/usr/sbin/hostapd /etc/hostapd/hostapd.conf -P /run/hostapd.pid $OTHER_ARGS (code=exited, status=1/FAILURE) Main PID: 6897 (code=exited, status=1/FAILURE) 9月 21 20:19:49 server hostapd[6897]: wlp2s0: interface state HT_SCAN->DISABLED 9月 21 20:19:49 server hostapd[6897]: wlp2s0: AP-DISABLED 9月 21 20:19:49 server hostapd[6897]: wlp2s0: Unable to setup interface. 9月 21 20:19:49 server hostapd[6897]: wlp2s0: interface state DISABLED->DISABLED 9月 21 20:19:49 server hostapd[6897]: wlp2s0: AP-DISABLED 9月 21 20:19:49 server hostapd[6897]: hostapd_free_hapd_data: Interface wlp2s0 wasn't started 9月 21 20:19:49 server hostapd[6897]: nl80211: deinit ifname=wlp2s0 disabled_11b_rates=0 9月 21 20:19:49 server systemd[1]: hostapd.service: main process exited, code=exited, status=1/FAILURE 9月 21 20:19:49 server systemd[1]: Unit hostapd.service entered failed state. 9月 21 20:19:49 server systemd[1]: hostapd.service failed.
上面实际上看不出任何问题的具体细节。
先看看 man hostapd 的手册了解一下如何进行调试。
man hostapd
[root@server ~]# man hostapd ……省略…… hostapd [-hdBKtv] [-P <PID file>] <configuration file(s)> -h Show usage. -d Show more debug messages. #调试选项 -dd Show even more debug messages. #调试选项详细输出 -B Run daemon in the background. -P <PID file> Path to PID file. -K Include key data in debug messages. -t Include timestamps in some debug messages. -v Show hostapd version. ……省略……
看样子很简单大致就是上面的内容。那接下来以调试模式运行。
/usr/sbin/hostapd /etc/hostapd/hostapd.conf -d
[root@server ~]# /usr/sbin/hostapd /etc/hostapd/hostapd.conf -d ……省略…… Could not set interface wlp2s0 flags (UP): Operation not possible due to RF-kill nl80211: Failed to set interface up after switching mode ……省略……
坑提示:“Operation not possible due to RF-kill”,那么 RF-kill 又是什么呢?关于 RF-kill 可以看看这篇《rfkill 无线设备软开关》。
好吧,先安装 rfkill 软件包。
yum install rfkill
看看无线网卡是否被关掉了
rfkill list
[root@server ~]# rfkill list 0: phy0: Wireless LAN Soft blocked: yes Hard blocked: no
解锁
rfkill unblock wlan
[root@server ~]# rfkill unblock wlan
再次运行调试模式
/usr/sbin/hostapd /etc/hostapd/hostapd.conf -d
OK一切正常,那么就可以结束调试以正常模式启动服务了
systemctl start hostapd.service
搞定。
在 hostapd AP模式的配置中实际可能会遇到以及需要解决的问题就是网桥的配置,而且有点奇葩。