搭建一个「最安全」的 Wi-Fi 网络


一、前言

  • 之前我写的一篇文章,简要地介绍了企业级 Wi-Fi 加密的基本原理以及 EAP-PEAP 的设置方法。EAP-PEAP 相比我们日常使用的 WPA(2)-PSK 认证方法,虽然安全性已经有了大幅的提升,但是依然存在密码被暴力破解的可能性

  • 那有没有“最安全”的 Wi-Fi 认证方法呢?有!接下来要说的这种认证方法叫 EAP-TLS ,用户不依靠密码进行身份验证,而是使用数字证书进行身份验证。理论上,只要用户和服务器中的数字证书私钥不泄漏,就不存在流量被窃听以及非法接入的情况,当然谁也别想破解这个 Wi-Fi 了(不考虑认证服务器、无线 AP 的软件有漏洞或设置不正确的情况)。

  • EAP-TLS 虽然非常安全,但是毕竟鱼和熊掌不可兼得,麻烦事还是有的。我认为最大的缺点就是:并不是日常生活中所有的设备都支持 EAP-TLS 认证(大部分国产品牌的电视盒子和智能家电都不支持);其次就是服务器和用户端的部署比较麻烦(服务器需要管理员维护一个 PKI 系统;每个用户设备都要安装数字证书)。结合兼容性以及便利性考虑,我觉得日常生活使用 EAP-PEAP 就已经够了,除非您对安全性有非常高的要求。

  • 下面放一张 EAP-TLS 流程图

  • 这次我们依然使用 hostapd 作为 Radius 认证服务器。

二、软件 & 系统环境

  • 操作系统:CentOS 7.3.1611
  • 开发环境:Development Tools 套件
  • 软件:hostapd 2.6

三、编译 & 安装 hostapd

3.1 下载 hostapd 源码包并解压

wget https://w1.fi/releases/hostapd-2.6.tar.gz && \
tar -xf hostapd-2.6.tar.gz

3.2 修改编译配置文件

cd hostapd-2.6/hostapd/
cat << EOF > .config

以下内容直接粘贴到命令行窗口中按回车即可。

CONFIG_DRIVER_NONE=y 
CONFIG_EAP=y 
CONFIG_EAP_TLS=y 
CONFIG_PKCS12=y 
CONFIG_RADIUS_SERVER=y 
CONFIG_IPV6=y 
EOF

说明
• 本着够用就好的原则,我们只安装必须的模块。

3.3 编译 & 安装

默认安装在 /usr/local/bin

make && make install

⚠️ 注意
• 由于各人系统环境各不相同,编译极有可能出错。请根据提示安装必要的系统库。


四、服务器的配置

4.1 创建配置目录

mkdir /etc/hostapd && \
cd /etc/hostapd

4.2 创建路由器密码文件

格式

(一行对应一个路由器)

<路由器 IP> <路由器密码>

例如

cat << EOF > routers

请按实际情况修改以下内容,然后粘贴到命令行窗口中按回车即可。

192.168.1.1 passwordradius
EOF

4.3 创建 Wi-Fi 客户端用户名密码文件

说明
• 下面只需要开启 EAP-TLS 认证就行了,不需要设置任何用户名以及密码。

cat << EOF > users

以下内容直接粘贴到命令行窗口中按回车即可。

* TLS
EOF

4.4 创建主配置文件

cat << EOF > hostapd.conf

请按实际情况以及注释提示修改以下内容,完成后去除 # 号和后面的注释,然后粘贴到命令行窗口中按回车即可。

driver=none
eap_server=1
eap_user_file=/etc/hostapd/users
server_cert=/etc/hostapd/certs/server_cert.pem
private_key=/etc/hostapd/certs/server_key.pem
ca_cert=/etc/hostapd/certs/ca_cert+crl.pem
check_crl=1
radius_server_clients=/etc/hostapd/routers
radius_server_auth_port=1812 # 服务器端口
EOF

4.5 防火墙放行端口

iptables 为例,端口为默认的 1812

iptables -A INPUT -p udp --dport 1812 -j ACCEPT

然后根据需要自行保存防火墙的配置。

4.6 创建系统服务文件

(仅限使用 systemd 的操作系统)

cat << EOF > /lib/systemd/system/hostapd.service 

以下内容直接粘贴到命令行窗口中按回车即可。

[Unit]
Description=hostapd
After=network.target 

[Service]
Type=forking
ExecStart=/usr/local/bin/hostapd -dd /etc/hostapd/hostapd.conf -B 
KillSignal=SIGTERM
KillMode=mixed

[Install]
WantedBy=multi-user.target
EOF

五、PKI 系统的配置

5.1 创建证书存储目录

mkdir -p /etc/hostapd/certs/users_export && \
cd /etc/hostapd/certs

其中,分发给 Wi-Fi 用户的证书包(.p12 后缀)文件以及 .crt 后缀的 CA 证书文件在 /etc/hostapd/certs/users_export 这个目录中。

5.2 创建证书序号文件以及签发列表

echo 01 > serial && \
touch index.txt 

5.3 创建 OpenSSL 配置文件

cat << EOF > openssl.cnf

以下内容直接粘贴到命令行窗口中按回车即可。

[ ca ]
default_ca = hostapd                

[ hostapd ]
dir = .
database = \$dir/index.txt
new_certs_dir = \$dir
certificate = \$dir/ca_cert.pem
serial = \$dir/serial
private_key = \$dir/ca_key.pem 
RANDFILE = \$dir/.rand

default_bits = 4096
default_days = 36500                    
default_crl_days = 36500                    
default_md = sha512                    
unique_subject = no                     

policy = policy_anything            

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
EOF

5.4 创建 CA 证书

openssl req -x509 -nodes -days 36500 -newkey rsa:4096 -keyout ca_key.pem -out ca_cert.pem -new -sha512 -subj "/O=EAP-TLS/CN=Certificate Authority/" && \
openssl x509 -outform der -in ca_cert.pem -out ./users_export/CA.crt

说明
• 理论上 EAP-TLS 并不需要客户端信任 CA 的身份。为了照顾下有信任 CA 身份需求的系统,这里还是生成下 .crt 后缀的 CA 证书。

5.5 签发服务器证书

openssl req -nodes -new -days 36500 -newkey rsa:4096 -keyout server_key.pem -out server_csr.pem -subj "/O=EAP-TLS/CN=Radius Server/" && \
openssl ca -in server_csr.pem -out server_cert.pem -config openssl.cnf && rm -rf server_csr.pem

然后按 y 回车两次即可确认签发。

5.6 签发用户证书

格式

以后如果想签发用户证书的话直接按照这个格式输入命令就可以了。

cd /etc/hostapd/certs && \
openssl req -nodes -new -days 36500 -newkey rsa:4096 -keyout user_<用户名>_key.pem -out user_<用户名>_csr.pem -subj "/O=EAP-TLS/CN=<用户名>/" && \
openssl ca -in user_<用户名>_csr.pem -out user_<用户名>_cert.pem -config openssl.cnf && \
rm -rf user_<用户名>_csr.pem && \
openssl pkcs12 -export -out ./users_export/<用户名>.p12 -inkey user_<用户名>_key.pem -in user_<用户名>_cert.pem -certfile ca_cert.pem

例如

用户名为 user1

cd /etc/hostapd/certs && \
openssl req -nodes -new -days 36500 -newkey rsa:4096 -keyout user_user1_key.pem -out user_user1_csr.pem -subj "/O=EAP-TLS/CN=user1/" && \
openssl ca -in user_user1_csr.pem -out user_user1_cert.pem -config openssl.cnf && \
rm -rf user_user1_csr.pem && \
openssl pkcs12 -export -out ./users_export/user1.p12 -inkey user_user1_key.pem -in user_user1_cert.pem -certfile ca_cert.pem

y 回车两次即可确认签发,然后设定一下证书包的导出密码即可。

5.7 证书字段的定义

上面三个步骤中 -subj 后面的参数即为证书的字段,可按以下说明自定义。

字段名 说明
O 组织名。所有证书必须保持一致
CN 公用名称。不能出现重复。用户证书中此字段作为用户名

5.8 创建证书吊销列表

openssl ca -gencrl -keyfile ca_key.pem -cert ca_cert.pem -out crl.pem -config openssl.cnf && \
cat ca_cert.pem crl.pem > ca_cert+crl.pem

5.9 吊销证书(可选)

如果有用户泄漏了证书的私钥,或者不再使用该网络,可以通过以下命令来吊销证书以防止非法接入(直接删除服务器上的证书是没有任何作用的)。如果该网络只有一人使用或者只使用一张证书的话,也可以将整个 PKI 系统删掉然后重建。

格式

以后如果想吊销证书的话直接按照这个格式输入命令就可以了。

cd /etc/hostapd/certs && \
openssl ca -revoke user_<用户名>_cert.pem -config openssl.cnf && \
openssl ca -gencrl -keyfile ca_key.pem -cert ca_cert.pem -out crl.pem -config openssl.cnf && \
cat ca_cert.pem crl.pem > ca_cert+crl.pem

例如

创建一个用户名为 fake_user1 的证书。

cd /etc/hostapd/certs && \
openssl req -nodes -new -days 36500 -newkey rsa:4096 -keyout user_fake_user1_key.pem -out user_fake_user1_csr.pem -subj "/O=EAP-TLS/CN=fake_user1/" && \
openssl ca -in user_fake_user1_csr.pem -out user_fake_user1_cert.pem -config openssl.cnf && \
rm -rf user_fake_user1_csr.pem && \
openssl pkcs12 -export -out ./users_export/fake_user1.p12 -inkey user_fake_user1_key.pem -in user_fake_user1_cert.pem -certfile ca_cert.pem

y 回车两次即可确认签发,然后设定一下证书包的导出密码即可。

接着吊销该证书。

openssl ca -revoke user_fake_user1_cert.pem -config openssl.cnf && \
openssl ca -gencrl -keyfile ca_key.pem -cert ca_cert.pem -out crl.pem -config openssl.cnf && \
cat ca_cert.pem crl.pem > ca_cert+crl.pem

注意
• 吊销证书之后需要重启 hostapd 才可生效。


六、程序的运行

(仅限使用 systemd 的操作系统)

启动服务,请执行:

systemctl start hostapd.service 

如需重启服务,请执行:

systemctl restart hostapd.service

如需开机启动,请执行:

systemctl enable hostapd.service 

如需获取调试信息,请执行:

killall hostapd ; /usr/local/bin/hostapd -dd /etc/hostapd/hostapd.conf

七、路由器的配置

下面以 TP-Link TL-WR340G 为例。不同路由器有不同的设置方法,普通家用路由器也不一定可以支持。

保存,然后等待重启即可。


八、用户设备的配置

EAP-TLS 需要手动把证书导入到设备中,比 EAP-PEAP 稍微复杂点。以下以 iOS 、 macOS 和 Android 设备为例,其他设备的配置方法如果搞不懂请使用搜索引擎搜索 “连接 EAP-TLS Wi-Fi”

8.1 iOS 设备的配置

首先,从服务器提取 /etc/hostapd/certs/users_export 这个目录中特定用户的证书包( .p12 后缀)文件到您的电脑上,然后用 AirDrop 或者邮件发送到 iPhone 上,然后根据提示输入 iOS 设备的密码以及上面步骤 5.6 中设定的导出密码来安装证书。

找到要连接的 Wi-Fi 名称,点进去,然后点击模式选项,然后选择 EAP-TLS用户名填写上面步骤 5.6 中证书 CN 字段中的值,身份点进去选择刚才导入的证书,再点击加入,最后信任服务器的证书即可连接。

8.2 macOS 设备的配置

首先,从服务器提取 /etc/hostapd/certs/users_export 这个目录中特定用户的证书包( .p12 后缀)文件到您的电脑上,然后双击打开,输入上面步骤 5.6 中设定的导出密码来安装证书。

找到要连接的 Wi-Fi 名称,点进去,然后点击模式选项,然后选择 EAP-TLS用户名填写上面步骤 5.6 中证书 CN 字段中的值,身份点进去选择刚才导入的证书,再点击加入,最后信任服务器的证书即可连接。

8.3 Android 设备的配置

(以 Android 7.1.2 原生界面的系统为例)

首先,从服务器提取 /etc/hostapd/certs/users_export 这个目录中特定用户的证书包( .p12 后缀)文件到您的电脑上,然后放到 Android 设备上。

然后,在 Wi-Fi 设置界面右上角的菜单中选择高级,然后点击安装证书

选择完证书之后,输入上面步骤 5.6 中设定的导出密码,然后随便输入一个证书名称凭据用途选择 WLAN,点击确定即可完成安装。

再返回到 Wi-Fi 设置界面,找到要连接的 Wi-Fi 名称,点进去。EAP方法选择 TLSCA证书选择不验证,用户证书选择刚才导入的证书,身份填写上面步骤 5.6 中证书 CN 字段中的值,最后点击连接即可连接。


九、注意事项

  1. 一定要保证服务器的安全。一旦 CA 的私钥泄漏,所有证书都必须重新签发!
  2. 用户设备的时间都要设置在证书生效的时间点(执行生成自签名证书命令那个时间点)之后,也就是说要确保服务器和用户设备的时间都是正确的,否则可能会导致无法验证证书而无法连接。一般来说都不要担心这个问题,但是我的 Apple TV 居然遇到了这个问题!结果自己瞎折腾了半天才想到的!所以请大家注意下。
  3. 如果有 macOS 设备,请避免多个 BSSID 共用一个 ESSID 。例如双频路由器两个频段的 SSID 不要设置一样。否则,可能会出现短时间内频繁断网的情况(如下图)。通过抓包发现原来系统刚在这个基站认证完就马上跑到另外一个同名基站去认证了,另一个没连接当然无法通过认证。 Google 了一下发现也有类似问题…… ??

  4. 没有最安全,只有更安全


十、参考文献

  1. 802.1x 概述和 EAP 类型
  2. WLAN 认证和加密技术白皮书
  3. RFC 5216

《搭建一个「最安全」的 Wi-Fi 网络》上有2条评论

发表评论