优化IP匹配规则的核心是减少匹配次数、提升查找速度、避免运行时解析开销:用geo模块替代if+deny/allow;合并连续IP为最简CIDR;将控制逻辑下沉至具体location;禁用不必要的realip模块链路。

IP 匹配规则执行效率低,通常是因为大量 deny/allow 指令线性扫描、未利用 CIDR 合并、或在错误作用域重复配置。优化核心是减少匹配次数、提升查找速度、避免运行时解析开销。
用 geo 模块替代 if + deny/allow
Nginx 的 if 块内使用 deny/allow 会强制每次请求都做字符串比对,性能差且易出错。推荐改用 geo 模块预构建 IP 映射表,底层基于哈希或二叉树查找,O(1) 或 O(log n) 时间复杂度。
- 在
http块中定义:
geo $blocked_ip {
default 0;
192.168.1.0/24 1;
203.0.113.42 1;
2001:db8::/32 1;
} - 在
server或location中使用:
if ($blocked_ip) { return 403; }(注意:仅限简单变量判断,不建议嵌套复杂逻辑)
合并连续 IP 段为最简 CIDR
避免逐条写 deny 192.168.1.1;、deny 192.168.1.2; 这类低效写法。应主动聚合为 CIDR 表示,大幅减少规则数量。
- 错误示例(20 条规则):
deny 203.0.113.10;
deny 203.0.113.11;
...
deny 203.0.113.29; - 正确做法:用工具(如 ipcalc 或在线 CIDR 合并器)合并为
203.0.113.8/28,一条规则覆盖全部
将 IP 控制逻辑下沉到 location 级别
全局 if ($remote_addr ~ ...) 或根 server 块中的 IP 判断,会在每个请求路径上都执行。应按需收敛到具体路径,例如只限制后台接口或上传入口:
- 只对管理路径生效:
location /admin/ {
allow 10.0.0.0/8;
deny all;
} - 静态资源、API 接口等非敏感路径完全不加 IP 判断,跳过匹配环节
禁用不必要的 realip 模块链路
若启用了 ngx_http_realip_module(如通过 set_real_ip_from),但未正确配置 real_ip_header 或信任代理链,Nginx 会在每次请求中反复解析 X-Forwarded-For,拖慢 IP 匹配。确认以下两点:
- 只在真正需要获取真实客户端 IP 的场景启用该模块
- 确保
set_real_ip_from仅列出可信代理(如负载均衡器 IP),避免通配符或大网段,防止误判和额外开销











