我在docker容器中运行nginx反向代理服务器。后端是在主机上运行的apache服务器,它正在侦听10082
端口。 Laravel
处理请求。我用
$request->getClientIp()
获得真正的IP。但是,http://myip:10082
直接访问服务器而没有代理的结果与反向代理访问服务器的结果相冲突。
laravel中的测试代码:
echo $request->ip().'<br>';
echo $request->headers->get('X-Real-IP').'<br>';
echo $request->getClientIp().'<br>';
代理的结果:
192.168.80.2
218.205.17.167
192.168.80.2
没有代理的结果(XX.XXX.236.29是我的真实IP):
XX.XXX.236.29
XX.XXX.236.29
nginx的配置:
server {
listen 80;
server_name myserver.com;
access_log logs/myserver.access.log main;
location / {
proxy_pass http://myip:10082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
我很困惑。有人可以帮我解决吗?谢谢!
答案 0 :(得分:1)
由于您已在nginx代理中设置了X-Real-IP
标头,因此它是真正的IP。
答案 1 :(得分:0)
我遇到了同样的问题,花了很多时间。
问题是由请求必须通过docker-proxy传递到容器的方式触发的。 IP已更改,基本上您将收到docker-network的网关IP,而不是物理服务器的网关IP。
最新版本的Laravel包含TrustProxies,但如果您收到的REMOTE_ADDR
不是您的服务器IP,则无效。
硬编码也不是解决方案,因为下次重新启动服务器/重新创建容器时,IP可能会更改。
我已经通过假设 - 当我的服务器IP与REMOTE_ADDR
有3个字节并且后者以.1
结尾时为自己解决了这个问题,可以安全地用作可信代理:
在TrustProxies
- 中间件的handle()
- 功能:
$remoteAddr = $request->server->get('REMOTE_ADDR');
$serverAddr = $request->server->get('SERVER_ADDR');
if ($serverAddr && $remoteAddr) {
$lastDot = strrpos($serverAddr, '.');
if ($lastDot !== false &&
substr($remoteAddr, $lastDot) === '.1' &&
strpos($remoteAddr, substr($remoteAddr, 0, $lastDot+1)) === 0) {
$this->proxies[] = $remoteAddr;
}
}