1. XFF header 的规则是这样,每经过一个代理 /CDN,这个代理 /CDN 就把上一个代理 /CDN/用户的 IP 附加到 XFF 后面,逗号分隔。这符合 HTTP 对于一个 Header 多个参数的规范。
例: 后端----前端(反代)------CDN/缓存------负载均衡器------用户
后端收到的 XFF 内容如下:用户 IP, 负载均衡器 IP, CDN/缓存 IP
参考:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For2. 关于获取 XFF 中用户的 IP:
Apache 和 Nginx 都有相关模块,请参考文档。
https://httpd.apache.org/docs/2.4/mod/mod_remoteip.htmlhttp://nginx.org/en/docs/http/ngx_http_realip_module.html3. PHP 获取 XFF header 的内容:
关于 PHP 获取 Header:
https://secure.php.net/manual/zh/function.getallheaders.php不过这个只适用于 Apache+mod_php,底下评论里有 Apache+PHP-FPM/Nginx 这类只能用 FPM 的 HTTP Server 所适用的解决方案
如果 XFF 有多个 IP,用 explode()逗号做 delimiter 转成数组再处理
4. 关于伪造 XFF,楼主想必看了些关于"伪造 XFF 绕过基于 IP 的 ACL"的文章。但我不得不说,you're so rigid. XFF 是 header,改个名字(X-Real-IP, X-Client-IP, etc)就不能被伪造了?
对付伪造, @
Reficul 所说的才是有效的解决方案。你需要的是白名单,即只接受(你所用 CDN 的)指定 IP 发来的请求中的 XFF。
参考 Apache mod_remoteip 的 RemoteIPTrustedProxy 和 RemoteIPTrustedProxyList 参数
Nginx 的 set_real_ip_from 参数。
-------
可算是把饭"喂到嘴"了,恁可以自己去查查文档吗?