温馨提示×

如何在Ubuntu上排查Nginx SSL错误

小樊
38
2025-12-30 16:20:20
栏目: 云计算

Ubuntu 上排查 Nginx SSL 错误的实用流程

一 快速定位与通用检查

  • 查看 Nginx 错误日志sudo tail -n50 /var/log/nginx/error.log,优先关注包含 SSL/TLS、certificate、key、handshake 的行,能直接指向证书路径、权限、链、密钥不匹配等根因。
  • 语法与包含关系检查:sudo nginx -t,确保站点配置被正确 include,证书路径无拼写错误。
  • 证书是否为 PEM 格式:文件应以 -----BEGIN CERTIFICATE----- 开头;若为 DER/PFX 需先转换。
  • 证书与私钥是否匹配:
    openssl x509 -noout -modulus -in server.crt | openssl md5
    openssl rsa -noout -modulus -in server.key | openssl md5
    两个 MD5 值必须一致。
  • 证书链是否完整:将中间证书追加到域名证书后部署,或单独配置 ssl_trusted_certificate;验证链:
    openssl verify -CAfile ca_bundle.crt your_domain.crt
  • 证书是否生效:
    echo | openssl s_client -connect 域名:443 -servername 域名 2>/dev/null | openssl x509 -noout -dates
    确认当前时间在 notBefore/notAfter 之间;系统时间错误请先同步。
  • 协议与套件基线:确保启用 TLSv1.2/TLSv1.3,禁用过时协议与弱套件。
  • 变更后重载:sudo nginx -s reload(或 systemctl reload nginx),避免直接重启造成短暂中断。

二 常见错误与修复对照表

症状 可能原因 快速验证 修复建议
nginx: [emerg] unknown directive "ssl" Nginx 未编译进 SSL 模块 或装了不带 SSL 的版本 `nginx -V 2>&1 grep – ‘–with-http_ssl_module’` 无输出
SSL_CTX_use_certificate:ee key too small RSA 密钥 < 2048 位 或系统加密策略过严 `openssl rsa -in server.key -text -noout grep “Private-Key”update-crypto-policies --show`
unable to load certificate ... PEM lib / Expecting: TRUSTED CERTIFICATE 证书非 PEM、文件损坏、路径错误 cat server.crt 看是否以 BEGIN CERTIFICATE 开头;ls -l 看路径与权限 转换为 PEM(DER→PEM、PFX→PEM);修正路径;确保 Nginx 可读
SSL_CTX_use_PrivateKey_file ... key values mismatch 证书与私钥不匹配 对比上面 MD5(modulus) 重新匹配证书与私钥或重新签发
替换证书后仍显示旧证书 reload、浏览器/CDN 缓存、配置命中错误 server 块、中间证书缺失 curl -vkI https://域名sudo nginx -s reload;检查 server_name 与证书链 执行 reload;清缓存或绕过 CDN 测试;合并中间证书;修正 server_name 与证书路径
SSL handshake failure(如 error code 5 域名不匹配、证书过期、TLS 版本/套件 不兼容、时间错误、中间设备拦截 openssl s_client -connect 域名:443 -servername 域名 看握手与协议;检查系统时间 统一 TLS1.2+ 与合规套件;修正域名/续期证书;校准时间;排查防火墙/代理/WAF

三 深入验证与网络排查

  • 指定 SNI 查看服务端证书与握手协议:
    echo | openssl s_client -connect 域名:443 -servername 域名 2>/dev/null | openssl x509 -noout -text | grep -E "DNS:|Not Before|Not After"
    echo | openssl s_client -connect 域名:443 -servername 域名 -tls1_2 2>/dev/null | grep "Protocol"
    echo | openssl s_client -connect 域名:443 -servername 域名 -tls1_3 2>/dev/null | grep "Protocol"
  • 客户端视角验证:
    curl -Iv https://域名(观察 SSL certificate verify、握手过程与返回码)。
  • 协议/套件基线示例(按需精简):
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;
    
  • 中间设备与网络:临时关闭 UFW 或旁路 CDN/代理 复测;必要时用 Wireshark 抓包定位握手中断点。

四 Let’s Encrypt 与自动化

  • 正确引用证书路径(Certbot 默认):
    ssl_certificate /etc/letsencrypt/live/域名/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/域名/privkey.pem;
  • 续期与自动重载:
    sudo certbot renew --dry-run(先演练);
    sudo certbot renew --post-hook "systemctl reload nginx"(续期后自动生效)。
  • renew 后 Nginx 未生效,优先检查语法与重载:sudo nginx -t && sudo nginx -s reload

五 Docker 场景的要点

  • 证书与配置挂载正确:容器内路径需与 Nginx server 配置一致,且 Nginx 进程可读
  • 容器内语法与日志:
    docker run --rm -v /etc/nginx:/etc/nginx nginx nginx -t
    docker exec -it <容器ID> cat /var/log/nginx/error.log
  • 证书不匹配与重载:
    docker exec -it <容器ID> sh -c "openssl x509 -noout -modulus -in /etc/nginx/ssl/server.crt | openssl md5"
    docker exec -it <容器ID> sh -c "openssl rsa -noout -modulus -in /etc/nginx/ssl/server.key | openssl md5"
    一致后执行:docker exec <容器ID> nginx -s reload

0