发现攻击后立刻封禁IP并降级流量是Nginx应对突发攻击最直接有效的双轨操作,核心在于分层拦截、快速生效、业务可退,涵盖实时识别(日志统计/连接筛查/状态码分析)、不重启封禁(geo+map+return 444/limit_conn限流/iptables)、分级降级(静态缓存/动态熔断/非关键路径跳转)及验证回滚机制。

发现攻击后立刻封禁 IP 并降级流量,是 Nginx 应对突发攻击最直接有效的双轨操作。关键不在于“全拦”或“全放”,而在于分层拦截、快速生效、业务可退。
一、实时识别恶意 IP 的三种可靠方式
封禁的前提是准确识别——不能靠猜,也不能只看单次请求。
-
日志高频统计:用命令快速抓出 5 分钟内请求超 200 次的 IP(适用于 HTTP Flood):
tail -n 50000 /var/log/nginx/access.log | awk '$9 ~ /^2|3/ {print $1}' | sort | uniq -c | sort -nr | awk '$1 > 200 {print $2}' -
连接状态筛查:用 ss 命令查异常长连接或 SYN 半开连接(适用于 Slowloris 类攻击):
ss -tn state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10 -
状态码异常定位:大量 499(客户端主动断开)、502/504(上游超时)往往意味着扫描器或代理型攻击正在压垮后端,对应源 IP 需重点观察:
awk '$9 ~ /499|502|504/ {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
二、不重启的 IP 封禁手段(立即生效)
所有操作均无需 reload 或 restart nginx,避免服务抖动。
-
geo + map + return 444 方式:轻量、高效、连接级切断
在 http 块中添加:
geo $bad_ip { default 0; 192.168.3.11 1; 203.0.113.42 1; }
map $bad_ip $blocked { 1 1; default 0; }
在 server 块中:
if ($blocked) { return 444; } -
利用 limit_conn_zone 动态限流代替硬封:对疑似攻击但又不确定是否误伤的 IP,先限为 1 连接/秒:
limit_conn_zone $binary_remote_addr zone=attack:10m;
limit_conn attack 1; -
配合 iptables 快速丢包(系统层兜底):
iptables -I INPUT -s 192.168.3.11 -j DROP
(注意:仅用于确认恶意且无白名单需求的 IP,避免影响 CDN 回源或健康检查)
三、流量降级的分级执行策略
不是所有请求都值得同等对待。按业务优先级做“保核心、舍边缘”的柔性调度。
-
静态资源优先缓存并降级响应:对 /static/、/img/、.js/.css 等路径,启用 proxy_cache 并设置较低过期时间;攻击期间可强制返回 503 + 缓存副本:
location ~* \.(js|css|png|jpg|gif)$ {
proxy_cache static_cache;
proxy_cache_valid 200 302 10s;
error_page 503 =200 /cached$uri;
} -
动态接口熔断与排队:对 /api/ 路径启用限流+队列缓冲,超出部分返回 503(而非超时):
limit_req zone=api burst=50 nodelay;
limit_req_status 503; -
非关键路径直接返回简化页:如搜索页、评论页等,在攻击高峰时统一跳转至轻量 HTML 提示页:
location /search {
return 302 /maintenance.html;
}
四、验证与回滚准备
每一步操作后必须验证效果,并留好退路。
- 用 curl 测试封禁 IP 是否真正断连:
curl -I -x "" http://yoursite.com --connect-timeout 3(应无响应或超时) - 监控 error.log 中是否新增大量 “client closed connection” 或 “upstream timed out”,判断降级是否生效
- 所有临时配置修改,务必记录时间戳和操作人;备份原 nginx.conf 和 geo 列表,确保 30 秒内可还原











