nginx 屏蔽不安全请求需多层防御:基于路径、user-agent、参数正则拦截;用 limit_req 按 uri 限流;geoip2 按地域屏蔽;外部文件热更新黑名单;核心是行为识别而非仅 ip 封禁。

在 Nginx 中屏蔽“不仅限特定 IP”的不安全访问请求,核心是跳出单纯封禁单个 IP 的思路,转向基于行为、特征、来源和上下文的多层防御。这类请求往往具备共性(如高频扫描、异常 User-Agent、非法路径、恶意参数),靠静态 IP 黑名单难以应对,需结合规则匹配、模块扩展与动态策略。
识别并拦截异常请求特征
很多不安全请求并非来自固定 IP,而是由自动化工具发起,带有明显指纹。可通过 location 和 if 配合正则精准拦截:
- 屏蔽常见扫描路径:如
/.git/config、/phpmyadmin/、/wp-admin/admin-ajax.php等,用location ~ ^/(?:\.git|phpmyadmin|wp-admin|adminer|shell|backup)\b+return 403; - 拒绝可疑 User-Agent:如包含
sqlmap、nmap、dirbuster、gobuster或空白 UA 的请求,用if ($http_user_agent ~* "(sqlmap|nmap|dirbuster|gobuster|^$)") { return 403; } - 拦截含危险参数的 GET 请求:如
?id=1%20UNION%20SELECT、?p=../etc/passwd,用if ($args ~* "(union\s+select|concat\(|base64_decode|../|\.\./)") { return 403; }
限制高频恶意行为(非 IP 绑定)
对短时间内大量请求的客户端(无论 IP 是否变化),使用 limit_req 模块按请求特征限流:
- 定义按请求 URI 或参数哈希限流的区域:
limit_req_zone $request_uri zone=uri_limit:10m rate=5r/s; - 对敏感接口(如登录、搜索、API)启用限流:
location /api/v1/login { limit_req zone=uri_limit burst=10 nodelay; } - 更精细可结合
$arg_token或$http_referer做维度控制,避免误杀正常用户
利用 GeoIP2 拦截高风险地域流量
当攻击源集中于某些国家或地区(如大量来自已知黑产活跃区的代理 IP),可基于地理位置动态拦截:
- 需提前编译安装
ngx_http_geoip2_module,并加载 MaxMind GeoLite2 Country 数据库 - 配置示例:
geoip2 /usr/share/GeoIP2/GeoLite2-Country.mmdb { $geoip2_data_country_code country iso_code; } - 在 server 或 location 中拦截:
if ($geoip2_data_country_code = "KP") { return 403; }或批量屏蔽:if ($geoip2_data_country_code ~ "(KP|MM|IQ|SO)") { return 403; }
统一管理黑名单并支持热更新
面对持续涌入的新恶意 IP(如爬虫池、代理集群),建议用外部文件 + include 方式实现快速响应:
- 新建
/etc/nginx/conf.d/blocked_patterns.conf,内容支持多种规则:deny 192.168.1.100;<br>deny 203.0.113.0/24;<br>if ($http_x_forwarded_for ~ "185\.19\.2[0-9]\.") { return 403; }<br>if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) { return 405; } - 在主配置中引入:
include /etc/nginx/conf.d/blocked_patterns.conf; - 修改后执行
nginx -t && nginx -s reload,无需重启,规则即时生效
不复杂但容易忽略:真正有效的防护不是堆砌规则,而是先分析 access.log 找出共性模式(比如某类 UA 总是扫同一组路径),再针对性编写可复用、易维护的拦截逻辑。IP 屏蔽只是起点,行为识别才是关键防线。











