Nginx stream模块MQTT上游客户端证书认证失效,报未知CA错误
Nginx Stream块MQTT客户端证书认证unknown ca问题排查与修复
核心报错来自日志中的tlsv1 alert unknown ca:SSL alert number 48,即TLS握手阶段,Nginx收到客户端提交的证书后,无法在信任列表中匹配到对应的签发CA,直接中断连接。按以下步骤逐项排查即可解决:
1. 核对信任CA文件内容匹配度
- 提取Nginx信任列表的CA元信息:
openssl x509 -in /root/clientca/ca.crt -noout -subject -issuer -fingerprint -sha256 - 提取客户端证书对应的签发CA元信息:
openssl x509 -in 客户端实际使用的证书文件.crt -noout -issuer -fingerprint -sha256 - 两组输出的
issuer字段、CA SHA256指纹必须完全一致,否则即为CA配置错误。常见踩坑场景:- 错把服务端证书用的CA塞到了
ssl_client_certificate指定路径 - CA文件缺少根CA或中间CA片段,只保留了单段证书
- 客户端证书由另一套密钥对生成的CA签发,和Nginx侧配置的CA不属于同一体系
- 错把服务端证书用的CA塞到了
- 若客户端证书由多级CA签发,需将所有信任CA按顺序合并为完整证书链文件,避免验证失败:
cat 根CA.crt 中间CA.crt > 客户端信任CA链.crt
2. 解决Nginx对CA文件的读取权限问题
当前配置中ssl_client_certificate指向的路径是/root/clientca/ca.crt,Nginx的worker进程默认以非root的nginx用户运行,没有权限读取/root目录下的文件。
这种场景下Nginx不会直接报权限不足错误,而是会默认将信任列表置空,最终触发unknown ca报错,是本场景最高频的踩坑点。
- 修复操作:将CA文件迁移到Nginx可正常读取的路径,并调整权限:
mkdir -p /etc/nginx/ssl/client_ca cp /root/clientca/ca.crt /etc/nginx/ssl/client_ca/ chown -R nginx:nginx /etc/nginx/ssl/client_ca/ chmod 644 /etc/nginx/ssl/client_ca/ca.crt - 将配置文件中
ssl_client_certificate的路径替换为上述新路径。
3. 补充缺失的SSL验证参数
当前配置缺少证书链深度的限制参数,会导致多级CA签发的客户端证书验证失败:
- 在server块中添加
ssl_verify_depth 2;配置,该参数定义Nginx最多可追溯的证书链层数,默认值为1,无法满足跨一级CA的验证场景。
4. 验证与测试
- 调整后的server块参考配置:
stream { upstream broker { server 10.110.0.4:1883 fail_timeout=10s max_fails=1; server 10.110.0.3:1883 fail_timeout=10s max_fails=1; server 10.110.0.6:1883 fail_timeout=10s max_fails=1; } server { error_log /var/log/nginx/mqtt_error.log debug; ssl_certificate /etc/nginx/ssl/mqtt.domain.com/server.crt; ssl_certificate_key /etc/nginx/ssl/mqtt.domain.com/server.key; # 客户端证书验证相关配置 ssl_client_certificate /etc/nginx/ssl/client_ca/ca.crt; ssl_verify_client on; ssl_verify_depth 2; ssl_protocols TLSv1.2; listen mqtt.domain.com:8883 ssl; proxy_pass broker; proxy_connect_timeout 1s; } } - 配置修改完成后,先执行
nginx -t校验语法、文件读取权限,确认无报错后重载Nginx服务,再用MQTT客户端携带证书发起连接测试。
内容的提问来源于stack exchange,提问作者TDawg
相关产品推荐
相关产品推荐

