hostapd HOWTO
目录
1. About #
hostapd 是一个运行在 Linux 用户空间的 daemon 程序,它可以将 IEEE 802.11 无线网卡切换为 AP 模式,也就是实现软 AP 功能,并提供 IEEE 802.1X/WPA/WPA2/EAP/RADIUS 的认证服务。它使用 nl80211 接口与内核进行通信,支持基于 mac80211 框架的无线驱动。下面是 Linux 的无线网络架构:
- IEEE 802.11 是现在的无线局域网通用的标准,我们通常把它与 Wi-Fi 混为一谈。
- mac80211 是 Linux 内核的 802.11 无线设备驱动框架,intel 的无线网卡驱动 iwlwifi 就是基于这个框架。
- cfg80211 是 Linux 内核中配置和管理 802.11 无线设备的接口,与 FullMAC 驱动, mac80211 驱动一起工作。
- nl80211 和 wext 是两种面向用户空间的接口标准,用于在用户空间配置和管理 802.11 无线设备,内核的 cfg80211 一起工作,目前两种标准同时存在于内核中,nl80211 正在逐步替代 wext ,hostapd 只支持 nl80211 。
iw 就是一个使用 nl80211 接口的命令,用它可以查看和配置无线网卡,支持 nl80211 标准,不支持老的 wext 标准。用 iw list
可以获取当前无线网卡的全部特性,在 Supported interface modes 和 software interface modes 中看到无线网卡是否支持 AP 模式,已经 AP 类型:
root@WR-IntelligentDevice:~# iw list
Wiphy phy0
......
Supported interface modes:
* IBSS
* managed
* AP
* AP/VLAN
* monitor
* P2P-client
* P2P-GO
software interface modes (can always be added):
* AP/VLAN
* monitor
......
用 ethtool 工具可以确定网卡使用的驱动:
root@WR-IntelligentDevice:~# ethtool -i wlan0
driver: iwlwifi
version: 3.4.91-WR5.0.1.24_standard_IDP-
firmware-version: 18.168.6.1
bus-info: 0000:01:00.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
查看连接在 AP 上的终端:
root@WR-IntelligentDevice:~# iw dev wlan0 station dump
Station bc:6c:21:6e:04:c3 (on wlan0)
inactive time: 20 ms
rx bytes: 159304
rx packets: 2076
tx bytes: 4368817
tx packets: 3068
tx retries: 293
tx failed: 2
signal: -41 dBm
signal avg: -40 dBm
tx bitrate: 54.0 MBit/s
authorized: yes
authenticated: yes
preamble: short
WMM/WME: no
MFP: no
TDLS peer: no
2. 配置 #
hostapd 的配置文件是 /etc/hostapd.conf ,这个文件里有详细的配置说明,下面是一些常用选项。
2.1. 无线接口 #
- interface:无线网卡的设备节点名称,就是 iwconfig 看到的名称,例如 wlan0 。
- bridge:指定所处网桥,对于一个同时接入公网、提供内部网和无线接入的路由器来说,设定网桥很有必要 。
- driver:设定无线驱动,我这里是 nl80211 。
2.2. 无线环境 #
- ssid:这个无线接入点对外显示的名称 。
- hw_mode:指定802.11协议,a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g 。这个选项是根据硬件特性设置的,g 是最常用的设置,它向下兼容 b 。
- channel:设定信道,必须是 hw_mode 指定协议能够支持的信道。信道的选择应该避免与同区域内的其他 AP 的信道产生重叠,这与 802.11 标准的信道划分有关,在 802.11b/g 中,83.5MHz 的带宽划分了 14 个信道,相邻的多个信道存在频率重叠,整个频段内只有 1、6、11 ,三个信道互不干扰。
2.3. 认证与加密 #
ignore_broadcast_ssid: 使能/禁止广播 SSID 。
macaddr_acl:可选,指定 MAC 地址过滤规则,0 表示除禁止列表外都允许,1 表示除允许列表外都禁止,2 表示使用外部 RADIUS 服务器。
accept_mac_file:指定 MAC 允许列表文件路径。
deny_mac_file:指定 MAC 禁止列表文件路径。
auth_algs: 指定认证算法,低两位有效,0 表示禁止,1 表示使能。bit0 表示开放系统认证(OSA),bit1 表示共享密钥认证(SKA),如果设为 3 ,表示两种认证方式都支持。
wpa: 指定加密算法,低两位有效,0 表示禁止,1 表示使能。bit0 表示 wpa,bit1 表示 wpa2 ,如果设为 3 ,表示 WPA/WPA2 加密方式。
wpa_passphrase: 共享秘钥,就是我们连接 Wi-Fi 时输入的密码。
wpa_psk:对共享秘钥加密后的 64 位十六进制数。可以通过 wpa_passphrase 命令获得:
root@WR-IntelligentDevice:~# wpa_passphrase usage: wpa_passphrase <ssid> [passphrase] If passphrase is left out, it will be read from stdin root@WR-IntelligentDevice:~# wpa_passphrase TP-Link password network={ ssid="TP-Link" #psk="password" psk=895b209c4c7ff1ea45d079eb5b04155cc1793669c6dc08470157c23fa6532694 }
wpa_key_mgmt: 指定秘钥管理算法,可选 WPA-PSK 和 WPA-EAP 。
wpa_pairwise: WPA 的加密选项,可选 TKIP 和 CCMP 。
rsn_pairwise: WPA2 和 RSN 的加密选项,可选 TKIP 和 CCMP 。
关于认证算法:
开放系统认证(Open system authentication)
开放系统认证是缺省使用的认证机制,也是最简单的认证算法,即不认证。如果认证类型设置为开放系统认证,则所有请求认证的客户端都会通过认证。开放系统认证包括两个步骤:第一步是无线客户端发起认证请求,第二步AP确定无线客户端是否通过无线链路认证并回应认证结果。如果认证结果为“成功”,那么客户端成功通过了AP的链路认证。
共享密钥认证(shared key authentication)
共享密钥认证是除开放系统认证以外的另外一种链路认证机制。共享密钥认证需要客户端和设备端配置相同的共享密钥。共享密钥认证的认证过程为:客户端先向AP发送认证请求,AP端会随机产生一个Challenge(即一个字符串)发送给客户端;客户端会将接收到Challenge加密后再发送给AP;AP接收到该消息后,对该消息解密,然后对解密后的字符串和原始字符串进行比较。如果相同,则说明客户端通过了Shared Key链路认证;否则Shared Key链路认证失败。
3. 运行 #
root@WR-IntelligentDevice:/etc# hostapd -h
hostapd v2.3
User space daemon for IEEE 802.11 AP management,
IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> and contributors
usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] \
[-g <global ctrl_iface>] [-G <group>] \
<configuration file(s)>
options:
-h show this usage
-d show more debug messages (-dd for even more)
-B run daemon in the background
-e entropy file
-g global control interface path
-G group for control interfaces
-P PID file
-K include key data in debug messages
-t include timestamps in some debug messages
-v show hostapd version
分享一个在 Ubuntu 12.04 下设置无线 AP 的脚本 install_wifi_access_point.sh ,内容如下:
#!/bin/bash
### Setup a wifi Access Point on Ubuntu 12.04 (or its derivatives).
### make sure that this script is executed from root
if [ $(whoami) != 'root' ]
then
echo "
This script should be executed as root or with sudo:
sudo $0
"
exit 1
fi
##############################################################
## Check whether the wireless card supports Access Point mode
##############################################################
### make sure that iw is installed
apt-get -y install iw
### check that AP is supported
supports_access_point=$(iw list | sed -n -e '/* AP$/p')
if [ "$supports_access_point" = '' ]
then
echo "AP is not supported by the driver of the wireless card."
echo "This script does not work for this driver."
exit 1
fi
##############################################################
## Setup and host a network
##############################################################
### install hostapd
apt-get -y install hostapd
### it should not start automatically on boot
update-rc.d hostapd disable
### get ssid and password
ssid=$(hostname --short)
read -p "The name of your hosted network (SSID) [$ssid]: " input
ssid=${input:-$ssid}
password='1234567890'
read -p "The password of your hosted network [$password]: " input
password=${input:-$password}
### get wifi interface
rfkill unblock wifi # enable wifi in case it is somehow disabled (thanks to Darrin Wolf for this tip)
wifi_interface=$(lshw -quiet -c network | sed -n -e '/Wireless interface/,+12 p' | sed -n -e '/logical name:/p' | cut -d: -f2 | sed -e 's/ //g')
### create /etc/hostapd/hostapd.conf
cat <<EOF > /etc/hostapd/hostapd.conf
interface=$wifi_interface
driver=nl80211
ssid=$ssid
hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=3
wpa_passphrase=$password
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
EOF
### modify /etc/default/hostapd
cp -n /etc/default/hostapd{,.bak}
sed -i /etc/default/hostapd \
-e '/DAEMON_CONF=/c DAEMON_CONF="/etc/hostapd/hostapd.conf"'
################################################
## Set up DHCP server for IP address management
################################################
### make sure that the DHCP server is installed
apt-get -y install isc-dhcp-server
### it should not start automatically on boot
update-rc.d isc-dhcp-server disable
### set the INTERFACES on /etc/default/isc-dhcp-server
cp -n /etc/default/isc-dhcp-server{,.bak}
sed -i /etc/default/isc-dhcp-server \
-e "/INTERFACES=/c INTERFACES=\"$wifi_interface\""
### modify /etc/dhcp/dhcpd.conf
cp -n /etc/dhcp/dhcpd.conf{,.bak}
sed -i /etc/dhcp/dhcpd.conf \
-e 's/^option domain-name/#option domain-name/' \
-e 's/^option domain-name-servers/#option domain-name-servers/' \
-e 's/^default-lease-time/#default-lease-time/' \
-e 's/^max-lease-time/#max-lease-time/'
sed -i /etc/dhcp/dhcpd.conf \
-e '/subnet 10.10.0.0 netmask 255.255.255.0/,+4 d'
cat <<EOF >> /etc/dhcp/dhcpd.conf
subnet 10.10.0.0 netmask 255.255.255.0 {
range 10.10.0.2 10.10.0.16;
option domain-name-servers 8.8.4.4, 208.67.222.222;
option routers 10.10.0.1;
}
EOF
#################################################
## Create a startup script
#################################################
cat <<EOF > /etc/init.d/wifi_access_point
#!/bin/bash
ext_interface=\$(ip route | grep default | cut -d' ' -f5)
function stop_wifi_ap {
### stop services dhcpd and hostapd
service isc-dhcp-server stop
service hostapd stop
### disable IP forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -D POSTROUTING -s 10.10.0.0/16 -o \$ext_interface -j MASQUERADE 2>/dev/null
### remove the static IP from the wifi interface
if grep -q 'auto $wifi_interface' /etc/network/interfaces
then
sed -i /etc/network/interfaces -e '/auto $wifi_interface/,\$ d'
sed -i /etc/network/interfaces -e '\$ d'
fi
### restart network manager to takeover wifi management
service network-manager restart
}
function start_wifi_ap {
stop_wifi_ap
sleep 3
### see: https://bugs.launchpad.net/ubuntu/+source/wpa/+bug/1289047/comments/8
nmcli nm wifi off
rfkill unblock wlan
### give a static IP to the wifi interface
ip link set dev $wifi_interface up
ip address add 10.10.0.1/24 dev $wifi_interface
### protect the static IP from network-manger restart
echo >> /etc/network/interfaces
echo 'auto $wifi_interface' >> /etc/network/interfaces
echo 'iface $wifi_interface' inet static >> /etc/network/interfaces
echo 'address 10.10.0.1' >> /etc/network/interfaces
echo 'netmask 255.255.255.0' >> /etc/network/interfaces
### enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 10.10.0.0/16 -o \$ext_interface -j MASQUERADE
### start services dhcpd and hostapd
service hostapd start
service isc-dhcp-server start
}
### start/stop wifi access point
case "\$1" in
start) start_wifi_ap ;;
stop) stop_wifi_ap ;;
esac
EOF
chmod +x /etc/init.d/wifi_access_point
### make sure that it is stopped on boot
sed -i /etc/rc.local \
-e '/service wifi_access_point stop/ d'
sed -i /etc/rc.local \
-e '/^exit/ i service wifi_access_point stop'
### display usage message
echo "
======================================
Wifi Access Point installed.
You can start and stop it with:
service wifi_access_point start
service wifi_access_point stop
"