Apache IP and Name Based Virtual Hosts Explained

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
Apache IP and name based virtual hosts explained

Apache IP and name based virtual hosts explained

Software Requirements and Conventions Used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution Independent
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 sudo command
$ – requires given linux commands to be executed as a regular non-privileged user

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 80.

In /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:

Listen 80

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 IP:PORT combination.

The Listen directive can be repeated multiple times, therefore is very easy to specify multiple combinations.

VirtualHost matching



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;
  • A * 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 93.184.216.34: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:

  1. Only one virtual host matches the request;
  2. No virtual hosts match the request;
  3. 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 <VirtualHost></VirtualHost>.

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>

Since *: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 ServerAlias directive:

<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 serverone.com.

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 IP:PORT combination.

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 93.184.216.34:80>
  ServerName: www.exampleone.com
  DocumentRoot "/var/www/exampleone"
</VirtualHost>

<VirtualHost 93.187.216.34: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.

Conclusion

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.



Comments and Discussions
Linux Forum