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.
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.
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.
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
If no vhost exists for a given IP:port combination, then the request is handled by the base configuration and vhost searching ends here.
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.
Apache sorts the found vhosts as follows:
This means a request to http://localhost
will check a virtual host for 127.0.0.1:80
before *:80
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:
StrictHostCheck Off
(default): Handle request using the first virtual host from the listStrictHostCheck On
: Return "HTTP 400 Bad Request"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.
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.
ServerName
priority over ServerAlias
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.
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.