如何配置NGINX过滤代理链产生的多IP,仅保留真实客户端IP?
解决方案
你遇到的是多层代理场景下X-Forwarded-For(以下简称XFF)头多IP拼接的典型问题,以下两种方案均可实现仅提取首个客户端IP透传给后端:
方案一:使用http_realip_module模块(推荐,全局生效)
该方案会直接修改Nginx内置的$remote_addr变量为真实客户端IP,所有依赖该变量的逻辑(访问控制、限速、日志、后端透传)都会自动使用单个IP,无需额外调整透传规则。
操作步骤
- 首先确认你的Nginx已编译该模块:
nginx -V 2>&1 | grep "with-http_realip_module"
如果有输出说明已支持,无输出则需要重新编译Nginx开启该模块。
2. 在Nginx配置的http块或对应站点的server块中添加以下配置:
# 声明Varnish的地址为可信代理,不会被当作客户端IP set_real_ip_from 127.0.0.1; # 指定从XFF头中提取真实IP real_ip_header X-Forwarded-For; # 开启递归查找,会跳过所有可信代理IP,提取最左侧的真实客户端IP real_ip_recursive on;
- 重载Nginx配置生效:
nginx -s reload
方案二:使用map指令自定义提取IP(无需额外模块,灵活度高)
如果你不需要修改全局$remote_addr,仅需要调整透传给后端的XFF头,可直接用正则截取首个IP,无需依赖额外模块。
操作步骤
- 在Nginx配置的
http块中添加以下映射规则:
map $http_x_forwarded_for $client_real_ip { # 匹配多IP格式,提取首个IP ~^(?<first_ip>[0-9a-fA-F:.]+),.* $first_ip; # 单个IP场景直接返回原值 default $http_x_forwarded_for; }
- 在转发请求到后端的
location块中,替换透传的XFF头:
- 如果是反向代理场景(proxy_pass转发):
location / { proxy_pass http://你的后端服务地址; # 替换为提取后的单IP proxy_set_header X-Forwarded-For $client_real_ip; # 其余原有proxy配置保持不变 }
- 如果是FastCGI场景(比如PHP服务):
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; # 替换为提取后的单IP fastcgi_param HTTP_X_FORWARDED_FOR $client_real_ip; # 其余原有fastcgi配置保持不变 }
- 重载Nginx配置生效。
内容的提问来源于stack exchange,提问作者user14709644
相关产品推荐
相关产品推荐

