Apache IP-Based vs Name-Based Virtual Hosts

In order to understand what are IP-based and Name-based virtual hosts in Apache HTTPD web server and the differences between them, you must completely understand what virtual hosts are and how are they defined using the <VirtualHost> directive. If you’re already aware then continue reading, otherwise I’d recommend you to go through the guide to virtual hosts.

So what are IP-based and Name-based Virtual Hosts ?

Basically, the Apache web server breaks the concept of virtual hosts into two further child concepts or types:

  • IP-based virtual hosts
  • Name-based virtual hosts

When you write your first virtual host using the <VirtualHost> block, you specify an address which generally is a combination of an IP address and an optional port. In order for this virtual host to be used, httpd must be listening on the ip-port combination and a client must send a request to the same. For instance, let’s say this is what my configuration has:

# Main server config

  DocumentRoot /var/www/public_html

<VirtualHost *>
  ServerName foo.com
  DocumentRoot /home/foo/public_html

Both the virtual hosts match some form of address-port combination which are “different”. Hence the virtual hosts do not share the address-port combination. As long as you continue to have non-shared virtual hosts or just one virtual host defined per address-port combination, they’ll be called IP-based virtual hosts.

If I dump my parsed vhosts setting (apachectl -D DUMP_VHOSTS or httpd -D DUMP_VHOSTS), this is what we’ll see:

$ apachectl -D DUMP_VHOSTS
VirtualHost configuration:    system-hostname (/etc/httpd/conf.d/welcome.conf:29)
*:*                    foo.com (/etc/httpd/conf.d/welcome.conf:38)

Seems fine. The ip-port of each virtual host along with the hostname of it (picked from ServerName).

Now if in order to serve another website from the same httpd instance (or the same machine basically), if I add another virtual host to my configuration like this:

... config specified above

<VirtualHost *>
  ServerName bar.com
  DocumentRoot /home/bar/public_html

And then dump my parsed vhost settings, we’ll see some interesting changes:

$ apachectl -D DUMP_VHOSTS
VirtualHost configuration:    system-hostname (/etc/httpd/conf.d/welcome.conf:29)
*:*                    is a NameVirtualHost
         default server foo.com (/etc/httpd/conf.d/welcome.conf:38)
         port * namevhost foo.com (/etc/httpd/conf.d/welcome.conf:38)
         port * namevhost bar.com (/etc/httpd/conf.d/welcome.conf:42)

See! As soon as I defined another virtual host for bar.com that shared the same address-port as that of the foo.com virtual host, both of them become a namevhost. *:* combination in itself is referred to as NameVirtualHost.

Thus, when you create multiple virtual hosts that share the same IP address and the optional port combination, they automatically turn into what is called, name-based virtual hosts. Oh and this is regardless of any ServerName or ServerAlias directive used.

From the documentation:

Any time an IP address and port combination is used in multiple virtual hosts, name-based virtual hosting is automatically enabled for that address.

Why the differentiation ?

A web server could bind to different interfaces and ports since old times and multiple virtual hosts would allow matching requests on different ip-port combinations to serve requests differently. So httpd could bind to and separately and virtual hosts could be defined for both the addresses to handle requests accordingly. It was natural to think of them as “ip-based”.

But with time, naturally it made sense to also be able to serve multiple websites on the same ip-port combination. It is a better option to running multiple websites on multiple machines with each of them running an httpd daemon. This could be achieved with the help of HTTP Host header which is matched with ServerName allowing us to have multiple virtual hosts with same ip-port, but differentiated on the basis of ServerName/ServerAlias – as we saw with the foo.com and bar.com virtual hosts above.

ServerName/ServerAlias directives set a unique hostname for every virtual host which was previously only “ip-based”. So it might have felt natural to differentiate them from “ip-based” vhosts and call them something like “name-based” virtual hosts. For the sake of better understanding maybe.

I don’t have a definitive answer to “why the differentiation?”. I mean having the same functionality without the distinction wouldn’t have made much of a difference I guess. But this hypothesis doesn’t seem too off.

Anyway, once you understand how the virtual host matching or resolution works in different cases, the differentiation or categorisation may not concern you at all.

Leave a Reply

Your email address will not be published. Required fields are marked *