stunnel强制使用TLSv1.2时客户端证书验证失败问题咨询
问题根因
你遇到的peer did not return a certificate报错核心原因是Nginx stream代理配置的证书参数使用错误,导致Nginx向stunnel发起TLS连接时没有携带客户端证书。
问题解答
1. 配置是否存在错误?
存在核心配置错误:你当前Nginx配置中使用的ssl_certificate、ssl_certificate_key参数是Nginx作为SSL服务端接收客户端连接时用来下发自身证书的配置。而你的场景是Nginx作为客户端主动向后端stunnel发起TLS连接,需要向stunnel出示客户端证书,必须使用proxy_ssl_certificate、proxy_ssl_certificate_key参数,这是stunnel收不到客户端证书的直接原因。
2. 服务端和客户端是否还有遗漏的配置项?
有遗漏的必要配置:
- Nginx侧需要新增
proxy_ssl_trusted_certificate配置,指定你的自签CA证书路径,用来校验stunnel返回的服务端证书合法性,避免中间人攻击。 - 如需开启完整双向校验,Nginx侧还需补充
proxy_ssl_verify on、proxy_ssl_verify_depth 1配置,强制验证服务端证书有效性。 - stunnel侧现有配置(verify=3、禁用低版本SSL/TLS)符合双向认证要求,无遗漏。
3. 为什么verify设为0时可以正常连接?
stunnel的verify=0表示完全关闭客户端证书校验,即使客户端未携带证书也可以正常建立TLS连接,直接掩盖了Nginx未发送客户端证书的配置错误。
排查解决步骤
- 修正Nginx stream配置,替换错误的证书参数,补充必要配置:
server { listen 10043; proxy_ssl on; proxy_ssl_protocols TLSv1.2; proxy_ssl_session_reuse on; # 向stunnel出示的客户端证书和密钥 proxy_ssl_certificate /etc/nginx/certs/tls_certs/client-cert.pem; proxy_ssl_certificate_key /etc/nginx/certs/tls_certs/client-key.pem; # 信任自签CA,校验服务端证书 proxy_ssl_trusted_certificate /etc/nginx/certs/tls_certs/ca-cert.pem; proxy_ssl_verify on; proxy_ssl_verify_depth 1; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; ssl_dhparam /etc/nginx/certs/tls_certs/dhparam.pem; access_log /var/log/nginx/lpe-ing.log proxy; proxy_pass 123.456.789.123:12345; }
- 验证文件权限:确保Nginx运行用户对
client-cert.pem、client-key.pem、ca-cert.pem有读取权限,密钥文件权限建议设置为600,避免权限泄露。 - 直接验证stunnel侧配置:执行以下命令跳过Nginx直接测试stunnel连接是否正常:
openssl s_client -connect 123.456.789.123:12345 -tls1_2 -cert client-cert.pem -key client-key.pem -CAfile ca-cert.pem
如果该命令可正常建立连接,说明stunnel侧配置无问题,仅需修正Nginx配置即可。 - 重启Nginx生效配置,重新测试端到端连接即可。
补充说明:你之前执行
openssl s_client -connect localhost:10043 -tls1_2报错是因为你当前Nginx的10043端口没有配置为SSL服务端(listen参数未加ssl标识),用SSL协议访问非SSL端口自然会报错,该测试方法不符合你当前的配置场景。
内容的提问来源于stack exchange,提问作者Tsu Wei Quan
相关产品推荐
相关产品推荐

