With the use of virtual hosts we can make an
httpd server manage multiple websites. We can use both IP and name-based virtual hosts; what are the differences between them?
How Apache decides what of the virtual hosts should be used to respond to a client request? We will answer these questions in this article, keep reading!In this tutorial you will learn:
- What are the differences between IP and name based virtual hosts
- What is the Listen directive and how it is used
- How Apache decides what virtual host should be used to respond to a request
Software Requirements and Conventions Used
|Category||Requirements, Conventions or Software Version Used|
|Software||No specific software needed|
|Other||Familiarity with the Apache web server and http basic concepts|
|Conventions|| # - requires given linux commands to be executed with root privileges either directly as a root user or by use of |
The “Listen” directive
The first thing to take in consideration, is the
Listen directive. This directive is mandatory, and is needed to tell the
httpd server to what
IP-PORT combination it should listen for requests. By default the server is usually configured to listen to every
IP on port
/etc/httpd/conf/httpd.conf which is the main
httpd configuration file on Fedora/RHEL/CentOS systems, at line
45, for example, we can read:
As you can see, only the port is specified with the
Listen directive. As a result, the server will listen on that port on all the machine IP addresses. If an address is specified, instead, the server will listen only on the provided
Listen directive can be repeated multiple times, therefore is very easy to specify multiple combinations.
Once the server is configured to listen to a specific address or port, Apache must decide what VirtualHost should be used to fulfill the client request. Before seeing the steps involved in this decision, let’s briefly see how a virtual host is defined.
The directive used to create and configure virtual host, is
VirtualHost; it uses the following syntax:
<VirtualHost addr[:port] [addr[:port]] ...> ... </VirtualHost>
As we can observe, each
VirtualHost directive needs an
addr; it can be specified as:
- An IP address, either IPv4 or IPv6 (IPv6 addresses must be enclosed in square brackets);
- A Fully Qualified Domain Name;
*wildcard (this will match all addresses)
All the parameters and configurations made inside the
<VirtualHost></VirtualHost> tags, are “local” to that specific virtual host. Here is an example of a virtual host configuration:
<VirtualHost 22.214.171.124:80> ServerName: www.exampleone.com DocumentRoot "/var/www/exampleone" </VirtualHost>
Or, using a wildcard:
<VirtualHost *:80> ServerName: www.exampleone.com DocumentRoot "/var/www/exampleone" </VirtualHost>
The first thing the server does is to analyze, in order, every virtual host, and check if their
addr matches the request. It’s important to notice that defined IP addresses have priority over wildcards, that are considered only if no exact matches are found. At this point we can have three cases:
- Only one virtual host matches the request;
- No virtual hosts match the request;
- Multiple virtual host matches the request;
The first case resolution is easy: if the client request matches only one specific virtual host, the
httpd server does respond by serving the content related to that virtual host. In this case we talk about
IP-based virtual hosts.
The second case is also easily explained: if no virtual host configuration satisfies the client request, the default server configuration is used to respond to the request. For default configuration, we intend everything set outside of
In the third case multiple virtual hosts match the client request. When this happens, the server must discriminate depending on some other factor other than the
IP:PORT combination: the scheme and hostname the virtual host uses to identify itself.
Name-based virtual hosts
The server does examine every matching virtual host in order of definition and selects which one should be used depending on the requested
host name. This are called “name-based” virtual hosts. The first virtual host that matches the request is used. If there are no matches, the server does use the first defined
VirtualHost as fallback.
The main advantage of using name-based virtual hosts, is that we can run multiple websites on the same IP address. Let’s see an example of a name-based VirtualHost:
<VirtualHost *:80> ServerName www.serverone.com DocumentRoot /var/www/serverone </VirtualHost>
*:80 is used as address, the virtual host will match every request made on port
80. What makes the difference in this case is the
ServerName directive. If this directive is omitted, the server will try to obtain a Fully Qualified Domain Name (FQDN) based on the operating system hostname.
The server checks if the host name specified in the request matches the one configured via the
ServerName directive, in this case
www.serverone.com. If it does, the content specified with the
DocumentRoot directive it’s served to the client.
Inside a virtual host configuration it’s also possible to define one or more aliases, to match multiple host names. This is accomplished by using the
<VirtualHost *:80> ServerName www.serverone.com ServerAlias *.serverone.com DocumentRoot /var/www/serverone </VirtualHost>
In the above configuration we added a
ServerAlias instruction using a wildcard. The configuration will now match also every subdomain of
IP-based virtual hosts
IP-based virtual hosts, as we already saw, are basically what the
httpd server uses by default. When using them, the ability to serve multiple websites is based on the client request
It goes by itself that, to use this type of virtual hosts, a machine must have multiple network addresses. This doesn’t mean that multiple physical network interfaces are required, since multiple addresses can be assigned to the same interface ( this is called
IP aliasing), and virtual interfaces can also be created (want to know how to create a virtual network interface on Linux?
Take a look at our article about creating virtual network interfaces on Linux. Here are two examples of IP-based virtual hosts:
Listen 8080 <VirtualHost 126.96.36.199:80> ServerName: www.exampleone.com DocumentRoot "/var/www/exampleone" </VirtualHost> <VirtualHost 188.8.131.52:8080> ServerName www.exampletwo.com DocumentRoot "/var/www/exampletwo" </VirtualHost>
Above we can see that even if the two virtual hosts have the same IP address, a different port is specified in the second example:
8080. In order for the server to be able to listen to that port we use the
Listen 8080 directive.
In this tutorial we saw how Apache virtual hosts work. We learned the difference between IP and name-based virtual hosts, and how the server determines what configuration should be used to respond to a client request. Please, take a look at installing Apache article if you want to know more about how to configure an Apache virtual host.