AWS Application Load Balancer真实用户ip问题

AWS Application Load Balancer real user ip problem

我运行 laravel AWS Elasticbeanstalk 上的应用程序,我使用Application Load Balancer。

Route::get('/what-is-my-ip', function(){ 
    return request()->ip();
});

当我 运行 这段代码时,我的 ip 没有显示,它显示了负载均衡器的 ip 地址。

用过cloudflare同样问题的也有cloudflare的经验和解决方法,但是我找不到AWS Application Load Balancer的解决方法

我在获取用户的 IP 地址和在维护模式下添加 --allow-ip 时遇到问题。

function real_IP() {

    $real_IP = '';

    if (getenv('HTTP_CLIENT_IP'))
        $real_IP = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $real_IP = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $real_IP = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $real_IP = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
        $real_IP = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $real_IP = getenv('REMOTE_ADDR');
    else
        $real_IP = 'UNKNOWN';

    return $real_IP;
}

当我 运行 这段代码给出了正确的 IP 地址时,我想在 laravel 中修复它。

您需要 trust the AWS load balancers as a proxy

If you are using AWS Elastic Load Balancing, your $headers value should be Request::HEADER_X_FORWARDED_AWS_ELB. For more information on the constants that may be used in the $headers property, check out Symfony's documentation on trusting proxies.

If you are using Amazon AWS or another "cloud" load balancer provider, you may not know the IP addresses of your actual balancers. In this case, you may use * to trust all proxies:

protected $proxies = '*';

使用 AWS 或任何其他云负载均衡器时的两个常见问题:

  1. HTTPS(Laravel 资产和路线):您应用了 SSL/TLS 并且 URL 在浏览器中受到保护,但 Laravel 不会加载您的资产并引发错误。该错误看起来像是阻止了 URLS,因为您正在尝试加载 http URL http 请求。大多数人在使用 AWS or any other cloud Load Balancer 时都会遇到这个问题。当 运行 您的应用程序位于终止 TLS / SSL 证书的负载平衡器后面时,您可能会注意到您的应用程序在使用 url 帮助程序时有时不会生成 HTTPS 链接。这通常是因为您的应用程序正在从端口 80 上的负载均衡器转发流量,并且不知道它应该生成安全链接。

  2. IP: 另一个问题是IP问题。您无法获取 user/visitor IP,它 returns 始终是服务器 IP。这个问题也是因为 proxies.

Solution:当您使用 AWS or any cloud Load Balancer 时,您可能不知道实际 Loads Balancer 的确切 IP 地址,因此应该允许所有代理,如下例所示。

使用 * 允许信任 TrustProxies 中间件中的所有代理。这是你的中间件 app/Http/Middlewares/TrustProxies.php.

namespace App\Http\Middleware;

use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var string|array
     */
     protected $proxies = '*';

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO;

如果您使用的是 AWS Elastic Load Balancing,您的 $headers 值应该是 Request::HEADER_X_FORWARDED_AWS_ELB. 有关 $headers 属性 中可能使用的常量的更多信息,请查看 Symfony 的文档trusting proxies.

namespace App\Http\Middleware;

use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array|string
     */
    protected $proxies = '*';

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;

我认为它可以解决您的 HTTPS、IP 和其他代理相关问题。要阅读更多详细信息,请阅读 Laravel doc。如果您遇到任何其他问题或需要改进,请在下方发表评论。