I am using mod_proxy_add_forward to get the correct IP address from the proxy
server, as described in the guide.  On my back-end mod_perl server, I want to
limit access only to requests coming from the proxy server.  I can't use simple
IP-based access control via mod_access because PerlPostReadRequestHandler runs
before PerlAccessHandler, so $r->remote_addr has already been changed to the
client's IP.

So, I wrote my own PerlAccessHandler that reads $r->notes to see if the request
came from the proxy:

<Perl>
sub My::ProxyAccessOnly {
    my $r = shift;
    my $from_proxy = $r->notes("PROXY_REQUEST");
    $r->warn("from_proxy = '$from_proxy'");
    return FORBIDDEN unless $from_proxy;
    return OK;
}
</Perl>
PerlAccessHandler My::ProxyAccessOnly


I added a line to Ask's My::ProxyRemoteAddr that sets $r->notes:

<Perl>
sub My::ProxyRemoteAddr($) {
    my $r = shift;

    # we'll only look at the X-Forwarded-For header if the requests
    # comes from our proxy at localhost
    return OK unless $r->connection->remote_ip eq '127.0.0.1';

    if (my ($ip) = $r->header_in('X-Forwarded-For') =~ /([^,\s]+)$/) {
        $r->notes("PROXY_REQUEST" => 1); #note that this comes from proxy
        $r->connection->remote_ip($ip);
        $r->warn("set remote ip to $ip");
    }

    return OK;
}
</Perl>
PerlPostReadRequestHandler My::ProxyRemoteAddr


In my log I get, for each request:

[Thu Sep 28 17:02:25 2000] [warn] set remote ip to 192.168.178.13
[Thu Sep 28 17:02:25 2000] [warn] from_proxy = '1'
[Thu Sep 28 17:02:25 2000] [warn] from_proxy = '0'


As it turns out, the second call to My::ProxyAccessOnly is an internal redirect,
because if I add the following line, everything works as expected, and I only
get one log line.

    return DECLINED if !$r->is_initial_req;

[Thu Sep 28 17:02:25 2000] [warn] set remote ip to 192.168.178.13
[Thu Sep 28 17:02:25 2000] [warn] from_proxy = '1'


Is there a logical reason why PerlAccessHandler should be called twice, the
second time from within Apache?  Also, is there a better way I should go about
accomplishing my desired goal of only allowing proxy-through requests to the
mod_perl server?

-Adi

Reply via email to