I just wanted to create an Apache virtual host responding to queries only over IPv6. That should have been most trivial considering that I had already been running a dual-stacked server, with all services accessible over both IPv4 and IPv6.

Following the established IPv4 practice, I set upon configuring the virtual host to respond only to queries directed to a specific IPv6 address. That is done by inserting the address in the opening of the VirtualHost stanza : <VirtualHost [2001:470:1f13:a4a::1]:80> – same as an IPv4 configuration, but with brackets around the address. It is simple and after adding an AAAA record for the name of the virtual host, it works as expected.

I should rather say it works even better than expected : all sub-domains of the second-level domain I’m using for this virtual host are now serving the same content that the new IPv6-only virtual host is supposed to serve… Ungood – cue SMS and mail from pissed-off users and a speedy rollback of the changes; the joys of cowboy administration in a tiny community-run host with no testing environment. As usual, I am not the first user to fall into the trap. Why Apache behaves that way with an IPv6-only virtual host is beyond my comprehension for now.

Leaving aside the horrible name-based hack proposed by a participant in the Sixxs thread, the solution is to give each IPv6-only virtual host his own IPv6 address. Since this server has been allocated a /64 subnet yielding him 18,446,744,073,709,551,616 addresses, that’s quite doable, especially since I can trivially get a /48 in case I need 1,208,925,819,614,629,174,706,176 more addresses. Remember when you had to fill triplicate forms and fight a host of mounted trolls to justify the use of just one extra IPv4 address ? Yes – another good reason to love IPv6 !

So let’s add an extra IPv6 address to this host – another trivial task : just create an aliased interface, like :

auto eth0:0
    iface eth0:0 inet6 static
    address 2001:470:1f13:a4a::1
    netmask 64
    gateway 2001:470:1f12:a4a::2

The result :

SIOCSIFFLAGS: Cannot assign requested address
Failed to bring up eth0:0.

This is not what we wanted… You may have done it dozens of time in IPv4, but in IPv6 your luck has ran out.

Stop the hair pulling right now : this unexpected behavior is bug – this one documented in Ubuntu, but I confirm it is also valid on my mongrel Debian system. Thanks to Ronny Roethof for pointing me in the right direction !

The solution : declare the additional address in a post-up command of the main IPv6 interface (and don’t forget to add the post-down command to kee things clean) :

auto he-ipv6
iface he-ipv6 inet6 v4tunnel
    address 2001:470:1f12:a4a::2
    netmask 64
    endpoint 216.66.84.42
    local 212.85.152.17
    gateway 2001:470:1f12:a4a::1
    ttl 64
    post-up ip -f inet6 addr add 2001:470:1f13:a4a::1 dev he-ipv6
    pre-down ip -f inet6 addr del 2001:470:1f13:a4a::1 dev he-ipv6

And now the IPv6-only virtual hosts serves as designed and the other virtual hosts are not disturbed. The world is peaceful and harmonious again – except maybe for that ugly post-up declaration in lieu of declaring an aliased interface the way the Unix gods intended.

All that just for creating an IPv6 virtual host… Systems administration or sleep ? Systems administration is more fun !