Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > b5b0f80e3c91c450a455ce638b1da68f > files > 5

apache-mod_extract_forwarded-2.0.2-8mdv2010.0.i586.rpm

This software is distributed at no charge and in accordance with the
Apache Software Foundation's Apache license. It is subject to the lack
of warranties and indemnities, and conditions given at the begining of
the mod_extract_forwarded.c file accompanying this file. No support is
offered or available from the author of this Apache module.

mod_extract_forwarded is designed to transparently (to other Apache modules)
modify the information about the connection over which an HTTP request is
received when that connection is not directly from a requesting client to the
Apache server but is instead via one or more intervening proxy servers.

Operation relies on the "X-Forwarded-For" headers, inserted by proxy servers.
This is a non-RFC-standard request header which was introduced by the Squid
caching proxy server's developers and which is now also supported, for reverse
proxy server operation, by Apache 2. If the intervening proxy servers doesn't
add such headers, we can't do anything about it. It is worth noting that a
normally configured Squid proxy server will add to the X-Forwarded-For. However,
when used as a proxy server, Apache prior to version 2 does not add
X-Forwarded-For headers unless the third party mod_proxy_add_forward module has
been added to it. This can leave potentially important gaps in the information
recorded in X-Forwarded-For header.

If the X-Forwarded-For header has been added properly by intervening proxy
servers we can determine the IP number of originating client machine BUT there
are some problems associated with this. 

Firstly, it would be inadvisable to trust what has been inserted into the
X-Forwarded-For header by any intervening machine outside the boundary of our
own local network. At best we should only trust what was said by the proxy
servers we control and which have handled the incoming request between the
boundary of our network and our destination server; even that trust should be
conditional as the header is plain text and eminently corruptible. It is vital
that our incoming proxy server on our local network border is reliable in adding
the X-Forwarded-For header so that we always have a clear demarcation in the
information; the public IP number of the machine connecting to our network
border. In practice, this means we can, at best, determine and show limited
trust in the IP number of the machine outside our local network border that made
the connection to our incoming (reverse) proxy server which it recorded the IP
number of in the X-Forwarded-For header. 

Secondly, there is limited use in determining the IP number of the client
machine originating a request where that request comes from outside our local
network and that IP number is a private IP number. This is because that client
IP number is by definition not unique and may well also be in use in our local
network; basing any decision on such an IP number and certainly relying on a DNS
look up of it is courting disaster.

Although these problems limit the usefulness of the information in
X-Forwarded-For header, we can make valid, albeit careful, use of it as a factor
in request processing, including access control, logging, and CGI use.

Basically, mod_extract_forwarded operates by modifying the connection record
associated with an HTTP request, for the period the request is being processed.
The changes this module makes spoof the rest of the Apache modules into
accepting as the IP originating the request something other than that of the
machine that originated the connection to our Apache server.

Because it is possible for a request to pass thru multiple proxies on
the way from the originating client to destination server, in which case
the X-Forwarded-For header should contain multiple IPs, this module
needs to know which of those proxies can be regarded as trusted, in
which case the entry it makes in the header can be trusted. As described
below, you can use directives in Apache's httpd.conf configuration file
to say which proxy server can be trusted,

Since the connection record is modified to remove references to the actual
connecting machines IP number, it is important that a record of this IP remains
available. This module optionally stores that IP number in an environment
variable immediately before altering the connection record. So CGIs have access
to IP number if they need it and other Apache modules can also get to the IP
number via the request_rec's subprocess_env table.

Using this module has potentially serious implications for host-based access
control to your server. Since "X-Forwarded-For" is just a piece of text in a
request header, spoofing it is trivial. To compensate for this
mod_extract_forwarded provides configuration directives to restrict the proxy
hosts for which X-Forwarded-For will be processed. Disallowing a proxy host with
these directives does not mean the proxy cannot get pages from your server, it
just means the forwarded IP it provided will not be used. It is strongly_advised
that you only process "X-Forwarded-For" entries from proxies you trust.

If a request has passed through multiple proxies then the X-Forwarded-For
may contain several IPs like this:

X-Forwarded-For: client1, proxy1, proxy2

Additionally there is the IP of the requesting host itself which is not included
in the header. Let's say the requesting host is proxy3. First we check that the
connecting host is in the is acceptable. Then we traverse the header from right
to left and the first encountered IP which is not acceptbale will be treated as
the client IP. For example if proxy1, proxy2, and proxy3 are acceptable then in
the above header client1 would be shown as the connecting IP. But in the
following header:

X-Forwarded-For: client1, untrusted1, proxy1, proxy2

untrusted1 would be shown as the connecting IP even though untrusted1 is
proxying for client1. (Because untrusted1 might be lying.)

The following Apache configuration directives can be used to specify the IP
number of those proxy servers which are to be regarded as trustworthy. The
directives can only be used in the default server configuration and in
<VirtualHost> containers. The operation of these directives is similar to the
operation of the mod_access allow/deny/order directives.

MEForder: can have either of two value 'refuse,accept' or 'accept,refuse' and
specifies the order in which the information in two associated directives,
MEFaccept and MEFrefuse, are intepreted. The MEFaccept and MEFrefuse directives
are each used to spcifiy one or more IP numbers.

MEFrefuse: this can be 'all' OR a list of IP numbers and/or domain names of
trusted proxy servers whose IP number can be derived by DNS from the domain
name. The presence of 'all' overrides any particular IP numbers and means that
no proxy servers are to be trusted. Individual IP numbers mean that those the
proxy servers having them are not to be trusted. This defaults to 'all'.

MEFaccept: this can be 'all' OR a list of IP numbers and/or domain names of
trusted proxy servers whose IP number can be derived by DNS from the domain
name. The presence of 'all' overrides any particular IP numbers and means that
all proxy servers are to be trusted. Individual IP numbers mean that those the
proxy servers having them are to be trusted. This defaults to an empty list of
trusted IP numbers.

Normal mode of use if to say:

   MEForder refuse,accept
   MEFrefuse all
   MEFaccept <space separated list of your trusted proxy servers' IP numbers>

with the MEForder directive saying apply the MEFrefuse rule first then the
MEFaccept rule. MEFrefuse rule says do not trust any proxy servers but this is
selectively overridden for particular IP numbers listed by the MEFaccept
directive.

MEFaddenv: this can be 'off', 'on' (the default) or a string. 'off'
means that when spoofing, do not add an environment variable whose value
is the IP number of the connecting machine. 'on' means that when
spoofing, add an environment variable called 'MEF_RPROXY_ADDR' whose
value is the IP number of the connecting machine. A string means that
when spoofing, add an environment variable named by the string supplied
whose value is the IP number of the connecting machine.

MEFdebug: this can be 'on' or 'off' (the default). When turned 'on'
information about how the mod_extract_forwarded module is processing
every request to your Apache 2 server, and any associated internal
redirects or subsrequests, is written to the server's error_log. Thhe
amount of output written and the way it is generated is such that you
would never normally want to turn this feature on. This feature is
intended for debugging operation of the mod_extract_forwarded module
and it is unlikely you will want to do that. See below for some examples
of the output that will be generated but note that then indentation for
clarity has been manually edited into the logged text:

A request involving subrequests and internal redirects
------------------------------------------------------

MEF: phase:post read request, started processing, /
MEF: phase:post read request, initial substituted 172.16.3.104 for 172.16.2.130, /
MEF: phase:URI translate, started processing, /
MEF: phase:URI translate, already done, NFA required, /
MEF: phase:access check, started processing, /
MEF: phase:access check, already done, NFA required, /

    MEF: phase:URI translate, started processing, /index.html
    MEF: phase:URI translate, not initial substituted 172.16.3.104 for 172.16.2.130, /index.html
    MEF: phase:access check, started processing, /index.html
    MEF: phase:access check, already done, NFA required, /index.html
    MEF: phase:cleanup not initial, redo spoof substituted 172.16.3.104 for 172.16.2.130, /

    MEF: phase:URI translate, started processing, /index.html.var
    MEF: phase:URI translate, not initial substituted 172.16.3.104 for 172.16.2.130, /index.html.var
        
        MEF: phase:post read request, started processing, /index.html.en
        MEF: phase:post read request, not initial substituted 172.16.3.104 for 172.16.2.130, /index.html.en
        MEF: phase:URI translate, started processing, /index.html.en
        MEF: phase:URI translate, already done, NFA required, /index.html.en
        MEF: phase:cleanup not initial, redo spoof substituted 172.16.3.104 for 172.16.2.130, /

    MEF: phase:cleanup not initial, redo spoof substituted 172.16.3.104 for 172.16.2.130, /
    
MEF: phase:cleanup initial, undo spoof substituted 172.16.2.130 for 172.16.3.104

A simple request
----------------

MEF: phase:post read request, started processing, /apache_pb.gif
MEF: phase:post read request, initial substituted 172.16.3.104 for 172.16.2.130, /apache_pb.gif
MEF: phase:URI translate, started processing, /apache_pb.gif
MEF: phase:URI translate, already done, NFA required, /apache_pb.gif
MEF: phase:access check, started processing, /apache_pb.gif
MEF: phase:access check, already done, NFA required, /apache_pb.gif
MEF: phase:cleanup initial, undo spoof substituted 172.16.2.130 for 172.16.3.104

A request which leads to reverse proxying
-----------------------------------------

MEF: phase:post read request, started processing, /mefx/cgi-bin/test.py
MEF: phase:post read request, initial substituted 172.16.3.104 for 172.16.2.130, /mefx/cgi-bin/test.py
MEF: phase:access check, started processing, /mefx/cgi-bin/test.py
MEF: phase:access check, already done, NFA required, /mefx/cgi-bin/test.py
MEF: phase:before proxy http, undo spoof substituted 172.16.2.130 for 172.16.3.104, /mefx/cgi-bin/test.py
MEF: phase:logging, redo spoof substituted 172.16.3.104 for 172.16.2.130, /mefx/cgi-bin/test.py
MEF: phase:cleanup initial, undo spoof substituted 172.16.2.130 for 172.16.3.104