访问日志里的用户IP怎么总是显示内网地址?
我在给项目做安全审计时发现,记录的访问日志里用户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?
X-Forwarded-For没有被正确传递。Nginx默认不会自动添加X-Forwarded-For头,需要手动配置。解决方法是修改Nginx的配置文件,在转发请求时确保它会把客户端的真实IP写入
X-Forwarded-For头。打开你的Nginx配置文件,找到对应的server块或者location块,加上下面这行:解释一下:
$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']不为空,避免潜在的空指针问题,改完大概是这样:总结一下,问题的核心是Nginx没配置好
X-Forwarded-For的转发,修复配置后基本就没问题了。如果还有疑问,可以检查整个请求链路上的代理配置,确保每层都正确传递了客户端IP。