1. Nginx HTTPS 部署实战指南
作为一名长期从事Web服务运维的工程师,我深知HTTPS部署和安全防护的重要性。每次接手新的Web项目,我都会优先考虑如何构建一个既安全又高效的HTTPS环境。下面我将分享一套经过实战检验的Nginx HTTPS配置方案,这些配置可以直接用于生产环境,帮助您快速搭建安全的Web服务。
HTTPS不仅能够加密数据传输,防止敏感信息被窃取,还能提升网站在搜索引擎中的排名。现代浏览器对非HTTPS网站会显示"不安全"警告,这直接影响用户体验和网站可信度。通过本文的配置,您将获得一个符合现代安全标准的HTTPS服务,同时还能防御常见的Web攻击。
2. HTTPS核心配置详解
2.1 HTTP强制跳转HTTPS
在配置HTTPS之前,我们需要确保所有HTTP请求都能自动跳转到HTTPS。这个配置看似简单,但有几个关键点需要注意:
nginx复制server {
listen 80;
server_name example.com; # 替换为您的实际域名
return 301 https://$host$request_uri; # 永久跳转,保留请求路径
}
这段配置有几个值得注意的地方:
- 使用301永久重定向,有利于SEO优化
$host变量会自动匹配请求的域名,适用于多域名场景$request_uri保留了原始请求的路径和参数
提示:在生产环境中,建议先配置好HTTPS并测试通过后再启用这个跳转,避免服务不可用。
2.2 HTTPS基础安全配置
下面是一个完整的HTTPS服务器配置模板,包含了安全加固的关键参数:
nginx复制server {
listen 443 ssl http2; # 开启SSL和HTTP/2
server_name example.com;
# 证书路径配置
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# 安全协议与加密套件
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 on;
# 会话优化
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# 安全响应头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" 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;
}
这个配置中几个关键安全设置的解释:
- TLS协议选择:仅启用TLS 1.2和1.3,禁用不安全的旧版本
- 加密套件:使用ECDHE密钥交换和AES-GCM加密算法,提供前向安全性
- HSTS头:强制浏览器使用HTTPS连接,有效期1年,包含子域名
- 安全响应头:防御点击劫持、MIME类型混淆和XSS攻击
3. Nginx安全防护进阶配置
3.1 基础安全加固
除了HTTPS配置外,Nginx本身也需要进行安全加固:
nginx复制# 隐藏Nginx版本号
http {
server_tokens off;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
}
# 上传目录禁止执行脚本
location /uploads/ {
location ~ \.(php|pl|py|jsp|asp|sh|cgi)$ {
deny all;
}
}
这些配置的作用:
- 隐藏版本号防止攻击者利用特定版本漏洞
- 禁止访问.git、.env等敏感隐藏文件
- 防止上传目录中的脚本文件被执行
3.2 防CC攻击配置
针对CC(Challenge Collapsar)攻击,我们可以配置请求频率限制:
nginx复制# 定义请求限制区域
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
# 应用请求限制
limit_req zone=req_limit burst=20 nodelay;
}
参数说明:
10m:共享内存区域大小,可存储约16万个IP状态10r/s:每个IP每秒允许的请求数burst=20:允许突发20个请求nodelay:突发请求不延迟处理
3.3 恶意请求过滤
我们可以通过识别User-Agent和请求路径来拦截恶意扫描:
nginx复制# 屏蔽恶意User-Agent
if ($http_user_agent ~* (sqlmap|nikto|python|scrapy|java|wget|curl)) {
return 403;
}
# 屏蔽敏感路径
location ~* (phpinfo|info\.php|test\.php|admin|wp-admin) {
return 403;
}
这些规则可以拦截常见的漏洞扫描工具和敏感路径访问,但需要注意:
- 不要过度拦截,避免影响正常用户
- 根据业务特点调整规则
- 定期更新规则以应对新的威胁
4. SSL证书管理
4.1 证书检查脚本
维护HTTPS服务时,证书过期是常见问题。下面这个脚本可以检查证书有效期:
bash复制#!/bin/bash
# 检查是否传入域名参数
if [ $# -ne 1 ]; then
echo "用法: $0 域名"
exit 1
fi
domain=$1
# 获取证书信息
echo "===== $domain SSL 证书信息 ====="
echo | openssl s_client -servername $domain -connect $domain:443 2>/dev/null | openssl x509 -noout -dates
# 计算剩余天数
not_after=$(echo | openssl s_client -servername $domain -connect $domain:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
expire=$(date -d "$not_after" +%s)
now=$(date +%s)
left=$(( (expire - now) / 86400 ))
echo "证书剩余有效天数:$left 天"
# 预警提示
if [ $left -lt 30 ]; then
echo "警告:证书即将在${left}天后过期!"
fi
使用方法:
bash复制chmod +x check_ssl.sh
./check_ssl.sh example.com
4.2 证书自动续期
对于Let's Encrypt等免费证书,建议设置自动续期:
bash复制# 使用certbot自动续期
certbot renew --quiet --no-self-upgrade --post-hook "systemctl reload nginx"
可以将此命令加入crontab,实现自动续期:
bash复制0 3 * * * /usr/bin/certbot renew --quiet --no-self-upgrade --post-hook "systemctl reload nginx"
5. 部署与验证
5.1 配置检查与生效
在修改Nginx配置后,务必执行以下步骤:
bash复制# 检查配置语法
nginx -t
# 重新加载配置
systemctl reload nginx
如果遇到问题,可以查看错误日志:
bash复制tail -f /var/log/nginx/error.log
5.2 安全评级测试
部署完成后,建议使用以下工具测试HTTPS配置的安全等级:
-
SSL Labs测试:https://www.ssllabs.com/ssltest/
- 目标评级应为A+
- 检查是否存在不安全的协议或加密套件
-
Security Headers测试:https://securityheaders.com/
- 检查安全响应头是否配置正确
- 目标评级应为A+
-
Mozilla Observatory:https://observatory.mozilla.org/
- 全面的Web安全测试
- 根据建议优化配置
6. 性能优化建议
6.1 SSL会话复用
通过会话复用可以减少SSL握手开销:
nginx复制ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off; # 使用更安全的会话缓存
6.2 OCSP Stapling
启用OCSP Stapling可以提升SSL握手速度:
nginx复制ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
6.3 HTTP/2优化
HTTP/2可以显著提升页面加载速度:
nginx复制listen 443 ssl http2;
启用HTTP/2后,建议:
- 启用SSL优化参数
- 调整SSL缓冲区大小
- 禁用旧版TLS协议
7. 常见问题排查
7.1 证书链不完整
症状:某些客户端无法建立SSL连接
解决:确保证书文件包含完整的证书链
7.2 混合内容警告
症状:HTTPS页面加载HTTP资源
解决:确保所有资源都使用HTTPS加载
7.3 HSTS预加载
考虑将域名加入HSTS预加载列表:
https://hstspreload.org/
7.4 性能问题
如果SSL握手影响性能,可以:
- 启用会话复用
- 使用更快的加密算法
- 考虑使用TLS 1.3
在实际运维中,我发现很多安全问题都源于配置不当或疏忽。这套配置方案经过多个生产环境验证,能够提供良好的安全性和性能。建议定期检查SSL配置和安全性,保持与最新安全标准同步。