@petebatin I ended up creating a dedicated middleware to pull the IP address reported by Cloudflare into my Laravel app because of the odd behaviour you’ve described yourself.
Cloudflare Remote IP and installation of Laravel Cloudflare Package for TrustProxies.php
Hi all,
2nd time poster here so go easy on me please.
Been a rough week or so and I've been at my wits end trying to get a load balancer to play nicely with sticky sessions (problem still ongoing). I want to be able to debug more or provide evidence of sticky sessions being broken (hence remote IP territory). The domain is proxied via Cloudflare and as a temporary measure I added the following to TrustProxies.php
protected $proxies = '*';
This was working ok and I'm able to get the visitors real IP from Cloudflare.
I then noticed that Apache wasn't recording the correct IP in it's logs, so I've added additional http/https directives (via Plesk) that use remoteip_module
RemoteIPHeader CF-connecting-IP
As a result the Apache logs are now being populated with the correct IPs. Once this was added, Laravel stopped detecting the correct remote IP. After doing a dump of $_SERVER and I can see that HEADER_X_FORWARDED_FOR contains 2 IP addresses (comma separated), the first is the correct IP, the second is either Cloudflare's IP or the Load Balancer's. Now there's nothing wrong with having more than one IP address in this header, that's what it's supposed to do and the correct IP is always the left-most value but why doesn't Laravel/TrustProxies Middleware return the correct one (left) and instead returns the last (right)?
I thought it might be because I'm allowing all proxies with the asterisk so I thought I'd do it properly and install this package from github monicahq/laravel-cloudflare. Installed with composer, no issues there and then got to step 2 of the instructions...
Replace TrustProxies middleware in your bootstrap/app.php file:
->withMiddleware(function (Middleware $middleware) {
$middleware->replace(
\Illuminate\Http\Middleware\TrustProxies::class,
\Monicahq\Cloudflare\Http\Middleware\TrustProxies::class
);
})
I've now looked through (literally just now) the previous releases and can see that the instruction is for Laravel 11 and the instruction for Laravel 10 (which I'm using) is in the previous release so I can look into that more tomorrow morning. But for now, does anyone know why request()->ip(); is returning the incorrect IP when more than one is present?
Is there a difference between...
/* Illuminate/Http/Request.php */
request()->ip()
and (i've yet to try this one)
/* symfony/http-foundation.php */
request()->getClientIp()
Has anyone used monicahq/laravel-cloudflare and do you know if it would solve my issue with multiple IP's in header or at least make it return the correct one?
For anyone else facing this issue, I can confirm that monicahq/laravel-cloudflare does solve this problem.
For Laravel v10 I had to use the instructions for release 3.6.0 found here monicahq/laravel-cloudflare/tree/3.6.0 but the latest release (that has instructions for Laravel v11) does work with v10. (P.S. this forum thinks it's the first day I've signed up so I can't include the full link to the instructions, just put github dot com/ in front of the path above).
You do need to ensure that Apache is getting the correct IP too from RemoteIPHeader CF-connecting-IP
If using nginx also then you'll need to add real_ip_header CF-Connecting-IP;
Once Apache is configured correctly and the monicahq/laravel-cloudflare package is installed then Laravel will report the correct IP.
Please or to participate in this conversation.