How Apache handles name based virtual hosts

Request handling is fairly simple, but may not be intuitive to new users. This document explains how Apache decides which virtual host to use to handle a request. You can click on the diagram to make it bigger.

Virtual host selection flowchart

New Request

Every new request is made using a given IP and port combination (See Listen directive).

Note: Apache listens only on the IP:port combinations defined in the Listen directives. If you define virtual hosts for any other IP:port combination, they will be unusable.

Checking for vhost

For the given IP and port combination, apache checks if any virtual hosts are defined.

Note: The IP part in a virtual host can be * or _default_ to match any IP address. These two terms are synonymous.

Plain vs SSL

Apache treats each host completely separately. It will not automatically create plain vhosts on port 80 if you create SSL vhosts on port 443. Consider using mod_md to automate this. An example configuration can be found here: https://cable.ayra.ch/certmon/modmd

No vhost

If no vhost exists for a given IP:port combination, then the request is handled by the base configuration and vhost searching ends here.

Base configuration

There is always one base configuration that apache makes available. It exists regardless of whether virtual hosts are defined or not. If there is at least one virtual host for every Listen directive, the base configuration becomes unreachable for clients, but some settings (such as rewrite rules) still propagate to the virtual hosts.

If you plan on using only virtual hosts, leave the base configuration as barren as possible to avoid unexpected behavior in your virtual hosts.

Sorting

Apache sorts the found vhosts as follows:

  1. Put vhosts into two groups, those with explicit IP addreses and those with wildcards.
  2. Sort each group in the order the vhosts appear in the configuration
  3. Sort the explicit group above the wildcard group

This means a request to http://localhost will check a virtual host for 127.0.0.1:80 before *:80

Searching every host

Once apache built the list it will now search it top to bottom for a matching host as explained in the "Searching for name match" chapter below. The first match will handle the request and further vhost searching will stop.

If no host could be found that matches the name, one of two actions will take place:

Searching for name match

Every vhost that matches a given IP:port configuration is checked using the ServerName and ServerAlias configurations. The names collected from these two directives are matched against the HTTP Host header from the client.

If multiple hosts listen on the same IP:port, they must have exactly one ServerName and may have any number of ServerAlias entries.

Host without name

One host of an IP:port set may have neither of these directives. In that case it may never match any client request and would be unusable, except if it's the first host for an IP:port set because it will then be used for requests that were not matched by any other vhost.

A virtual host without any names will inherit the name of the global configuration. This is why only one virtual host of an IP:port set can have no names defined. If a second host were to have no names, it would also inherit and create a duplicate name.

Priorities

Example: A host that defines ServerAlias *.example.com will stop hosts later in the configuration from matching using ServerName test.example.com

In other words, always declare explicitely names vhosts before wildcard vhosts.

Debugging

Running apache with -t -D DUMP_VHOSTS will dump the vhost configuration to the console. This shows you for each IP:port combination all defined hosts in the order they would be processed. It also shows where these hosts are defined and what the ServerName of each host is.

Copyright © 2021 by Kevin Gut 📧 | More services | Generated for 18.116.42.233