问题根源是Nginx未正确发送CertificateRequest及certificate_authorities字段,导致Go等严格TLS客户端不发送证书而返回400;根本原因在于ssl_client_certificate配置错误或CA文件无效、缺失中间CA、格式不合规,或Nginx未实际加载该配置。

这个问题其实不是“客户端证书链不完整”,而是服务端 Nginx 没有正确提供可信 CA 列表,导致 Go 或其他严格 TLS 实现的客户端根本不会发送证书——于是服务端返回 400 Bad Request: No required SSL certificate was sent。
确认是不是服务端没发 CertificateRequest
用 OpenSSL 模拟客户端握手,看服务端是否真的发了证书请求:
- 运行:
openssl s_client -connect your-domain.com:443 -servername your-domain.com -cert client.crt -key client.key -CAfile ca.crt -tlsextdebug 2>/dev/null | grep "CertificateRequest" - 如果输出里没有
CertificateRequest,或虽有但certificate_authorities字段为空/只含乱码,说明 Nginx 根本没把 CA 列表传下去 - 此时 curl 可能成功,是因为它会“试探性”发证书;Go 不会,这是协议合规性差异,不是 bug
检查 ssl_client_certificate 文件是否有效
Nginx 的 ssl_client_certificate 必须指向一个完整、干净、顺序正确的 PEM 文件:
- 执行
cat /etc/nginx/client-ca.pem,确认至少包含一个-----BEGIN CERTIFICATE-----块(即根 CA 或中间 CA) - 不能是空文件、不能含 BOM、不能有 Windows 换行(CRLF)、不能有空行或注释
- 若客户端证书由中间 CA 签发,而你只放了根 CA,Nginx 无法构建有效
certificate_authorities列表——应把中间 CA 和根 CA 按“中间 → 根”顺序拼在一起(Nginx 要求的是验证客户端证书所需的全部签发者,不含客户端证书本身) - 验证命令:
openssl x509 -in /etc/nginx/client-ca.pem -text -noout 2>/dev/null | head -5,确保能正常解析
验证 Nginx 是否真正加载并使用该 CA 文件
即使配置写了,也可能因路径错、权限不足或语法错误被忽略:
- 检查 Nginx 配置中是否在对应 server 或 location 块内设置了:
ssl_client_certificate /etc/nginx/client-ca.pem;和ssl_verify_client on; - 运行
nginx -t确认语法无误,再nginx -s reload - 查 error.log:搜索
client certificate或ssl_client_certificate,看是否有 warning 如 “no suitable certificate found” 或 “failed to load CA” - 临时加日志:在 location 中加
error_log /var/log/nginx/debug.log debug;,然后抓握手过程细节(需编译时带 --with-debug)
排除客户端证书本身的问题
400 错误常被误判为“客户端证书不对”,但实际多数是服务端未触发发送:
- 用 curl 验证基础通路:
curl -v --cert client.crt --key client.key --cacert ca.crt https://your-domain.com/api。若成功,说明证书和 CA 都没问题 - 用 Go 写最简测试(不用框架):
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{Certificates: []tls.Certificate{cert}},观察是否仍 400 - 若 curl 成、Go 不成,100% 是服务端未发
certificate_authorities—— 回头重点修ssl_client_certificate配置


















