You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Jen mlists <pr...@gmail.com> on 2007/08/03 12:29:39 UTC

X_FORWARDED_FOR original IP

Hello members,

I meet a problem about getting client's original IP.
Some clients use proxy servers to access our sites,and I need to get
their original IPs instead of proxy servers' IPs.

In CGI I can write it like:

my $ip = $ENV{'HTTP_X_FORWARDED_FOR'} ? $ENV{'HTTP_X_FORWARDED_FOR'} :
$c->remote_ip;

but now I'm running under pure mod_perl (mp1),this can't work.
the configure is:

PerlModule DLAuth

<Location /path>
    SetHandler perl-script
    PerlAccessHandler DLAuth
</Location>


please help me.Thanks!

Re: X_FORWARDED_FOR original IP

Posted by Clinton Gormley <cl...@traveljury.com>.
On Fri, 2007-08-03 at 20:02 +0800, Jen mlists wrote:
> No.Here both PHP and CGI scripts can get the X_FORWARDED_FOR ip,but
> modperl can't.Is the %ENV hash not useful under modperl?

No it's not - mod_perl has access to all of that (plus a whole lot more)
via other means, so apache doesn't need to set up the environment for
every request.

As Torsten said, you can access the X-forwarded-for headers with this:

    $r->headers_in->{$header_name}

Clint


Re: X_FORWARDED_FOR original IP

Posted by Torsten Foertsch <to...@gmx.net>.
On Friday 03 August 2007 14:02, Jen mlists wrote:
> No.

To which part of my answer to your question relates that "No"?

> Here both PHP and CGI scripts can get the X_FORWARDED_FOR ip,but 
> modperl can't.Is the %ENV hash not useful under modperl?

Apache maintains an internal representation of the environment that it calls 
subprocesses with that is accessible in Perl via $r->subprocess_env. So all 
values set in this table are visible through %ENV to CGI subprocesses.

If you run your Perl CGI script as registry script then the registry wrapper 
populates %ENV for you (from $r->subprocess_env) just before calling the 
actual script.

HTTP_X_FORWARDED_FOR is set this way according to the incoming X-Forwarded-For 
HTTP header. Under mod_perl all incoming headers are accessed via 
$r->headers_in. So the value you are looking for is in 
$r->headers_in->{'X-Forwarded-For'}

Torsten

Re: X_FORWARDED_FOR original IP

Posted by Carl Johnstone <mo...@fadetoblack.me.uk>.
> No.Here both PHP and CGI scripts can get the X_FORWARDED_FOR ip,but
> modperl can't.Is the %ENV hash not useful under modperl?

mod_perl is not CGI.

With mod_perl your perl interpreter is part of the apache process itself. So 
making apache set up the environment is a waste of time, you can just access 
*anything* you want within apache internally.

You shouldn't use X-Forwarded-For for this purpose:

1) You can't trust the header! Anybody could make requests from your system 
and set a bogus X-Forwarded-For header and therefore feed fake IPs into your 
system. You have a major security problem is you rely on this for any access 
control, and any auditing process will have fake information.

2) Multiple clients may use the same internal IP ranges. So you'll get 
addresses 192.168.0.173 from clients on both Client A's network and on 
Client B's network.

All you can do is use the public IP you are receiving, and leave it to your 
clients to figure out which internal user it was from their own internal 
proxy logs.

The only time it would be safe to use X-Forwarded-For would be when there 
*always* is a proxy server that you control (for example a reverse proxy).

Carl


Re: X_FORWARDED_FOR original IP

Posted by Jen mlists <pr...@gmail.com>.
No.Here both PHP and CGI scripts can get the X_FORWARDED_FOR ip,but
modperl can't.Is the %ENV hash not useful under modperl?

2007/8/3, Torsten Foertsch <to...@gmx.net>:
> On Friday 03 August 2007 12:29, Jen mlists wrote:
>
> > I meet a problem about getting client's original IP.
> > Some clients use proxy servers to access our sites,and I need to get
> > their original IPs instead of proxy servers' IPs.
> >
> > In CGI I can write it like:
> >
> > my $ip = $ENV{'HTTP_X_FORWARDED_FOR'} ? $ENV{'HTTP_X_FORWARDED_FOR'} :
> > $c->remote_ip;
>
> This idea won't work in general. First, not all proxies set an X-Forwarded-For
> header. Second, many proxies sit in front of private networks 10.0.0.0/8 or
> 172.16.0.0/16 or 192.168.0.0/16 or 127.0.0.0/8. If they set the header you
> get different clients with the same IP-address. Also, be aware that a request
> can travel through multiple proxies. Thus, you can get multiple
> X-Forwarded-For headers.
>
> That said, you can access all incoming headers via
> $r->headers_in->{$header_name}.
>
> Torsten
>
>

Re: X_FORWARDED_FOR original IP

Posted by Jen mlists <pr...@gmail.com>.
Thank you all guys.I've known this issue and know how to handle it.
Thanks again.

--jen

Re: X_FORWARDED_FOR original IP

Posted by Jonathan Vanasco <jv...@2xlp.com>.
On Aug 3, 2007, at 7:03 AM, Torsten Foertsch wrote:

> This idea won't work in general. First, not all proxies set an X- 
> Forwarded-For
> header. Second, many proxies sit in front of private networks  
> 10.0.0.0/8 or
> 172.16.0.0/16 or 192.168.0.0/16 or 127.0.0.0/8. If they set the  
> header you
> get different clients with the same IP-address. Also, be aware that  
> a request
> can travel through multiple proxies. Thus, you can get multiple
> X-Forwarded-For headers.

I'll go a step further, and say that this is a particularly bad  
idea.  ( for essentially the same reasons above ).

The only proxy server headers you should care about or trust are  
those that are from your own LAN.

Your firewall/gateway/whatever should ideally strip the x-forwarded- 
for , or rename it to something else.  xff should your internal lan  
marking.  its trivial for people to spoof headers, its trivial for  
poorly designed networks to just insert inane headers as well.

Its not a matter of whether its feasable to access that information -  
its just that the information is worthless and not trustable simply  
by the design of the protocol and current global implementations.

in almost any case, using these will lead to issues in your system .


That said, for header manipulation, you can reference these module
	MP1 	http://search.cpan.org/dist/Apache-ForwardedFor/
	MP2 	http://search.cpan.org/dist/Apache2-xForwardedFor

note they both operate as a handler and override the info in $r ; you  
ESPECIALLY DO NOT want to do that in your case
	

// Jonathan Vanasco

Founder/President - FindMeOn
Fonder/CEO - RoadSound
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
- - - - - - - - - - - - - - - - - - -
|      FindMeOn.com - The cure for Multiple Web Personality Disorder
|      Web Identity Management and 3D Social Networking
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
- - - - - - - - - - - - - - - - - - -
|      RoadSound.com - Tools For Bands, Stuff For Fans
|      Collaborative Online Management And Syndication Tools
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
- - - - - - - - - - - - - - - - - - -



Re: X_FORWARDED_FOR original IP

Posted by Torsten Foertsch <to...@gmx.net>.
On Friday 03 August 2007 12:29, Jen mlists wrote:

> I meet a problem about getting client's original IP.
> Some clients use proxy servers to access our sites,and I need to get
> their original IPs instead of proxy servers' IPs.
>
> In CGI I can write it like:
>
> my $ip = $ENV{'HTTP_X_FORWARDED_FOR'} ? $ENV{'HTTP_X_FORWARDED_FOR'} :
> $c->remote_ip;

This idea won't work in general. First, not all proxies set an X-Forwarded-For 
header. Second, many proxies sit in front of private networks 10.0.0.0/8 or 
172.16.0.0/16 or 192.168.0.0/16 or 127.0.0.0/8. If they set the header you 
get different clients with the same IP-address. Also, be aware that a request 
can travel through multiple proxies. Thus, you can get multiple 
X-Forwarded-For headers.

That said, you can access all incoming headers via 
$r->headers_in->{$header_name}.

Torsten