nginx中需启用http_realip_module,配置set_real_ip_from和real_ip_header等指令,用$realip_remote_addr替代$remote_addr记录日志并透传给fastcgi后端,确保php等应用获取真实客户端ip。

在 Nginx 中使用 FastCGI(如 PHP-FPM)时,日志记录真实客户端 IP 的核心逻辑和反向代理场景一致:不能依赖 $remote_addr(它只是 PHP-FPM 与 Nginx 的连接地址,通常是 127.0.0.1),而必须通过 http_realip_module 处理 X-Forwarded-For,再将可信的真实 IP 注入 FastCGI 参数供后端读取,同时确保 access log 也体现该真实 IP。
启用 realip 模块并配置可信代理
这是所有后续操作的前提。Nginx 必须能从 X-Forwarded-For 中准确提取用户真实 IP:
- 确认模块已启用:
nginx -V 2>&1 | grep -o http_realip应有输出 - 在
http或server块中声明可信来源,例如:set_real_ip_from 192.168.0.0/16;set_real_ip_from 10.0.0.0/8;set_real_ip_from 100.64.0.0/10;(匹配云厂商 SLB、内网 LB 等) - 指定头字段:
real_ip_header X-Forwarded-For; - 开启递归解析:
real_ip_recursive on;——否则多级代理下可能取到最后一级可信代理的 IP,而非用户真实 IP
修改日志格式,使用 $realip_remote_addr
启用 realip 后,$realip_remote_addr 变量会自动承载校验后的用户真实 IP(若校验失败则回退为原始 $remote_addr)。日志中应直接使用它:
- 在
http块中定义日志格式:log_format main '$realip_remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; - 确保
access_log引用该格式:access_log /var/log/nginx/access.log main; - 避免使用
$http_x_forwarded_for替代主 IP 字段——它可被伪造、含多个 IP、格式不稳定
透传真实 IP 给 FastCGI 后端(如 PHP)
仅改日志不够,PHP 等应用仍需拿到真实 IP。不能用 $_SERVER['REMOTE_ADDR'](固定是 127.0.0.1),而应由 Nginx 显式传入:
- 在
location ~ \.php$块中添加:fastcgi_param REMOTE_ADDR $realip_remote_addr; - 同时建议补全其他相关参数:
fastcgi_param HTTP_X_REAL_IP $realip_remote_addr;fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for; - PHP 中即可安全使用:
$_SERVER['REMOTE_ADDR'](已被 Nginx 覆盖)或$_SERVER['HTTP_X_REAL_IP']
验证与常见问题
配置完成后需快速验证是否生效:
- 临时加一条调试日志格式:
log_format debug '$http_x_forwarded_for ←→ $realip_remote_addr ←→ $remote_addr';
对比三者值,确认$realip_remote_addr已脱离127.0.0.1或代理 IP - 检查上游是否透传了
X-Forwarded-For:CDN 或 LB 必须设置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;,且不能重复添加导致格式异常(如1.1.1.1, 1.1.1.1) - 若仍记录为本地地址,优先排查
set_real_ip_from是否覆盖了实际代理出口 IP 段











