IP访问控制不生效主因是真实客户端IP未抵达策略执行点,需从请求头透传、Nginx解析(set_real_ip_from + real_ip_header)、应用层取值($realip_remote_addr而非$remote_addr)三层逐级验证,并确保白名单末尾加deny all。

IP访问控制在Nginx中不生效,绝大多数情况不是规则写错了,而是真实客户端IP没传到策略执行点——要么被中间代理覆盖,要么后端读错了字段,要么配置本身缺关键收口。排查要从请求头透传、Nginx解析逻辑、应用层取值三个层面逐层验证。
确认真实IP是否真正抵达Nginx
如果最外层入口(如CDN、云LB、前置Nginx)根本没把用户真实IP放进请求头,后面所有allow/deny都形同虚设。
- 用curl直连入口,加-v看响应头里X-Forwarded-For的值:第一个IP必须是你预期的公网地址,不能是内网或回源IP
- Cloudflare用户需额外配置信任段:set_real_ip_from 173.245.48.0/20;等,并设real_ip_header CF-Connecting-IP;
- 启用Proxy Protocol时,Nginx需配set_real_ip_from + real_ip_header proxy_protocol
检查每一层代理是否正确追加X-Forwarded-For
中间节点若用$remote_addr覆盖而非$proxy_add_x_forwarded_for追加,原始IP就会丢失。
- Nginx代理层必须用:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;(注意是_add_,不是$http_x_forwarded_for)
- HAProxy需开启:option forwardfor;Envoy需设xff_num_trusted_hops为实际跳数
- 临时加日志记录每层收到的$http_x_forwarded_for,对比是否连续、是否被截断成单一内网IP
验证Nginx是否基于可信IP做判断
即使X-Forwarded-For传到了,如果location里直接用allow作用于$remote_addr(即连接来源IP),那永远只拦住最后一跳的IP,不是用户真实IP。
- 必须让Nginx先通过set_real_ip_from和real_ip_header识别可信头,再用$realip_remote_addr或map提取的真实IP来匹配allow/deny
- 白名单配置末尾必须加deny all;,否则前面的allow只是“允许”,不阻止其他IP
- 测试时用curl带不同X-Forwarded-For头模拟,同时查access.log确认记录的是哪个IP
排除配置加载与语法问题
看似生效的配置,可能根本没被Nginx读取或解析成功。
- 运行nginx -t检查语法;用nginx -V确认加载的是你修改的那个配置文件路径
- 重载用nginx -s reload,不是systemctl restart;避免旧worker进程残留
- 检查Nginx运行用户对配置文件、证书、日志目录是否有读写权限











