使用加密私鑰的 SSL 證書會導致 Nginx 每次啟動/重載都要求輸入密碼,嚴重影響自動化部署、容器啟動、系統重啟恢復。本文提供標準解決方案:使用 OpenSSL 生成無加密私鑰副本,並調整文件權限保障安全。
server.key)以 AES-256 加密,PEM 格式包含 Proc-Type: 4,ENCRYPTED 與 DEK-Info。ssl_certificate_key /path/server.key; 時,nginx -t、systemctl start nginx、docker run 均會阻塞等待密碼輸入。# 1. 備份原始加密私鑰
cp server.key server.key.encrypted.bak
# 2. 生成無加密副本 (需輸入原密碼)
openssl rsa -in server.key -out server.key.unencrypted
# 3. 驗證生成結果
head -n 5 server.key.unencrypted
# 應顯示:
# -----BEGIN RSA PRIVATE KEY-----
# (無 Proc-Type/DEK-Info 行)
# ...
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/server.crt; # 證書鏈 (含中間證書)
ssl_certificate_key /etc/ssl/private/server.key.unencrypted; # 無密碼私鑰
# 安全建議
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 off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
}
# 僅 root 可讀,防止進程洩露
chown root:root /etc/ssl/private/server.key.unencrypted
chmod 400 /etc/ssl/private/server.key.unencrypted
# 驗證權限
ls -l /etc/ssl/private/server.key.unencrypted
# -r-------- 1 root root 3243 Jan 1 12:00 server.key.unencrypted
原則:無密碼私鑰等同於明文憑證,必須嚴格限制文件系統級訪問權限,彌補加密層面的缺失。
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 生成無密碼私鑰 (本文) | 簡單、通用、無額外依賴、支援所有 Nginx 版本 | 私鑰文件明文存儲,需嚴格權限控制 | 大多數單機、容器、VM 部署 |
Nginx ssl_password_file | 私鑰保持加密,密碼外置文件 | 密碼文件同樣需權限保護;舊版 Nginx 不支援 | 合規要求嚴禁明文私鑰落盤 |
| 使用 OpenSSL 引擎 / HSM / TPM | 私鑰永不離開硬體安全模組 | 成本高、配置複雜、需硬體支援 | 金融、軍工、高合規環境 |
| Kubernetes Secret + cert-manager | 聲明式管理、自動輪換、RBAC 控制 | 需 K8s 集群、學習曲線陡峭 | 雲原生、微服務架構 |
# 語法檢查 (不再提示密碼)
nginx -t
# 熱重載
nginx -s reload
# 系統服務測試
systemctl restart nginx
journalctl -u nginx -f
# 容器測試
docker run -d -p 443:443 -v /etc/ssl:/etc/ssl nginx:alpine
完成上述步驟後,Nginx 所有生命週期操作均無需人工干預,完美支援 CI/CD、基礎設施即代碼(IaC)與高可用架構。