必须使用绝对路径,如/etc/nginx/ssl/fullchain.pem和/etc/nginx/ssl/privkey.pem;相对路径在systemd、crontab等场景下极易失效,且ssl_certificate必须为完整证书链(域名证书+中间证书),私钥须无密码、权限600并属主为Nginx worker用户。

ssl_certificate 和 ssl_certificate_key 路径必须用绝对路径
相对路径(如 cert/example.com.crt 或 ./cert.key)在 Nginx 启动时大概率失效,因为 Nginx 的工作目录不等于你执行 nginx -t 时的当前目录。系统服务启动、reload、crontab 自动更新等场景下,路径会更不可控。
正确做法是全部使用绝对路径,例如:/etc/nginx/ssl/fullchain.pem、/etc/nginx/ssl/privkey.pem。路径建议统一放在 /etc/nginx/ssl/ 或 /usr/local/nginx/conf/ssl/ 这类明确、权限可控的位置。
- 用
file /path/to/cert.pem确认是 PEM 格式(输出含PEM certificate) - 用
openssl x509 -in /path/to/cert.pem -noout -subject检查域名是否匹配server_name - 私钥不能加密:若含
DEK-Info行,Nginx 启动会卡住或报SSL_CTX_use_PrivateKey_file failed (SSL: error:0906406D:...problems getting password);用openssl rsa -in encrypted.key -out decrypted.key去密
证书文件必须是 fullchain.pem,不是单个 crt
只放域名证书(如 example.com.crt)会导致 iOS、部分安卓设备和旧版 Chrome 校验失败,报“无法验证服务器身份”——因为缺少中间 CA 证书链。Nginx 的 ssl_certificate 必须指向拼接好的完整证书链文件。
Let’s Encrypt 用户应直接用 fullchain.pem(即 cert.pem + chain.pem 合并);商业证书下载包里通常带 xxx_bundle.crt,这就是你要用的文件。不要手动只复制 domain.crt。
- 验证是否完整:运行
openssl crl2pkcs7 -nocrl -certfile /etc/nginx/ssl/fullchain.pem | openssl pkcs7 -print_certs -noout,应输出至少两个证书(域名证书 + 中间证书) - 错误示例:若只配了
ssl_certificate /etc/nginx/ssl/example.com.crt,nginx -t可能通过,但浏览器会静默失败 -
ssl_certificate_key始终只指向私钥文件(privkey.pem或example.com.key),它不参与证书链拼接
server 块中 listen 443 ssl 缺一不可
漏掉 ssl 关键字,或只写 listen 443 不加 ssl,Nginx 会把该 server 当作普通 HTTP 服务处理,HTTPS 请求根本不会进入这个块——没有报错,也没有日志,请求直接 404 或被其他 server 拦截。
同时,ssl_certificate 和 ssl_certificate_key 必须在同一 server 块内成对出现。跨块、跨文件引用(比如在 http 块里定义再 include)无效。
- 最小可用 HTTPS server 片段:
server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; location / { return 200 "OK"; } } - HTTP → HTTPS 跳转建议用
return 301 https://$host$request_uri;,避免rewrite引发循环或变量丢失 - 不要在同一个 server 块里混用
listen 80和listen 443 ssl;80 端口应单独写一个 server 块做跳转
权限与 nginx -t 校验是上线前最后防线
Nginx 主进程以 root 启动,但 worker 进程默认以 www-data 或 nginx 用户运行。如果证书文件权限太严(如 600 且属主不是 worker 用户),worker 读取私钥时会失败,报 SSL_CTX_use_PrivateKey_file("") failed (SSL: error:0200100D:system library:fopen:Permission denied)。
最稳妥的权限设置是:chmod 644 /etc/nginx/ssl/fullchain.pem(证书可公开),chmod 600 /etc/nginx/ssl/privkey.pem(私钥仅所有者可读),并确保私钥文件属主为 Nginx worker 用户(如 chown nginx:nginx /etc/nginx/ssl/privkey.pem)。
- 每次修改证书或配置后,必须执行
nginx -t;只有输出successful才能nginx -s reload - 证书更新务必原子替换:先
mv new.pem old.pem && mv temp.pem new.pem,避免 reload 期间文件短暂缺失 - 别依赖浏览器刷新判断——用
curl -I https://example.com看HTTP/2 200或HTTP/1.1 200,以及openssl s_client -connect example.com:443 -servername example.com直接抓握手细节


















