nginx的ip_hash仅用于会话保持而非封禁,需通过geo+if或allow/deny在server/location块中前置拦截被禁ip,再由upstream ip_hash处理未被拦截的请求,二者分层协作不冲突。

Nginx 的 ip_hash 本身不用于封禁客户端,它是一种负载均衡策略,作用是将同一客户端 IP 的请求始终分发到同一台后端服务器(会话保持),而非访问控制手段。你想实现的“封禁 HASH 客户端”,实际应理解为:在启用 ip_hash 的前提下,对特定客户端 IP 实施访问限制(如 403 拒绝)。这需要把 IP 访问控制(allow/deny 或 geo+if)与 ip_hash 负载均衡解耦、协同使用。
关键点在于:ip_hash 在 upstream 块中生效;而 IP 封禁逻辑必须放在 server 或 location 块中(即请求进入代理前就拦截),二者属于不同配置层级,不能混写,但可通过 include 实现规则集中管理。
以下是清晰可行的批量管理方案:
一、用独立文件定义被封禁的 IP 列表(推荐 geo + include)
适合需动态增删、跨多个 server 复用的场景。
创建 /etc/nginx/conf.d/blocked_ips.conf:
geo $blocked_ip {
default 0;
192.168.5.100 1;
203.0.113.42 1;
2001:db8::1 1;
# 可继续添加,支持 CIDR:192.168.10.0/24 1;
}
在 http 块顶部(必须在所有 server 之前)引入:
http {
include /etc/nginx/conf.d/blocked_ips.conf;
# 其他全局配置...
}
再在每个需管控的 server 的 location 中加入拦截逻辑:
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
location / {
if ($blocked_ip) {
return 403;
}
proxy_pass http://backend_pool;
# 其他 proxy_* 设置...
}
✅ 优势:规则统一维护、支持 IPv6 和 CIDR、不干扰
ip_hash工作流;
⚠️ 注意:geo必须在http级定义,if语句仅限location内使用,且避免嵌套复杂判断。
二、用 allow/deny + include 管理黑白名单(简单直接)
适合规则较少、无需变量逻辑的场景。
创建 /etc/nginx/conf.d/ip_access_rules.conf:
# 先放允许的(如有白名单) # allow 203.0.113.25; # allow 2001:db8::/32; # 再放拒绝的(封禁列表) deny 192.168.5.100; deny 203.0.113.42; deny 2001:db8::1; deny all; # 必须放最后
在目标 server 的 location / 中引用:
location / {
include /etc/nginx/conf.d/ip_access_rules.conf;
proxy_pass http://backend_pool;
}
✅ 优势:语法简洁、无需
if、匹配效率高;
⚠️ 注意:deny all必须位于所有allow/deny末尾,否则后续规则失效;该方式不支持条件组合(如“封禁某 IP 但放行其 API 路径”),需配合多location细粒度控制。
三、结合 upstream ip_hash 与前置封禁,确保逻辑不冲突
ip_hash 仅影响 proxy_pass 路由阶段,而封禁必须发生在代理前。只要封禁逻辑写在 proxy_pass 之前(如上面两个方案所示),就不会与 ip_hash 冲突。典型安全顺序应为:
- 请求到达 → 解析真实 IP(必要时配
set_real_ip_from)→ - 执行
geo判断或allow/deny匹配 → 若命中封禁,立即返回 403 → - 未封禁,则进入
proxy_pass,由upstream中的ip_hash决定转发目标。
示例完整片段:
upstream backend_pool {
ip_hash;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
server {
listen 80;
server_name example.com;
location / {
include /etc/nginx/conf.d/ip_access_rules.conf;
proxy_pass http://backend_pool;
proxy_set_header X-Real-IP $remote_addr;
}
}
不复杂但容易忽略。










