Nginx 反向代理后日志全是 127.0.0.1:用 proxy_set_header 与 real_ip 三步还原真实 IP
上周查访问日志时发现一个怪现象:所有访问来源都显示 127.0.0.1,限流、统计、封禁全都失灵。原因很简单:Nginx 在前面做反向代理,后端应用看到的连接来源就是本机 Nginx,而不是真实访客。下面三步可以把真实 IP 还原回来。
第一步:先确认链路里到底丢了什么
在后端服务器上看一眼日志格式和请求头。Nginx 默认不会把客户端 IP 原样透传给后端,后端只能拿到直连它的那个地址。先用下面命令确认 Nginx 配置和监听情况:
nginx -t
ss -tlnp | grep nginx
curl -I http://127.0.0.1/
如果后端日志里 remote_addr 全是 127.0.0.1,基本可以确定是透传问题,而不是应用本身写错了日志。
第二步:在反向代理处把真实 IP 透传过去
在 Nginx 的 location 或 server 段里加上这几行:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
关键点有两个:X-Real-IP 只放直连客户端的地址,适合单层代理;X-Forwarded-For 会把链路上的地址依次追加,适合多层代理。改完先检查再重载,不要直接重启生产服务:
nginx -t && nginx -s reload
第三步:让 Nginx 自己也用真实 IP 记日志和做判断
只透传给后端还不够,Nginx 自己的 access_log 和限流模块默认还是看直连地址。需要在 http 段声明可信代理,并把日志格式里的 $remote_addr 换成 $http_x_forwarded_for 或配合 realip 模块使用:
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
注意:set_real_ip_from 只能写你真正信任的代理地址,不能写成 0.0.0.0/0,否则任何人伪造一个 X-Forwarded-For 就能冒充别人 IP。改完后用手机流量和家宽各访问一次,再看日志里是否出现两个不同的真实地址。
验证清单
- 重载后 nginx -t 通过,服务没有报错退出。
- 日志里不再清一色 127.0.0.1,能区分不同访客。
- 限流测试:同一 IP 连续刷新能被正常计数,而不是所有人共享一个计数。
常见坑:只改了 proxy_set_header,却没有改日志格式,结果应用对了、Nginx 日志还是错的;或者在多层代理下只用了 X-Real-IP,中间那层代理的地址又被当成了客户端。先画清代理链路,再决定用哪一个头,问题就解决了一大半。
- 点赞
- 收藏
- 关注作者
评论(0)