省建设厅执业资格注册中心网站,网站建设 中企动力厨具,山西省住房和建设厅网站,高雅不俗气的公司名字目录
1 背景
2 常见误区
3 X-Forwarded-For 解析规则
4 real_ip() 函数 —— 一行代码落地
5 与框架方法的协同
6 Nginx 端最小配置
7 生产落地 checklist
8 常见 QA
9 总结 在反向代理环境下精准获取客户端真实 IP 的最佳实践 — 基于自定义 real_ip() 函数的完…目录
1 背景
2 常见误区
3 X-Forwarded-For 解析规则
4 real_ip() 函数 —— 一行代码落地
5 与框架方法的协同
6 Nginx 端最小配置
7 生产落地 checklist
8 常见 QA
9 总结 在反向代理环境下精准获取客户端真实 IP 的最佳实践 — 基于自定义 real_ip() 函数的完整思路与落地方案 1 背景
在生产环境里Web 服务通常位于负载均衡或 Nginx 反向代理之后。 浏览器 → CDN → Nginx → PHP (FPM) 的多层链路会导致
变量实际值问题$_SERVER[REMOTE_ADDR]127.0.0.1或 Nginx 节点内网 IP仅表示最后一跳反向代理$request-ip()ThinkPHP同上未启用 信任代理 时失真
由此带来日志定位、风控校验、限流等功能全部“失灵”。 2 常见误区 只改 Nginx proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 头已经传了但 PHP 不解析 → 仍旧拿不到。 滥信所有 X-Forwarded-For 该头可被伪造直接用来做安全逻辑 → 风险极高。 中间件里 late setTrustedProxies() Request 对象早已初始化IP 已经确定再信任也来不及。 3 X-Forwarded-For 解析规则
X-Forwarded-For: client, proxy1, proxy2└──────┘ ← 我们真正想要的最左侧 是浏览器的公网 IP 后续是各级代理依次追加 若配合私网过滤可快速鉴别伪造或内网穿透 4 real_ip() 函数 —— 一行代码落地
/*** 精准返回客户端真实 IP** param \think\Request $request* return string*/
function real_ip(\think\Request $request): string
{$xff $request-header(x-forwarded-for);if ($xff) {$ip trim(explode(,, $xff)[0]); // 取最左侧// 过滤私网 保留地址防注入$opts FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;if (filter_var($ip, FILTER_VALIDATE_IP, $opts)) {return $ip;}}// 回落到框架默认REMOTE_ADDR / 127.0.0.1return $request-ip();
}核心思路 1️⃣ 先尝试解析 X-Forwarded-For2️⃣ 利用 FILTER_VALIDATE_IP 保证是合法公网 IP 3️⃣ 任何异常都回退到 $request-ip()保证业务不崩。 5 与框架方法的协同
场景建议风控 / 日志一律用 real_ip()保证公网地址唯一可信白名单校验先 real_ip()再比对企业固定 IP 段统计报表real_ip() $request-ip()避免把所有人都归为 127.0.0.1
Tip在 ThinkPHP 里可做 Helper全局调用
// app/common.php
function ip(): string
{return real_ip(request());
}6 Nginx 端最小配置
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;若有多级反代CDN → Nginx应在每一层都 追加 而非覆盖 X-Forwarded-For。 反代本机 IP 请加入服务端白名单防止伪造
$trusted [127.0.0.1, 10.0.0.0/8];
// 如果 REMOTE_ADDR 不在 trusted拒绝自定义 XFF7 生产落地 checklist
项是否完成备注Nginx 传递 X-Forwarded-For✅$proxy_add_x_forwarded_forPHP 层封装 real_ip()✅私网过滤 回退机制安全校验使用 real_ip()✅登录限频、验证码、黑名单等日志中记录 real_ip()✅ELK / Loki / Graylog 8 常见 QA
问题解答同局域网压力测试获取 192.168.*内网环境可取消 FILTER_FLAG_NO_PRIV_RANGE 过滤或透传 X-Forwarded-For 私网地址。CDN 已做真实 IP 回注 (True-Client-IP)可把 True-Client-IP 加入 header 检测链优先级视业务而定。Laravel / Symfony 可以复用吗同理只需把 real_ip() 的 $request 类型替换成对应框架的 Request。 9 总结 Nginx 只负责传递头PHP 才是最终裁判。 自定义 real_ip() 可控 安全 不依赖框架魔术。 私网保留段过滤能有效抵抗伪造回退逻辑保证全链路稳健。
落地后一条日志里看到的将再也不是“127.0.0.1”而是真正的客户 IP——为审计、风控、可观测性打下坚实基础。