Nginx配置HTTPS安全连接的完整指南
一、准备工作
1.1 获取SSL证书
购买商业证书:从DigiCert、GeoTrust等机构购买
免费证书:使用Let's Encrypt(推荐)
自签名证书:仅用于测试环境
1.2 安装必要工具
bash
Ubuntu/Debian
sudo apt update
sudo apt install nginx openssl certbot python3-certbot-nginx
CentOS/RHEL
sudo yum install nginx openssl certbot python3-certbot-nginx
二、使用Let's Encrypt获取免费证书
2.1 使用Certbot自动配置
bash
自动获取并配置证书
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
仅获取证书(不修改配置)
sudo certbot certonly --nginx -d yourdomain.com
2.2 手动获取证书
bash
1. 停止Nginx
sudo systemctl stop nginx
2. 使用standalone模式获取证书
sudo certbot certonly --standalone -d yourdomain.com
3. 重新启动Nginx
sudo systemctl start nginx
三、Nginx HTTPS基础配置
3.1 基本HTTPS配置
nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# SSL证书路径
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL会话设置
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# 现代加密套件配置
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:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS (可选但推荐)
add_header Strict-Transport-Security "max-age=63072000" always;
# 其他安全头部
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# 网站根目录
root /var/www/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
3.2 HTTP重定向到HTTPS
nginx
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
# 重定向所有HTTP请求到HTTPS
return 301 https://$server_name$request_uri;
# 或者使用Certbot的推荐方式
# location / {
# return 301 https://$host$request_uri;
# }
}
四、高级安全配置
4.1 OCSP Stapling配置
nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
4.2 更严格的安全配置
nginx
仅使用TLS 1.3(最安全,但可能影响老旧客户端)
ssl_protocols TLSv1.3;
或者使用TLS 1.2及以上
ssl_protocols TLSv1.2 TLSv1.3;
更严格的加密套件
ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256';
DH参数增强(需要生成)
ssl_dhparam /etc/nginx/dhparam.pem;
4.3 生成DH参数
bash
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
五、性能优化
5.1 SSL会话缓存优化
nginx
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_buffer_size 4k;
5.2 启用HTTP/2
nginx
listen 443 ssl http2;
5.3 SSL证书缓存
nginx
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
ssl_session_ticket_key /etc/nginx/ssl_ticket.key;
生成会话票据密钥:
bash
sudo openssl rand 80 > /etc/nginx/ssl_ticket.key
sudo chmod 600 /etc/nginx/ssl_ticket.key
sudo chown nginx:nginx /etc/nginx/ssl_ticket.key
六、多域名配置
6.1 单个服务器块多域名
nginx
server {
listen 443 ssl http2;
server_name domain1.com www.domain1.com domain2.com www.domain2.com;
# 使用通配符证书或SAN证书
ssl_certificate /etc/ssl/certs/wildcard.crt;
ssl_certificate_key /etc/ssl/private/wildcard.key;
# 根据域名设置不同的根目录
if ($host = 'domain1.com') {
set $root_path /var/www/domain1;
}
if ($host = 'domain2.com') {
set $root_path /var/www/domain2;
}
root $root_path;
# ... 其他配置
}
6.2 多个服务器块
nginx
# 域名1
server {
listen 443 ssl http2;
server_name domain1.com www.domain1.com;
ssl_certificate /etc/ssl/domain1/fullchain.pem;
ssl_certificate_key /etc/ssl/domain1/privkey.pem;
root /var/www/domain1;
# ... 其他配置
}
# 域名2
server {
listen 443 ssl http2;
server_name domain2.com www.domain2.com;
ssl_certificate /etc/ssl/domain2/fullchain.pem;
ssl_certificate_key /etc/ssl/domain2/privkey.pem;
root /var/www/domain2;
# ... 其他配置
}
七、证书自动续期
7.1 手动测试续期
bash
sudo certbot renew --dry-run
7.2 设置自动续期
bash
编辑crontab
sudo crontab -e
添加以下行(每周日凌晨2点检查续期)
0 2 * * 0 /usr/bin/certbot renew --quiet && systemctl reload nginx
7.3 强制续期
bash
sudo certbot renew --force-renewal
八、故障排除
8.1 测试SSL配置
bash
使用OpenSSL测试
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
使用在线工具
SSL Labs: https://www.ssllabs.com/ssltest/
SSL Checker: https://www.sslshopper.com/ssl-checker.html
8.2 检查Nginx配置
bash
测试配置文件语法
sudo nginx -t
查看详细错误日志
sudo tail -f /var/log/nginx/error.log
查看访问日志
sudo tail -f /var/log/nginx/access.log
8.3 常见错误解决
错误1:证书路径错误
nginx: [emerg] cannot load certificate "/path/to/cert.pem"
解决:确保证书文件存在且路径正确
错误2:权限问题
nginx: [emerg] BIO_new_file("/path/to/key.pem") failed
解决:确保私钥文件权限为600,且nginx用户有读取权限
bash
sudo chmod 600 /etc/ssl/private/yourdomain.key
sudo chown nginx:nginx /etc/ssl/private/yourdomain.key
错误3:端口冲突
nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
解决:检查是否有其他服务占用443端口
bash
sudo netstat -tulpn | grep :443
九、完整配置示例
nginx
/etc/nginx/sites-available/yourdomain.com
HTTP重定向
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
HTTPS配置
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
SSL证书
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem;
SSL协议和加密套件
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:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
会话设置
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
OCSP Stapling
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=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
根目录和索引
root /var/www/yourdomain.com/html;
index index.html index.htm index.nginx-debian.html;
主location块
location / {
try_files $uri $uri/ =404;
}
静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
禁止访问隐藏文件
location ~ /\. {
deny all;
}
错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
十、部署和验证
1. 保存配置文件
2. 创建符号链接(如果使用sites-available/sites-enabled)
bash
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
3. 测试配置
bash
sudo nginx -t
4. 重载Nginx**
bash
sudo systemctl reload nginx
5. 验证HTTPS
bash
curl -I https://yourdomain.com
安全建议
1. 定期更新证书:设置自动续期
2. 监控证书过期:使用监控工具
3. 保持Nginx更新:定期更新到最新版本
4. 使用安全扫描工具:定期检查配置
5. 备份配置:定期备份SSL证书和Nginx配置
这份指南涵盖了从基础到高级的Nginx HTTPS配置,可根据实际需求调整配置参数。