Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple layers of load balancers in 4.0 #107

Closed
niclashedam opened this issue Feb 8, 2018 · 14 comments
Closed

Multiple layers of load balancers in 4.0 #107

niclashedam opened this issue Feb 8, 2018 · 14 comments

Comments

@niclashedam
Copy link

Our setup has multiple LB IP addresses, first a local one 10.* and then a public one 130.*. Lastly the users IP. This means that TrustedProxy should filter out 10.* and 130.*, but no matter what I do, it only filters out the first IP.

Everything worked correctly in version 3.*, but after upgrading to 4.*, it stopped working. Doesn't TrustedProxy support multiple layers of load balancers anymore?

Our environment is Google Cloud Platform with Laravel 5.6 and PHP 7.1.

@niclashedam
Copy link
Author

niclashedam commented Feb 8, 2018

When I call Request::ips() I get an array of two IPs, where index 0 is 130.*.

image

    protected $proxies = '*';

@fideloper
Copy link
Owner

fideloper commented Feb 8, 2018 via email

@niclashedam
Copy link
Author

niclashedam commented Feb 23, 2018

Hi, Sorry that I haven't responded until now.

Are the trusted proxies you have set a chain of proxies?

Yes.

I found out that if I only trust one level of proxies, then the next level will become the client IP.

  | [REDIRECT_STATUS] => 200
  | [HTTP_HOST] => xx
  | [HTTP_CACHE_CONTROL] => max-age=0
  | [HTTP_UPGRADE_INSECURE_REQUESTS] => 1
  | [HTTP_USER_AGENT] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
  | [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
  | [HTTP_DNT] => 1
  | [HTTP_ACCEPT_ENCODING] => gzip, deflate, br
  | [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.9
  | [HTTP_X_CLOUD_TRACE_CONTEXT] => aa5a75e58e03d50cb323e452a4114e28/2672460875832957278
  | [HTTP_VIA] => 1.1 google
  | [HTTP_X_FORWARDED_FOR] => 185.206.224.209, 130.211.43.142
  | [HTTP_X_FORWARDED_PROTO] => https
  | [HTTP_CONNECTION] => Keep-Alive
  | [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  | [SERVER_SIGNATURE] => <address>Apache/2.4.18 (Ubuntu) Server at xxx Port 80</address>
  |  
  | [SERVER_SOFTWARE] => Apache/2.4.18 (Ubuntu)
  | [SERVER_NAME] => xxxxxxx
  | [SERVER_ADDR] => 10.76.3.44
  | [SERVER_PORT] => 80
  | [REMOTE_ADDR] => 10.132.0.4
  | [DOCUMENT_ROOT] => /var/www/public
  | [REQUEST_SCHEME] => http
  | [CONTEXT_PREFIX] =>
  | [CONTEXT_DOCUMENT_ROOT] => /var/www/public
  | [SERVER_ADMIN] => xxxxx
  | [SCRIPT_FILENAME] => /var/www/public/index.php
  | [REMOTE_PORT] => 63699
  | [REDIRECT_URL] => /login
  | [GATEWAY_INTERFACE] => CGI/1.1
  | [SERVER_PROTOCOL] => HTTP/1.1
  | [REQUEST_METHOD] => GET
  | [QUERY_STRING] =>
  | [REQUEST_URI] => /login
  | [SCRIPT_NAME] => /index.php
  | [PHP_SELF] => /index.php
  | [REQUEST_TIME_FLOAT] => 1519400295.321
  | [REQUEST_TIME] => 1519400295

@MichMich
Copy link

I'm seem to be having the same issue on an app running on AWS behind cloud front. The Request has the following headers:

REMOTE_ADDR: 172.16.1.231
HTTP_X_FORWARDED_FOR: 193.34.4.230, 54.240.150.52

The IP I'm looking for is 193.34.4.230. The IP I'm getting without any settings in TrustProxies is 172.16.1.231. If I use $poxies = '*', then I'm getting the 54.240.150.52. I'm unable to get the desired IP.

@fideloper
Copy link
Owner

Hi @MichMich !

Can you show me your laravel trustproxies middleware, and what version of laravel you're on? In your case, it sounds like it's not looking at X-Forwarded-For at all (instead of just grabbing the wrong IP from X-Forwarded-For).

@MichMich
Copy link

It seems to be working if I use multiple proxy options:

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies = ['172.0.0.0/8', '54.0.0.0/8', '216.0.0.0/8'];

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

If I use '*', then I get the 172.16.1.231 ip. The above solution isn't ideal because I'm not sure of all the Amazon loadbalancing IP's.

@MichMich
Copy link

So, I did some digging and the following is the issue:

  • Server is behind an Amazon Load Balancer
  • The Load Balancer is behind Amazon Cloud Front

Because of this, my HTTP_X_FORWARDED_FOR contains 2 IPs.

In the previous version of TrustedProxies, this could be solved with: $proxies = "**" as stated in https://github.com/fideloper/TrustedProxy#configure-trusted-proxies

In version 4, ** doesn't have any effect. The only way to currently solve this, is by manually defining all proxies. But a wildcard would be preferable.

Any suggestions are welcome.

@MichMich
Copy link

Ah, rubber ducky debugging strikes again!

Using the following results in a wildcard for all proxies:

protected $proxies = ['0.0.0.0/0'];

@boynet
Copy link

boynet commented May 27, 2018

@MichMich thanks, I couldn't find anywhere, what is the danger of just trusting all ips?

I am using cloudflare, and when user is using google date saver, I am also getting double ip list, but always the google one is used(HTTP_X_FORWARDED_FOR look like 0.0.0.0,1.1.1.1) where I couldn't get a list of all google ip address to trust them

@Justintime50
Copy link

@MichMich you're my hero! Been stewing on this same issue for multiple days. Thank you!

@antriver
Copy link

antriver commented Oct 1, 2018

@MichMich Thanks! That solved my problem.

If you're using '0.0.0.0/0' (and maybe it needs Laravel 5.6?) you don't need to use this package at all.
In your AppServiceProvider.php boot() method (or somewhere similar if you prefer) you can put:

        Request::setTrustedProxies(
            [
                '0.0.0.0/0'
            ],
            Request::HEADER_X_FORWARDED_FOR
        );

and remove the TrustProxies middleware from your stack.

@pvledoux
Copy link

pvledoux commented Jan 9, 2019

@MichMich Thank you! You saved my day. I spent literally 2h searching why a dockerized Laravel app was always generating http instead of https urls.

@MichMich
Copy link

Keep in mind this isn't very secure since it allows you to spoof the original IP address.

@gtjamesa
Copy link

I created a package that will "replace" the fideloper/proxy package: ge-tracker/laravel-vapor-trusted-proxies. It sits in front of fideloper/proxy to dynamically build the proxies array from the server-side Vapor headers, which change on every request. It also respects the proxies that you have configured which is safer than blindly trusting all proxies.

LukeTowers added a commit to wintercms/storm that referenced this issue Aug 4, 2022
This reinstates the behaviour originally present in fideveloper/trustedproxy where setting ** as the value for app.trustedProxies would allow all proxies vs * which would only allow the most recent one in a chain of proxies (as determined by $_SERVER['REMOTE_ADDR']). See fideloper/TrustedProxy@6018dfb for when & why it was originally added.

The '**' wildcard was removed in v4 of that package (fideloper/TrustedProxy@1d09591) with no explanation and was never added back in when Laravel merged it into the core in laravel/framework#38295.

This causes problems for environments where you have multiple proxies in a chain (i.e. Amazon CloudFront in front of Amazon ELB). These problems are documented in fideloper/TrustedProxy#115 & fideloper/TrustedProxy#107, and spawned fideloper/TrustedProxy#142 & https://github.com/ge-tracker/laravel-vapor-trusted-proxies to resolve them.

Ultimately, this commit serves to reintroduce the original behaviour of fideveloper/trustproxies v3 and make it so that you can use `**` as the value for app.trustProxies in order to get the correct client IP address when running Winter on Laravel Vapor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants