访问日志里的用户IP怎么总是显示内网地址?

闲人思晨 阅读 5

我在给项目做安全审计时发现,记录的访问日志里用户IP都是172.16.0.1这类内网地址,但实际用户应该是在外网访问的。

之前后端用了express框架,直接取req.ip,部署到服务器后发现全是Nginx的代理IP。后来查资料改用X-Forwarded-For头,但写成这样:


app.use((req, res, next) => {
  const ip = req.headers['x-forwarded-for'] || req.ip;
  log.ip = ip.split(',')[0].trim();
  next();
});

测试时故意用代理工具访问,发现日志里还是记录着服务器真实IP,而X-Forwarded-For头显示的是用户IP,代理IP,172.16.0.1这样的格式。这中间件配置哪里有问题?该怎么正确获取用户真实IP?

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
一一钧
一一钧 Lv1
问题应该出在Nginx的配置上,你现在的中间件逻辑其实没啥大问题,但Nginx没有正确设置转发请求时的头信息,导致 X-Forwarded-For 没有被正确传递。Nginx默认不会自动添加 X-Forwarded-For 头,需要手动配置。

解决方法是修改Nginx的配置文件,在转发请求时确保它会把客户端的真实IP写入 X-Forwarded-For 头。打开你的Nginx配置文件,找到对应的server块或者location块,加上下面这行:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


解释一下:$proxy_add_x_forwarded_for 是Nginx的一个内置变量,它会把客户端的真实IP追加到现有的 X-Forwarded-For 头后面,如果没有这个头,就直接用客户端的真实IP。

另外,如果你还用了其他代理层(比如负载均衡器、CDN),也需要确认这些中间层是否正确设置了 X-Forwarded-For,否则Nginx拿到的可能还是内网IP。

改完Nginx配置后记得重启服务,命令一般是 sudo nginx -s reload,具体看你环境。然后可以再测试一下,看看日志里是不是能正确记录用户的真实IP了。

对了,你的中间件代码里,req.headers['x-forwarded-for'] 这个值可能是逗号分隔的多个IP,所以你取第一个IP的逻辑是对的,这部分不用改。不过建议加个判断,确保 req.headers['x-forwarded-for'] 不为空,避免潜在的空指针问题,改完大概是这样:

app.use((req, res, next) => {
const xff = req.headers['x-forwarded-for'];
const ip = (xff && xff.split(',')[0].trim()) || req.ip;
log.ip = ip;
next();
});


总结一下,问题的核心是Nginx没配置好 X-Forwarded-For 的转发,修复配置后基本就没问题了。如果还有疑问,可以检查整个请求链路上的代理配置,确保每层都正确传递了客户端IP。
点赞 2
2026-02-16 19:01