Nginx代理传递真正的ip不起作用

时间:2017-02-06 08:12:02

标签: php laravel nginx docker

我在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; 
    }

}

我很困惑。有人可以帮我解决吗?谢谢!

2 个答案:

答案 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;
   }
}