Different VirtualHost entries for IPv4 and IPv6 in apache

The VirtualHost directive in Apache configuration enables us to run multiple websites on a single server. I wanted to have two different VirtualHost entries for the same domain on different IPv4 and IPv6 addresses. I am using adas.example.org as the domain name in the example mentioned here.

<VirtualHost 192.168.0.5:80>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>


<VirtualHost 192.168.0.5:443>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>


<VirtualHost [fe80::9e73:870f:e789:e053]:80>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>


<VirtualHost [fe80::9e73:870f:e789:e053]:443>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>
 

I was doing the task via ansible for multiple servers. However, for every server, the IP addresses are different. Therefore, I can not hard code them in a configuration file. So, I tried to use 0.0.0.0 for IPv4 [::] for IPv6. Now the configurations look like the following :

<VirtualHost 0.0.0.0:80>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>


<VirtualHost 0.0.0.0:443>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>


<VirtualHost [::]:80>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>


<VirtualHost [::]:443>
    ServerName "adas.example.org"
    DocumentRoot "/var/www/adas.example.org"
</VirtualHost>
 

The problem

After a successful ansible run, I encounter the problem that Apache is accessing only the topmost virtual host entry. Apache counts all virtual host entries as the same, one for port 80 and one for 443. apachectl -S is a handy command to see the VirtualHost settings as parsed from the config file.
The apachectl -S command shows this :

VirtualHost configuration:
*:80                   is a NameVirtualHost
         default server adas.example.org (/etc/apache2/sites-enabled/vhost.conf:1)
         port 80 namevhost adas.example.org (/etc/apache2/sites-enabled/vhost.conf:1)
         port 80 namevhost adas.example.org (/etc/apache2/sites-enabled/vhost.conf:13)
*:443                  is a NameVirtualHost
         default server adas.example.org (/etc/apache2/sites-enabled/vhost.conf:7)
         port 443 namevhost adas.example.org (/etc/apache2/sites-enabled/vhost.conf:7)
         port 443 namevhost adas.example.org (/etc/apache2/sites-enabled/vhost.conf:19)

Solution

We can not have 0.0.0.0 and [::] in the Virtual entries in the particular use case. 0.0.0.0 is the IP address mentioned in the first VirtualHost abovementioned apache configuration. The Apache process takes the first entry as 0.0.0.0, which means all IPv4 addresses.

We have to use the exact IP addresses (both for IPv4 and IPv6). The output of the apachectl -S shows four different entries correctly as it is meant to.


VirtualHost configuration:
192.168.0.5:80         adas.example.org (/etc/apache2/sites-enabled/vhost.conf:1)
192.168.0.5:443        adas.example.org (/etc/apache2/sites-enabled/vhost.conf:7)
[fe80::9e73:870f:e789:e053]:80 adas.example.org (/etc/apache2/sites-enabled/vhost.conf:13)
[fe80::9e73:870f:e789:e053]:443 adas.example.org (/etc/apache2/sites-enabled/vhost.conf:19)

To automate this via ansible we have to use ansible_default_ipv4.address and ansible_default_ipv6.address for getting the ipv4 and ipv6 address.

In finding the solution to the problem, I asked for help in the #httpd IRC channel. I want to thank the httpd community for helping and showing the direction to the solution.

Show Comments