Chapter 5. Virtual Hosting

This chapter explains how to host multiple websites with a single instance of the Apache server, using both IP-address–based and name-based virtual hosting. It also covers other topics related to providing hosting for multiple users, such as home directories and per-directory configuration files.

What Is Virtual Hosting?

Virtual hosting is a feature provided by most modern web servers that allows you to serve multiple websites, each one identified by one or more domains, using a single instance of a server. This provides for a centralized administration and an efficient use of system resources. Many commercial web hosting providers are able to provide service to hundreds of customers using a single server instance instead of having hundreds of Apache servers running in the background.

What Is IP-based Virtual Hosting?

<VirtualHost 192.168.200.4:80>
(...)
</VirtualHost>

The easiest way to provide virtual hosting is based on the IP address/port combination that the client connects to. We can configure Apache to support IP-based virtual hosting using <VirtualHost> sections. Each <VirtualHost> contains configuration directives that will be applied for requests addressed to the IP address (and optionally port number) specified in the opening tag. Of course, the server Apache is running on must have been configured with those IP addresses.

Note

If you are listening on nonstandard ports, make sure to provide a Listen directive for each one of them. Just listing them on the <VirtualHost> section will not cause Apache to listen for request in those ports.

IP-based virtual hosting has the drawback of having to assign a different IP address to each different virtual host.

Configuring IP-based Virtual Hosting

The example in Listing 5.1 shows three IP-based virtual hosts serving content for three websites: www.example.com, a staging version of www.example.com, and www.example.net. The ServerName directive inside each container will be used for constructing self-referential URLs. The DocumentRoot directive specifies a different location for the website’s content for each virtual host. It is also possible to log requests and errors for each virtual host to a different file. This can be done by placing logging directives such as TransferLog and ErrorLog inside the virtual host container, as explained in Chapter 3.

The addresses and ports listed inside the opening tag of a <VirtualHost> definition will not have any effect on what addresses or ports Apache listens to, so you still need to provide the appropriate Listen directives. If no port is specified in a <VirtualHost> definition, the one specified in the most recent Apache directive will be used. It is also possible to specify a wildcard *” to listen for requests in all ports that Apache is listening in, as shown in the example.net virtual host.

Example 5.1. Configuring IP-Based Virtual Hosts

Listen 8080
Listen 80
<VirtualHost 192.168.200.2>
    ServerName www.example.com
    DocumentRoot /usr/local/apache/sites/example.com
</VirtualHost>

<VirtualHost 192.168.200.2:8080>
    ServerName www.example.com
    DocumentRoot /usr/local/apache/sites/staging
</VirtualHost>

<VirtualHost 192.168.200.4:*>
    ServerName www.example.net
    DocumentRoot /usr/local/apache/sites/example.net
</VirtualHost>

What Is Name-based Virtual Hosting?

As seen in the previous sections, IP virtual hosting requires a different IP address for each website. This creates quite a few problems if you need to host a great number of websites or you cannot get or do not want to pay for more than one IP address. An example where this would be the case would be if you wanted to run several personal websites out of your own server at the end of a DSL line.

Name-based virtual hosting takes advantage of the fact that most browsers in widespread use (and almost all recent ones) transmit a Host: header in their HTTP request. This is a requirement of the HTTP/1.1 protocol, but is also present in most implementations of HTTP/1.0. Thus, we can decide which information to present to the user based on data from the HTTP request, rather than on data from the connection itself. This allows several virtual hosts to share the same IP address and port combination.

Configuring Name-based Virtual Hosting

The configuration for named virtual hosts is similar to IP virtual hosts. The example in Listing 5.2 shows two virtual hosts sharing the 192.168.200.2 IP address.

Apache will decide to which virtual host to “route” the request based on the value of the Host: header of the HTTP request. It will be compared for a match with the hostname provided by ServerName and any additional hostnames provided by the ServerAlias directives, which are optional.

Example 5.2. Configuring Name-based Virtual Hosts

Listen 80
NameVirtualHost 192.168.200.2
<VirtualHost 192.168.200.2>
    ServerName www.example.com
    ServerAlias example.com web.example.com
    DocumentRoot /usr/local/apache/sites/example.com
</VirtualHost>

<VirtualHost 192.168.200.2>
    ServerName www.example.net
    DocumentRoot /usr/local/apache/sites/example.net
</VirtualHost>

The NameVirtualHost directive is required to tell Apache that a particular IP address will be used for name-based virtual hosts. You can tell Apache to use any available IP address for name-based virtual hosting with

NameVirtualHost *

Of course, your DNS servers need to be configured properly so the domains www.example.com, example.com, and web.example.com resolve to the 192.168.200.2 address.

What Happens If a Request Does Not Match Any Virtual Host?

If a request does not match any virtual host then it will be served by the main server in the case of IP-based virtual hosting. In the case of name-based virtual hosting, the first name-based virtual host will be used. See the next couple of sections for details on how to configure a default catch-all virtual host.

Configuring a Default Name-based Virtual Host

NameVirtualHost *
<VirtualHost *>
...
</VirtualHost>

As mentioned in the previous section, the first virtual host present in the configuration file will answer requests for domains that are not explicitly handled by other virtual hosts. If you host multiple websites, it can be useful to set up that virtual host so it returns a page that either provides a list of available websites in the machine or explains why that particular website is not recognized. You can do so by placing such a file (default.html in the example in Listing 5.3) in the document root and redirecting all requests to it with an AliasMatch directive. You can achieve a similar effect replacing it with an ErrorDocument directive:

ErrorDocument 404 /default.html

Or you can even send users directly to one of your other websites with a Redirect directive.

RedirectMatch /* http://www.example.com

Example 5.3. Configuring a Default Name-based Virtual Host

NameVirtualHost *
# The section below needs to be placed on top of any
other virtual host section
<VirtualHost *>
ServerName default.example.com
DocumentRoot /usr/local/apache/sites/default
AliasMatch /* /default.html
</VirtualHost>

Configuring a Default IP-based Virtual Host

<VirtualHost _default_ >
ServerName default.example.com
DocumentRoot /usr/local/apache/sites/default
</VirtualHost>

The special _default_ syntax allows you to define a virtual host that will serve requests for addresses and port combinations not covered by other virtual hosts. You can also specify a port number in combination with the _default_ keyword, as in the following example, taken from the default Apache mod_ssl configuration. It specifies a virtual host that will listen for requests on that particular port, in all addresses not explicitly handled by other virtual hosts:

<VirtualHost _default_:443>
SSLEngine on
ServerName secure.example.com:443
DocumentRoot /usr/local/apache/sites/default
...
</VirtualHost>

Mixing Name-based and IP-based Virtual Hosts

It is possible to mix and match IP-based and name-based virtual hosts, as shown in Listing 5.4. Instead of using NameVirtualHost *, you will need to provide separate NameVirtualHost directives for each IP address that will be associated with name-based virtual hosts. This example shows two name-based virtual hosts associated with the 192.168.200.2 IP address and one IP-based virtual host associated with IP address 192.168.200.4.

Example 5.4. Mixing IP-based and Name-based Virtual Hosting

NameVirtualHost 192.168.200.2
<VirtualHost 192.168.200.2>
    ServerName www.example.com
    DocumentRoot /usr/local/apache/sites/example.com
</VirtualHost>

<VirtualHost 192.168.200.2>
    ServerName staging.example.com
    DocumentRoot /usr/local/apache/sites/staging
</VirtualHost>

<VirtualHost 192.168.200.4>
    ServerName www.example.net
    DocumentRoot /usr/local/apache/sites/example.net
</VirtualHost>

Debugging Virtual Host Setups

You can invoke the httpd binary with the -S option, as shown in Listing 5.5, and Apache will parse the configuration file. After processing all of the virtual host related information, it will present you with information about each configured virtual host and default host values. This is a very handy tool for debugging complex virtual host setups.

Example 5.5. Checking the Virtual Host Configuration

# httpd -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:*                    is a NameVirtualHost
         default server example.com
(/usr/local/www/conf/httpd.conf:1055)
         port * namevhost example.com
(/usr/local/www/conf/httpd.conf:1055)
         port * namevhost example.org
(/usr/local/www/conf/httpd.conf:1082)
         port * namevhost example.net
(/usr/local/www/conf/httpd.conf:1094)
Syntax Ok

Using SSL with Name-based Virtual Hosts

The short answer is that SSL cannot be used with name-based virtual hosts, as there are currently no mainstream browsers that support it. See the related section in Chapter 7 for a more in-depth explanation.

Alternate Virtual Hosting

UseCanonicalName Off
VirtualDocumentRoot /usr/local/apache/vhosts/%0
VirtualScriptAlias 
    /usr/local/apache/vhosts/%0/cgi-bin

If you maintain a great number of virtual hosts, it may be desirable to use a different approach for virtual hosting. This is particularly true for ISPs that host thousands of customers, as it would require entering details for each one of the virtual hosts in the configuration file and restarting the server each time a change is required.

The mod_virtualhost_alias allows you to set up a different document root for each virtual host dynamically. This means that the request is mapped to a certain path on the file system based on information from the request itself, such as the IP address or the hostname. This example maps requests for a particular hostname to a path in the file system that includes that hostname (represented by the %0 in the path). Similarly, the VirtualScriptAlias directive allows execution of CGI scripts in a directory path based on the hostname referred to by the request. If a user sends a request for /manual/index.html to the www.example.com host, this directive will map that to /usr/local/apache/vhosts/www.example.com/manual/index.html.

In a similar manner, you can map IP addresses instead of hostnames, for IP-based virtual hosting using the VirtualDocumentRootIP and VirtualScriptAliasIP directives.

You can decide to map requests based only on parts of the hostname or IP address or based on the port of the request. For that, you can use different %-based sequences, such as %p for the port number, or %1 for the first part of the domain, %2 for the second, and so on.

Alternate Virtual Hosting Modules

The mod_vhost_alias module is probably one of the most popular mass virtual host modules, due to the fact that is bundled with Apache. There are, however, a number of alternatives such as the following:

Chapter 11 covers a number of Multi-Processing Modules (MPMs), such as mod_perchild, that allow you to run different virtual hosts under different user ids.

Per-directory Configuration Files

AccessFilename .htaccess

An issue related to hosting multiple websites is that of providing hosting services for multiple clients. If the number of clients is significant, you may want to use per-directory configuration files. Per-directory configuration files are usually called htaccess files because they used to be used mostly for access control tasks. When this functionality is enabled, Apache will look for special configuration files in all directories leading to the file being requested. For example, if Apache receives a request for /usr/local/apache2/htdocs/index.html, it will look for per-directory configuration files in the /, /usr/, /usr/local/, /usr/local/apache2, and /usr/local/apache2/htdocs directories, in that order.

If found, the content for these configuration files is processed and merged with the main configuration from httpd.conf read at startup time. This is quite convenient for the system administrator, as it can allow users to self-manage their configurations. Also, since the files are parsed on-the-fly, the server does not need to be restarted for each change. On the downside, this has a performance penalty. Apache must perform expensive disk operations looking for these files in every request, even if the files do not exist.

The directive AccessFilename allows you to provide a list of filenames that Apache will look for when looking for per-directory configuration files.

Controlling the Scope of Per-directory Configuration Files

AllowOverride Indexes Limit AuthConfig

If .htaccess is present in the Context: field in the directive reference syntax description of the Apache documentation, it means that directive can be placed in per-directory configuration files.

The AllowOverride directive allows you to control the kind of configuration directives that can appear in per-directory configuration files. For example, you can let users change directory-indexing directives but not those related to authorization. Possible values are

  • AuthconfigAuthorization directives

  • FileInfoDirectives controlling document types

  • IndexesDirectives controlling directory indexing

  • LimitHost access control directives

  • OptionsDirectives controlling specific directory features

  • AllAll directives belonging to above groups can be used

  • NoneDisable per-directory configuration files for that directory tree

Disabling Per-directory Configuration Files

<Directory />
AllowOverride None
</Directory>

If you do not have a use for per-directory configuration files, you can disable this functionality altogether with the configuration shown here. This will increase the security and performance of the server, at the cost of the flexibility and convenience provided by these files.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.233.205