Apache doesn't log remoteIP when RemoteIPHeader X-Forwarded-For is present

I'm using Apache/2.4.27

Within the VirtualHost I'm forwarding the remote client IP header from the Loadbalancer with:

RemoteIPHeader X-Forwarded-For

Which is needed by the application served by that Virtualhost.

This is the log format within the main httpd.conf context.

LogFormat "%h (%{X-Forwarded-For}i) %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

When I have the RemoteIPHeader X-Forwarded-For listed within the virtualhost, Apache stops writting the remote-client IP into logs.

When I remove it from the VirtualHost, the remote-client IP starts appearing again within the logs.

Any ideas why the RemoteIPHeader X-Forwarded-For doesn't play with (%{X-Forwarded-For}i) from the LogFormat ?

Thanks !


Solution 1:

Proxy Layer (Nginx)

proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header        X-Real-IP       $remote_addr;

Backend Layer (Apache)

# Log format config
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" common
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
CustomLog "logs/access_log" common env=forwarded

# Header config
RemoteIPHeader X-Real-IP
RemoteIPHeader X-Client-IP
RemoteIPInternalProxy 192.168.10.10 192.168.10.11

Description:

proxy_set_header - directive sets headers that nginx sends to backend; so in this example We sends two variables (to headers): X-Forwarded-For and X-Real-IP

X-Forwarded-For - on the proxy side it must be set that this header should be passed to backends and accessible from their layer

X-Real-IP - it does not affect the required variables on the web page but we leave it enabled so that the Apache server places the client's address in the logs (you also need to set the log format itself):

### X-Real-IP enabled
172.217.20.206 - - [03/Jun/2017:11:12:11 +0200] "GET /tls-check.php?9832 HTTP/1.0" 200 1409
### X-Real-IP disabled
172.16.21.11 - - [03/Jun/2017:15:12:49 +0200] "GET /tls-check.php?13266 HTTP/1.0" 200 1448

Curl

:~$ curl -H Cache-Control: no-cache -ks https://example.com/tls-check.php?${RANDOM} | grep "HTTP_X_FORWARDED_FOR\|HTTP_X_REAL_IP\|SERVER_ADDR\|REMOTE_ADDR"
[HTTP_X_FORWARDED_FOR] => 172.217.20.206
[HTTP_X_REAL_IP] => 172.217.20.206
[SERVER_ADDR] => 192.168.10.100
[REMOTE_ADDR] => 192.168.10.10

tls_check.php

<?php

echo '<pre>';
print_r($_SERVER);
echo '</pre>';
exit;

?>

Solution 2:

Restore %a to that format if you're going to use mod_remoteip.

In bugzilla, mod_remoteip fills in %a while it removes from %{X-Forwarded-For}i. So in a simple case with one trusted proxy, %a will hold the value used to see in X-Forwarded-For because of mod_remoteip

Solution 3:

It works for me. Replaced %h to %a

LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined