Ubuntu下Nginx SSL配置出错排查与修复
一、快速自检清单
- 检查语法与配置路径:执行sudo nginx -t,确保配置无语法错误且证书、密钥路径正确。
- 查看错误日志:执行sudo tail -f /var/log/nginx/error.log,优先定位报错行与文件。
- 确认模块与依赖:执行nginx -V | grep http_ssl_module查看是否包含**–with-http_ssl_module**;执行openssl version确认系统已安装OpenSSL。
- 验证证书与私钥:
- 查看证书信息:openssl x509 -noout -text -in /path/to/cert.pem
- 校验证书与私钥是否匹配:
- openssl x509 -noout -modulus -in cert.pem | openssl md5
- openssl rsa -noout -modulus -in key.pem | openssl md5
- 在线检测与本地连通性:使用curl -Iv https://your_domain;必要时测试端口:openssl s_client -connect your_domain:443 -servername your_domain。
- 防火墙与安全组:确认云厂商安全组与系统防火墙已放行TCP 443。
二、常见错误与修复
-
未启用SSL模块
现象:报错**“the ‘ssl’ parameter requires ngx_http_ssl_module”或“unknown directive ‘ssl’”**。
处理:
- 查看模块:nginx -V | grep http_ssl_module;若无,则需编译进模块。
- 安装依赖:sudo apt-get update && sudo apt-get install openssl libssl-dev。
- 进入Nginx源码目录重新配置并编译:
- ./configure --with-http_ssl_module(保留原有参数)
- make(不要直接 make install)
- 备份旧二进制:sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
- 覆盖新二进制:sudo cp ./objs/nginx /usr/local/nginx/sbin/
- 验证:nginx -V | grep http_ssl_module 应出现**–with-http_ssl_module**。
- 重载:sudo systemctl reload nginx。
-
监听端口未启用SSL
现象:访问HTTPS出现ERR_SSL_PROTOCOL_ERROR;curl 报error:0A00010B:SSL routines::wrong version number。
原因:配置写成listen 443; 而未加ssl,Nginx在443端口以明文方式工作。
修复:改为listen 443 ssl;(IPv6 对应listen [::]:443 ssl;)。
-
证书路径错误或文件不可读
现象:日志提示BIO_new_file … No such file or directory或权限拒绝。
处理:
- 使用绝对路径并确保文件存在;
- 证书与私钥权限建议600,属主为root;
- 再次测试:sudo nginx -t。
-
证书链不完整或证书与私钥不匹配
现象:浏览器提示证书无效/CA验证失败。
处理:
- 确保ssl_certificate指向包含完整链的证书文件(常见为fullchain或已拼接中间证书);
- 使用上面的modulus对比命令校验证书与私钥是否匹配;
- 必要时重新下载或拼接中间证书后再测试。
-
协议与加密套件配置不当
现象:握手失败或兼容性问题。
处理:在server块中显式配置:
- ssl_protocols TLSv1.2 TLSv1.3;
- ssl_ciphers HIGH:!aNULL:!MD5;
- 按需开启ssl_prefer_server_ciphers on;与ssl_stapling on;(并配置resolver)。
三、最小化可用HTTPS示例
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /var/www/html;
index index.html;
}
}
- 启用站点:sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
- 测试与生效:sudo nginx -t && sudo systemctl reload nginx
- 自动获取证书(可选):sudo apt install certbot python3-certbot-nginx,然后sudo certbot --nginx -d example.com -d www.example.com。
四、仍未解决时的定位建议
- 抓包与握手细节:执行sudo tcpdump -i any -nn port 443 -w ssl.pcap,用Wireshark查看ClientHello/ServerHello与告警;或用openssl s_client -connect your_domain:443 -servername your_domain -debug观察握手过程。
- 最小化配置法:临时替换为仅含HTTPS的最小server块逐项排除干扰项(代理、缓存、gzip、第三方模块等)。
- 版本与兼容性:确认Nginx与OpenSSL版本匹配;如从源码编译,避免跨版本覆盖安装导致的不一致。
- 社区与厂商工单:携带error.log关键行、证书链信息、Nginx版本与nginx -V输出,便于快速定位。