Created: 24/August/1998

Latest release: 2/Feb/2006


mod_ip_forwarding v2.0


Outline of the document

Special considerations

This module is dependent on the Apache API. If you'd like to use the module on an Apache version higher than v/2.x / v1.3.x, please mail me.

Notation

apache/
The apache source directory

1. Purpose

The motivation for this module was to be able to forward the IP address of the source of a request between a proxy and the final destination server. Under normal circumstances, this information is lost and the server only sees the proxy's IP address. This hampers access control based on IP addresses. This module answers this limitation in a transparent and secure way.

Proxies forward the IP address inside a custom HTTP header. A server only accepts this new header from a list of user-defined authorized proxies. Once the header is accepted, it's internally substituted with the proxy's IP address, so that this value is used for all access control and CGI modules. This doesn't affect the actual IP address used to answer the proxy (they are stored in different places).

2. Compiling the IP forwarding module into Apache

2.1 Apache 2.x

This is what I do to compile the module under Apache 2.0.54. I compile it as a shared library under Debian Sarge. You don't need to compile apache yourself anymore. Isn't life beautiful? These steps may change or not under newer versions of Apache.

  1. Copy the latest apache 2 file mod_ip_forwarding.c to a local directory
  2. Compile and install the module as follows:

    # /path/to/this/tool/apxs2 -i -a -c /path/to/mod_ip_forwarding.c

Note that module has to have the highest priority among the access control modules. If you're using other proprietary access control modules, this module should correspond to the last activate-module option. Alternatively, you may use the Apache ClearModuleList and AddModule configuration directives to reorder the modules. Also note that you need to enable the proxy module too, as you want to proxy requests.

2.2 Debian Sarge package for Apache 2.x (or superior)

This is what I do to make a Debian Sarge package of this module for Apache 2.0.54.

  1. Make a cvs checkout of the entire mod_ip_forwarding directory:

    $ cvs -d dev.w3.org:/sources/public co apache-modules/mod_ip_forwarding

  2. $ cd apache-modules/mod_ip_forwarding
  3. As root, type:

    # dpkg-buildpackage -us -us

    (obmit the last two parameters if you want to sign the module)

  4. Once the module is created, it will be stored on the parent directory, with a name such as libapache2-mod-ip-forward_20051129-1_i386.deb. You can install

    it using the usual debian command (as root):

    # dpkg --install libapache2-mod-ip-forward_20051129-1_i386.deb

2.3 Apache 1.3.x

This is what I do to compile the module under Apache 1.3.4. These steps may change or not under newer versions of Apache.

  1. Copy the apache (1) file mod_ip_forwarding.c to the apache/src/modules/extra directory.

    Note that you must follow this link to get the correct version of this file. The latest version will only compile on apache 2.x..

  2. Compile the module as follows:

    # cd apache

    # ./configure --prefix=/usr/local/apache \

    --enable-module=proxy \

    --activate-module=src/modules/extra/mod_ip_forwarding.c

    # make

    # make install

Note that module has to have the highest priority among the access control modules. If you're using other proprietary access control modules, this module should correspond to the last activate-module option. Alternatively, you may use the Apache ClearModuleList and AddModule configuration directives to reorder the modules. Also note that you need to enable the proxy module too, as you want to proxy requests.

3. Configuring the IP forwarding module

3.1 New directives

The IP Forwarding module introduces three directives to Apache:

ForwardClientIPAddress [on/off default = off]
Controls forwarding of the X_Client_Address header
AcceptForwardedClientIPAddress [on/off default = off]
Authorizes accepting an X_Client_Address header
LogUnauthorizedIPForwarding [on/off default = on]
Logs any unauthorized attemp to forward an IP address
X_ClientIPAddrHeader string [default = X_Fwd_IP_Addr]
Customizable header string for sending the client ip _addr
AuthorizedProxies [space separated list of IP addresses]
List of authorized proxies who can send an X_Client_Address header

Note that you need to set up this module on both the proxy server and the final destination server. In addition, both servers must use the same X_ClientIPAddrHeader value. Finally, the final destination server must add the address of the proxy server using the AuthorizedProxies directive. This protects against intruders spoofing this header (unless they also spoof the IP address).

The following is a tip contributed by Paul Roe. Thanks!

If you're using this module as an Apache precompiled module (dynamic modules that are downloaded at runtime), you need to add the following configuration directive:

LoadModule ip_forwarding_module /path_to_apache_modules/mod_ip_forwarding.so

Note that the Debian apache-common-1.3.12-1 package seems to have renamed this module as w3c_ip_forwarding_module. In this case, you need to load the precompiled module as follows:

LoadModule w3c_ip_forwarding_module /path_to_apache_modules/mod_ip_forwarding.so

3.2 Example

Let's suppose I have a proxy on 134.129.20.116 and a server on 134.129.20.130. In addition, my client is at 123.123.123.123. Here's a fragment of the proxy and final server's configuration:

## Proxy configuration (may also be setup using mod_rewrite)
ProxyPass / http://134.129.20.130/
ForwardClientIPAddress On
## Server Configuration
AcceptForwardedClientIPAddress On
AuthorizedProxies 132.129.20.116

When the proxy contacts the server, it includes the following header:

X_Forward_IP_Addr: 123.123.123.123

When the server calls a CGI-script, it sends the following environment variable:

REMOTE_ADDR: 123.123.123.123

Note that the value of the REMOTE_ADDR environment variable corresponds to the one in the X_FWD_IP_ADDR header. Also, the X_ header was removed, as the final server is not configured to forward the X_ header. To continue forwarding the same header, you need to set the ForwardClientIPAddress in that server too.

If a non-authorized proxy (say, 132.129.20.116) sends the custom header, the module will remove it from the headers and add the following entry in the error log:

[Mon Aug 24 15:57:48 1998] Unauthorized Proxy (132.129.20.116) tried to forward
a client IP address (123.123.123.123)

4. Security notes

This module does not implement a full-blown secure ip@ forwarding mechanism. In particular, there are two weak security points:


Jose
$Author: kahan $ $Date: 2006/02/03 16:00:00 $