From c1c51cd783c35212ab764533b2afc82637b57e2a Mon Sep 17 00:00:00 2001 From: brian Date: Fri, 15 Jan 1999 00:57:10 +0000 Subject: [PATCH] This is the document on how to use mod_rewrite to eliminate the need for virtualhost settings in the config file. Many thanks to Tony Finch for contributing this! git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@82655 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/vhosts/mass.html | 330 +++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 docs/manual/vhosts/mass.html diff --git a/docs/manual/vhosts/mass.html b/docs/manual/vhosts/mass.html new file mode 100644 index 0000000000..4ecd952e2d --- /dev/null +++ b/docs/manual/vhosts/mass.html @@ -0,0 +1,330 @@ + + +Dynamically configured mass virtual hosting + + + + + +

Dynamically configured mass virtual hosting

+ +

This document describes how to efficiently serve an arbitrary number +of virtual hosts with Apache 1.3. Some familiarity with +mod_rewrite is +useful.

+ + + +

Contents:

+ + + +

Motivation

+ +

The techniques described here are of interest if your +httpd.conf contains hundreds of +<VirtualHost> sections that are substantially the +same, for example: +

+NameVirtualHost 111.22.33.44
+<VirtualHost 111.22.33.44>
+	ServerName		           www.customer-1.com
+	DocumentRoot		/www/hosts/www.customer-1.com/docs
+	ScriptAlias  /cgi-bin/  /www/hosts/www.customer-1.com/cgi-bin
+</VirtualHost>
+<VirtualHost 111.22.33.44>
+	ServerName		           www.customer-2.com
+	DocumentRoot		/www/hosts/www.customer-2.com/docs
+	ScriptAlias  /cgi-bin/  /www/hosts/www.customer-2.com/cgi-bin
+</VirtualHost>
+# blah blah blah
+<VirtualHost 111.22.33.44>
+	ServerName		           www.customer-N.com
+	DocumentRoot		/www/hosts/www.customer-N.com/docs
+	ScriptAlias  /cgi-bin/  /www/hosts/www.customer-N.com/cgi-bin
+</VirtualHost>
+
+

+ +

The basic idea is to replace all of the static +<VirtualHost> configuration with a mechanism that +works it out dynamically. This has a number of advantages: +

    +
  1. Your configuration file is smaller so Apache starts faster and + uses less memory. +
  2. Adding virtual hosts is simply a matter of creating the + appropriate directories in the filesystem and entries in the DNS - + you don't need to reconfigure or restart Apache. +
+

+ +

The main disadvantage is that you cannot have a different log file +for each server; however if you have very many virtual hosts then +doing this is dubious anyway because it eats file descriptors. It's +better to log to a pipe or a fifo and arrange for the process at the +other end to distribute the logs (and perhaps accumulate statistics, +etc.). A LogFormat directive that includes +%v for the virtual host makes it easy to do this.

+ + +

Overview of the technique

+ +

All of the dynamic virtual hosts will either be configured as part +of the main server configuration, or within a +<VirtualHost> section. For a simple (very uniform) +setup, <VirtualHost> sections aren't needed at all.

+ +

A couple of things need to be `faked' to make the dynamic virtual +host look like a normal one. The most important is the server name +(configured with ServerName and available to CGIs via the +SERVER_NAME environment variable). The way it is +determined is controlled by the UseCanonicalName +directive: with UseCanonicalName off the server name +comes from the contents of the Host: header in the +request. If there is no Host: header then the value +configured with ServerName is used instead.

+ +

The other one is the document root (configured with +DocumentRoot and available to CGIs via the +DOCUMENT_ROOT environment variable). This is used by the +core module when mapping URIs to filenames, but in the context of +dynamic virtual hosting its value only matters if any CGIs or SSI +documents make use of the DOCUMENT_ROOT environment +variable. This is an Apache extension to the CGI specification and as +such shouldn't really be relied upon, especially because this +technique breaks it: there isn't currently a way of setting +DOCUMENT_ROOT dynamically.

+ +

The meat of the mechanism works via Apache's URI-to-filename +translation API phase. This is used by a number of modules: +mod_rewrite, +mod_alias, +mod_userdir, +and the core module. +In the default configuration these modules are called in that order +and given a chance to say that they know what the filename is. Most of +these modules do it in a fairly simple fashion (e.g. the core module +concatenates the document root and the URI) except for +mod_rewrite, which provides enough functionality to do +all sorts of sick and twisted things (like dynamic virtual hosting). +Note that because of the order in which the modules are called, using +a mod_rewrite configuration that matches any URI means +that the other modules (particularly mod_alias) will +cease to function. The examples below show how to deal with this.

+ +

The dynamic virtual hosting idea is very simple: use the +server name as well as the URI to determine the corresponding +filename.

+ + +

Simple name-based dynamic virtual hosts

+ +

This extract from httpd.conf implements the virtual +host arrangement outlined in the Motivation +section above, but in a generic fashion.

+ +

The first half shows some other configuration options that are +needed to make the mod_rewrite part work as expected; the +second half uses mod_rewrite to do the actual work. Some +care is taken to do a per-dynamic-virtual-host equivalent of +ScriptAlias.

+ +
+# dynamic ServerName
+UseCanonicalName Off
+
+# splittable logs
+LogFormat "%v %h %l %u %t \"%r\" %s %b" vcommon
+CustomLog logs/access_log vcommon
+
+<Directory /www/hosts>
+	# ExecCGI is needed here because we can't force
+	# CGI execution in the way that ScriptAlias does
+	Options FollowSymLinks ExecCGI
+</Directory>
+
+# now for the hard bit
+
+RewriteEngine On
+
+# a ServerName derived from a Host: header may be any case at all
+RewriteMap  lowercase  int:tolower
+
+## deal with normal documents first:
+# allow Alias /icons/ to work - repeat for other aliases
+RewriteCond  %{REQUEST_URI}  !^/icons/
+# allow CGIs to work
+RewriteCond  %{REQUEST_URI}  !^/cgi-bin/
+# do the magic
+RewriteRule  ^/(.*)$  /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
+
+## and now deal with CGIs - we have to force a MIME type
+RewriteCond  %{REQUEST_URI}  ^/cgi-bin/
+RewriteRule  ^/(.*)$  /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1  [T=application/x-httpd-cgi]
+
+# that's it!
+
+ + +

A virtually hosted homepages system

+ +

This is an adjustment of the above system tailored for an ISP's +homepages server. Using slightly more complicated rewriting rules we +can select substrings of the server name to use in the filename so +that e.g. the documents for www.user.isp.com are found in +/home/user/. It uses a single cgi-bin +directory instead of one per virtual host.

+ +
+RewriteEngine on
+
+RewriteMap   lowercase  int:tolower
+
+# allow CGIs to work
+RewriteCond  %{REQUEST_URI}  !^/cgi-bin/
+
+# check the hostname is right so that the RewriteRule works
+RewriteCond  ${lowercase:%{HTTP_HOST}}  ^www\.[a-z-]+\.isp\.com$
+
+# concatenate the virtual host name onto the start of the URI
+# the [C] means do the next rewrite on the result of this one
+RewriteRule  ^(.+)  ${lowercase:%{HTTP_HOST}}$1  [C]
+
+# now create the real file name
+RewriteRule  ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2
+
+# define the global CGI directory
+ScriptAlias  /cgi-bin/  /www/std-cgi/
+
+ + +

Using a separate virtual host configuration file

+ +

This arrangement uses a separate configuration file to specify the +translation from virtual host to document root. This provides more +flexibility but requires more configuration.

+ +

The vhost.map file contains something like this: +

+www.customer-1.com  /www/customers/1
+www.customer-2.com  /www/customers/2
+# ...
+www.customer-N.com  /www/customers/N
+
+

+ +

The http.conf contains this: +

+RewriteEngine on
+
+RewriteMap   lowercase  int:tolower
+
+# define the map file
+RewriteMap   vhost      txt:/www/conf/vhost.map
+
+# deal with aliases as above
+RewriteCond  %{REQUEST_URI}               !^/icons/
+RewriteCond  %{REQUEST_URI}               !^/cgi-bin/
+RewriteCond  ${lowercase:%{SERVER_NAME}}  ^(.+)$
+# this does the file-based remap
+RewriteCond  ${vhost:%1}                  ^(/.*)$
+RewriteRule  ^/(.*)$                      %1/docs/$1
+
+RewriteCond  %{REQUEST_URI}               ^/cgi-bin/
+RewriteCond  ${lowercase:%{SERVER_NAME}}  ^(.+)$
+RewriteCond  ${vhost:%1}                  ^(/.*)$
+RewriteRule  ^/(.*)$                      %1/cgi-bin/$1
+
+

+ + +

Using more than one virtual hosting system on the same server

+ +

With more complicated setups, you can use Apache's normal +<VirtualHost> directives to control the scope of +the various rewrite configurations. For example, you could have one IP +address for homepages customers and another for commercial customers +with the following setup. This can of course be combined with +convential <VirtualHost> configuration +sections.

+ +
+UseCanonicalName Off
+
+LogFormat "%v %h %l %u %t \"%r\" %s %b" vcommon
+CustomLog logs/access_log vcommon
+
+<Directory /www/commercial>
+	Options FollowSymLinks ExecCGI
+	AllowOverride All
+</Directory>
+
+<Directory /www/homepages>
+	Options FollowSymLinks
+	AllowOverride None
+</Directory>
+
+<VirtualHost 111.22.33.44>
+	ServerName www.commercial.isp.com
+
+	RewriteEngine On
+	RewriteMap    lowercase  int:tolower
+
+	RewriteCond   %{REQUEST_URI}  !^/icons/
+	RewriteCond   %{REQUEST_URI}  !^/cgi-bin/
+	RewriteRule   ^/(.*)$  /www/commercial/${lowercase:%{SERVER_NAME}}/docs/$1
+
+	RewriteCond   %{REQUEST_URI}  ^/cgi-bin/
+	RewriteRule   ^/(.*)$  /www/commercial/${lowercase:%{SERVER_NAME}}/cgi-bin/$1  [T=application/x-httpd-cgi]
+</VirtualHost>
+
+<VirtualHost 111.22.33.45>
+	ServerName www.homepages.isp.com
+
+	RewriteEngine on
+	RewriteMap    lowercase  int:tolower
+
+	RewriteCond   %{REQUEST_URI}  !^/cgi-bin/
+
+	RewriteCond   ${lowercase:%{HTTP_HOST}}  ^www\.[a-z-]+\.isp\.com$
+	RewriteRule   ^(.+)  ${lowercase:%{HTTP_HOST}}$1  [C]
+	RewriteRule   ^www\.([a-z-]+)\.isp\.com/(.*) /www/homepages/$1/$2
+
+	ScriptAlias   /cgi-bin/ /www/std-cgi/
+</VirtualHost>
+
+ + +
+ +

+ Apache HTTP Server Version 1.3 +

+ +Index +Home + + + -- 2.40.0