证书和私钥必须分开存放、严格限权、路径明确:推荐统一存于/etc/nginx/ssl/下按域名建子目录(如/etc/nginx/ssl/example.com/),私钥设600权限且属主root,证书链合并为fullchain.pem,配置中使用绝对路径引用,禁止硬编码或符号链接。

证书和私钥必须分开存放、严格限权、路径明确,且不能混入配置文件中硬编码。
证书文件存放位置与目录结构
推荐统一存放在 /etc/nginx/ssl/ 目录下,按域名或用途分层管理:
- 每个域名建独立子目录,例如
/etc/nginx/ssl/example.com/ - 该目录内只放本域名所需文件:域名证书(
fullchain.pem)、私钥(privkey.key)、可选的中间证书(不单独保留,已合并进 fullchain) - 避免将证书放在网站根目录、
/tmp或用户主目录等易被意外暴露的位置
私钥权限必须设为 600
私钥是最高敏感资产,任何读取权限泄露都等于交出服务器身份控制权:
- 执行
sudo chmod 600 /etc/nginx/ssl/example.com/privkey.key - 确认属主为
root(Nginx 主进程通常以 root 启动,worker 进程会降权但能读取该文件) - 禁止组和其他用户有任何访问权限(
ls -l输出应类似-rw-------) - 若使用非 root 用户运行 Nginx(如 www-data),需额外用
sudo setfacl -m u:www-data:r /etc/nginx/ssl/example.com/privkey.key授予最小读取权限
证书链必须合并为单一 PEM 文件
Nginx 的 ssl_certificate 指令只接受一个 PEM 文件,它必须包含完整信任链:
- 顺序固定:先放你的域名证书,再追加所有中间证书(根证书不用放)
- 命令示例:
cat example.com.crt ca-bundle.crt > /etc/nginx/ssl/example.com/fullchain.pem - 验证是否完整:
openssl crl2pkcs7 -nocrl -certfile /etc/nginx/ssl/example.com/fullchain.pem | openssl pkcs7 -print_certs -noout应输出至少两段证书(域名证书 + 中间证书)
配置中使用绝对路径并禁用符号链接
Nginx 不解析软链接指向的私钥或证书,且符号链接可能绕过权限检查:
- 在 server 块中明确写绝对路径:
ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem; - 不要用相对路径、环境变量或
$document_root等动态路径 - 避免创建指向私钥的软链接(如
ln -s /var/secrets/key.key privkey.key),Nginx 会拒绝加载
禁止在配置里写死密码或密钥内容
绝不在 nginx.conf 或站点配置中嵌入 Base64 编码的证书内容或私钥字符串:
- 这类做法导致配置文件本身成为高危凭证载体,极易随 Git 提交、日志打印或备份泄露
- 所有证书材料必须以独立文件形式存在,由 Nginx 进程按需读取
- 如需加密私钥(不推荐生产环境使用),应使用
openssl rsa -aes256 -in key.pem -out key.enc.pem,但 Nginx 不支持自动解密,需手动输入密码启动,无法平滑 reload











