This section explains a configuration setup for proxying your backend mod_perl servers when you need to use virtual hosts.
Apache supports three flavors of virtual hosts:
In the dual-server setup, which virtual host flavor is used on the frontend (reverse proxy) server is irrelevant. When running a large number of virtual hosts, it is generally preferable to use name-based virtual hosts, since they share a single IP address. HTTP clients have been supporting this since 1995.
SSL-enabled sites cannot use this scheme, however. This is because when using SSL, all HTTP traffic is encrypted, and this includes the request's Host: header. This header is unavailable until the SSL handshake has been performed, and that in turn requires that the request has been dispatched to the appropriate virtual host, because the SSL handshake depends on that particular host's SSL certificate. For this reason, each SSL-enabled virtual host needs its own, unique IP address. You can still use name-based virtual hosts along with SSL-enabled virtual hosts in the same configuration file, though.
For the backend mod_perl-enabled server, we recommend using port-based virtual hosts using the IP address 127.0.0.1 (localhost). This enforces the fact that this server is accessible only from the frontend server and not directly by clients.
When using virtual hosts, any configuration directive outside of a <VirtualHost> container is applied to a virtual host called the main server, which plays a special role. First, it acts as the default host when you're using name-based virtual hosts and a request can't be mapped to any of the configured virtual hosts (for example, if no Host: header is provided). Secondly, many directives specified for the main server are merged with directives provided in <VirtualHost> containers. In other words, virtual hosts inherit properties from the main server. This allows us to specify default behaviors that will apply to all virtual hosts, while still allowing us to override these behaviors for specific virtual hosts.
In the following example, we use the PerlSetupEnv directive to turn off environment population for all virtual hosts, except for the www.example.com virtual host, which needs it for its legacy CGI scripts running under Apache::Registry:
PerlSetupEnv Off Listen 8001 <VirtualHost 127.0.0.1:8001> ServerName www.example.com PerlSetupEnv On </VirtualHost>
The following example illustrates the use of name-based virtual hosts. We define two virtual hosts, www.example.com and www.example.org, which will reverse-proxy dynamic requests to ports 8001 and 8002 on the backend mod_perl-enabled server.
Listen 192.168.1.2:80 NameVirtualHost 192.168.1.2:80
Replace 192.168.1.2 with your server's public IP address.
LogFormat "%v %h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\""
The log format used is the Common Log Format prefixed with %v, a token representing the name of the virtual host. Using a combined log common to all virtual hosts uses fewer system resources. The log file can later be split into seperate files according to the prefix, using splitlog or an equivalent program.
The following are global options for mod_rewrite shared by all virtual hosts:
RewriteLogLevel 0 RewriteRule \.(gif|jpg|png|txt|html)$ - [last]
This turns off the mod_rewrite module's logging feature and makes sure that the frontend server will handle files with the extensions .gif, .jpg, .png, .txt, and .html internally.
If your server is configured to run traditional CGI scripts (under mod_cgi) as well as mod_perl CGI programs, it would be beneficial to configure the frontend server to run the traditional CGI scripts directly. This can be done by altering the (gif|jpg|png|txt|html) rewrite rule to add cgi if all your mod_cgi scripts have the .cgi extension, or by adding a new rule to handle all /cgi-bin/* locations internally.
The virtual hosts setup is straightforward:
##### www.example.com <VirtualHost 192.168.1.2:80> ServerName www.example.com ServerAdmin webmaster@example.com DocumentRoot /home/httpd_docs/htdocs/www.example.com RewriteEngine on RewriteOptions 'inherit' RewriteRule ^/(perl/.*)$ http://127.0.0.1:8001/$1 [P,L] ProxyPassReverse / http://www.example.com/ </VirtualHost> ##### www.example.org <VirtualHost 192.168.1.2:80> ServerName www.example.org ServerAdmin webmaster@example.org DocumentRoot /home/httpd_docs/htdocs/www.example.org RewriteEngine on RewriteOptions 'inherit' RewriteRule ^/(perl/.*)$ http://127.0.0.1:8002/$1 [P,L] ProxyPassReverse / http://www.example.org/ </VirtualHost>
The two virtual hosts' setups differ in the DocumentRoot and ProxyPassReversesettings and in the backend ports to which they rewrite.
This section describes the configuration of the backend server.
The backend server listens on the loopback (localhost) interface:
BindAddress 127.0.0.1
In this context, the following directive does not specify a listening port:
Port 80
Rather, it indicates which port the server should advertise when issuing a redirect.
The following global mod_perl settings are shared by all virtual hosts:
##### mod_perl settings PerlRequire /home/httpd/perl/startup.pl PerlFixupHandler Apache::SizeLimit PerlPostReadRequestHandler Book::ProxyRemoteAddr PerlSetupEnv Off
As explained earlier, we use the Book::ProxyRemoteAddr handler to get the real remote IP addresses from the proxy.
We can then proceed to configure the virtual hosts themselves:
##### www.example.com Listen 8001 <VirtualHost 127.0.0.1:8001>
The Listen directive specifies the port to listen on. A connection to that port will be matched by this <VirtualHost> container.
The remaining configuration is straightforward:
ServerName www.example.com ServerAdmin webmaster@example.com <Location /perl> SetHandler perl-script PerlHandler Apache::Registry Options +ExecCGI </Location> <Location /perl-status> SetHandler perl-script PerlHandler Apache::Status </Location> </VirtualHost>
We configure the second virtual host in a similar way:
##### www.example.org Listen 8002 <VirtualHost 127.0.0.1:8002> ServerName www.example.org ServerAdmin webmaster@example.org <Location /perl> SetHandler perl-script PerlHandler Apache::Registry Options +ExecCGI </Location> </VirtualHost>
You may need to specify the DocumentRootsetting in each virtual host if there is any need for it.
Copyright © 2003 O'Reilly & Associates. All rights reserved.