核心原理、落地实操、进阶优化、全维度防护、排错运维全流程,系统讲解 Nginx HTTPS 部署与安全防护,所有配置均适配生产环境,可直接复用。
一、前置环境准备
1.1 版本与模块要求
表格
| 组件 | 推荐版本 | 核心要求 |
|---|---|---|
| Nginx | 1.24+ 稳定版 | 最低不低于 1.20 LTS,修复 HTTP/2 Rapid Reset 等高危漏洞 |
| OpenSSL | 1.1.1w+ / 3.0+ LTS | 禁用 1.1.1 以下版本(存在 Heartbleed 等高危漏洞) |
| 核心模块 | 必须启用 | http_ssl_module、http_v2_module、http_realip_module、http_limit_conn_module、http_limit_req_module |
1.2 模块检查与安装
-
检查已编译模块:
nginx -V 2>&1 | grep -o with-http_ssl_module
-
无 SSL 模块时重新编译示例:
./configure --with-http_ssl_module --with-http_v2_module
--with-http_realip_module --with-http_limit_conn_module
--with-http_limit_req_module && make && make install
二、HTTPS 部署全流程详细解析
2.1 HTTPS 核心原理
HTTPS = HTTP + TLS/SSL,通过三层机制保障安全:
- 非对称加密:完成密钥协商,解决密钥安全传递问题
- 对称加密:实现传输内容加密,防窃听、防篡改
- 数字证书:完成服务端身份认证,防域名劫持、钓鱼攻击
2.2 SSL/TLS 证书准备
2.2.1 证书选型
| 证书类型 | 适用场景 | 验证级别 | 颁发速度 | 费用 |
|---|---|---|---|---|
| DV 域名验证型 | 个人网站、测试环境 | 仅验证域名所有权 | 分钟级 | 免费(Let's Encrypt 等) |
| OV 组织验证型 | 企业官网、中小业务 | 验证域名 + 企业主体 | 1-3 个工作日 | 付费 |
| EV 扩展验证型 | 金融、电商强信任场景 | 最高级别企业验证 | 3-7 个工作日 | 高额付费 |
2.2.2 证书核心文件说明
- fullchain.pem:证书链文件,包含域名证书 + CA 中间证书,必须完整配置,否则浏览器会报不安全
- privkey.pem :非对称加密私钥,必须严格保密,权限强制设置为
600
2.2.3 免费证书一键申请(Let's Encrypt + acme.sh)
Let's Encrypt 证书有效期 90 天,支持自动续期,适配绝大多数公网业务场景。
# 1. 安装acme.sh
curl https://get.acme.sh | sh -s email=your-email@example.com
# 2. 域名验证(DNS模式支持泛域名,示例为阿里云DNS)
acme.sh --issue --dns dns_ali -d example.com -d *.example.com
# 3. 证书安装到Nginx指定目录,自动配置重载命令
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/privkey.pem \
--fullchain-file /etc/nginx/ssl/fullchain.pem \
--reloadcmd "systemctl reload nginx"
# 4. 自动续期:acme.sh安装后默认自动配置定时任务,无需手动操作
2.2.4 内网自签名证书(仅内网测试用,公网浏览器不信任)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/privkey.pem \
-out /etc/nginx/ssl/fullchain.pem \
-subj "/C=CN/ST=Henan/L=Zhengzhou/O=Test/CN=example.com"
2.3 基础 HTTPS 服务配置
2.3.1 HTTP 强制跳转 HTTPS(80 端口跳转 443)
强制所有 HTTP 请求永久跳转到 HTTPS,兼容 ACME 证书验证。
server {
listen 80;
server_name example.com www.example.com;
# 301永久跳转,保留原请求路径与参数
return 301 https://$server_name$request_uri;
# 兼容ACME证书验证路径
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
}
2.3.2 443 端口 HTTPS 基础配置
server {
listen 443 ssl http2; # 启用HTTPS+HTTP/2,大幅提升传输性能
server_name example.com www.example.com;
# 核心证书配置(必填)
ssl_certificate /etc/nginx/ssl/fullchain.pem; # 证书链文件
ssl_certificate_key /etc/nginx/ssl/privkey.pem; # 私钥文件
# 网站根目录与默认页
root /usr/share/nginx/html;
index index.html index.htm;
# 常规路由配置
location / {
try_files $uri $uri/ =404;
}
}
2.4 HTTPS 进阶安全与性能优化(核心)
以下配置优先放在http块全局生效,也可放在server块针对单域名定制。
2.4.1 TLS 协议与加密套件加固
禁用所有不安全的协议与加密算法,仅保留行业标准安全配置。
# 禁用SSLv3、TLS1.0、TLS1.1,仅启用TLS1.2、TLS1.3
ssl_protocols TLSv1.2 TLSv1.3;
# 优先使用服务端加密套件,禁用客户端弱套件协商
ssl_prefer_server_ciphers on;
# 安全加密套件:优先GCM模式、ECDHE密钥交换,禁用CBC、SHA1等弱算法
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;
# 安全椭圆曲线配置,优先X25519
ssl_ecdh_curve X25519:secp384r1:secp256r1;
2.4.2 HSTS 强制 HTTPS 访问(防降级攻击)
强制浏览器 1 年内仅通过 HTTPS 访问该域名及子域名,彻底杜绝 HTTP 降级攻击。
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
max-age=31536000:HSTS 生效时长 1 年(单位:秒)includeSubDomains:覆盖所有子域名preload:可提交到浏览器 HSTS 预加载列表,彻底禁用 HTTP 访问always:强制所有状态码的响应都携带该头,必加
2.4.3 OCSP Stapling 证书吊销装订
服务端提前获取证书吊销状态,无需客户端单独请求 CA 服务器,提升握手速度 + 保护用户隐私。
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/fullchain.pem; # 信任的CA证书链
# OCSP DNS解析配置
resolver 223.5.5.5 114.114.114.114 valid=300s;
resolver_timeout 5s;
2.4.4 TLS 会话复用(性能优化)
复用 TLS 握手会话,减少 HTTPS 握手耗时,提升页面加载速度。
# 共享会话缓存,10m内存可存储约4万个会话
ssl_session_cache shared:SSL:10m;
# 会话有效期1天
ssl_session_timeout 1d;
# 可选:禁用会话票证(提升安全性,轻微损失性能)
ssl_session_tickets off;
2.4.5 HTTP/3 QUIC 配置(进阶,Nginx 1.25.0 + 支持)
基于 UDP 的 QUIC 协议,进一步降低延迟、提升弱网环境稳定性。
server {
listen 443 quic reuseport;
server_name example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# 通知浏览器支持HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400' always;
}
2.5 HTTPS 配置验证与生效
-
配置语法校验(必须执行,报错先修复,禁止直接重启):
nginx -t
-
重载配置生效(优先重载,不中断业务;仅首次安装用 restart):
systemctl reload nginx
-
功能验证 :浏览器访问
https://example.com,地址栏显示锁标,无安全警告 -
安全评级验证 :使用SSL Labs Server Test检测,目标 A + 评级
-
命令行验证:
openssl s_client -connect example.com:443 -tls1_3
三、Nginx 全维度安全防护详细解析
3.1 基础系统层安全加固
3.1.1 隐藏版本信息,减少攻击面
关闭版本号泄露,避免攻击者针对特定版本漏洞发起攻击。
# http块全局配置,隐藏Nginx版本号
server_tokens off;
# 反向代理场景,隐藏后端服务版本头
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
效果:响应头Server仅显示nginx,无版本号;错误页面也不会泄露版本信息。
3.1.2 最小化运行权限,防止提权攻击
-
创建专用非 root 运行用户:
useradd -s /sbin/nologin -M nginx
-
nginx.conf首行配置运行用户:user nginx nginx;
-
目录权限加固:
- 配置文件:
chmod 640 /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf - 私钥文件:
chmod 600 /etc/nginx/ssl/privkey.pem && chown root:root 私钥文件 - 网站根目录:
chown -R nginx:nginx /usr/share/nginx/html && chmod -R 750 网站目录
- 配置文件:
3.1.3 最小化模块与端口,缩减攻击面
-
编译时禁用无用模块,示例:
./configure --with-http_ssl_module --with-http_v2_module
--without-http_autoindex_module \ # 禁用目录浏览
--without-http_ssi_module \ # 禁用SSI
--without-http_fastcgi_module \ # 不用PHP则禁用
--without-http_uwsgi_module
--without-http_scgi_module -
防火墙仅开放必要端口:firewalld/iptables 仅放行
80/tcp、443/tcp、443/udp(HTTP/3),禁用其他端口 -
关闭服务器上不必要的服务,仅保留 Nginx 相关业务服务
3.2 访问控制与身份认证
3.2.1 IP 黑白名单访问控制
基于ngx_http_access_module实现,可全局 / 单 server / 单 location 配置,示例:后台路径仅允许办公 IP 访问。
location /admin/ {
allow 192.168.1.0/24; # 允许内网段
allow 123.123.123.123; # 允许办公公网IP
deny all; # 禁止其他所有IP
}
3.2.2 HTTP Basic Auth 账号密码认证
针对敏感路径添加二次身份认证,适配后台管理、phpMyAdmin 等场景。
-
安装密码生成工具:
CentOS/RHEL
yum install httpd-tools
Ubuntu/Debian
apt install apache2-utils
-
生成密码文件:
htpasswd -c /etc/nginx/.htpasswd admin # 创建admin用户,按提示输入密码
-
Nginx 配置:
location /admin/ {
auth_basic "Restricted Access"; # 认证提示语
auth_basic_user_file /etc/nginx/.htpasswd; # 密码文件路径
} -
权限加固:
chmod 640 /etc/nginx/.htpasswd && chown root:nginx /etc/nginx/.htpasswd
3.3 Web 攻击防护(SQL 注入、XSS、路径穿越等)
3.3.1 危险请求方法限制
仅允许业务所需的GET/POST/HEAD方法,禁用PUT/DELETE/TRACE/CONNECT等危险方法,防范 XST 跨站跟踪攻击。
# server块中配置
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405 Method Not Allowed;
}
3.3.2 敏感路径与文件访问禁止
# 禁止访问所有隐藏文件(.git/.svn/.env等),防止源码/配置泄露
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 禁止访问敏感后缀文件,防止泄露备份、数据库、脚本文件
location ~* \.(env|ini|sql|bak|log|conf|sh|py)$ {
deny all;
}
# 防路径穿越攻击,过滤../相对路径
if ($request_uri ~* \.\./ ) {
return 403 Forbidden;
}
3.3.3 基础注入与 XSS 攻击过滤
注意:复杂业务场景推荐使用专业 WAF 模块,Nginx 原生 if 指令存在局限性,无法覆盖所有攻击场景。
# 过滤URL参数中的SQL注入关键字
if ($query_string ~* (union|select|insert|delete|update|drop|alter|truncate|exec|script|iframe|onerror)) {
return 403 Forbidden;
}
# 过滤请求中的XSS标签
if ($request_uri ~* (<|>|%3C|%3E)) {
return 403 Forbidden;
}
# 禁止空User-Agent访问(多数攻击工具使用空UA)
if ($http_user_agent ~ "^$") {
return 403 Forbidden;
}
# 禁止恶意爬虫/扫描工具UA
if ($http_user_agent ~* (bot|crawler|spider|scraper|scan|sqlmap|nmap)) {
return 403 Forbidden;
}
3.3.4 专业 WAF 模块部署(推荐)
替代手动规则,实现企业级 Web 攻击防护,主流方案:
- ModSecurity WAF:OWASP 官方推荐的开源 Web 应用防火墙,支持 Nginx,集成 OWASP 核心规则集(CRS),可防御 OWASP Top 10 全类型攻击
- ngx_lua_waf:基于 OpenResty 的轻量级高性能 WAF,支持 IP 黑白名单、URL 过滤、Cookie 过滤、CC 防护等,配置灵活、性能优异
3.4 DDoS/CC 攻击防护
3.4.1 单 IP 并发连接数限制
基于ngx_http_limit_conn_module,限制单个 IP 的最大并发连接数,防范 TCP 连接耗尽攻击。
# http块中定义限流zone,基于客户端IP
limit_conn_zone $binary_remote_addr zone=per_ip_conn:10m;
# server块中生效,限制单个IP最大并发连接数为20,可根据业务调整
limit_conn per_ip_conn 20;
3.4.2 单 IP 请求频率限制(防 CC 核心配置)
基于ngx_http_limit_req_module,限制单个 IP 每秒的请求数,是抵御脚本化 CC 攻击最有效的基础手段。
# http块中定义限流zone,rate=10r/s表示每秒最多10个请求,可根据业务调整
limit_req_zone $binary_remote_addr zone=per_ip_req:10m rate=10r/s;
# server块中生效,burst=20表示突发请求上限,nodelay表示超过阈值直接拒绝
limit_req zone=per_ip_req burst=20 nodelay;
3.4.3 慢连接攻击防护(Slowloris 等)
缩短超时时间,减少半开连接占用服务器资源,防范慢连接 DoS 攻击。
# http块全局配置
client_body_timeout 10s; # 客户端请求体超时
client_header_timeout 10s; # 客户端请求头超时
keepalive_timeout 5s; # 长连接超时,默认75s,缩短为5s
send_timeout 10s; # 服务端发送数据超时
# 限制单个长连接的最大请求数
keepalive_requests 100;
3.4.4 其他攻击防护
-
大文件上传攻击防护:限制请求体最大大小
client_max_body_size 10m; # 普通网站建议10m以内,根据业务调整
-
HTTP/2 Rapid Reset 攻击防护:升级 Nginx 到 1.21.6 + 稳定版,添加配置
http2_max_concurrent_streams 100;
http2_max_requests 100;
3.5 安全响应头配置(防前端攻击)
所有配置均添加always参数,确保所有状态码的响应都携带头信息,全局配置在http块中。
# 1. 防点击劫持,禁止恶意网站iframe嵌套,SAMEORIGIN仅允许同域名嵌套,DENY完全禁止
add_header X-Frame-Options "SAMEORIGIN" always;
# 2. 防MIME类型嗅探,禁止浏览器自动解析文件类型,防范恶意文件执行
add_header X-Content-Type-Options "nosniff" always;
# 3. XSS防护,浏览器启用XSS过滤并拦截恶意页面
add_header X-XSS-Protection "1; mode=block" always;
# 4. 内容安全策略CSP,限制资源加载,是防XSS最有效的手段(根据业务调整规则)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self';" always;
# 5. Referrer策略,控制Referer信息传递,保护用户隐私
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 6. 权限控制,禁用不必要的浏览器API
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
3.6 日志审计与应急响应
3.6.1 日志规范配置
自定义日志格式,记录全量访问信息,方便攻击溯源与问题排查。
# http块中配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time';
# 开启访问日志与错误日志
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
3.6.2 日志自动轮转
配置logrotate自动轮转日志,防止日志占满磁盘,留存 30 天日志用于溯源。
# /etc/logrotate.d/nginx 配置文件
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 640 nginx nginx
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
3.6.3 攻击溯源与审计
- 定期审计日志,筛选 403、404、503 状态码的异常请求,识别攻击行为
- 针对异常 IP,查看请求路径与参数,确认攻击类型,及时拉黑
- 配合 ELK 等日志分析平台,实现可视化监控与异常告警
3.7 持续安全运维规范
- 版本升级:关注 Nginx、OpenSSL 官方安全公告,及时升级到最新稳定版,修复高危漏洞
- 漏洞扫描:定期使用 Nessus、AWVS 等工具扫描 Web 服务漏洞,及时修复
- 配置备份:定期备份 Nginx 配置文件与 SSL 证书,防止配置丢失
- 权限巡检:定期检查目录、文件、证书的权限,避免权限过大导致的安全风险
- 证书监控:监控 SSL 证书有效期,提前续期,避免证书过期导致服务不可用
四、生产环境完整配置示例
4.1 全局 nginx.conf 配置
user nginx nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;
# 核心性能配置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 超时配置(防慢连接攻击)
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 5s;
send_timeout 10s;
keepalive_requests 100;
# 基础安全配置
server_tokens off;
client_max_body_size 10m;
# HTTPS全局安全配置
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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_ecdh_curve X25519:secp384r1:secp256r1;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 223.5.5.5 114.114.114.114 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;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# CC/DDOS限流配置
limit_conn_zone $binary_remote_addr zone=per_ip_conn:10m;
limit_req_zone $binary_remote_addr zone=per_ip_req:10m rate=10r/s;
# 包含子配置文件
include /etc/nginx/conf.d/*.conf;
}
4.2 单域名 server 配置(/etc/nginx/conf.d/example.com.conf)
# HTTP强制跳转HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
}
# HTTPS主服务
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# 证书配置
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_trusted_certificate /etc/nginx/ssl/fullchain.pem;
# 网站根目录
root /usr/share/nginx/html;
index index.html index.htm;
# 限流配置
limit_conn per_ip_conn 20;
limit_req zone=per_ip_req burst=20 nodelay;
# 危险请求方法限制
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405 Method Not Allowed;
}
# 防路径穿越
if ($request_uri ~* \.\./ ) {
return 403 Forbidden;
}
# 禁止空UA
if ($http_user_agent ~ "^$") {
return 403 Forbidden;
}
# 常规路由
location / {
try_files $uri $uri/ =404;
}
# 后台路径IP白名单+密码认证
location /admin/ {
allow 123.123.123.123;
deny all;
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# 禁止访问隐藏文件与敏感文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location ~* \.(env|ini|sql|bak|log|conf|sh)$ {
deny all;
}
}
五、常见问题与排错指南
5.1 HTTPS 相关常见问题
-
浏览器报 "您的连接不是私密连接"
- 常见原因:证书链不完整(未用 fullchain.pem)、证书域名与访问域名不匹配、证书过期、系统时间错误
- 排查:执行
openssl s_client -connect example.com:443查看证书信息,确认证书链、有效期、域名
-
HTTPS 配置后 Nginx 启动失败
- 常见原因:证书路径错误、私钥权限过大(非 600)、SELinux 限制、ssl 模块未启用
- 排查:先执行
nginx -t查看具体报错,检查证书路径与权限,关闭 SELinux 或配置正确的上下文
-
HSTS 配置后无法访问 HTTP
- 正常现象:HSTS 会强制浏览器使用 HTTPS,如需恢复,先清除浏览器 HSTS 缓存,再修改
max-age=0重载配置
- 正常现象:HSTS 会强制浏览器使用 HTTPS,如需恢复,先清除浏览器 HSTS 缓存,再修改
5.2 安全防护相关常见问题
-
限流配置不生效
- 常见原因:
limit_req_zone定义在 server 块中(必须定义在 http 块)、zone 名称不匹配、配置未重载 - 排查:
nginx -t检查语法,确认 zone 定义在 http 块,执行systemctl reload nginx
- 常见原因:
-
安全响应头不生效
- 常见原因:未加
always参数(仅 2xx/3xx 响应携带)、配置在 location 块中被覆盖 - 解决:添加
always参数,全局安全头统一配置在 http 块中
- 常见原因:未加
-
反向代理获取不到客户端真实 IP
-
常见原因:未配置 X-Real-IP/X-Forwarded-For 头、多层代理未正确传递 IP
-
解决:添加以下配置到反向代理 location 中
proxy_set_header X-Real-IP remote_addr; proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for;
proxy_set_header Host $host;
-
六、最佳实践总结
- 安全优先:HTTPS 部署必须使用完整证书链、禁用不安全 TLS 版本与加密套件、启用 HSTS,目标 SSL Labs A + 评级
- 最小化原则:最小化运行权限、最小化开放端口、最小化启用模块,最大程度缩减攻击面
- 纵深防御:基础配置 + 访问控制 + 限流防护 + WAF 模块 + 安全头 + 日志审计,构建多层防护体系,避免单点失效
- 持续运维:定期升级版本、监控证书有效期、审计日志、漏洞扫描,持续修复安全风险
- 性能平衡:在保障安全的前提下,通过 HTTP/2、会话复用、OCSP 装订等优化 HTTPS 访问性能