The cost of running a VPS is becoming cheaper and cheaper. There are more things we could get for the same bucks. Once your site is ready for a VPS, there are multiple server stack options available, than the traditional LAMP setup. For example, you could completely ignore Apache and can use Nginx with php-fpm . Either case, you wouldn’t have any issues related to IPs in comments. However, on a complicated setups, such as Varnish => Nginx => php-fpm or Nginx => Apache, or Varnish => Apache, WordPress doesn’t display the IP address of the visitors correctly. There is nothing wrong with WordPress. It’s all about the implementation. Forwarding the correct client IP can be tricky as the complexity of the server stack increases. There are situations where you just don’t have any options to forward the correct address.
The use-case
Lately, I installed Varnish in a MediaTemple dv server. By default, it comes with Apache. However, no matter how much I try, I could not enable mod_rpaf for Apache. I’m not alone, either. There is a quick fix, provided by the community. I do not trust such quick-fix solutions. When I searched the internet, I found some great solutions. However, each has its own advantage and disadvantage.
Getting the correct IP
There are multiple ways to get the client IP for WordPress from X-Forwarded-For header. All techniques insert a piece of code in wp-config.php
file. X-Forwarded-For header usually contains the real IP plus other IP addresses. The general format of X-Forwarded-For is fi.rs.t.ip, se.co.nd.ip, th.ir.d.ip, and.so.on.ips
. So, the trick is to catch the first address in the list. There are multiple ways to do. Here are a couple of them…
Method #1
This technique uses preg_match to get the IP address…
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] )
&& preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/',
$_SERVER['HTTP_X_FORWARDED_FOR'] ) )
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
Ref: http://naze.mine.nu/?p=363
Method #2
This uses explode function.
# Replace the variable name to be unique!
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$tiny_xffaddrs = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $tiny_xffaddrs[0];
}
Ref: https://www.benjaminwiedmann.net/wordpress-behind-reverse-proxy-fix-wrong-ip-insert-x-forwarded-for-ip.html
As you may understood, some techniques can become a performance bottleneck, if used incorrectly. Still the best way to achieve this, is by using the server-side tools you have. So, please use the above techniques, only if you really need to!
If using Varnish, this is what you need to do.
In ‘/etc/varnish/default.vcl’:
[code]sub vcl_recv {
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
[…]
}[/code]
In ‘wp-config.php’:
[code]if ( isset( $_SERVER[ "HTTP_X_FORWARDED_FOR" ] ) ) {
$_SERVER[ ‘REMOTE_ADDR’ ] = $_SERVER[ "HTTP_X_FORWARDED_FOR" ];
}[/code]
I’ve tested it, and it does the job.
Sources: ocaoimh.ie, systemsarchitect.net
Not sure why the <code></code> tags got removed.
Hi Aahan,
Appreciate sharing the solution that worked with Varnish.
On code tags: You seem to have used < and >. However, the syntax highlighter plugin accepts only [ and ]. So, I fixed it now.
Pothi