[Techtalk] apache mod_proxy access

Almut Behrens almut-behrens at gmx.net
Tue Apr 13 22:21:41 EST 2004


On Fri, Apr 09, 2004 at 11:31:00AM -0700, Kristina Clair wrote:
>  
>  I am trying to find a solution that will allow me to limit access to a
>  proxied location based on the full request URL, and it is proving to be
>  very frustrating.

Hi Kristina,

I guess I'm a little behind on reading my mail... so maybe you've
solved the issue yourself in the meantime.  In case you're still
interested, here are a couple of thoughts.

>  
>  We are using ProxyPass and ProxyPassReverse for the proxying:
>  ProxyPass /proxy_me http://internal.server/
>  ProxyPassReverse /proxy_me http://internal.server/
>  
>  The issue is that I only want access to be granted on the internal
>  server if the following regular expression is true:
>  ^http://([^\/]+)/proxy_me/\1\/?   (matched against the requested URL)
>  
>  I have tried various methods:
>  
>  - using mod_rewrite on the internal server: the problem with this is
>  that I cannot find an environment variable that mod_rewrite can use that
>  contains the whole URL request string.   I also tried the following:
>  	RewriteCond %{HTTP_HOST} !^http://$1 [NC]
>  	RewriteRule /proxy_me/([^\/]+) - [F]
>  but as far as I can tell, that $1 in the regex doesn't contain what I
>  think it should.

The main problem with this is, that the $1 doesn't get interpolated
into the regex at all. All regexes used here are statically compiled
upon reading the config file, and are thus not as fully featured as
in scripting languages like perl. In particular, you may not have
dynamically evaluated substrings like $1 or %1, and no immediate
backreferences (like \1) either.  $1, %{HTTP_HOST}, etc. are only
expanded on the lefthand side, i.e. in the so-called teststring you
match against.

Also, HTTP_HOST on the internal server will probably not be what you
need (I'm assuming you want to match against the hostname specified in
the _original_ URL (i.e. one of the names the proxying server is bound
to), not "internal.server" -- I'm not entirely sure I correctly
understood what you need to do, though).  Btw, HTTP_HOST never
includes the protocol part "http://".

Theoretically, you could work around these problems by using some
dynamic rewrite map, but this would get a little cumbersome...

On the other hand, if the issue is to make sure that the path component
following /proxy_me/ matches the current hostname in the URL, why not
simply generate that path component yourself?  Then you can be 100%
sure it matches -- no more need to explicitly test for it.

You could achieve this using mod_rewrite on the proxying server:

  RewriteCond  %{HTTP_HOST}     ^(.+)$
  RewriteRule  /proxy_me/(.*)   http://internal.server/%1/$1 [P]

The RewriteCond line sets %1 to the current server name, which you can
then interpolate into the substitution string in the RewriteRule.

All proxy subrequest paths will thus automatically be prefixed with the
correct server name of the original request, e.g.

  http://my.server/proxy_me/any/path/
  
will internally be mapped to

  http://internal.server/my.server/any/path/

The above RewriteRule assumes that there in fact is no server name
following /proxy_me/ in the URL. If, for some reason, you want to keep
specifying /proxy_me/my.server/any/path explicitly, you could modify
the RewriteRule to read

  RewriteRule  /proxy_me/[^\/]+/(.*)  http://internal.server/%1/$1 [P]

This would match that my.server path component, but then simply throw
it away, replacing it with what it should be.

Due to the option [P], the rewritten string is directly passed through
to mod_proxy, so you no longer need the ProxyPass directive (but you
still need the ProxyPassReverse directive to correctly adjust the URL
in the "Location" header on HTTP redirect responses).

In case you still somewhere have to know the server name of the
original URL on the internal server side, you can make use of the
HTTP header "X-Forwarded-Host:" or the environment variable
HTTP_X_FORWARDED_HOST.

Good luck,

Almut
 


More information about the Techtalk mailing list