深入理解 Nginx HTTPS 配置与安全加固
本文是 Nginx 实操专栏的第四篇,我们将深入探讨 HTTPS 配置、SSL/TLS 优化以及安全加固措施,帮助你构建更加安全可靠的 Web 服务。
引言
随着网络安全意识的不断提高,HTTPS 已经成为现代网站的标准配置。Nginx 作为流行的 Web 服务器和反向代理,提供了强大的 SSL/TLS 支持。在本文中,我们将详细介绍如何在 Nginx 中配置 HTTPS,优化 SSL/TLS 性能,并实施各种安全加固措施。
SSL/TLS 基础知识
在深入配置之前,我们需要了解一些 SSL/TLS 的基础知识。
什么是 SSL/TLS?
SSL(Secure Sockets Layer)和它的继任者 TLS(Transport Layer Security)是用于在网络上提供通信安全的加密协议。它们通过以下方式保护数据:
- 加密传输数据 - 防止窃听
- 验证服务器身份 - 防止中间人攻击
- 保证数据完整性 - 防止篡改
证书类型
- 域名验证证书(DV) - 验证域名所有权
- 组织验证证书(OV) - 验证域名所有权和组织信息
- 扩展验证证书(EV) - 最严格的验证,显示绿色地址栏
基本 HTTPS 配置
获取 SSL 证书
首先,你需要获取 SSL 证书。有几种方式可以获得证书:
- 购买商业证书 - 从受信任的证书颁发机构购买
- Let's Encrypt - 免费的自动化证书颁发机构
- 自签名证书 - 仅用于测试环境
使用 Let's Encrypt 获取证书的示例:
# 安装 Certbot
sudo apt install certbot python3-certbot-nginx
# 获取证书
sudo certbot --nginx -d example.com -d www.example.com基本 HTTPS 服务器配置
server {
# 监听 HTTPS 端口
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# SSL 证书文件路径
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/private.key;
# 网站根目录
root /var/www/example.com;
index index.html;
# 其他配置...
}HTTP 重定向到 HTTPS
为了确保所有流量都通过 HTTPS 传输,我们需要将 HTTP 请求重定向到 HTTPS:
# HTTP 服务器块 - 重定向到 HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# 永久重定向到 HTTPS
return 301 https://$server_name$request_uri;
}SSL/TLS 优化配置
协议版本和加密套件
为了平衡安全性和兼容性,我们需要选择合适的协议版本和加密套件:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/private.key;
# 支持的协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# 加密套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384;
# 优先使用服务器定义的加密套件
ssl_prefer_server_ciphers off;
# 启用会话复用
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 启用 OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
}Diffie-Hellman 参数
为了增强前向安全性,建议使用自定义的 Diffie-Hellman 参数:
# 生成 DH 参数文件(可能需要较长时间)
openssl dhparam -out /etc/nginx/dhparam.pem 2048然后在 Nginx 配置中引用:
ssl_dhparam /etc/nginx/dhparam.pem;HTTP/2 支持
HTTP/2 提供了更好的性能,但只能在 HTTPS 下使用:
listen 443 ssl http2;安全加固措施
安全头设置
通过设置适当的安全头,可以增强网站的安全性:
server {
listen 443 ssl http2;
server_name example.com;
# 隐藏服务器版本信息
server_tokens off;
# 防止点击劫持
add_header X-Frame-Options DENY;
# 防止 MIME 类型嗅探
add_header X-Content-Type-Options nosniff;
# 启用 XSS 过滤
add_header X-XSS-Protection "1; mode=block";
# 强制 HTTPS(HSTS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'";
# 引用策略
add_header Referrer-Policy "strict-origin-when-cross-origin";
}强制 HTTPS(HSTS)
HTTP Strict Transport Security (HSTS) 告诉浏览器只能通过 HTTPS 访问网站:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;参数说明:
max-age- 指定时间内浏览器应只使用 HTTPSincludeSubDomains- 包括所有子域名preload- 可选,表示希望加入浏览器预加载列表
防止协议降级攻击
通过设置适当的 TLS 配置防止协议降级攻击:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;性能优化
SSL 会话复用
启用 SSL 会话复用可以减少握手开销:
# SSL 会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 票据会话复用(TLS 1.3)
ssl_session_tickets on;OCSP Stapling
OCSP Stapling 可以提高证书验证速度:
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;内容压缩
虽然启用了 HTTP/2,但仍可以使用 gzip 压缩:
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;高级配置示例
多域名 SNI 支持
Server Name Indication (SNI) 允许在同一个 IP 地址上托管多个 HTTPS 网站:
# 网站 A
server {
listen 443 ssl http2;
server_name sitea.com;
ssl_certificate /path/to/sitea.crt;
ssl_certificate_key /path/to/sitea.key;
root /var/www/sitea;
}
# 网站 B
server {
listen 443 ssl http2;
server_name siteb.com;
ssl_certificate /path/to/siteb.crt;
ssl_certificate_key /path/to/siteb.key;
root /var/www/siteb;
}客户端证书认证
对于需要更高安全性的应用,可以要求客户端证书:
server {
listen 443 ssl;
server_name secure.example.com;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
# 要求客户端证书
ssl_client_certificate /path/to/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
location / {
# 可以通过变量访问客户端证书信息
add_header X-Client-CN $ssl_client_s_dn;
}
}通配符证书配置
使用通配符证书可以简化多子域名的配置:
server {
listen 443 ssl http2;
server_name *.example.com;
ssl_certificate /path/to/wildcard.crt;
ssl_certificate_key /path/to/wildcard.key;
# 根据子域名提供不同内容
location / {
root /var/www/$host;
}
}监控和故障排除
SSL 错误日志
配置专门的 SSL 错误日志:
error_log /var/log/nginx/ssl_error.log debug;测试 SSL 配置
使用在线工具测试 SSL 配置:
或者使用命令行工具:
# 测试 SSL 连接
openssl s_client -connect example.com:443
# 检查证书信息
echo | openssl s_client -showcerts -connect example.com:443 2>/dev/null | openssl x509 -inform pem -noout -text最佳实践总结
1. 证书管理
# 使用完整的证书链
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/private.key;
# 设置正确的文件权限
# chmod 600 /path/to/private.key
# chmod 644 /path/to/fullchain.pem2. 安全配置
# 禁用不安全的协议和加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE+AESGCM:ECDHE+CHACHA20:!aNULL:!MD5:!DSS;
# 启用安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;3. 性能优化
# 启用会话复用
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 启用 OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;自动化证书管理
使用 Certbot 自动续期
# 测试续期
sudo certbot renew --dry-run
# 设置定时任务自动续期
# 添加到 crontab: 0 12 * * * /usr/bin/certbot renew --quiet使用 acme.sh
# 安装 acme.sh
curl https://get.acme.sh | sh
# 获取证书
acme.sh --issue -d example.com -w /var/www/html
# 安装证书到 Nginx
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "service nginx force-reload"总结
通过合理的 HTTPS 配置和安全加固措施,我们可以显著提高网站的安全性。关键要点包括:
- 使用强加密协议和加密套件
- 正确配置证书和私钥
- 实施必要的安全头
- 启用性能优化功能
- 定期更新和续期证书
在下一章中,我们将探讨 Nginx 的负载均衡功能,帮助你构建高可用的 Web 应用架构。
要点回顾:
- HTTPS 配置需要有效的 SSL 证书
- 合理选择协议版本和加密套件以平衡安全性和兼容性
- 通过安全头增强网站安全性
- 启用性能优化功能如会话复用和 OCSP Stapling
- 定期管理和更新 SSL 证书