Mailing List Archive

[mod_backhand-users] How to avoid erratic MIME-types?
Hello to all:

Our backhand cluster (http://www.cebit.de) is up and running for some time
now and it's doing a great job! A big THANK YOU to all who made this
possible!

However, here's a problem I encountered today:

In our implementation, one lean front end server passes all requests to the
fully-featured backends (including one back end at the same machine).
Because the front end is stripped down, it does not know how to handle e.g.
php scripts (which are supposed to be processed by the back ends, of
course). If for any reasons, no back end is available (I had to restart all
of them today due to configuration changes), the front end delivers the
scripts "as-is" i.e the source code. This is not what we want...
It would be nice if I could set a kind of "forced BackhandSelf" directive,
so that the front end would deny any delivery or show an error page if no
backend is available.

Any suggestions?

Tilman


--
Tilman Kastner DEVICE/N GmbH
kastner@devicen.de Ilse-ter-Meer-Weg 7
PGP key available 30449 Hannover, Germany
[mod_backhand-users] How to avoid erratic MIME-types? [ In reply to ]
Tilman Kastner wrote:
> It would be nice if I could set a kind of "forced BackhandSelf" directive,
> so that the front end would deny any delivery or show an error page if no
> backend is available.
>
> Any suggestions?

There are a couple of way of doing this.

(1) run another instance (preferably lighter wieght -- like thttpd) on a
document root that only serves the error page desired -- on 127.0.0.1:8080.
Have the front-end mod_backhand server advertise itself as 127.0.0.1:8080
(MulticastStats 127.0.0.1:8080 <brodcastaddr:port>) and turn on
"BackhandSelfRedirect On". Assuming that you always stick the local machine
on the _end_ of the list:
Backhand removeSelf
[ your normal backhand directives ]
Backhand addSelf
if all else fails it will choose the local machine and proxy the connection to
127.0.0.1:8080.

(2) I think it would be more simplistic to have all of you "special content"
like php scripts and perl scripts and cgi's to owned by the group readable by
the Apache GID, but _not_ readable by other:
-rw-r---- user apachegid file.php3
Then, simply run the frontend instance under a different group id. If it
fails to mod_backhand something, it will get a permission denied (403 I think)
and you can specify an ErrorDocument 403 in the Apache config to show whatever
you like.
This has the advantage (over 1) that you can still serve all your static
content even if all the backend machines are down.

(3) There is probably a neat trick you can play with mod_rewrite to do what
you need. The things people manage to do with mod_rewrite never ceases to
amaze me ;-)


I am sure there are several other ways to accomplish this.

--
Theo Schlossnagle
1024D/A8EBCF8F/13BD 8C08 6BE2 629A 527E 2DC2 72C2 AD05 A8EB CF8F
2047R/33131B65/71 F7 95 64 49 76 5D BA 3D 90 B9 9F BE 27 24 E7
[mod_backhand-users] How to avoid erratic MIME-types? [ In reply to ]
Tilman,

If you read my (long) post, I am doing something similar. The trick is
to run one "lite" apache server on the front ends and two apache servers
(one "lite", one mod_php) on the backends. The front end apache servers
reverse proxy using RewriteRules the php documents to the mod_php apache
server. To support virtual hosts, you must use different ports on the
mod_php server.

Look at this documentation under "Reverse Proxy" for more information.

http://httpd.apache.org/docs/misc/rewriteguide.html

Also, look at this documentation. It is for mod_perl, but it also
applies to mod_php.

http://perl.apache.org/guide/strategy.html#Adding_a_Proxy_Server_in_http_Ac


Example:

Servers:

www1.mydomain.com
www2.mydomain.com
www3.mydomain.com

On all servers:

apache 1.3.17 mod_backhand
Virtual Hosts defined on port 80: www.mydomain.com, www.mydomain2.com

On www3.mydomain.com

apache 1.3.17 mod_php (with it's own httpd.conf, etc.)
(i guess you can also have mod_bakchand for this type of apache server
if running several backend machines, but you would have to use a
different MulticastStats address or AcceptStats address to have a
separate backhand cluster)
Virtual Hosts defined on port 8080: www.mydomain.com
Virtual Hosts defined on port 8081: www.mydomain2.com

Flow:

1) Request for http://www.mydomain.com/forums/index.php3
2) Accepted by a frontend selected by mod_backhand
3) /forums/index.php3 matches the reverse proxy RewriteRule
4) frontend reverse proxies the request to www3.mydomain.com:8080
5) Reply to client transparently (he doesn't see the 8080 port crap)

This means you can set up a nice ErrorDocument on the frontend in case
the backend doesn't respond. Also, all static content (images, etc) are
still served by the frontend, so only the actual dynamic content request
is reverse proxied.

This is what my configuration looks like:

I use a RewriteMap to select the backend server and appropriate backend
port.

Contents of RewriteMap file cluster.txt:

static www1.mydomain.com|www2.mydomain.com|www3.mydomain.com #
not necessary with mod_backhand
dynamic www3.mydomain.com # (you can add others)

Contents of RewriteMap file ports.txt:

www.mydomain.com 8080
www1.mydomain.com 8080
www2.mydomain.com 8080
www3.mydomain.com 8080
www.mydomain2.com 8081
www1.mydomain2.com 8081
www2.mydomain2.com 8081
www3.mydomain2.com 8081


-----------------------------------
Frontend apache server configuration:

ServerName www1.mydomain.com
...
<IfModule mod_backhand.c>
UnixSocketDir /home/apache/backhand
MulticastStats 225.0.0.2:4445,1
AcceptStats 1.1.1.0/24
<Location "/backhand/">
SetHandler backhand-handler
</Location>
</IfModule>
...
<Directory /home/httpd/www/www.mydomain.com>
Backhand byAge
Backhand byRandom
Backhand addSelf
</Directory>
...

NameVirtualHost 1.1.1.2

SendBufferSize 32768

RewriteEngine On

RewriteMap cluster rnd:/home/httpd/www/conf/cluster.txt # Randomly
choose
RewriteMap ports txt:/home/apache/conf/ports.txt # To choose
good port

RewriteRule ^proxy:.* - [F] # some security
RewriteRule ^/apache-rproxy-status.* - [L]
RewriteRule ^(http|ftp)://.* - [F]

...

<VirtualHost 1.1.1.2>
ServerName www.mydomain.com
ServerAlias www1.mydomain.com
ServerAlias www2.mydomain.com
ServerAlias www3.mydomain.com

...

ErrorDocument 400 /404.html # give nice error messages
ErrorDocument 404 /404.html
ErrorDocument 405 /404.html
ErrorDocument 406 /404.html
ErrorDocument 406 /404.html
ErrorDocument 407 /404.html
ErrorDocument 408 /404.html
ErrorDocument 409 /404.html
ErrorDocument 410 /404.html
ErrorDocument 411 /404.html
ErrorDocument 412 /404.html
ErrorDocument 413 /404.html
ErrorDocument 414 /404.html
ErrorDocument 415 /404.html
ErrorDocument 500 /404.html
ErrorDocument 501 /404.html
ErrorDocument 502 /404.html
ErrorDocument 503 /404.html
ErrorDocument 504 /404.html
ErrorDocument 505 /404.html

...

RewriteEngine On

RewriteOptions 'inherit'
RewriteRule \.(gif|jpg|png|txt|html|cgi|pl)$ - [last]
RewriteRule /$ - [last]
RewriteRule ^/cgi-bin - [last] # I execute my lite CGI locally

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} -d # fix trailing
slash
RewriteRule ^(.+[^/])$ $1/ [R,last]

RewriteRule ^/(.+)$ http://${cluster:dynamic}:${ports:%{HTTP_HOST}}/$1
[P] # proxy to backend
# I guess I could use SERVER_NAME instead and save me some
entries in port.txt ...

...
</VirtualHost>

<VirtualHost 1.1.1.2>
ServerName www.mydomain2.com
ServerAlias www1.mydomain2.com
ServerAlias www2.mydomain2.com
ServerAlias www3.mydomain2.com

...
(same as above)
...
</VirtualHost>

(repeat for other servers)

--------------------------------
Backend Server configuration:

ServerName www3.mydomain.com
...
(add mod_backhand if more than one backend, with different
MultiCastStats and AccepStats)
...
SendBufferSize 32768

php3_engine Off # I only want the engine where I need it

Listen www3.mydomain.com:8080

<VirtualHost waterdeep:8080>
ServerName www.mydomain.com
ServerAlias www1.mydomain.com
ServerAlias www2.mydomain.com
ServerAlias www3.mydomain.com

...

ErrorDocument 400 /404.html # give nice error messages
ErrorDocument 404 /404.html
ErrorDocument 405 /404.html
ErrorDocument 406 /404.html
ErrorDocument 406 /404.html
ErrorDocument 407 /404.html
ErrorDocument 408 /404.html
ErrorDocument 409 /404.html
ErrorDocument 410 /404.html
ErrorDocument 411 /404.html
ErrorDocument 412 /404.html
ErrorDocument 413 /404.html
ErrorDocument 414 /404.html
ErrorDocument 415 /404.html
ErrorDocument 500 /404.html
ErrorDocument 501 /404.html
ErrorDocument 502 /404.html
ErrorDocument 503 /404.html
ErrorDocument 504 /404.html
ErrorDocument 505 /404.html

...

<Location /forums>
php3_engine On
php3_memory_limit 4096
</Location>

</VirtualHost>

Listen www3.mydomain.com:8081

<VirtualHost waterdeep:8081>
ServerName www.mydomain2.com
ServerAlias www1.mydomain2.com
ServerAlias www2.mydomain2.com
ServerAlias www3.mydomain2.com

...
(same as above)
...

</VirtualHost>


If the backend fails, the client gets a nice "Sorry...." page.

Hope it helps,

Dejan

--__--__--

Message: 5
Date: Thu, 01 Mar 2001 18:08:53 +0100
From: Tilman Kastner <kastner@devicen.de>
To: <backhand-users@lists.backhand.org>
Subject: [mod_backhand-users] How to avoid erratic MIME-types?

Hello to all:

Our backhand cluster (http://www.cebit.de) is up and running for some
time
now and it's doing a great job! A big THANK YOU to all who made this
possible!

However, here's a problem I encountered today:

In our implementation, one lean front end server passes all requests to
the
fully-featured backends (including one back end at the same machine).
Because the front end is stripped down, it does not know how to handle
e.g.
php scripts (which are supposed to be processed by the back ends, of
course). If for any reasons, no back end is available (I had to restart
all
of them today due to configuration changes), the front end delivers the
scripts "as-is" i.e the source code. This is not what we want...
It would be nice if I could set a kind of "forced BackhandSelf"
directive,
so that the front end would deny any delivery or show an error page if
no
backend is available.

Any suggestions?

Tilman


--
Tilman Kastner DEVICE/N GmbH
kastner@devicen.de Ilse-ter-Meer-Weg 7
PGP key available 30449 Hannover, Germany
[mod_backhand-users] How to avoid erratic MIME-types? [ In reply to ]
Oops, used my local machine names. Change "waterdeep" with
"www3.mydomain.com" in the example.

Dejan


Dejan Macesic wrote:
>
> Tilman,
>
> If you read my (long) post, I am doing something similar. The trick is
> to run one "lite" apache server on the front ends and two apache servers
> (one "lite", one mod_php) on the backends. The front end apache servers
> reverse proxy using RewriteRules the php documents to the mod_php apache
> server. To support virtual hosts, you must use different ports on the
> mod_php server.
>
> Look at this documentation under "Reverse Proxy" for more information.
>
> http://httpd.apache.org/docs/misc/rewriteguide.html
>
> Also, look at this documentation. It is for mod_perl, but it also
> applies to mod_php.
>
> http://perl.apache.org/guide/strategy.html#Adding_a_Proxy_Server_in_http_Ac
>
> Example:
>
> Servers:
>
> www1.mydomain.com
> www2.mydomain.com
> www3.mydomain.com
>
> On all servers:
>
> apache 1.3.17 mod_backhand
> Virtual Hosts defined on port 80: www.mydomain.com, www.mydomain2.com
>
> On www3.mydomain.com
>
> apache 1.3.17 mod_php (with it's own httpd.conf, etc.)
> (i guess you can also have mod_bakchand for this type of apache server
> if running several backend machines, but you would have to use a
> different MulticastStats address or AcceptStats address to have a
> separate backhand cluster)
> Virtual Hosts defined on port 8080: www.mydomain.com
> Virtual Hosts defined on port 8081: www.mydomain2.com
>
> Flow:
>
> 1) Request for http://www.mydomain.com/forums/index.php3
> 2) Accepted by a frontend selected by mod_backhand
> 3) /forums/index.php3 matches the reverse proxy RewriteRule
> 4) frontend reverse proxies the request to www3.mydomain.com:8080
> 5) Reply to client transparently (he doesn't see the 8080 port crap)
>
> This means you can set up a nice ErrorDocument on the frontend in case
> the backend doesn't respond. Also, all static content (images, etc) are
> still served by the frontend, so only the actual dynamic content request
> is reverse proxied.
>
> This is what my configuration looks like:
>
> I use a RewriteMap to select the backend server and appropriate backend
> port.
>
> Contents of RewriteMap file cluster.txt:
>
> static www1.mydomain.com|www2.mydomain.com|www3.mydomain.com #
> not necessary with mod_backhand
> dynamic www3.mydomain.com # (you can add others)
>
> Contents of RewriteMap file ports.txt:
>
> www.mydomain.com 8080
> www1.mydomain.com 8080
> www2.mydomain.com 8080
> www3.mydomain.com 8080
> www.mydomain2.com 8081
> www1.mydomain2.com 8081
> www2.mydomain2.com 8081
> www3.mydomain2.com 8081
>
> -----------------------------------
> Frontend apache server configuration:
>
> ServerName www1.mydomain.com
> ...
> <IfModule mod_backhand.c>
> UnixSocketDir /home/apache/backhand
> MulticastStats 225.0.0.2:4445,1
> AcceptStats 1.1.1.0/24
> <Location "/backhand/">
> SetHandler backhand-handler
> </Location>
> </IfModule>
> ...
> <Directory /home/httpd/www/www.mydomain.com>
> Backhand byAge
> Backhand byRandom
> Backhand addSelf
> </Directory>
> ...
>
> NameVirtualHost 1.1.1.2
>
> SendBufferSize 32768
>
> RewriteEngine On
>
> RewriteMap cluster rnd:/home/httpd/www/conf/cluster.txt # Randomly
> choose
> RewriteMap ports txt:/home/apache/conf/ports.txt # To choose
> good port
>
> RewriteRule ^proxy:.* - [F] # some security
> RewriteRule ^/apache-rproxy-status.* - [L]
> RewriteRule ^(http|ftp)://.* - [F]
>
> ...
>
> <VirtualHost 1.1.1.2>
> ServerName www.mydomain.com
> ServerAlias www1.mydomain.com
> ServerAlias www2.mydomain.com
> ServerAlias www3.mydomain.com
>
> ...
>
> ErrorDocument 400 /404.html # give nice error messages
> ErrorDocument 404 /404.html
> ErrorDocument 405 /404.html
> ErrorDocument 406 /404.html
> ErrorDocument 406 /404.html
> ErrorDocument 407 /404.html
> ErrorDocument 408 /404.html
> ErrorDocument 409 /404.html
> ErrorDocument 410 /404.html
> ErrorDocument 411 /404.html
> ErrorDocument 412 /404.html
> ErrorDocument 413 /404.html
> ErrorDocument 414 /404.html
> ErrorDocument 415 /404.html
> ErrorDocument 500 /404.html
> ErrorDocument 501 /404.html
> ErrorDocument 502 /404.html
> ErrorDocument 503 /404.html
> ErrorDocument 504 /404.html
> ErrorDocument 505 /404.html
>
> ...
>
> RewriteEngine On
>
> RewriteOptions 'inherit'
> RewriteRule \.(gif|jpg|png|txt|html|cgi|pl)$ - [last]
> RewriteRule /$ - [last]
> RewriteRule ^/cgi-bin - [last] # I execute my lite CGI locally
>
> RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} -d # fix trailing
> slash
> RewriteRule ^(.+[^/])$ $1/ [R,last]
>
> RewriteRule ^/(.+)$ http://${cluster:dynamic}:${ports:%{HTTP_HOST}}/$1
> [P] # proxy to backend
> # I guess I could use SERVER_NAME instead and save me some
> entries in port.txt ...
>
> ...
> </VirtualHost>
>
> <VirtualHost 1.1.1.2>
> ServerName www.mydomain2.com
> ServerAlias www1.mydomain2.com
> ServerAlias www2.mydomain2.com
> ServerAlias www3.mydomain2.com
>
> ...
> (same as above)
> ...
> </VirtualHost>
>
> (repeat for other servers)
>
> --------------------------------
> Backend Server configuration:
>
> ServerName www3.mydomain.com
> ...
> (add mod_backhand if more than one backend, with different
> MultiCastStats and AccepStats)
> ...
> SendBufferSize 32768
>
> php3_engine Off # I only want the engine where I need it
>
> Listen www3.mydomain.com:8080
>
> <VirtualHost waterdeep:8080>
> ServerName www.mydomain.com
> ServerAlias www1.mydomain.com
> ServerAlias www2.mydomain.com
> ServerAlias www3.mydomain.com
>
> ...
>
> ErrorDocument 400 /404.html # give nice error messages
> ErrorDocument 404 /404.html
> ErrorDocument 405 /404.html
> ErrorDocument 406 /404.html
> ErrorDocument 406 /404.html
> ErrorDocument 407 /404.html
> ErrorDocument 408 /404.html
> ErrorDocument 409 /404.html
> ErrorDocument 410 /404.html
> ErrorDocument 411 /404.html
> ErrorDocument 412 /404.html
> ErrorDocument 413 /404.html
> ErrorDocument 414 /404.html
> ErrorDocument 415 /404.html
> ErrorDocument 500 /404.html
> ErrorDocument 501 /404.html
> ErrorDocument 502 /404.html
> ErrorDocument 503 /404.html
> ErrorDocument 504 /404.html
> ErrorDocument 505 /404.html
>
> ...
>
> <Location /forums>
> php3_engine On
> php3_memory_limit 4096
> </Location>
>
> </VirtualHost>
>
> Listen www3.mydomain.com:8081
>
> <VirtualHost waterdeep:8081>
> ServerName www.mydomain2.com
> ServerAlias www1.mydomain2.com
> ServerAlias www2.mydomain2.com
> ServerAlias www3.mydomain2.com
>
> ...
> (same as above)
> ...
>
> </VirtualHost>
>
> If the backend fails, the client gets a nice "Sorry...." page.
>
> Hope it helps,
>
> Dejan
>
> --__--__--
>
> Message: 5
> Date: Thu, 01 Mar 2001 18:08:53 +0100
> From: Tilman Kastner <kastner@devicen.de>
> To: <backhand-users@lists.backhand.org>
> Subject: [mod_backhand-users] How to avoid erratic MIME-types?
>
> Hello to all:
>
> Our backhand cluster (http://www.cebit.de) is up and running for some
> time
> now and it's doing a great job! A big THANK YOU to all who made this
> possible!
>
> However, here's a problem I encountered today:
>
> In our implementation, one lean front end server passes all requests to
> the
> fully-featured backends (including one back end at the same machine).
> Because the front end is stripped down, it does not know how to handle
> e.g.
> php scripts (which are supposed to be processed by the back ends, of
> course). If for any reasons, no back end is available (I had to restart
> all
> of them today due to configuration changes), the front end delivers the
> scripts "as-is" i.e the source code. This is not what we want...
> It would be nice if I could set a kind of "forced BackhandSelf"
> directive,
> so that the front end would deny any delivery or show an error page if
> no
> backend is available.
>
> Any suggestions?
>
> Tilman
>
> --
> Tilman Kastner DEVICE/N GmbH
> kastner@devicen.de Ilse-ter-Meer-Weg 7
> PGP key available 30449 Hannover, Germany