启用realip模块并正确配置set_real_ip_from、real_ip_header和real_ip_recursive后,$remote_addr才代表真实客户端ip;否则日志记录的是代理ip。

直接在 log_format 中使用 $remote_addr 就能记录 IP,但前提是它已经是真实客户端 IP——这需要 RealIP 模块正确生效,而不是简单地“写进去就完事”。否则日志里记的只是代理或负载均衡器的出口 IP。
确保 $remote_addr 是真实 IP 的前提配置
RealIP 模块必须启用并正确设置可信来源,否则 $remote_addr 始终是上一跳连接地址:
- 在
http或server块中声明可信代理网段,例如:set_real_ip_from 10.0.0.0/8;set_real_ip_from 172.16.0.0/12;set_real_ip_from 192.168.0.0/16; - 指定从哪个 HTTP 头读取原始 IP:
real_ip_header X-Forwarded-For;(主流 CDN/WAF/SLB 都用这个) - 开启递归解析,自动剥离可信代理 IP,取最左侧非信任项:
real_ip_recursive on;
定义含真实 IP 的日志格式
配置生效后,$remote_addr 就代表用户真实 IP,可放心用于日志。推荐基础安全审计格式:
log_format security '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time';
说明:
• $remote_addr 此时已是经 RealIP 解析后的结果
• $request 包含完整请求行,便于识别恶意路径或参数注入
• $request_time 和 $upstream_response_time 可辅助发现慢速攻击或后端异常
验证是否真正生效
不能只看日志有没有字段,要确认内容是否准确:
- 临时加一条测试响应:
location /ip { return 200 "Client: $remote_addr\n"; }
然后curl http://your-domain/ip查看返回值 - 检查访问日志中同一请求的
$remote_addr是否与你本地公网 IP 一致(排除代理干扰) - 若仍显示内网或固定代理 IP,说明
set_real_ip_from范围没覆盖上游设备真实出口 IP,或real_ip_header与实际透传头不匹配(比如某些 WAF 用X-Real-IP)
不建议混用 $http_x_forwarded_for 写日志
即使格式里加上 "$http_x_forwarded_for",也只是原样记录请求头,该字段可被客户端随意伪造,不具备溯源价值。它适合调试链路,但不能替代 RealIP 模块的可信解析。











