ssl_password_file
是 NGINX 中的一个指令,用于指定一个包含密码的文件,这个文件用于提供 SSL/TLS 私钥的密码。该指令在 NGINX 启动时会读取该文件,并用于加载私钥文件时解锁加密的私钥。如果私钥是加密的,那么 NGINX 需要密码才能使用它,密码错误会导致nginx启动或者重新加载失败。
语法
Syntax: ssl_password_file file;
Default: —
Context: http, server
This directive appeared in version 1.7.3.
<file>
:指定包含密码的文件路径。这个文件应该包含一个用于解锁 SSL 私钥的密码。- 指定一个包含密钥密码的文件,每个密码都位于单独的一行。在加载密钥时,密码将按顺序尝试。
默认值
- 默认情况下,
ssl_password_file
指令不被启用,即没有设置密码文件。
使用场景
该指令通常在以下情况下使用:
1. 私钥加密:当生成 SSL/TLS 私钥时,如果你为私钥设置了密码保护,那么每次 NGINX 启动时,都需要提供密码才能加载私钥。
配置示例
生成四组自签名证书及私钥, 其中RSA算法两个, ECC算法两个,两组证书中一个带密码,一个不带密码。使用脚本生成
#!/bin/bash
# Set directory variables
CERTS_DIR="/etc/nginx/ssl"
# Create the certificate directory if it doesn't exist
mkdir -p $CERTS_DIR
# Set passwords for different key types
PASSWORD_RSA_WITH="password123"
PASSWORD_ECC_WITH="password789"
# Create password files for multiple certificates
echo $PASSWORD_RSA_WITH > "$CERTS_DIR/rsa_password.txt"
chmod 600 "$CERTS_DIR/rsa_password.txt"
echo $PASSWORD_ECC_WITH > "$CERTS_DIR/ecc_password.txt"
chmod 600 "$CERTS_DIR/ecc_password.txt"
cat "$CERTS_DIR/rsa_password.txt" "$CERTS_DIR/ecc_password.txt" > "$CERTS_DIR/password_file.txt"
# Set certificate information
COUNTRY="CN"
STATE="BEIJING"
LOCALITY="BEIJING"
ORG="test"
ORG_UNIT="test-unit"
EMAIL="email@example.com"
# Generate RSA private key with password
openssl genpkey -algorithm RSA -aes256 -out "$CERTS_DIR/rsa_private_key_with_password.pem" -pass pass:$PASSWORD_RSA_WITH
echo "Generated RSA private key with password: rsa_private_key_with_password.pem"
# Generate RSA private key without password
openssl genpkey -algorithm RSA -out "$CERTS_DIR/rsa_private_key_without_password.pem"
echo "Generated RSA private key without password: rsa_private_key_without_password.pem"
# Generate RSA Certificate Signing Request (CSR) with password, avoiding interactive input
COMMON_NAME="example1.com"
openssl req -new -key "$CERTS_DIR/rsa_private_key_with_password.pem" -out "$CERTS_DIR/rsa_csr_with_password.pem" \
-passin pass:$PASSWORD_RSA_WITH \
-subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL"
echo "Generated RSA CSR with password: rsa_csr_with_password.pem"
# Generate RSA CSR without password, avoiding interactive input
COMMON_NAME="example2.com"
openssl req -new -key "$CERTS_DIR/rsa_private_key_without_password.pem" -out "$CERTS_DIR/rsa_csr_without_password.pem" \
-subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL"
echo "Generated RSA CSR without password: rsa_csr_without_password.pem"
# Use the RSA private key to sign the certificate
openssl x509 -req -in "$CERTS_DIR/rsa_csr_with_password.pem" -signkey "$CERTS_DIR/rsa_private_key_with_password.pem" -out "$CERTS_DIR/rsa_certificate_with_password.pem" -days 365 -passin pass:$PASSWORD_RSA_WITH
openssl x509 -req -in "$CERTS_DIR/rsa_csr_without_password.pem" -signkey "$CERTS_DIR/rsa_private_key_without_password.pem" -out "$CERTS_DIR/rsa_certificate_without_password.pem" -days 365
echo "Generated RSA certificates"
# Generate ECC private key with password
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -aes256 -out "$CERTS_DIR/ecc_private_key_with_password.pem" -pass pass:$PASSWORD_ECC_WITH
echo "Generated ECC private key with password: ecc_private_key_with_password.pem"
# Generate ECC private key without password
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out "$CERTS_DIR/ecc_private_key_without_password.pem"
echo "Generated ECC private key without password: ecc_private_key_without_password.pem"
# Generate ECC CSR with password, avoiding interactive input
COMMON_NAME="example3.com"
openssl req -new -key "$CERTS_DIR/ecc_private_key_with_password.pem" -out "$CERTS_DIR/ecc_csr_with_password.pem" \
-passin pass:$PASSWORD_ECC_WITH \
-subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL"
echo "Generated ECC CSR with password: ecc_csr_with_password.pem"
# Generate ECC CSR without password, avoiding interactive input
COMMON_NAME="example4.com"
openssl req -new -key "$CERTS_DIR/ecc_private_key_without_password.pem" -out "$CERTS_DIR/ecc_csr_without_password.pem" \
-subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=$COMMON_NAME/emailAddress=$EMAIL"
echo "Generated ECC CSR without password: ecc_csr_without_password.pem"
# Use the ECC private key to sign the certificate
openssl x509 -req -in "$CERTS_DIR/ecc_csr_with_password.pem" -signkey "$CERTS_DIR/ecc_private_key_with_password.pem" -out "$CERTS_DIR/ecc_certificate_with_password.pem" -days 365 -passin pass:$PASSWORD_ECC_WITH
openssl x509 -req -in "$CERTS_DIR/ecc_csr_without_password.pem" -signkey "$CERTS_DIR/ecc_private_key_without_password.pem" -out "$CERTS_DIR/ecc_certificate_without_password.pem" -days 365
echo "Generated ECC certificates"
# Print the generated file paths
echo "RSA Certificate (with password): $CERTS_DIR/rsa_certificate_with_password.pem"
echo "RSA Private Key (with password): $CERTS_DIR/rsa_private_key_with_password.pem"
echo "RSA Certificate (without password): $CERTS_DIR/rsa_certificate_without_password.pem"
echo "RSA Private Key (without password): $CERTS_DIR/rsa_private_key_without_password.pem"
echo "ECC Certificate (with password): $CERTS_DIR/ecc_certificate_with_password.pem"
echo "ECC Private Key (with password): $CERTS_DIR/ecc_private_key_with_password.pem"
echo "ECC Certificate (without password): $CERTS_DIR/ecc_certificate_without_password.pem"
echo "ECC Private Key (without password): $CERTS_DIR/ecc_private_key_without_password.pem"
ssl_password_file
来指定该文件:
user root;
worker_processes 1;
error_log logs/error.log debug;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
#large_client_header_buffers 4 16k;
# Global settings for SSL password file
ssl_password_file /etc/nginx/ssl/password_file.txt;
# Default SSL settings for all server blocks
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Server block for example1.com using RSA certificate with password
server {
listen 443 ssl;
server_name example1.com;
ssl_certificate /etc/nginx/ssl/rsa_certificate_with_password.pem;
ssl_certificate_key /etc/nginx/ssl/rsa_private_key_with_password.pem;
# Other SSL-related settings
#ssl_password_file /etc/nginx/ssl/rsa_password.txt;
location / {
# Custom location settings for example1.com
#root /var/www/html;
#index index.html;
return 200 "This is the response for example3.com\n";
}
}
# Server block for example2.com using RSA certificate without password
server {
listen 443 ssl;
server_name example2.com;
ssl_certificate /etc/nginx/ssl/rsa_certificate_without_password.pem;
ssl_certificate_key /etc/nginx/ssl/rsa_private_key_without_password.pem;
# Other SSL-related settings
#ssl_password_file /etc/nginx/ssl/rsa_password_without.txt;
location / {
# Custom location settings for example2.com
#root /var/www/html;
#index index.html;
return 200 "This is the response for example3.com\n";
}
}
# Server block for example3.com using ECC certificate with password
server {
listen 443 ssl;
server_name example3.com;
ssl_certificate /etc/nginx/ssl/ecc_certificate_with_password.pem;
ssl_certificate_key /etc/nginx/ssl/ecc_private_key_with_password.pem;
# Other SSL-related settings
#ssl_password_file /etc/nginx/ssl/ecc_password.txt;
location / {
# Custom location settings for example3.com
#root /var/www/html;
#index index.html;
return 200 "This is the response for example3.com\n";
}
}
# Server block for example4.com using ECC certificate without password
server {
listen 443 ssl;
server_name example4.com;
ssl_certificate /etc/nginx/ssl/ecc_certificate_without_password.pem;
ssl_certificate_key /etc/nginx/ssl/ecc_private_key_without_password.pem;
# Other SSL-related settings
#ssl_password_file /etc/nginx/ssl/ecc_password_without.txt;
location / {
# Custom location settings for example4.com
#root /var/www/html;
#index index.html;
return 200 "This is the response for example4.com\n";
}
}
}
在这个配置中,NGINX 会在启动时自动读取 /etc/nginx/ssl_password.txt
文件,提取其中的密码,并使用它解锁 server.key
文件,以便加载和使用 SSL 私钥。
验证一下
curl --resolve example1.com:443:127.0.0.1 -H "Host: example1.com" https://example1.com -k -v
curl --resolve example2.com:443:127.0.0.1 -H "Host: example2.com" https://example2.com -k -v
curl --resolve example3.com:443:127.0.0.1 -H "Host: example3.com" https://example3.com -k -v
curl --resolve example4.com:443:127.0.0.1 -H "Host: example4.com" https://example4.com -k -v
以其中一个为例可以看到具体使用的证书信息
[root@iZ8vbd88lmglnbsnad85q3Z nginx-quic]# curl --resolve example1.com:443:127.0.0.1 -H "Host: example1.com" https://example1.com -k -v
* Added example1.com:443:127.0.0.1 to DNS cache
* Hostname example1.com was found in DNS cache
* Trying 127.0.0.1:443...
* Connected to example1.com (127.0.0.1) port 443
* ALPN: curl offers http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / RSASSA-PSS
* ALPN: server accepted http/1.1
* Server certificate:
* subject: C=CN; ST=BEIJING; L=BEIJING; O=test; OU=test-unit; CN=example1.com; emailAddress=email@example.com
* start date: Dec 1 12:54:50 2024 GMT
* expire date: Dec 1 12:54:50 2025 GMT
* issuer: C=CN; ST=BEIJING; L=BEIJING; O=test; OU=test-unit; CN=example1.com; emailAddress=email@example.com
* SSL certificate verify result: self-signed certificate (18), continuing anyway.
* Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/1.x
> GET / HTTP/1.1
> Host: example1.com
> User-Agent: curl/8.6.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
< Server: nginx/1.25.4
< Date: Tue, 03 Dec 2024 13:53:19 GMT
< Content-Type: text/plain
< Content-Length: 38
< Connection: keep-alive
<
This is the response for example3.com
* Connection #0 to host example1.com left intact
安全性注意事项
- 确保
ssl_password_file
文件的权限设置非常严格,因为它包含私钥的密码。如果设置启动用户为 nginx, 可以设置用户限制只有 nginx 用户才能读取该文件。例如,你可以使用以下命令来限制文件权限:chmod 600 /etc/nginx/ssl_password.txt chown nginx:nginx /etc/nginx/ssl_password.txt
小结
–ssl_password_file
是加载加密私钥的有效工具,可提高自动化部署效率。
-确保密码文件权限设置正确,以免泄露私钥密码。
-在部署中建议结合密码管理工具,进一步提升安全性。
Comments are closed.