Assign IPv6 to KVM machine

kvm_ipv6_thumb

We all need IPv6

It is kind of awesome, the internet of things is incoming, which is going to be a security desaster, and so IPv6 does, along with other advantages that IPv6 provides we definitely want it especially because of the mass of available addresses.
Also we have to, IPv6 will replace IPv4 in 5 or 100 years, or just never...

Advantages

One big advantage of IPv6 is that you can allocate one IP Address per Application, or whatever desire you have to use more than one IP Adress. It's not a problem anymore.
Everyone gets minimum a /64 Block referring to SLAAC, that means 64bit or 2^64 or 18.446.744.073.709.551.616 or just enough...

That's great! No NAT anymore or no worries about ports wich are already in use anymore!

Why I'm so happy about IPv6

I own many dedicated Servers, but only a few of them got multiple IPv4 Addresses allocated. That's a problem for example if I want to setup VMs, which I do commonly often.

It's not a big deal to setup the NAT over iptables and sharing this IP Address, but I want to have my Servers listen on any Port, without caring about the Port may be already in use. In this case I have to build awkward workarounds, like using NGINX which is proxying to the other NGINX on the VM or a modified HAProxy. Or I just allocate the Port to this single machine, stuff like that and much more...

This times are over, thanks to IPv6!
Well... , or maybe not, yet it does not seem that it is going to be used anytime soon, but hey however, let's get IPv6 ready anyway!

So lets assign a dedicated IPv6 to our KVM machine.

Configuration

One way would be to use the router advertisment daemon radvd, the other way would be to statically assign the IP Addresses.

I will setup now only a static IP, for setting up radvd you may consider reading:
http://www.mueller.mn/2014/01/ipv6-ueber-dhcp-an-kvm-gaeste-verteilen/

It's in german but the configuration parameters should tell you enough about what you have to do.
Also this post mentions some problems using router advertisment together with forwarding. If you want more Information about this you might read this post:
http://strugglers.net/~andy/blog/2011/09/04/linux-ipv6-router-advertisements-and-forwarding/

The Bridge

So the first thing we have to setup, is our bridge. In this case I'm on debian and edit my /etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo  
iface lo inet loopback

auto eth0  
iface eth0 inet manual

auto br0  
iface br0 inet dhcp  
        bridge_ports eth0
        bridge_fd 9
        bridge_hello 2
        bridge_maxage 12
        bridge_stp off

iface br0 inet6 static  
        address 2001:beef:2:9dd0::
        netmask 64
        post-up /sbin/ip -f inet6 route add 2001:beef:2:9dff:ff:ff:ff:ff dev br0
        post-up /sbin/ip -f inet6 route add default via 2001:beef:2:9dff:ff:ff:ff:ff
        pre-down /sbin/ip -f inet6 route del default via 2001:beef:2:9dff:ff:ff:ff:ff
        pre-down /sbin/ip -f inet6 route del 2001:beef:2:9dff:ff:ff:ff:ff dev br0

The IPv4 I get over DHCP on this Server, my new IPv6 block I have to setup statically.
The post up define and set the gateway on the last Adress of the block.

Also you need to edit or add the following options in /etc/sysctl.conf to be enabled:

net.ipv6.conf.all.proxy_ndp  = 1
net.ipv6.conf.all.forwarding = 1

The KVM Settings

Next you configure your KVM and add an interface of the type bridge like the following:

    <interface type='bridge'>
      <mac address='52:54:00:0a:41:d5'/>
      <source bridge='br0'/>
      <target dev='vnet2'/>
      <model type='virtio'/>
      <alias name='net2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </interface>

Now you can configure the IPv6 in your VM.

The tricky part

It's not really tricky, but you've to know it. But there are several issues that can happen to you.

Neighbour Discovery Proxy

You may need to tell the System that it should "split your subnet into parts". You accomplish this by doing this:

ip -6 neigh add proxy 2001:beef:2:9dd0::12 dev br0

This should be of course your configured IPv6 of your VM and you need to configure this every time you add a new IP. You may read more about this here.

By the way, if you want to add a new IPv6 to your host System you only need to execute this command:

ip -6 addr add 2001:beef:2:9dd0::29 dev br0

That's all. No iptable forwarding stuff, no NAT, no Portforwarding. Just a dedicated IPv6, or more Addresses if you want to, for this single virtual machine.

Alternatively if you want to give a specific VM a whole subnet (for example a /122), I recommend to use ndppd.

I recommend you also to read the ip-neighbour(8).

Troubleshooting

Dadfailed

Unix

If you restart your VM it may happen, that you can't use your IPv6 again with the error global tentative dadfailed. This means that your address is already in use, to prevent this deactivate net.ipv6.conf.all.accept_dad in your /etc/sysctl.conf.

More information about this you may get by reading this:
http://blog.tankywoo.com/linux/2013/09/27/ipv6-dadfailed-problem.html

Windows

Oh ok, you're using windows.
Then you need to use netsh.

netsh int ipv6 show addresses

You should find your address that can't be assigned because of DAD-Status duplicate.

Ok, so how to disable dad_accept on Windows?
First execute this

netsh int ipv6 show int

Now get from the displayed list the Idx of your Network Interface. In our case the Idx will be 19.

To list which options are enabled for your interface enter this command:

netsh int ipv6 show int 19

Now execute the following command to disable accept_dad:

netsh int ipv6 set int 19 dadtransmit=0

Thats all.

For more information view the MS Docu:
http://technet.microsoft.com/en-us/library/cc740203%28v=ws.10%29.aspx