The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Apache::ForwardedFor - Re-set remote_ip to incoming client's ip when running mod_perl behind a reverse proxy server. In other words, copy the first IP from X-Forwarded-For header, which was set by your reverse proxy server, to the remote_ip connection property.

SYNOPSIS

  in httpd.conf

  PerlModule                 Apache::ForwardedFor
  PerlPostReadRequestHandler Apache::ForwardedFor

  PerlSetVar  ForwardedForAccept 192.168.1.1
  PerlAddVar  ForwardedForAccept 192.168.1.2

DESCRIPTION

We often want to run Apache behind a reverse proxy so that we can delegate light-weight (static content) requests to a small httpd and proxy heavy-weight requests (dynamic mod_perl generated content) to a big httpd. This is a well known technique to overcome the memory contraints of running a busy mod_perl site.

A small problem when doing this is that our "remote_ip" for the backend (mod_perl) httpd is that of the front-end proxy'ing httpd. This is not a good representation of the end client's real IP address - making it difficult to implement IP-based access control and tracking usage through your logs.

Before:

 +--------+     +-------------+     +----------------+
 | Client | <-> | httpd/proxy | <-> | httpd/mod_perl |
 +--------+     +-------------+     +----------------+
  My IP           My IP               My IP
   2.3.4.5         2.9.1.2             192.168.1.2
                  remote_ip           remote_ip
                   2.3.4.5             2.9.1.2

After:

 +--------+     +-------------+     +----------------+
 | Client | <-> | httpd/proxy | <-> | httpd/mod_perl |
 +--------+     +-------------+     +----------------+
  My IP           My IP               My IP
   2.3.4.5         2.9.1.2             192.168.1.2
                  remote_ip           remote_ip
                   2.3.4.5             2.3.4.5

This program takes advantage of the existance of the X-Forwarded-For or header which is automatically added by software such as mod_proxy and Squid. Obviously you can imagine that if a savvy user sets their own X-Forwarded-For header that they could potentially be considered coming from a trusted IP.

To ensure some measure of security: 1 - make sure you can trust the httpd/proxy machine (ie/ its in your organization); 2 - set this module to accept X-Forwarded-For headers only from this machine.

From my understanding of the X-Forwarded-For header - each proxy server will prepend the remote_ip to this header. That means that if the request passes through several proxies we want to pick up only the last proxy's change - which is the first IP found in this header.

USAGE

At this time you simply need to load the module and add it to the PerlPostReadRequestHandler phase of your mod_perl-enabled httpd.

APACHE CONFIGURATION

The following can be set using either the PerlSetVar or PerlAddVar directives.

i.e. PerlSetVar ForwardedForDeny 127.0.0.1 PerlAddVar ForwardedForAccept 192.168.1.1 PerlAddVar ForwardedForAccept 192.168.1.2 PerlAddVar ForwardedForAccept 192.168.1.3

ForwardedForAccept IPaddress

By using either the PerlSetVar or PerlAddVar directive you can list hosts for which we will only be allowing handling of Forwarded headers from.

That means if you put one host in this list then all non-listed hosts will be blocked.

Netblocks are not supported at this time - you must supply the full IP address.

ForwardedForDeny

By using either the PerlSetVar or PerlAddVar directive you can list hosts for which we will be blocking handling of Forwarded headers from.

This means that all hosts except the ones listed here will be accepted for processing.

Netblocks are not supported at this time - you must supply the full IP address.

N.B. - if you specify both Accept and Deny items then you effectively follow the logic of Deny first, then Accept afterwards. This is virtually pointless but will be more useful when/if netblock support is added.

BUGS

Please report your bugs and suggestions for improvement to info@infonium.com ... For faster service please in clude "Apache::ForwardedFor" and "bug" in your subject line.

I have not yet found written documentation on the usage of the X-Forwarded-For header. My implementation assumes that the first IP in the incoming header is for your (the most recent) proxy server.

SUPPORT

For technical support please email to info@infonium.com ... for faster service please in clude "Apache::ForwardedFrom" and "help" in your subject line.

AUTHOR

 Jay J. Lawrence - jlawrenc@cpan.org
 Infonium Inc., Canada
 http://www.infonium.com/perl

COPYRIGHT

Copyright (c) 2002 Jay J. Lawrence. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the LICENSE file included with this module.

ACKNOWLEDGEMENTS

 ahosey@systhug.com - mod_extract_forwarded
 Vivek Khera        - Apache::HeavyCGI::SquidRemoteAddr

SEE ALSO

perl, mod_perl, mod_extract_forwarded.