This article assumes that the physical node that is setup with OpenVz already has Native IPv6 setup and running, and that you are using OpenVz containers connected with a venet device. For those who need help getting their physical node setup with IPv6 on CentOS/RHEL click here.
Ideally IPv6 works best over a veth adapter, as they have a MAC address and play much more nicely with auto configuration within the container. However not all of us have the luxury of getting an OpenVz container with a bridged veth adapter AND IPv6.
In a nutshell, using a venet adapter suffers the following:
venet devices are not fully IPv6 compliant, but still works if you statically assign IPv6 addresses. They do not properly support MAC addresses and consequently link local addresses and can not play nice with neighbor discovery or router advertisements, router discovery, or auto-conf. They also require additional modifications to the layer 3 forwarding behaviour of the host via sysctl.
The wiki of course tells you how to add an IPv6 address to a container, but doesn’t go into details on actually getting it to work. I only know of these steps to work on a CentOS and Debian container.
It’s important that the following has been set on the physical server for the following guide to work
sysctl net.ipv6.bindv6only 1
Adding an IP
In the case of the server kbeezie.com is on, I have a /64 block assigned to me by my datacenter. For those not familiar, a /64 block equates to about 18 quintillion addresses. In SolusVm you normally add a range of IPv6 addresses by randomly generating about a 100 addresses at a time. But you can also manually define an address like I did with kbeezie, choosing 2001:4858:aaaa:6::6 for this site. The :: represents an area that is filled with zeros, as such the long address would be 2001:4858:aaaa:0006:0000:0000:0006.
Now to add this address to a container we would simply use vzctl:
vzctl set <id> --ipadd <ipv6_addr> --save
For example if your containers’ CTID is 101, and you wanted to add 2001:4858:aaaa:6::1, you would perform the following:
vzctl set 101 --ipadd 2001:4858:aaaa:6::1 --save
Verifying IPv6 Connectivity
Now when you log into your container, you should be able to perform the following:
If you get an error that there’s no connection to host, or you simply time out, then first double check that the IPv6 address shows in your ifconfig output. If it’s there then try the following command to add a default route from the container to the host node:
On CentOS/RHEL container:
ip route add 2000::/3 dev venet0
On Debian/Ubuntu container:
ip route add ::/0 dev venet0
You can verify the default route has been added with:
Once that has been added, then try to ping6 ipv6.google.com once a gain. If you see ping responses then you’re done with that. If not move onto the next step.
Adding route to container at physical node
Sometimes when you add an IP address to a container, the traffic simply doesn’t make it to the containers. I’ve had this annoyance a number of times especially when I add an IP address to a container in SolusVm.
Lets say for example you added 2001:4858:aaaa:6::1 to a container, but traffic simply is not making it thru. You may need to re-add the route between the container and the eht0 adapter. To do this use the following command:
ip -6 neigh add proxy 2001:4858:aaaa:6::1 dev eth0
Once thats done, log back into the container and try to ping6 ipv6.google.com again. At this point you should be getting a response.
Configuring Web Servers
As mentioned in the openvz wiki, link local and other features will not be available with a venet adapter. A prime example of this is listening on all available IPv6 interfaces such as [::]:80 will not work in most cases as the software will often complain of the address already being bound. Likewise any services that can listen on both IPv4 and IPv6 will need to be set to only handle IPv6 traffic over IPv6 (since its possible for IPv6 to handle both IPv6 and IPv4 traffic).
It helps to have Google’s nameservers ( 8.8.8.8 and 8.8.4.4 ) in your /etc/resolv.conf if you do not already have a IPv6-friendly nameserver configured.
The following are tweaks you can use to make IPv6 work in various webservers.
Nginx
Before you can use IPv6 with Nginx, the webserver needs to be compiled with the –with-ipv6 option. You may already have this option enabled, you can check by calling nginx -V. To listen on IPv6 you can add the following line to your server block:
listen [2001:4858:aaaa:6::1]:80 ipv6only=on;
Remember that each server block will need to have it’s own unique IPv6 address and that you cannot bind to all [::] interfaces. The option ipv6only=on needs to be enabled in order to play nicely with venet. If the physical node already has ipv4 binding turned off then ipv6only may not be necessary, but its a good idea to use anwyays with the venet adapter. To ensure that a server block is listening on both IPv6 and IPv4 you may need to have the following:
listen 0.0.0.0:80;
listen [2001:4858:aaaa:6::1]:80 ipv6only=on;
You can also choose to listen on a specific IPv4 address. The listen line for IPv4 is needed, since otherwise the server block will only be listening on IPv6.
More information on Nginx’s listen directive can be found in the Wiki.
Lighttpd
I’m not entirely familiar with lighttpd myself, but it does share a similar directive to nginx for forcing IPv6 listeners to only handle IPv6 traffic. IPv6 setup is outlined in Wiki overview. Which shows V6_ONLY is already enabled in most common cases where you have to statically define the IP address.
Again you cannot bind to [::] when using venet on OpenVz.
Apache/httpd
Apache does not have a v6-only type of directive. Instead you have to recompile apache with –disable-v4-mapped. Once Apache has been compiled you can use the [IPv6]:80 format, you’ll need to have a Listen directive set to your new IPv6 address, as well as any virtual hosts. Like with both nginx and lighttpd above, you cannot bind to all interfaces ([::]), only specifically assigned addresses.
Control panels, Firewalls, etc
Firewall software such as UFW (uncomplicated firewall by ubuntu), and such do not play nicely with IPv6 and OpenVz (over venet). So thats something to keep in mind when setting up firewall software that rely on kernel modules and such that are not often available in a virtualized environment (Xen is typically more suited for something like that).
Not all control panels are IPv6 ready. DirectAdmin for example does have the option to enable IPv6, and will let you manage IPv6 addresses in the IP configuration and DNS area. However it does not configure the services like apache, bind9, dovecot and so forth for you. For those services you’ll have to configure manually.
Conclusion
For the purpose of hosting websites and logging into my server via SSH, the above guidelines work just fine. I currently host kbeezie.com, kbeezie.net (static CDN), ionvz.com and a few other websites behind IPv6 with Nginx on such a configuration.
If you do not have IPv6 connectivity from your home or office machine, you can use a free tunnnel service such as HE.net’s IPv6 Tunnel Broker Service. which I’m using here at home. I currently use Hurricane Electric for my servers backbone (native IPv6 for my servers), Home IPv6 Tunneling, and Free DNS Service which seems to work much better than using my domain registrar’s DNS.