nginx 不支持 ssl_password_file 指令,配置会报错“unknown directive”;必须在启动前用 openssl 预解密私钥为无密码格式,并通过 systemd execstartpre 自动执行解密、设权(600)、属主变更,确保 nginx 仅加载已解密私钥。

Nginx 本身不支持通过配置文件自动读取密码来解密私钥——它没有 ssl_password_file 指令,也不会从文件、环境变量或 stdin 自动获取口令。所谓“自动录入”,实际是在 Nginx 启动前,由外部脚本完成解密,再让 Nginx 加载无密码私钥。
下面直接说明可行、安全、可落地的操作路径:
如何确认私钥是否加密
执行命令验证:
openssl rsa -noout -check -in /etc/nginx/ssl/server.key
- 若提示
Enter pass phrase for ...或报错RSA key error: bad decrypt,说明该私钥受密码保护; - 若直接输出
RSA key ok,则无需密码,可跳过解密步骤。
用 OpenSSL 预解密私钥(最常用)
在 Nginx 启动前运行一条命令,把加密私钥转为无密码版本:
openssl rsa -in server.key.enc -out server.key -passin file:/etc/nginx/secrets/pass.txt
-
/etc/nginx/secrets/pass.txt是纯文本密码文件,仅含一行口令,权限必须为600,属主为root; - 解密后生成的
server.key必须设为600,且属主属组为 Nginx 运行用户(如nginx:nginx); - 原始加密私钥(
.enc)和密码文件绝不上传到线上服务器的 Git 仓库或 Web 可访问目录。
在 systemd 中自动化执行(推荐)
修改 Nginx 的 service 单元,添加启动前解密步骤:
在 /etc/systemd/system/nginx.service.d/override.conf 中写入:
[Service] ExecStartPre=/usr/bin/openssl rsa -in /etc/nginx/ssl/server.key.enc -out /etc/nginx/ssl/server.key -passin file:/etc/nginx/secrets/pass.txt ExecStartPre=/usr/bin/chmod 600 /etc/nginx/ssl/server.key ExecStartPre=/usr/bin/chown nginx:nginx /etc/nginx/ssl/server.key
然后重载并启用:
systemctl daemon-reload systemctl restart nginx
这样每次 systemctl start nginx 都会先解密、设权、再启动,全程无人值守。
安全红线:这些操作必须避免
- 不要用
echo "pwd" | nginx或expect脚本向 Nginx 输入密码——Nginx 根本不从 stdin 读取口令,该方式完全无效; - 不要把密码硬编码在 shell 脚本、Nginx 配置或环境变量里,极易被日志、ps、备份泄露;
- 不要把密码文件放在
/tmp、/var/www或用户家目录下,即使权限设为400,路径本身已不安全; - 不要相信网上所谓“添加 ssl_password_file xxx”就能生效的教程——Nginx 源码里没有这个指令,加了必报
unknown directive。
Nginx 的设计就是“不碰密码”,只加载已解密的私钥。真正要做的,是把解密动作提前、隔离、可控。











