Nginx 部署 PFX 后 curl 报 60:检查是否漏了中间证书
浏览器正常而 curl 提示 unable to get local issuer certificate,先检查线上发送的链,再按叶证书、中间证书顺序组合,保留客户端证书校验。
把 PFX 证书转换成 PEM 后部署到 Nginx,浏览器能打开网站,curl 或应用却提示 unable to get local issuer certificate。如果 Nginx 的 ssl_certificate 文件只包含域名证书,没有配套中间证书,客户端可能无法建立完整信任链。
浏览器可能已经缓存中间证书,或能够通过其他机制补齐证书链。一个浏览器能访问,不足以证明服务器发送的链完整。这个故障也可能与客户端 CA 库有关,应先区分服务端缺链和客户端不信任。
看线上实际发送了哪些证书
下面的示例以 OpenSSL 检查 HTTPS 端点,example.com 需要替换为站点域名。-servername 会发送 SNI,避免多站点服务器返回默认证书:
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
查看返回链中的第一张证书是否属于该站点,以及是否包含签发它的中间证书。如果是由中间 CA 签发的域名证书,却只返回这一张叶证书,优先修复服务器链。
这条命令展示的是当前连接端点。如果域名前面有 CDN,它可能展示 CDN 的边缘证书;检查源站时,可把 -connect 改成自己源站的 IP 和端口,仍保留站点域名作为 -servername。不要把边缘证书正常误当作源站证书正常。
如果线上链完整而只有某台客户端失败,检查该客户端使用的 CA 库、curl 的 TLS 后端和应用指定的 CA 文件。私有 CA 需要通过可信渠道分发相应根证书;公开 CA 的证书则检查客户端信任库是否缺失或过旧,不要把任意下载的证书加入信任库。
把域名证书和中间证书按顺序组合
从证书签发方取得与这张证书匹配的中间证书链。不要仅按证书名称相似就混用另一个签发链。
以下命令是文件组合示例,假设 domain.crt 只包含域名证书,intermediate-chain.pem 已按签发顺序包含所需中间证书。两个输入文件与输出文件不能是同一个路径,否则输出重定向可能先清空输入:
cat domain.crt intermediate-chain.pem > fullchain.pem
组合文件第一张应是域名证书,随后是签发它的中间证书,再往上延伸。服务器通常不需要发送客户端已信任的根证书。不要把私钥拼进 fullchain.pem;私钥仍由独立文件提供并限制访问权限。
Nginx 的配置片段示例:
ssl_certificate /etc/nginx/tls/fullchain.pem;
ssl_certificate_key /etc/nginx/tls/domain.key;
路径需要替换为真实文件,私钥必须与域名证书匹配。如果使用 Certbot 管理的证书,一般应让 ssl_certificate 指向对应的 fullchain.pem,不要只使用 cert.pem;同时检查续期后 Nginx 能否重新加载新证书。
修改后验证客户端仍在校验证书
先保存原证书文件和站点配置,在正确的 Nginx 实例上检查配置。默认配置实例的操作示例:
nginx -t
nginx -s reload
只在配置检查成功后重载。非默认配置、容器或服务管理器启动的实例,应使用对应的配置和管理方式。重载会让新连接使用新的证书配置,旧连接可能仍由原工作进程处理;发现异常时恢复原文件和配置,重新检查后重载。
重新检查端点发出的证书链,并在最初失败的客户端重试请求。curl 不带 -k,应用也不关闭证书验证时,应能完成 TLS 校验;HTTP 层即使返回正常的 401 或其他业务状态,也应与证书校验失败区分。服务器链已完整但客户端仍失败时,继续查客户端信任库和实际连接的端点,不要反复追加无关证书。


