前言
Nginx 是当今互联网上使用最广泛的 Web 服务器之一,全球超过 30% 的网站运行在 Nginx 上。对于个人站长来说,Nginx 不仅是高性能的反向代理工具,更是网站安全的第一道防线。一个配置不当的 Nginx 可能导致网站被黑、数据泄露或被 DDoS 攻击打垮。本文从实战角度出发,系统讲解 Nginx 的安全加固和性能优化配置,每一条配置都有具体的背景说明和使用场景。
一、HTTPS 配置最佳实践
Let's Encrypt 让免费 SSL 证书成为可能,如今还有 ZeroSSL 和 Cloudflare 等更多选择。HTTPS 已经不再是可选项,而是所有网站的标配。
自动续签 SSL 证书
使用 acme.sh 脚本可以完全自动化证书申请和续签:
# 安装 acme.sh
curl https://get.acme.sh | sh
# 申请证书(DNS 模式支持通配符)
acme.sh --issue --dns dns_cf -d zz1984.com -d *.zz1984.com
# 安装证书到 Nginx
acme.sh --install-cert -d zz1984.com --key-file /etc/nginx/ssl/zz1984.com.key --fullchain-file /etc/nginx/ssl/zz1984.com.crt设置自动续签的 crontab 任务:
0 3 * * * /root/.acme.sh/acme.sh --cron --home /root/.acme.sh > /dev/nullNginx SSL 配置模板
server {
listen 443 ssl http2;
server_name zz1984.com;
ssl_certificate /etc/nginx/ssl/zz1984.com.crt;
ssl_certificate_key /etc/nginx/ssl/zz1984.com.key;
# 仅允许安全的 TLS 协议和加密套件
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;
# 开启 HSTS(告诉浏览器永远使用 HTTPS)
add_header Strict-Transport-Security "max-age=63072000" always;
# SSL 会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# OSCP Stapling(提升证书验证速度)
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;
}二、安全防护配置
屏蔽恶意请求
# 屏蔽常见的扫描工具和爬虫
if ($http_user_agent ~* (sqlmap|nikto|nmap|masscan|zgrab|acunetix|netscan|python-requests|Go-http-client)) {
return 444;
}
# 屏蔽恶意 IP 段
deny 10.0.0.0/8;
deny 172.16.0.0/12;
deny 192.168.0.0/16;限制请求频率(防 CC 攻击)
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server {
# 全局限流
location / {
limit_req zone=one burst=20 nodelay;
}
# 登录接口单独限流
location /login {
limit_req zone=login burst=3 nodelay;
}
}隐藏 Nginx 版本号
server_tokens off;这条配置虽然简单,但非常有效。黑客在发起攻击前通常会扫描目标的 Nginx 版本号,寻找已知漏洞。隐藏版本号可以增加攻击者的成本。
限制请求正文大小
# 限制上传文件大小为 10MB
client_max_body_size 10m;这条配置可以防止恶意用户通过上传超大文件耗尽服务器资源。
三、防盗链配置
防止图片被第三方网站盗用
location ~ \.(jpg|jpeg|png|gif|webp|bmp|ico)$ {
valid_referers none blocked server_names
~\.zz1984\.com
~\.baidu\.com
~\.google\.com;
if ($invalid_referer) {
return 403;
}
expires 30d;
add_header Cache-Control "public, no-transform";
}注意:none 参数表示允许直接访问(如从浏览器地址栏输入 URL 访问),blocked 允许缺少 Referer 头的请求(如微信内置浏览器)。如果希望严格到只有自己的页面才能引用图片,可以去掉 none blocked。
通过 Referer 防盗链的局限性
Referer 防盗链是最基础的手段,但容易被伪造。对于价值较高的资源,建议配合 Token 鉴权或自建 CDN 的 Referer 白名单功能。
四、性能优化配置
开启 Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff
font/woff2;Gzip 可以将文本类资源的传输体积减少 60%-80%,是最简单且最有效的性能优化手段。压缩级别建议设为 6,太高(9)收益微乎其微但 CPU 消耗翻倍。
浏览器缓存控制
# 静态资源长期缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# HTML 页面不缓存或短缓存
location ~* \.html$ {
expires 5m;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}对于资源文件(图片、CSS、JS),强烈建议在文件名中加入版本号或哈希值,这样更新时可以直接替换,不需要用户手动清除缓存。
开启 HTTP/2 和 HTTP/3
# HTTP/2 在 listen 指令中开启(已在 SSL 配置中写了 http2)
# HTTP/3 需要编译时支持 quiche 或使用 Cloudflare 等 CDN
listen 443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400';HTTP/2 支持多路复用,可以同时发送多个请求而不需要等待响应,消除了 HTTP/1.1 的队头阻塞问题。HTTP/3 基于 QUIC 协议,进一步减少了连接建立延迟。
连接池优化
keepalive_timeout 65;
keepalive_requests 100;保持连接复用可以减少 TCP 握手的开销。对于高并发场景,适当增加 keepalive_requests 的值可以让 Nginx 更充分地利用已建立的连接。
调整 Worker 进程数
worker_processes auto;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 10240;
multi_accept on;
}worker_processes auto 会自动设置为 CPU 核心数。worker_connections 乘以进程数就是 Nginx 能同时处理的最大连接数。在 Linux 上使用 epoll 事件模型可以获得最佳性能。
五、日志优化与安全审计
日志格式定制
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $request_time $upstream_response_time';
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
error_log /var/log/nginx/error.log warn;加入 $request_time 和 $upstream_response_time 可以帮助你快速定位慢请求。
日志轮转
在 /etc/logrotate.d/nginx 中配置日志轮转:
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
/usr/sbin/nginx -s reload
endscript
}日志轮转可以防止日志文件无限膨胀撑爆磁盘。建议保留 30 天的日志,日常排查够用,又不会占用太多空间。
六、使用 CDN 加速
通过 Nginx 反向代理到 CDN
upstream cdn_backend {
server cdn.zz1984.com:443;
keepalive 64;
}
location /static/ {
proxy_pass https://cdn_backend;
proxy_set_header Host cdn.zz1984.com;
# 如果 CDN 故障,回源到本地
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_next_upstream_tries 3;
proxy_connect_timeout 5s;
}使用 Cloudflare
对于面向国内用户的网站,Cloudflare 的免费 CDN 速度可能不够理想,但它的安全防护(WAF、DDoS 防护)依然是顶级水准。推荐用 Cloudflare + 国内 CDN 的组合方案:Cloudflare 做安全过滤,国内 CDN 做加速。
七、配置检查与监控
配置检查
每次修改配置后,一定要先检查再 reload:
nginx -t
# 输出:syntax is ok 且 test is successful 才能执行 reload
nginx -s reload使用 Nginx Amplify 监控
Datadog 和 Nginx Amplify 都提供了 Nginx 的监控面板,可以实时查看 QPS、连接数、响应时间等关键指标。对于个人站长来说,Nginx Amplify 的免费额度已经足够使用。
总结
Nginx 的配置优化是一个持续迭代的过程,不存在一套通用的「最佳配置」适用于所有场景。本文提供的配置模板可以作为起点,在实际运营中根据网站的流量特征、内容类型和服务器硬件进行调整。建议每个月 review 一次 Nginx 配置,检查是否有安全漏洞的更新(比如 OpenSSL 的 CVE 公告),并根据流量趋势调整限流和缓存参数。Web 安全是持久战,保持配置的持续更新比一步到位的「完美配置」更重要。