9.1 核心概念
- 限流(Rate Limiting)
- 限制单位时间内某来源的请求数,抵御暴力破解、爬虫、CC 攻击。Nginx 用漏桶算法平滑放行。
- limit_req
- 基于请求速率的限流,如"每 IP 每秒最多 10 个请求"。用
limit_req_zone定义规则,limit_req应用。 - limit_conn
- 限制单个来源的并发连接数,防止一个客户端占用过多连接(如慢速攻击、大量下载)。
- allow / deny
- 基于 IP/网段的黑白名单,按顺序匹配,先中先决。常用于把管理后台限制到公司 IP。
- Basic Auth
- HTTP 基本认证,用用户名密码保护路径。密码存在 htpasswd 文件里,简单但仅在 HTTPS 下才安全。
- 防盗链(Hotlink Protection)
- 校验请求的 Referer 头,阻止其他站点直接盗用你的图片/视频,节省带宽。
9.2 请求限流 limit_req
http {
# 定义限流区:按客户端 IP,每秒 10 个请求,占 10MB 内存
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
# burst 允许瞬时突发 20 个,nodelay 不排队直接放行
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429; # 超限返回 429 Too Many Requests
proxy_pass http://backend;
}
}
}
burst 与 nodelay 的含义
rate=10r/s 是稳态速率;burst=20 是允许排队的突发缓冲。不加 nodelay 时超出速率的请求会被延迟放行(平滑但慢);加 nodelay 时突发内的请求立即处理、超过 burst 才拒绝。真实站点几乎都用 nodelay。
9.3 连接数限流 limit_conn
http {
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
# 单 IP 最多 10 个并发连接
limit_conn conn_limit 10;
location /download/ {
# 限制下载带宽,防单用户拖垮出口
limit_rate 1m; # 每连接 1MB/s
}
}
}
9.4 IP 黑白名单
# 管理后台只允许公司出口 IP
location /admin/ {
allow 203.0.113.0/24;
allow 198.51.100.7;
deny all; # 其余全部拒绝
proxy_pass http://backend;
}
# 封禁已知恶意 IP
location / {
deny 192.0.2.66;
allow all;
}
反代后要看真实 IP
如果 Nginx 前面还有 CDN/LB,$remote_addr 是上游代理的 IP,allow/deny 会失效。需要配置 set_real_ip_from + real_ip_header X-Forwarded-For,让 Nginx 从可信代理头里还原真实客户端 IP,再做限流和黑白名单。
9.5 Basic Auth
# 生成密码文件
$ sudo apt install apache2-utils
$ sudo htpasswd -c /etc/nginx/.htpasswd admin
location /internal/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://backend;
}
Basic Auth 必须配 HTTPS
Basic Auth 把用户名密码用 Base64(不是加密)放在请求头里。在 HTTP 明文下等于裸奔,任何中间人都能解出密码。它只是"简单挡一下"的手段,务必在 HTTPS 之上使用,且不要用于真正敏感的系统。
9.6 防盗链
location ~* \.(jpg|jpeg|png|gif|mp4)$ {
# 只允许本站和搜索引擎引用;none 允许直接访问(无 Referer)
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
9.7 隐藏版本号与常见加固
http {
server_tokens off; # 响应头/错误页不显示 Nginx 版本
# 限制请求体大小,防超大 body 攻击
client_max_body_size 10m;
# 限制请求头缓冲,防慢速头攻击
large_client_header_buffers 4 8k;
server {
# 只允许安全的 HTTP 方法
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}
# 禁止访问隐藏文件(.git / .env 等)
location ~ /\.(?!well-known) {
deny all;
}
}
}
9.8 安全加固清单
| 项 | 做法 |
|---|---|
| 隐藏版本 | server_tokens off; |
| 只用现代 TLS | ssl_protocols TLSv1.2 TLSv1.3; |
| 安全响应头 | HSTS / X-Frame-Options / X-Content-Type-Options / CSP |
| 限流 | 登录、API 加 limit_req;全局 limit_conn |
| 请求体上限 | client_max_body_size 按业务设 |
| 隐藏文件 | 拒绝 .git / .env / .htpasswd |
| 后台白名单 | /admin 只放公司 IP + Basic Auth |
| 真实 IP | CDN 后配 real_ip 还原客户端 IP |
9.9 小结与下一步
- limit_req 限速率(burst+nodelay)、limit_conn 限并发、limit_rate 限带宽。
- allow/deny 做 IP 黑白名单,CDN 后需 real_ip 还原真实 IP。
- Basic Auth 简单挡一下,务必配 HTTPS。
- 防盗链校验 Referer;server_tokens off 隐藏版本;拒绝隐藏文件。
- 下一章把所学拼成完整方案——实战与部署。