Nginx SSL/HTTPS配置 #
一、SSL/TLS概述 #
1.1 什么是SSL/TLS #
SSL(Secure Sockets Layer)和TLS(Transport Layer Security)是用于在网络上提供安全通信的加密协议。HTTPS即HTTP over TLS,通过TLS加密HTTP通信。
1.2 TLS版本 #
| 版本 | 发布年份 | 状态 |
|---|---|---|
| SSL 2.0 | 1995 | 已弃用 |
| SSL 3.0 | 1996 | 已弃用 |
| TLS 1.0 | 1999 | 已弃用 |
| TLS 1.1 | 2006 | 已弃用 |
| TLS 1.2 | 2008 | 推荐 |
| TLS 1.3 | 2018 | 最佳 |
二、证书获取 #
2.1 Let’s Encrypt免费证书 #
使用Certbot获取免费证书:
bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot certonly --nginx -d example.com
sudo certbot renew --dry-run
2.2 自动续期 #
Certbot会自动添加续期任务:
bash
sudo systemctl status certbot.timer
sudo crontab -e
添加定时任务:
text
0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
2.3 商业证书 #
购买商业证书后,通常获得以下文件:
- 证书文件(.crt/.pem)
- 私钥文件(.key)
- 中间证书(CA Bundle)
三、基本HTTPS配置 #
3.1 最简配置 #
nginx
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/example.com;
index index.html;
}
3.2 完整HTTPS配置 #
nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
四、HTTP到HTTPS重定向 #
4.1 简单重定向 #
nginx
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
}
4.2 通用重定向 #
nginx
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
4.3 www重定向 #
nginx
server {
listen 80;
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
}
五、SSL参数详解 #
5.1 协议配置 #
nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
5.2 推荐密码套件 #
TLS 1.2+推荐:
nginx
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
兼容性优先:
nginx
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA;
5.3 DH参数 #
生成DH参数:
bash
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
配置:
nginx
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
5.4 会话配置 #
nginx
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_session_cache builtin:1000 shared:SSL:10m;
| 参数 | 说明 |
|---|---|
| shared:SSL:10m | 共享缓存,10MB约存储40000个会话 |
| builtin:1000 | 内置缓存,存储1000个会话 |
| ssl_session_timeout | 会话超时时间 |
| ssl_session_tickets | 会话票据(建议关闭) |
六、OCSP装订 #
6.1 启用OCSP装订 #
nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
6.2 OCSP说明 #
OCSP(Online Certificate Status Protocol)装订可以让服务器预先获取证书状态,减少客户端验证时间。
七、HSTS配置 #
7.1 基本HSTS #
nginx
add_header Strict-Transport-Security "max-age=31536000" always;
7.2 完整HSTS #
nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
| 参数 | 说明 |
|---|---|
| max-age | 有效期(秒) |
| includeSubDomains | 包含子域名 |
| preload | 允许加入浏览器预加载列表 |
7.3 HSTS预加载 #
访问 hstspreload.org 提交域名。
八、安全头配置 #
8.1 完整安全头 #
nginx
server {
listen 443 ssl;
server_name example.com;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:;" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
}
8.2 安全头说明 #
| 头 | 说明 |
|---|---|
| Strict-Transport-Security | 强制HTTPS |
| X-Frame-Options | 防止点击劫持 |
| X-Content-Type-Options | 防止MIME类型嗅探 |
| X-XSS-Protection | XSS保护 |
| Referrer-Policy | Referer策略 |
| Content-Security-Policy | 内容安全策略 |
| Permissions-Policy | 权限策略 |
九、证书链配置 #
9.1 证书链顺序 #
正确的证书链顺序:
- 服务器证书
- 中间证书
- 根证书(可选)
9.2 合并证书 #
bash
cat server.crt intermediate.crt > fullchain.pem
9.3 验证证书链 #
bash
openssl verify -CAfile chain.pem server.crt
openssl s_client -connect example.com:443 -showcerts
十、多证书配置 #
10.1 多域名证书 #
nginx
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
}
server {
listen 443 ssl;
server_name blog.example.com;
ssl_certificate /etc/nginx/ssl/blog.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/blog.example.com.key;
}
10.2 SNI配置 #
Nginx支持SNI(Server Name Indication),可以在同一IP上配置多个证书:
nginx
server {
listen 443 ssl;
server_name site1.example.com;
ssl_certificate /etc/nginx/ssl/site1.crt;
ssl_certificate_key /etc/nginx/ssl/site1.key;
}
server {
listen 443 ssl;
server_name site2.example.com;
ssl_certificate /etc/nginx/ssl/site2.crt;
ssl_certificate_key /etc/nginx/ssl/site2.key;
}
十一、客户端证书认证 #
11.1 基本配置 #
nginx
server {
listen 443 ssl;
server_name secure.example.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
}
11.2 可选认证 #
nginx
ssl_verify_client optional;
location / {
if ($ssl_client_verify != SUCCESS) {
return 403;
}
proxy_pass http://backend;
}
11.3 传递客户端证书信息 #
nginx
location / {
proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
proxy_set_header X-SSL-Client-S-DN $ssl_client_s_dn;
proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
proxy_pass http://backend;
}
十二、SSL变量 #
12.1 常用SSL变量 #
nginx
$ssl_protocol
$ssl_cipher
$ssl_server_name
$ssl_client_fingerprint
$ssl_client_verify
$ssl_client_s_dn
$ssl_client_i_dn
$ssl_session_id
$ssl_session_reused
12.2 日志记录SSL信息 #
nginx
log_format ssl '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'ssl_protocol=$ssl_protocol ssl_cipher=$ssl_cipher';
十三、SSL测试 #
13.1 测试工具 #
13.2 命令行测试 #
bash
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
nmap --script ssl-enum-ciphers -p 443 example.com
十四、完整配置示例 #
nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
十五、总结 #
本章我们学习了:
- SSL/TLS基础:协议版本和选择
- 证书获取:Let’s Encrypt和商业证书
- 基本配置:证书路径和参数
- HTTP重定向:强制HTTPS
- 安全参数:协议、密码套件、DH参数
- OCSP装订:提升证书验证速度
- HSTS配置:强制HTTPS策略
- 安全头:完整的安全头配置
- 客户端证书:双向认证
掌握SSL/HTTPS配置后,让我们进入下一章,学习缓存配置!
最后更新:2026-03-27