Ubuntu FreeRADIUS 802.1X EAP-TLS 双向认证排错
简介:面向网络运维、无线安全测试及物联网设备调试人员的一份802.1X认证实操文档,围绕在Ubuntu服务器上使用Freeradius搭建EAP-TLS双向认证测试环境展开,可用于验证路由器、终端等设备的WPA企业级认证兼容性。资源包共1个文件,为docx格式文档,压缩包约472KB,篇幅精炼、便于随查随用。文档从环境准备讲起,依次记录Freeradius与openssl的安装、users与client.conf的配置要点、certs目录下根证书与服务端证书的生成流程、eap模块中私钥密码与证书路径的修改方法,并补充了启动时报证书权限错误、1812端口被占用等问题的处理思路,最后给出client.p12证书导入终端并完成EAP-TLS连接的验证步骤。目前已有2926人学习,适合希望快速跑通双向认证链路、减少证书配置试错的读者参考。
1. 一次典型的 802.1X 联调:为什么 Ubuntu 上的 FreeRADIUS EAP-TLS 环境总卡在最后一步
Ubuntu 上用 FreeRADIUS 搭一套 802.1X 的 EAP-TLS 双向认证测试环境,整套动作其实只有四步:装包、写两个配置文件、事先生成一批证书、改 eap 模块。可真到现场,最常出现的画面是这样的:AP 的管理页面里 RADIUS 地址、1812 端口、共享密钥都填了,终端那边选 EAP-TLS,装好 client.p12,点连接,转两圈显示“已保存”,然后就没有然后了。
回到服务器执行freeradius -X,要么屏幕上全是红字,要么日志里连一条 Access-Request 都没有。这套认证组合用在企业无线准入预演、设备出厂前的 EAP 兼容性回归、IoT 终端接入 WPA2-Enterprise 之前的连通性验证上,几乎每次都会遇到。麻烦的地方在于四个变量:证书、密钥、端口、文件权限,混在一份日志里,改一个试一次,一上午就没了。下面按我实际执行的顺序写。
2. 环境准备:Ubuntu 版本、桥接网络与 FreeRADIUS 3.0 的目录约定
在真正敲命令之前,有三件事必须先确认下来,否则后面每一步都是盲改:虚拟机的网络能不能让 AP 看见、apt 装到的到底是哪个大版本的 FreeRADIUS、配置目录长什么样。这三件事最耗时的地方在于,任何一件没对齐,症状看起来都像“证书配错了”。
2.1 桥接模式:虚拟机和 AP 必须互相能看见
如果 FreeRADIUS 装在 VMware 或 VirtualBox 里,网络连接方式要改成桥接。NAT 模式下虚拟机拿到的是宿主机内部地址,AP 根本路由不过去,表现就是“终端一直转圈、服务器一条日志没有”。桥接之后虚拟机相当于直接挂在 AP 所在的二层网络上,拿到了同网段的地址,后面 clients.conf 里填 AP 的 IP 才有意义。
改完先看地址和路由:
ip -4 addr show # 看虚拟机拿到的是不是 192.168.1.x 段 ip route # 确认默认网关就是 AP 的管理地址 ping -c 3 192.168.1.1 # 从服务器 ping AP,通不通决定后面有没有戏第一行确认网卡地址落在 AP 的 DHCP 池里;第二行确认网关;第三行最直接——服务器 ping 不通 AP 的话,后面所有配置都白做。反方向也要测一次,有些 AP 的管理页面带“RADIUS 服务器连通性测试”按钮,点一下能省很多猜的时间。
常见做法是给这台服务器配静态地址,别用 DHCP。测试环境经常要关机、换网卡、重启服务,地址一变 clients.conf 里的 ipaddr 就失效,日志里会直接报 unknown client,很容易被误判成密钥填错。
2.2 版本对齐:apt 仓库里的 freeradius 到底是 3.0 还是 3.2
输入的这套资料是围绕 3.0 写的,配置路径/etc/freeradius/3.0/、证书目录、eap 模块的tls-config tls-common块,都基于 3.0 的结构。问题在于不同 Ubuntu 发行版仓库里的 freeradius 版本不一样,20.04 和 22.04 一般是 3.0.x 系列,更新的发行版仓库里会升到 3.2 系列。3.2 的包仍然把配置放在/etc/freeradius/3.0目录下,路径能对上,但 eap 模块的配置结构、部分默认值都发生了变化。
装之前先看一眼:
apt policy freeradius # 看候选版本号,确认是 3.0.x 还是 3.2.x ls /etc/freeradius/ # 确认配置目录名,只有 3.0 一个就对了apt policy输出里的 Candidate 那一行就是即将安装的版本。如果显示 3.2 系列,别硬套 3.0 的写法,先打开包自带的示例文件mods-available/eap,里面有大段注释说明当前版本的写法,照着改比抄旧文档稳。
提示:同一个测试环境里,服务器版本、客户端设备批次、AP 固件版本最好是固定的。任何一个变了,出问题时就很难分清是配置错还是兼容性差异。
2.3 装之前的四条检查命令
我自己养成习惯,装包之前先执行四条检查,把基线状态摸清楚,出问题时有对照:
id freerad # 确认 freerad 用户是否存在(包安装后才会创建) ss -lunp | grep -E '1812|1813' # 看 1812/1813 有没有被别的进程占着 apt list --installed 2>/dev/null | grep -E 'freeradius|openssl' # 看有没有残留安装 systemctl status freeradius 2>&1 | head -5 # 看服务是不是已经在跑第一条用来判断包是否已经装过;第二条最关键,1812 和 1813 是 RADIUS 的认证和计费端口,如果是重装环境,旧进程可能还占着端口,后面freeradius -X会直接因端口冲突启动失败,而错误信息看起来跟证书无关,很容易误判;第三条防止重复安装;第四条确认 systemd 服务没有在后台运行——这点在后面排查章节还会单独说。
3. 安装与基础配置:users、clients.conf 和 AP 侧的共享密钥对齐
装包本身只有三条命令,真正需要花时间的是两个配置文件:users 和 clients.conf。前者决定账号能不能过认证,后者决定客户端设备发出的请求会不会被服务器接收。两份文件改完都要重启服务才生效,而重启后最容易犯的错是只看终端提示、不看服务器日志。
3.1 三条命令装完 freeradius 与 openssl
先切到 root,然后升级软件包索引并安装:
sudo su # 切到 root,后面全在 root 下操作 apt update # 刷新软件包索引,不做这一步可能装到旧版本 apt-get install freeradius openssl vim # freeradius 服务本体 + openssl 工具 + 编辑器apt update不能省。索引没刷新时,apt 可能拿不到仓库里的最新版本,装完发现路径、配置结构和文档对不上。openssl 是必须的,因为后面 certs 目录里的 Makefile 全部靠 openssl 命令行生成证书和 DH 参数,缺了它make会直接报错。vim 在最小化安装的 Ubuntu 里经常没有,先装上,这是输入资料里明确提到的注意点。
装完验证一下版本,顺便确认服务名:
freeradius -v # 输出 FreeRADIUS Version 3.0.x systemctl status freeradius # Ubuntu 下服务名就是 freeradiusfreeradius -v打印的就是实际版本号,跟前面apt policy对照一下。装完默认会拉起 systemd 服务,先别急着让它跑着,后面调试要用-X前台模式,两者抢同一个端口。
3.2 users 文件:那条 Cleartext-Password 究竟影响什么
进入配置目录编辑 users:
cd /etc/freeradius/3.0/ vim users在文件末尾追加一行:
Testing Cleartext-Password := "password"这里的 Testing 是身份名称,password 是密码。EAP-TLS 的认证主体靠证书,严格来说这条账号在纯 TLS 流程里不是决定性的——证书链对上了就放行。那为什么还要写?两个用途:一是验证基础链路,用radtest打一发 PAP 请求,能立刻确认 clients.conf 的密钥和 users 文件都生效了,把“服务能不能认人”和“证书对不对”两个问题拆开;二是后面如果切换成 PEAP/MSCHAPv2 做对比测试,这条账号就是真正起作用的凭据,留着省事。
改完可以立刻自测一把,不用等 AP:
systemctl restart freeradius radtest Testing password 127.0.0.1 0 testing123radtest的五个参数依次是用户名、密码、RADIUS 服务器地址、NAS 端口号、共享密钥。最后那个 testing123 必须和 clients.conf 里 localhost 那段保持一致。返回Received Access-Accept说明服务、users、密钥三者都对;返回 Access-Reject 基本是 users 内容写错或被另一个文件覆盖;完全无响应就是服务没起来或端口没监听。
提示:如果改完 users 不生效,别急着怀疑语法。3.0 里 files 模块实际读取的可能是
mods-config/files/authorize,而不是/etc/freeradius/3.0/users,排查章节会展开。
3.3 clients.conf:把 AP 的地址和共享密钥写进去
客户端设备本身不直接跟 RADIUS 说话,中间那一跳是 AP。所以要在 clients.conf 里登记的是 AP 的地址:
vim /etc/freeradius/3.0/clients.conf在末尾加一段:
client client1 { ipaddr = 192.168.1.1 secret = testing123 require_message_authenticator = no }client1是这台 AP 的别名,取什么名字无所谓,日志里会带出来,建议按位置或型号命名,多台设备时才不混乱。ipaddr是 AP 的管理地址,注意这不是终端的地址——这是最常见的填错点。secret是共享对称密钥,可以改,但必须和 AP 页面上填的完全一致,大小写、空格、尾部换行都算。require_message_authenticator = no是给老设备留的余地:新版本 FreeRADIUS 默认要求报文里带 Message-Authenticator 属性,而一些旧固件的 AP 不发这个属性,结果是请求被静默丢弃,日志里连个明确的报错都没有。
改完同样重启并观察日志:
systemctl restart freeradius tail -f /var/log/freeradius/radius.log日志里出现 AP 的 IP 和 Access-Request 记录,说明 clients.conf 生效了。如果一直是Ignoring request from unknown client,就是 ipaddr 写错或网段不对。
3.4 AP 侧配置:WPA-Enterprise 与 RADIUS 三个参数对齐
服务器这边配好,接下来是 AP。用网线连上 AP,浏览器打开管理地址(这套环境里是 192.168.1.1),进无线设置,把安全模式改成 WPA/WPA2-Enterprise,也就是 802.1X 模式,然后填三项:RADIUS 服务器地址填 FreeRADIUS 那台机器的 IP,认证端口填 1812,共享密钥填 testing123。
三项里最容易出错的是地址。很多 AP 的 RADIUS 服务器地址字段只接受 IP,不认主机名;如果服务器地址是 DHCP 拿的,重启后变了,AP 就会一直超时。计费端口 1813 在纯认证测试里可以先不填,填了但服务器没配 accounting 也不影响认证,只是日志里会多几行写不进去的告警。
保存之后 AP 一般会自动重启无线模块,终端侧会看到这个 SSID 变成了需要用户名密码或证书的形式。这一步做完再回去看服务器日志,如果 AP 保存时做了连通性测试,应该能看到一条 Access-Request。
4. 证书与 EAP 模块:certs 目录 make 出来的五个文件怎么用
EAP-TLS 叫双向认证,意思是服务器用证书证明自己,客户端也用证书证明自己,双方都要验对方的链。所以证书不是“配一下”,而是这套环境的核心。FreeRADIUS 自带的 certs 目录里有一个 Makefile,一条make就能把整套测试证书生成出来,省掉手写 openssl 配置的麻烦。
4.1 make 一次生成什么:五个产物逐个对应
cd /etc/freeradius/3.0/certs make这条命令跑完会生成一系列文件,其中五个是必须认识的:
| 文件 | 作用 | 用在哪 |
|---|---|---|
| ca.pem | 自签发的根证书 | 服务器验证客户端证书、客户端验证服务器证书 |
| server.pem | 服务器证书 | eap 模块的 certificate_file |
| server.key | 服务器私钥,保护密码默认 whatever | eap 模块的 private_key_file |
| client.p12 | PKCS#12 格式的个人证书,含证书、私钥,密码 whatever | 导入到终端设备 |
| dh | Diffie-Hellman 参数文件 | eap 模块的 dh_file |
make不是秒回的。生成 dh 参数时 openssl 要算大素数,2048 位在虚拟机上跑几分钟很正常,屏幕卡着不动不代表挂了。我第一次等的时候以为死机,Ctrl+C 中断了三次,结果每次都只生成了一半文件,后面freeradius -X报 dh 文件不存在——这个坑很典型,耐心等它跑完,看到提示符回来再动。
另外提醒一点:make会覆盖已有证书。测试环境里如果已经给某台设备导过 client.p12,重新 make 之后旧证书就废了,设备得重新导入。我一般会在 make 之前把整个 certs 目录打包备份一份,需要回滚时直接换回去,比重新配一遍快。
4.2 eap 模块:tls-config 块里的五个参数逐个改
证书生成完,接下来让 eap 模块知道去哪找它们:
cd /etc/freeradius/3.0/mods-enabled/ vim eap找到tls-config tls-common块,把下面五个参数对齐:
eap { default_eap_type = tls # 默认认证方式改成 tls tls-config tls-common { private_key_password = whatever # 与 server.key 的保护密码一致 private_key_file = ${certdir}/server.key # 服务器私钥 certificate_file = ${certdir}/server.pem # 服务器证书 ca_file = ${cadir}/ca.pem # 根证书,用于验客户端 dh_file = ${certdir}/dh # DH 参数 } }default_eap_type从默认的 md5 改成 tls,这一步决定服务器收到 EAP 请求时走哪条分支,不改的话终端发起 TLS 协商会被拒。private_key_password必须和生成 server.key 时用的密码一致,Makefile 里默认就是 whatever,改了证书密码却忘了改这里,启动时会报私钥解密失败。${certdir}和${cadir}是 radiusd.conf 里定义的变量,两个都指向/etc/freeradius/3.0/certs,所以证书文件必须留在原目录;想把证书挪到别处,就得同时改这两个变量的值,只改 eap 里的路径不管用。
mods-enabled/eap是一个指向mods-available/eap的软链接。有些环境下 vim 存盘时会把软链接替换成普通文件,之后mods-available里那份就不再被读取,改配置的时候会觉得“明明改了却没生效”。改之前执行ls -l eap看一眼箭头指向,改完再确认一次,两秒钟的事。
改完重启:
systemctl restart freeradius freeradius -X-X是前台调试模式,会把整条认证链路的每一步都打出来,包括 TLS 握手过程。看到Ready to process requests就说明配置语法和证书都过关了。
4.3 client.p12 导出与终端安装
证书留在服务器上没用,客户端那份要导出去。用 scp 拷到本机,再传到设备上:
scp /etc/freeradius/3.0/certs/client.p12 user@192.168.1.100:/tmp/拷出来之后先在本机验证一下文件本身没坏、密码对不对:
openssl pkcs12 -in client.p12 -noout -info系统会提示输入密码,输 whatever。能正常打印出证书信息,说明这个 p12 是完整的,问题就只可能在设备端的安装方式上;如果这一步就报错,别折腾设备了,回服务器重新 make。
设备端安装时,把 client.p12 导入为“个人证书”或“客户端证书”,加密方式选 EAP-TLS。输入资料里写“CA 证书不用选择”,在部分设备上确实可以不选直接连;但一些较新的系统把这个下拉框做成了必选项,此时要么选“不验证”,要么把 ca.pem 改名成 ca.crt 一起装进设备。哪种方式能连上,取决于设备固件对证书校验的严格程度,测试环境里两种都试一遍最快。
5. 避坑与排查:启动红字、1812 端口占用和那对中文引号
下面五条是按实际频率排的,几乎每次重建环境都会撞上至少两条。写法统一成“现象、原因、解决”,方便对照自己的日志。
5.1 现象:freeradius -X 一启动就报证书读取失败
现象:终端刷出一屏红字,提示打开 ca.pem 或 server.key 失败,权限不足;但文件明明就在那里,ls也看得见。
原因:FreeRADIUS 启动后会把权限从 root 降到 freerad 用户运行,而 certs 目录是 make 时以 root 身份生成的,私钥文件默认权限是 600,freerad 用户读不到。
解决:在 certs 目录下放开权限,或者更规范地把属主改掉:
cd /etc/freeradius/3.0/certs chown freerad:freerad ca.pem dh server.key server.pem chmod 640 ca.pem dh server.key server.pem输入资料里给的是chmod 777再chmod o-w,实际效果是 775,能用,但私钥文件对所有人可读在测试环境之外不合适。用 chown 加上 640 更干净:属主可读写,同组可读,其他用户无权限。freerad 这个用户在装包时就创建好了,id freerad能查到。
5.2 现象:1812 被占用,提示 Address already in use
现象:freeradius -X报绑定 1812 端口失败,服务起不来。
原因:systemd 管理的 freeradius 服务已经在后台跑着,占用了 1812 和 1813。apt 安装完默认会启动服务,这一点很多人没注意。
解决:输入资料里写的是重启服务器,其实没必要。停掉后台服务即可:
systemctl stop freeradius ss -lunp | grep -E '1812|1813' # 再确认一次端口空出来了 freeradius -X如果确认服务停了端口还是被占,看第二行的输出里是谁占的——偶尔会是上次-X的进程没退干净,pkill freeradius收掉。调试期间建议顺手systemctl disable freeradius,免得下次开机又抢端口。
5.3 现象:users 改了不生效,认证还是 Reject
现象:往/etc/freeradius/3.0/users里加了账号,重启服务,radtest还是返回 Access-Reject。
原因:3.0 之后 files 模块的默认读取路径变了,实际生效的往往是mods-config/files/authorize,/etc/freeradius/3.0/users那份可能压根没被加载。
解决:先查配置文件里到底指向哪个文件:
grep -r usersfile /etc/freeradius/3.0/mods-enabled/files输出里如果有mods-config/files/authorize,就在那个文件里也写上同一行账号。两处都写是最省事的做法,反正测试环境不在乎冗余。改完systemctl restart freeradius,再用 radtest 验证。
5.4 现象:一条 Cleartext-Password 引发 Access-Reject
现象:users 里那行账号看起来完全正常,radtest 就是过不去,或者命令行提示密码错误。
原因:从文档、聊天记录、网页里复制配置时,引号经常变成中文全角引号,冒号变成全角冒号,行尾还可能带一个看不见的全角空格。FreeRADIUS 解析时会把引号当成密码的一部分,或者直接整行解析失败。
解决:把那一行删掉重敲一遍,全部用英文半角输入。写完用cat -A users | tail -5看一眼,行尾出现的^M说明是 Windows 换行,M-BM-之类说明混进了非 ASCII 字符,都得清掉。这个坑很隐蔽,日志里通常只报“用户未找到”,不会告诉你是引号的问题。
5.5 现象:AP 侧超时,服务器一条日志都没有
现象:终端连不上,AP 日志里显示 RADIUS 服务器无响应,回服务器看,freeradius -X的输出干干净净,一条 Access-Request 都没有。
原因:三种可能。clients.conf 里登记的不是 AP 的实际地址,请求被判为未知客户端后直接丢弃;共享密钥两边不一致,部分实现会静默丢弃;或者 AP 和服务器根本不在一个可达网段,报文到不了。
解决:按顺序排。先ping一次 AP 的地址,通不通;再看-X模式下有没有Ignoring request from unknown client字样,有就说明地址登记错了;地址对了还是没反应,就把 clients.conf 里require_message_authenticator显式设成 no 再试;都不行,去 AP 那一侧确认共享密钥有没有多余空格——密码框里肉眼看不见的尾随空格,是这类问题的老常客。
6. 验证跑通:从 radtest 到终端真正拿到 IP
配置写完不等于装完,得有一组能重复执行的验证动作。我一般按下面顺序走一遍,从底层往上,每层都能独立定位问题。
第一步,确认服务在跑且端口在听:
ss -lunp | grep -E '1812|1813' # 两个端口都要有 freeradius 在 listen第二步,确认基础认证链路通。这一步跟证书无关,只验 clients.conf 和 users:
radtest Testing password 127.0.0.1 0 testing123返回Access-Accept就说明服务认人了。
第三步,验证书链本身。这一步能提前发现很多“设备装不上”的问题:
cd /etc/freeradius/3.0/certs openssl verify -CAfile ca.pem server.pem # 服务器证书是否由该 CA 签发 openssl x509 -in server.pem -noout -subject -dates # 看 CN 和有效期第四步,盯调试日志。freeradius -X前台跑着,终端发起连接,日志里滚出一串 TLS 握手记录,最后出现Sent Access-Accept,就说明双向认证走通了;这时候终端应该能拿到 IP 并上网。
| 验证点 | 命令或现象 | 通过标准 |
|---|---|---|
| 端口监听 | ss -lunp | grep 1812 | freeradius 在 listen |
| 账号链路 | radtest ... 127.0.0.1 ... | Received Access-Accept |
| 证书链 | openssl verify -CAfile ca.pem server.pem | 输出 OK |
| 客户端证书 | openssl pkcs12 -in client.p12 -noout -info | 提示密码后可打印信息 |
| 端到端 | -X日志 + 终端连接 | 日志出现 Access-Accept,终端拿到 IP |
有个细节值得单独说:服务器证书的 CN 如果在 make 时跟的是主机名,而设备端又勾选了校验,就会因名称不匹配握手失败,日志里报的是一大段 TLS alert,看不出是 CN 的问题。测试环境里最简单的做法是让设备端不校验 CA,等链路跑通之后再回去补 CN,重建一次证书。血泪经验是别一开始就把校验开到最严,否则每次失败都要在四个变量里找一个。
从那以后我每次重建这套环境,都会先把radtest和openssl verify这两步跑一遍,确认底层没问题再去碰 AP 和设备端,省下的排查时间比配置本身多得多。希望这套流程能帮到你。
本文还有配套的精品资源,点击获取