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 143.110.176.71: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:
143.110.176.71: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 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
</VirtualHost>
And then dump my parsed vhost settings, we’ll see some interesting changes:
$ apachectl -D DUMP_VHOSTS
VirtualHost configuration:
143.110.176.71: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 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 192.168.1.2:80
and 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 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.