Identifying the originating IP address

Apache and X-Forwarded-For Header (XFF)

Application Management Published on 4 mins Last updated

It's easier to get Apache to log client IP addresses utilizing X-Forwarded-For Headers than it is using IIS. By default, the logs do not record source IP addresses for clients - but as of Apache version 2.4 you can use the ErrorLogFormat directive in the httpd.conf file as explained below.

->Did you want to learn about XFF on IIS?

There’s been a lot of debate here in the office about how best to capture both your Loadbalancer’s IP and the Source IP of the user in your access_log in Apache 2.4. This is the tried and tested method we've come up with.

How to log X-Forwarded For Headers using Apache 2.4

CentOS 7

When you start out, your httpd.conf will look something like this:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common

CustomLog "logs/access_log" combined

Now the %h is already there to capture your header, which, by default, will capture the IP of the Loadbalancer (the last proxy server that the traffic came from). All of these entries need to commented out.

Free consultancy
from the load balancer experts

Assuming you have X-Forwarded-For enabled in the load balancer (or whatever proxy server you're using), you can capture the source IP from the original client. You'll need to change your config file entries to look like this:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
CustomLog "logs/access_log" combined env=!forwarded
CustomLog "logs/access_log" proxy env=forwarded

After making this change, restart the httpd service:

systemctl restart httpd

If you review the logs on the web server now, you'll see the client source address, which has been passed through using the X-Forward-For Header:

192.168.88.10 - - [19/Oct/2017:17:16:59 +0100] "GET /homepage.php HTTP/1.1" 200 1400 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36"

Debian/Ubuntu

Directives should be added to the specific site configuration file, /etc/apache2/sites-available/000-default.conf.

You will also need to enable the following modules:

a2enmod remoteip && a2enmod headers

Next, add the logging directives into the site specific configuration file:

SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" forwarded
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined env=!forwarded
CustomLog ${APACHE_LOG_DIR}/access.log forwarded env=forwarded

After making these changes, restart the apache2 service:

systemctl restart apache2

If you have any questions or experience any issues, email support@loadbalancer.org and the team will be happy to help.

apache_feather

How to log X-Forwarded For headers using Apache 2.2

The standard LogFormat directive:

LogFormat "%h %l %u %t "%r" %>s %b" common

To add the client's source IP address, just change this to:

LogFormat "%h %l %u %t "%r" %>s %b %{X-Forwarded-For}i" common

To add the client's source IP address and put quotes around each field (useful when importing the logs into a spreadsheet or database):

LogFormat ""%h" "%l" "%u" "%t" "%r" "%>s" "%b" "%{X-Forwarded-For}i"" common

Once you’ve made the change, restart Apache and you’re done. The examples below show the resulting log entries for each configuration.

Standard logs:

192.168.2.210 - - [09/Feb/2011:09:59:31 +0000] "GET / HTTP/1.1" 200 44

Client IPs added:

192.168.2.210 - - [09/Feb/2011:10:00:16 +0000] "GET / HTTP/1.1" 200 44 192.168.2.7

Client IPs added and all fields encapsulated in quotes:

"192.168.2.210" "-" "-" "[09/Feb/2011:10:01:10 +0000]" "GET / HTTP/1.1" "200" "44""192.168.2.7"

Note:

  • 192.168.2.210 is the IP of the Ethernet interface (eth0) on the load balancer
  • 192.168.2.7 is the IP of my test PC

One other point. If you also have Pound SSL in your configuration, once you’ve added the X-Forwarded-For bit to your LogFormat directive, the logs will also record an additional entry for the Pound virtual server as shown below:

192.168.2.210 - - [09/Feb/2011:10:02:16 +0000] "GET / HTTP/1.1" 200 44 192.168.2.7, 192.168.2.212

The additional IP address (192.168.2.212) in this example  is the IP of the Pound Virtual Server.

Want more?

IIS and X-Forwarded-For-Header