在企业网络安全管理中,802.1x认证就像是大楼的门禁系统。而FreeRADIUS作为开源界的"老牌门卫",配合EAP-TLS这种高安全级别的"身份证识别技术",能有效防止"陌生人混入"。我去年给一家200人规模的公司部署这套系统时,发现相比传统的PEAP/MSCHAPv2认证方式,证书认证的稳定性提升了60%以上,再没出现过半夜被认证问题叫起来救火的情况。
EAP-TLS的核心优势在于双向证书验证——不仅客户端要验证服务器身份,服务器也会严格检查客户端证书。这就好比不仅访客要刷卡,门卫也会主动出示工作证。这种机制彻底杜绝了密码泄露风险,特别适合研发部门这类需要高安全级别的场景。实测下来,整套系统在Ubuntu 20.04上运行时的认证响应时间可以控制在200ms以内,完全满足企业级并发需求。
在开始前,建议先给Ubuntu 20.04做个"体检"。我习惯用以下命令检查系统状态:
bash复制# 更新系统并安装基础工具
sudo apt update && sudo apt upgrade -y
sudo apt install -y net-tools htop openssl
内存建议至少4GB,特别是要集成MySQL时。曾经有客户在2GB内存的机器上跑FreeRADIUS,认证高峰期直接OOM崩溃。磁盘空间不能小于20GB,证书文件和日志会占用不少空间。
官方源里的FreeRADIUS 3.0.20版本最稳定,别被新版本诱惑。安装命令看似简单,但有些细节要注意:
bash复制sudo apt install -y freeradius freeradius-mysql mysql-server mysql-client
这里有个坑:Ubuntu 20.04默认安装MariaDB而不是MySQL。如果坚持要用MySQL,需要先添加官方源:
bash复制sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29
echo "deb http://repo.mysql.com/apt/ubuntu focal mysql-8.0" | sudo tee /etc/apt/sources.list.d/mysql.list
安装完成后,立即检查服务状态:
bash复制sudo systemctl status freeradius
如果发现异常,大概率是权限问题。我遇到过因为/var/log/freeradius目录权限不对导致服务起不来的情况,用sudo chown -R freerad:freerad /var/log/freeradius就能解决。
FreeRADIUS自带的certs/目录下有Makefile模板,但直接使用会有安全隐患。建议修改以下参数:
makefile复制CA_DEFAULT_DAYS=3650 # 改为730
KEY_SIZE=2048 # 建议改为4096
生成证书时有个实用技巧:先备份原始Makefile,然后执行:
bash复制cd /etc/freeradius/3.0/certs
sudo make destroycerts # 清理旧证书
sudo make
这里容易踩的坑是证书有效期设置。有次我给客户设置的CA有效期只有1年,结果第二年全员无法认证。正确的做法是:CA证书10年,服务器证书2年,客户端证书1年,并建立定期轮换机制。
在server.cnf中必须设置subjectAltName,否则现代浏览器会报错:
ini复制[ v3_req ]
subjectAltName = DNS:radius.yourcompany.com
生成服务器证书后,记得验证其内容:
bash复制openssl x509 -in server.pem -text -noout | grep -A1 "Subject Alternative Name"
客户端证书建议批量生成时使用脚本自动化。这里分享我的证书签发脚本片段:
bash复制#!/bin/bash
for user in $(cat userlist.txt); do
openssl req -new -newkey rsa:4096 -nodes -keyout $user.key -out $user.csr
openssl x509 -req -days 365 -CA ca.pem -CAkey ca.key -CAcreateserial -in $user.csr -out $user.crt
done
/etc/freeradius/3.0/mods-enabled/eap的配置直接影响认证性能。推荐配置:
text复制eap {
default_eap_type = tls
timer_expire = 60
ignore_unknown_eap_types = no
tls {
certdir = ${confdir}/certs
cadir = ${confdir}/certs
private_key_password = whatever
private_key_file = ${certdir}/server.key
certificate_file = ${certdir}/server.pem
dh_file = ${certdir}/dh
random_file = /dev/urandom
cipher_list = "HIGH:!aNULL:!MD5"
verify_mode = 1 # 必须设为1开启客户端证书验证
}
}
特别要注意cipher_list配置。有次客户要求兼容老设备,我改成"ALL"后,安全扫描直接报警告。建议使用Mozilla的现代兼容性配置。
在clients.conf中,每个网络设备应该有自己的secret:
text复制client switch-1 {
ipaddr = 192.168.1.10
secret = 5up3rS3cr3tK3y!
require_message_authenticator = yes
}
调试阶段可以开启详细日志:
text复制client localtesting {
ipaddr = 127.0.0.1
secret = testing123
shortname = local
nastype = other
debug = yes
}
官方提供的schema.sql可能不适合生产环境。我通常会做这些修改:
sql复制ALTER TABLE radcheck MODIFY COLUMN value VARCHAR(255);
ALTER TABLE radreply ADD INDEX (username);
创建存储过程自动清理过期会话:
sql复制DELIMITER //
CREATE PROCEDURE cleanup_sessions()
BEGIN
DELETE FROM radacct WHERE acctstoptime IS NULL AND acctstarttime < DATE_SUB(NOW(), INTERVAL 1 DAY);
END //
DELIMITER ;
在mods-available/sql中调整连接池参数:
text复制sql {
...
pool {
start = 5
min = 5
max = 20
spare = 10
uses = 0
lifetime = 0
idle_timeout = 60
}
}
遇到性能瓶颈时,可以启用查询缓存:
text复制mysql {
...
tls {
# 前面证书配置
}
query_cache = yes
query_cache_size = 100
}
启动调试模式时加上-D参数可以显示更多细节:
bash复制sudo freeradius -X -D /path/to/your/debug/dir
关键日志位置:
证书验证失败:检查客户端证书的CN是否与用户名一致,我遇到过Windows客户端因为证书主题包含特殊字符导致认证失败的情况。
TLS握手超时:可能是MTU问题,尝试:
bash复制sudo sysctl -w net.ipv4.tcp_mtu_probing=1
数据库连接泄漏:在sql配置中添加:
text复制sql {
...
connect_failure_retry_delay = 60
lifetime = 3600
max_queries = 1000
}
推荐使用双机热备方案:
配置示例:
text复制home_server primary {
type = auth
ipaddr = 10.0.0.1
port = 1812
secret = shared_secret
status_check = status-server
}
home_server secondary {
type = auth
ipaddr = 10.0.0.2
port = 1812
secret = shared_secret
status_check = status-server
}
home_server_pool failover {
type = fail-over
home_server = primary
home_server = secondary
}
在radiusd.conf中调整这些参数:
text复制thread {
max_servers = 100
min_spare_servers = 10
max_spare_servers = 20
max_requests_per_server = 0
}
security {
max_attributes = 200
reject_delay = 1
}
对于无线网络密集场景,建议启用:
text复制recv {
recv_window = 128
dynamic_clients = yes
}