FreeRadius EAP-TLS 配置
简介
相比使用预共享密钥 (WPA2),更安全的方式是使用 EAP-TLS 并为每个设备使用单独的证书。在之前的教程 在 Raspberry Pi 上使用 VPN 的 Linux 路由器 中,我提到过我会用 (Ubiquiti UniFi AP) 来做这件事。我已经用两部运行 CyanogenMod 11 (Android 4.4.4) 的手机测试过了。
安装
安装 FreeRadius
apk add freeradius freeradius-eap
证书
你将需要创建你的证书。最简单的方法是使用 FreeRadius 提供的脚本。这些脚本允许你轻松创建 CA(证书颁发机构)、服务器证书和客户端证书。记住要增加过期时间,如果默认的 60 天不适合你,并在 .cnf 文件中填写其他信息,就像 README 文件中说的那样。
该脚本的 readme 文件在 /etc/raddb/certs/README 中,或者可以在 这里 找到。
证书吊销列表
CRL 不是由脚本创建的,你必须手动创建。
我创建了一个名为 crl.cnf 的文件
[ ca ] default_ca = CA_default [ CA_default ] dir = ./ certs = $dir crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir certificate = $dir/ca.pem serial = $dir/serial crl = $dir/crl.pem private_key = $dir/ca.key RANDFILE = $dir/.rand name_opt = ca_default cert_opt = ca_default default_days = 730 default_crl_days = 730 default_md = sha256 preserve = no policy = policy_match crlDistributionPoints = URI:http://www.example.com/example_ca.crl [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] prompt = no distinguished_name = cacrl default_bits = 2048 input_password = <password1> output_password = <password2> x509_extensions = v3_ca [certificate_authority] countryName = <COUNTRY_CODE> stateOrProvinceName = Radius localityName = <REGION> organizationName = FreeRadius emailAddress = freeradius@localhost commonName = "FreeRadius Certificate Authority" [v3_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = CA:true crlDistributionPoints = URI:http://www.example.com/example_ca.crl
创建吊销列表
openssl ca -gencrl -keyfile ca.key -cert ca.pem -out crl.pem -config crl.cnf
最后,创建一个新文件,它将同时保存 CA 和吊销的证书
cat ca.pem crl.pem > cacrl.pem
创建 Diffie-Hellman nonce 文件
openssl dhparam -check -text -5 -out /etc/raddb/certs/dh 1024
或者你可以使用更大的,例如(如果你不走运,这可能需要一段时间!)。
openssl dhparam -check -text -5 -out /etc/raddb/certs/dh 4096
服务器配置
WPA3 规范 (p12) 对 EAP 做了一些更改。即使你没有使用 WPA3,它仍然会影响你的 EAP RADIUS 认证,特别是对于 Android 11+ 等客户端。更多讨论在 这里。
5.1.2 STA 配置了 EAP 凭据,该凭据明确指定了与接收到的服务器证书消息中的根证书匹配的 CA 根证书,并且如果 EAP 凭据还包含域名(FQDN 或仅后缀),则它与接收到的服务器证书消息中的证书 [2] 的域名(如果存在 SubjectAltName dNSName,否则为 SubjectName CN)匹配。
5.1.3 STA 配置了 EAP 凭据,该凭据包含与接收到的服务器证书消息中的证书 [2] 的域名(如果存在 SubjectAltName dNSName,否则为 SubjectName CN)匹配的域名(FQDN 或仅后缀),并且该证书的根证书存在于 STA 的信任根存储中。如果没有这些更改,你会在 logcat 中看到类似以下的错误
EAP: Status notification: remote certificate verification (param=self signed certificate in certificate chain) SSL: SSL3 alert: write (local SSL3 detected an error):fatal:unknown CA EAP: Status notification: local TLS alert (param=unknown CA)
/etc/raddb/server.cnf
[ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names # This should be a host name of the RADIUS server. # Note that the host name is exchanged in EAP *before* # the user machine has network access. So the host name # here doesn't really have to match anything in DNS. + [alt_names] + DNS.1 = radius.example.com + + # NAIRealm from RFC 7585 + otherName.0 = 1.3.6.1.5.5.7.8.8;FORMAT:UTF8,UTF8:*.example.com
然后,当您添加 WiFi 网络时,您需要在“域”框中输入 “radius.example.com”。它在 wpa_supplicant.conf 或 NetworkManager 配置文件中也称为 “domain_suffix_match”。
/etc/raddb/certs/xpextensions
然后,您需要在进行配置之前更新 xpextensions。
+ [ xpserver_ext] + extendedKeyUsage = 1.3.6.1.5.5.7.3.1 + crlDistributionPoints = URI:http://www.example.com/example_ca.crl + subjectAltName = @alt_names and then at the bottom: + [alt_names] + DNS.1 = radius.example.com + # NAIRealm from RFC 7585 + otherName.0 = 1.3.6.1.5.5.7.8.8;FORMAT:UTF8,UTF8:*.example.com
配置
/etc/raddb/clients.conf
首先,我们要添加一个客户端,这是你的 WiFi AP
client home { ipaddr = 192.168.1.10 proto = * secret = <PASSWORD USED BY YOUR AP TO AUTHENTICATE WITH THIS RADIUS SERVER> shortname = <YOUR_SSID> require_message_authenticator = no nas_type = other limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } }
/etc/raddb/mods-enabled/eap
接下来我们配置 eap。请注意 + 和 - 代表删除和添加的行,不要将它们包含在你的配置中!
你将要进行这些更改
- default_eap_type = md5 + default_eap_type = tls
- private_key_password = whatever + private_key_password = <Password you set output_password in server.cnf> private_key_file = ${certdir}/server.pem
- ca_file = ${cadir}/ca.pem + ca_file = ${cadir}/cacrl.pem
- random_file = /dev/urandom + random_file = /dev/random
- # check_crl = yes + check_crl = yes
将密码列表从 DEFAULT 减少到 HIGH,甚至是一个特定的列表
- cipher_list = "DEFAULT" + cipher_list = "HIGH"
或者更短的列表,如果你决定的话(可能会导致一些设备兼容性问题)
+ cipher_list = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-CAMELLIA128-SHA"
将 ecdh 曲线更改为更强的曲线
- ecdh_curve = "prime256v1" + ecdh_curve = "secp384r1"
你也可以将曲线增加到更高的位数 (521),但这可能会导致兼容性问题。
+ ecdh_curve = "secp521r1"
这些都适用于 Android 4.4.4,但是如果你有更旧的设备,你可能需要将列表设置为 HIGH 或 DEFAULT。
还有一些其他需要更改的地方
- #name = "EAP module" + name = "EAP-TLS"
- #persist_dir = "${logdir}/tlscache" + persist_dir = "${logdir}/tlscache"
/etc/raddb/sites-enabled/default
将监听端口更改为适合你的端口
- ipaddr = * + ipv4addr = 192.168.1.1
禁用 chap
# The chap module will set 'Auth-Type := CHAP' if we are # handling a CHAP request and Auth-Type has not already been set - chap + # chap
禁用 mschap
# the MS-CHAP-Challenge attribute, and add 'Auth-Type := MS-CHAP' # to the request, which will cause the server to then use # the mschap module for authentication. - mschap + # mschap
禁用 pap
# This module should be listed last, so that the other modules # get a chance to set Auth-Type for themselves. - pap + #pap
禁用我们不使用的认证类型
- Auth-Type PAP { - pap - } + #Auth-Type PAP { + # pap + #} - Auth-Type CHAP { - chap - } + #Auth-Type CHAP { + # chap + #} - Auth-Type MS-CHAP { - mschap - } + #Auth-Type MS-CHAP { + # mschap + #}
启用 eap
-# eap + eap
/etc/raddb/sites-available/tls
tls { - private_key_password = whatever + private_key_password = <Password you set input_password in server.cnf> private_key_file = ${certdir}/server.pem
IPtables 规则
接下来,你将需要一些 iptables 规则。
#Accept incoming connections from client FreeRadius iptables -A IN_ETH0 -p tcp -s 192.168.1.10/24 --dport 1812 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -A IN_ETH0 -p udp -s 192.168.1.10/24 --dport 1812 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
我还注意到,对于 Ubiquiti 设备,你需要允许这个才能使 AP 采纳工作
#Ubiquiti UAP Device Discovery Broadcast iptables -A IN_ETH0 -p udp -s 192.168.1.10/24 --dport 10001 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
请注意,这些规则取决于最初在此处创建的链 在 Raspberry Pi 上使用 VPN 的 Linux 路由器#基本 IPtables 防火墙和路由。
配置 AP
你将需要配置你的接入点以与你的新 Radius 服务器通信。
使用 clients.conf 中的 secret 和 shortname 将它们输入到你的接入点管理面板中。
启动 Radius
service radiusd start
添加到默认运行级别。
rc-update add radiusd default
你可以从控制台使用 radiusd -X 调试它,或者检查 /var/log/radius/radius.log,如果这不起作用。
配置设备
在 Android 上,我进入 “设置 > 安全 > 从存储设备安装” 并选择 ca.pem
然后我进行 “设置 > 安全 > 从存储设备安装” 并选择 client.p12”
输入正确的密码后,它应该可以工作。在 Android 上,你可能会看到一个警告,例如 “网络可能受到未知第三方的监控”。你可以通过将 CA 从 /data/misc/keychain/cacerts-added 移动到 /system/etc/security/cacerts 来修复此问题,确保用户和组是 root,并且权限设置为 644,即每个人都可读,只有 root 具有写入文件的权限。将其保存在 /sdcard/ 中,以便在您使用较新的 ROM 重新刷机时可以将其移回。
吊销证书
如果将来你想吊销特定用户的证书,你可以这样做
openssl ca -revoke user@example.com.pem -keyfile ca.key -cert ca.pem -config ca.cnf
<输入来自 ca.cnf 的 output_password>
现在,花点时间打开 index.txt,你应该看到证书索引号旁边有 “R”。如果你需要再次使此证书有效,你将编辑带有 “R” 的行以匹配其他证书的格式。
现在你需要再次创建 crl 列表,就像教程开始时所做的那样
openssl ca -gencrl -keyfile ca.key -cert ca.pem -out crl.pem -config crl.cnf
<输入来自 ca.cnf 的 output_password>
cat ca.pem crl.pem > cacrl.pem
吊销证书后,你需要重启 FreeRadius。
service radiusd restart
你可以使用以下命令验证证书是否被吊销
openssl crl -in /etc/raddb/certs/cacrl.pem -text
如果没有证书被吊销,你会看到
No Revoked Certificates.
如果一个或多个证书被吊销,你会看到
Revoked Certificates: Serial Number: <number of your cert>