Welcome to part five of my multipart series on IPv6. In this post I’ll cover how to configure an IPv6 tunnel on (Ubuntu/Debian) linux. An IPv6 tunnel is necessary if you’re trying to get IPv6 support to a host or network that does not have native IPv6 connectivity.
There are many IPv6-in-IPv4 tunnel providers out there, but I chose to use Hurricane Electric. They seem to be well regarded and they’re free. By default they assign a /64 for the tunnel itself, and then another /64 for your internal network. Should you need more than one subnet, they’ll also assign you a /48, which you can divide as you please. One nice feature about HE is that once you’ve signed up for the tunnel, they include a list of operating systems and the commands required to get the tunnel up and running on each one. However, to make the tunnel survive a reboot, you’ll need to make some changes to some files.
To configure an IPv6 tunnel on (Debian/Ubuntu) Linux, add the following stanza to /etc/network/interfaces:
# cat /etc/network/interfaces | grep -A6 he-ipv6
iface he-ipv6 inet6 v4tunnel
This creates an interface on the Xen dom0 called he-ipv6, over which all the subnets assigned to the tunnel will route. Here’s what the interface looks like:
he-ipv6 Link encap:IPv6-in-IPv4
inet6 addr: 2001:0DB8:1c:619::2/64 Scope:Global
inet6 addr: fe80::d056:ff9a/128 Scope:Link
UP POINTOPOINT RUNNING NOARP MTU:1480 Metric:1
RX packets:82883 errors:0 dropped:0 overruns:0 frame:0
TX packets:53768 errors:0 dropped:0 overruns:0 carrier:0
RX bytes:80544014 (76.8 MiB) TX bytes:6121693 (5.8 MiB)
Note there are actually two IPv6 addresses on the interface. One is the link-local address (the one starting with fe80), which is used for neighbor and router solicitation and discovery purposes, among other uses. The link-local address is assigned automatically, and is based on the MAC address. The other is the globally routable IPv6 address that is what other IPv6 enabled hosts will use to communicate with this host.
The next step is to assign the second subnet from HE to the interface used to serve the other hosts on the network and then enable IPv6 packet forwarding. First, assign the interface in question the first IP in the subnet by adding the following stanza to /etc/network/interfaces:
# cat /etc/network/interfaces | grep -A 2 “eth0 inet6″
iface eth0 inet6 static
You should substitute eth0 and the address for the correct values for your LAN. There is no gateway required for the LAN interface, because IPv6 traffic should use the he-ipv6 interface. Note also that this stanza is separate from any IPv4 configuration you may have on this interface (and that you can have both configurations enabled simultaneously). Here’s what the interface looks like now:
# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:26:b9:88:42:c5
inet addr: 203.0.113.154 Bcast: 203.0.113.159 Mask:255.255.255.248
inet6 addr: 2001:0DB8:1d:619::1/64 Scope:Global
inet6 addr: fe80::226:b9ff:fe88:42c5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3049624 errors:0 dropped:0 overruns:0 frame:0
TX packets:1801797 errors:0 dropped:0 overruns:0 carrier:0
RX bytes:371125460 (353.9 MiB) TX bytes:341605661 (325.7 MiB)
Also, here’s what the IPv6 routing table looks like:
# ip -f inet6 route show
2001:0DB8:1c:619::1 dev he-ipv6 metric 1024 mtu 1480 advmss 1420 hoplimit 4294967295
2001:0DB8:1c:619::/64 via :: dev he-ipv6 proto kernel metric 256 mtu 1480 advmss 1420 hoplimit 4294967295
2001:0DB8:1d:619::/64 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
fe80::/64 via :: dev he-ipv6 proto kernel metric 256 mtu 1480 advmss 1420 hoplimit 4294967295
fe80::/64 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295
default via 2001:0DB8:1c:619::1 dev he-ipv6 metric 1024 mtu 1480 advmss 1420 hoplimit 4294967295
By default, your system will not forward IPv6 packets between interfaces, which means only the host terminating the tunnel will be accessible. To fix that, run the following commands:
# sysctl net.ipv6.conf.all.forwarding=1
# sed -i ‘s/net.ipv6.conf.all.forwarding=0/net.ipv6.conf.all.forwarding=1/’ /etc/sysctl.conf
The first command will enable the forwarding of IPv6 packets between interfaces, while the second will make sure the change lasts through a reboot. Now any packets destined for 2001:0DB8:1d:619::/64 that arrive on the he-ipv6 interface will forward to the eth0 interface and vice versa.
There is now IPv6 connectivity on the internal network, but the Xen dom0 is not performing any sort of router advertisement over the network, so hosts on the internal network will not pick up IPv6 addresses automatically via SLAAC. Because all of the hosts on the internal network are servers, I configure them with static IPv6 addresses as they’re easier to remember than the typical SLAAC address.