You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Garrett Goebel <ga...@scriptpro.com> on 2003/07/24 22:14:45 UTC

reverse proxy in depth tutorial?

This is slightly off-topic, but as it hits on Mason, optimizing mod_perl for
performance, and is covered in passing in the practical and mod_perl
cookbook books, I figured I'd ask here first.

Can anyone point me toward a good in depth article or documentation on using
reverse proxying with apache? And no, I'm sorry but the apache reference
docs on modules and directives is too spartan. I'm looking to minimize
memory utilization and maximize performance, and am slowly working through
the tips from the books and available online documentation. 

Most everything I'm stumbled upon has been short on detail and examples. For
instance, I never found an example of how to just reverse proxy everything
for a given backend server. All the examples I saw showed how to proxy
something like http://foo/bar but not http://foo. Eventually I came up with
the following:

[Reverse Proxy]
...
Listen 192.168.1.1:80
RewriteEngine on
RewriteRule	^/?(.*) http://127.0.0.1:80/$1 [P]
ProxyPassReverse / http://127.0.0.1:80/
...

[Backend Server]
...
Listen 127.0.0.1:80
...

Is this kosher? 

Is there a better way to do this? 

A way to do it without mod_rewrite using only mod_proxy directives?

Are there any strong arguments against using a mod_proxy/mod_rewrite httpd
accelerator? Or preferred alternatives?

Using the loopback for the backend has the security advantage of completely
isolating the backend from any direct communication with external hosts. How
do I keep the backend on 127.0.0.1 _and_ handle name based virtual hosts?

What are the issues with regard to virtual hosting and ssl?

Any tips on keeping the config files maintainable?

For instance if I'm doing a mason site with co-branding through multiple
component roots... What would minimal configurations for proxy and backend
servers look like in order to redirect an externally exposed ip address on
the proxy to a backend on 127.0.0.1 and still preserve the name based
virtual hosts? It that possible? What are the variations, tradeoffs, and
issues scaling it out to multiple physical servers? etc.

--
Garrett Goebel
IS Development Specialist

ScriptPro                  Direct: 913.403.5261
5828 Reeds Road            Main:   913.384.1008
Mission, KS 66202          Fax:    913.384.2180
www.scriptpro.com          garrett at scriptpro dot com


Re: reverse proxy in depth tutorial?

Posted by Igor Sysoev <is...@rambler-co.ru>.
On Fri, 25 Jul 2003, Igor Sysoev wrote:

> On Thu, 24 Jul 2003, Garrett Goebel wrote:

> > Using the loopback for the backend has the security advantage of completely
> > isolating the backend from any direct communication with external hosts. How
> > do I keep the backend on 127.0.0.1 _and_ handle name based virtual hosts?
> 
> Using mod_proxy you can set up backend listening on several loopback
> addresses: 127.0.0.1, 127.0.0.2, etc. Of course, you need to configure these
> additional addresses in OS before the use.  Also backend can listen
> on several ports and the single address: 127.0.0.1:8000, 127.0.0.1:8001, etc.
> 
> Here is example for two virtual hosts on several addresses, note that
> 1) the frontend servers are name based while the backend ones are IP based;
> 2) ServerName of the virtual server pairs are the same.
> 
> [Reverse Proxy]
> 
> NameVirtualHost frontend
> 
> <VirtualHost frontend>
>     ServerName   name1
>     ProxyPass          /   http://127.0.0.1:80/
>     ProxyPassReverse   /   http://127.0.0.1:80/
>     ...
> </VirtualHost>
> 
> <VirtualHost frontend>
>     ServerName   name2
>     ProxyPass          /   http://127.0.0.2:80/
>     ProxyPassReverse   /   http://127.0.0.2:80/
>     ...
> </VirtualHost>
> 
> [Backend Server]
> 
> UseCanonicalName  on
> 
> <VirtualHost 127.0.0.1>
>     ServerName   name1
>     ...
> </VirtualHost>
> 
> <VirtualHost 127.0.0.2>
>     ServerName   name2
>     ...
> </VirtualHost>

Sorry, if the backend set "UseCanonicalName on" then ProxyPassReverse
should be changed to
     ProxyPassReverse   /   http://name1/
and
     ProxyPassReverse   /   http://name2/
or these two directives can be added to the existent ones.


Igor Sysoev
http://sysoev.ru/en/


Re: reverse proxy in depth tutorial?

Posted by Igor Sysoev <is...@rambler-co.ru>.
On Thu, 24 Jul 2003, Garrett Goebel wrote:

> Most everything I'm stumbled upon has been short on detail and examples. For
> instance, I never found an example of how to just reverse proxy everything
> for a given backend server. All the examples I saw showed how to proxy
> something like http://foo/bar but not http://foo. Eventually I came up with
> the following:
> 
> [Reverse Proxy]
> ...
> Listen 192.168.1.1:80
> RewriteEngine on
> RewriteRule	^/?(.*) http://127.0.0.1:80/$1 [P]
> ProxyPassReverse / http://127.0.0.1:80/
> ...
> 
> [Backend Server]
> ...
> Listen 127.0.0.1:80
> ...
> 
> Is this kosher? 
> 
> Is there a better way to do this? 
> 
> A way to do it without mod_rewrite using only mod_proxy directives?

It can be done easy without mod_rewrite:

ProxyPass         /  http://127.0.0.1:80/
ProxyPassReverse  /  http://127.0.0.1:80/

> Are there any strong arguments against using a mod_proxy/mod_rewrite httpd
> accelerator? Or preferred alternatives?

I can not say about Apache2's mod_proxy (I do not use Apache2) but
Apache 1.3's one has several drawbacks when it serves the big responses
for the slow clients. It reads the backend response and synchronously
sends it to client. The maximum size of the data that can be read
from backend without delay is ProxyIOBufferSize + frontend kernel TCP
send buffer + frontend kernel TCP recieve buffer + backend kernel TCP
send buffer. Kernel TCP buffers are usually 16K-64K but can be made bigger.

To eliminate many mod_proxy drawbacks I had written more than two years
ago mod_accel module to do the reverse-proxing. mod_accel allows to configure
read buffer in memory but if the response is bigger then it saves it to
the temporary file and frees the backend as soon as possible.
mod_accel has directives to configure the caching backend responses, to
limit the connections to some backend to avoid the starvation of other
hosts and many other features.

mod_accel is clean module and is used for two years on several
Russian loaded sites. One of them serves 100 requests per seconds
without any segfaults.

The main mod_accel drawback for non-Russian users is that there's
no complete English documentation. Here is very incomplete documentaion
http://dapi.chaz.ru/articles/plain/en/mod_accel.xml
Also there're some English links on http://sysoev.ru/en/

> Using the loopback for the backend has the security advantage of completely
> isolating the backend from any direct communication with external hosts. How
> do I keep the backend on 127.0.0.1 _and_ handle name based virtual hosts?

Using mod_proxy you can set up backend listening on several loopback
addresses: 127.0.0.1, 127.0.0.2, etc. Of course, you need to configure these
additional addresses in OS before the use.  Also backend can listen
on several ports and the single address: 127.0.0.1:8000, 127.0.0.1:8001, etc.

Here is example for two virtual hosts on several addresses, note that
1) the frontend servers are name based while the backend ones are IP based;
2) ServerName of the virtual server pairs are the same.

[Reverse Proxy]

NameVirtualHost frontend

<VirtualHost frontend>
    ServerName   name1
    ProxyPass          /   http://127.0.0.1:80/
    ProxyPassReverse   /   http://127.0.0.1:80/
    ...
</VirtualHost>

<VirtualHost frontend>
    ServerName   name2
    ProxyPass          /   http://127.0.0.2:80/
    ProxyPassReverse   /   http://127.0.0.2:80/
    ...
</VirtualHost>

[Backend Server]

UseCanonicalName  on

<VirtualHost 127.0.0.1>
    ServerName   name1
    ...
</VirtualHost>

<VirtualHost 127.0.0.2>
    ServerName   name2
    ...
</VirtualHost>

Using mod_accel you can use the same scheme and also there's another way:
[PH] flag of the AccelPass directive preserves "Host" header.

[Reverse Proxy]

AccelPass   /   http://127.0.0.1/   [PH]

[Backend Server]

UseCanonicalName  on
NameVirtualHost 127.0.0.1

<VirtualHost 127.0.0.1>
    ServerName   name1
    ...
</VirtualHost>

<VirtualHost 127.0.0.1>
    ServerName   name2
    ...
</VirtualHost>

> What are the issues with regard to virtual hosting and ssl?

All your SSL-enabled sites have to be IP-based.

> Any tips on keeping the config files maintainable?

> For instance if I'm doing a mason site with co-branding through multiple
> component roots... What would minimal configurations for proxy and backend
> servers look like in order to redirect an externally exposed ip address on
> the proxy to a backend on 127.0.0.1 and still preserve the name based
> virtual hosts? It that possible?

Yes it's possible, see previous examples.

> What are the variations, tradeoffs, and
> issues scaling it out to multiple physical servers? etc.

mod_accel supports the primitive load balancing and fault tolerance using DNS.

mod_proxy in Apache 1.3 also has code that allows to connect to the next
server returned by DNS but this code is broken - it uses the same socket to
connect to the next backend and this always fails.


Igor Sysoev
http://sysoev.ru/en/