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 <VirtualHost 220.127.116.11:8080> DocumentRoot /var/www/public_html </VirtualHost> <VirtualHost *> ServerName foo.com DocumentRoot /home/foo/public_html </VirtualHost>
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: 18.104.22.168:8080 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
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 </VirtualHost>
And then dump my parsed vhost settings, we’ll see some interesting changes:
$ apachectl -D DUMP_VHOSTS VirtualHost configuration: 22.214.171.124:8080 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
*:* combination in itself is referred to as
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
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
192.168.1.4:9999 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
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.