Docker环境下NGINX+Laravel获取客户端真实IP的方法
解决方案:Docker Nginx + Laravel 多环境获取客户端真实IP问题
核心原因
问题本质是外层代理(Docker网关/办公防火墙)未正确传递客户端真实IP,导致Nginx/Laravel拿到的是代理层的IP而非客户端IP。需要从「Nginx配置」和「防火墙/代理层配置」两方面同步调整。
一、Nginx 配置调整(通用所有环境)
Nginx需要明确信任代理层的IP,从X-Forwarded-For头中提取真实客户端IP,并传递给PHP/Laravel。
站点配置示例(/etc/nginx/conf.d/your-site.conf)
server { listen 80; server_name your-domain.com; root /var/www/html/public; # 关键:添加可信代理IP/网段 # 本地Docker环境:信任Docker默认子网(可通过`docker network inspect bridge`查看实际子网) set_real_ip_from 172.17.0.0/16; # 办公防火墙环境:添加防火墙的内网IP(比如防火墙LAN口IP 192.168.1.1) # set_real_ip_from 192.168.1.1; # 指定从X-Forwarded-For头读取真实IP real_ip_header X-Forwarded-For; # 开启递归解析:当X-Forwarded-For有多个IP时,取最外层的客户端IP real_ip_recursive on; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass php-fpm:9000; # 替换为你的PHP容器服务名/IP fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; # 把解析后的真实IP传递给PHP fastcgi_param REMOTE_ADDR $remote_addr; include fastcgi_params; } }
二、Laravel 代理信任配置
Laravel默认会过滤代理IP,需要在中间件中添加可信代理,确保从X-Forwarded-For头获取真实IP。
修改app/Http/Middleware/TrustProxies.php:
<?php namespace App\Http\Middleware; use Illuminate\Http\Middleware\TrustProxies as Middleware; use Illuminate\Http\Request; class TrustProxies extends Middleware { // 添加可信代理的IP/网段 protected $proxies = [ '172.17.0.0/16', // 本地Docker子网 '192.168.1.1', // 办公防火墙内网IP ]; // 指定Laravel识别代理的HTTP头 protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO; }
三、办公防火墙配置(WatchGuard/Fortigate)
必须让防火墙在转发请求时,将客户端真实IP写入X-Forwarded-For头:
Fortigate 配置
- 进入「Policy & Objects」→「Virtual IPs」,找到对应业务的VIP
- 编辑VIP,在「HTTP Header Forwarding」中启用Forward Client IP,确保自动添加
X-Forwarded-For头 - 检查对应端口转发规则,确认未拦截HTTP头
WatchGuard 配置
- 进入「Firewall」→「NAT Rules」,找到目标端口转发规则
- 编辑规则,切换到「Advanced」标签页
- 勾选Add X-Forwarded-For header选项,保存规则
四、本地Docker环境额外说明
本地Docker默认用bridge网络,网关IP一般在172.17.0.0/16网段,若你的Docker网络是自定义的,可通过docker network inspect <network-name>查看子网,再更新Nginx和Laravel的可信网段。
内容的提问来源于stack exchange,提问作者SScotti
相关产品推荐
相关产品推荐

