How to get IPv6 running with Debian Linux

Recently, since the advent of RFC3068 it has become much easier to setup IPv6 by encapsulating IPv6 packets in IPv4 packets. The RFC specifies an anycast address so that your nearest 6to4 router will take these encapsulated packets and send them on, using its own IPv6 address as the source, and return the contents back to you in a IPv4 packet. I'm on the end of a cablemodem, with a DHCP-allocated address. Although I've written these instructions for Debian Linux, they should work with any version as long as you've got the right userland programs. (Caveat: these commands work for me, but things change; in future, I'd expect dhclient to do all this work, really. YMMV. Correct as at November 2004). So the first thing is to install IPv6 tools that you'll need, so:

apt-get install ipv6calc radvd iputils-tracepath iputils-ping iproute ip6tables

The anycast address that is advertised via BGP is, so we need to set up an IPv6 tunnel device, and then set the packets to be sent to this address. I've also got an internal network on a 10.x.x.x for my Windoze box, etc. and I'll want to forward IPv6 packets from Windows too. The /etc/network/interfaces file specifies the interface details, but since this is changed depending on the IPv4 address allocated by DHCP, we have to give it a static address first, then change it after we know the IPv4 address. 6to4 addresses are created by adding the 2002: prefix, then taking the IPv4 address bitwise and this provides a /48 subnet just for this one IP address. So in my case, if my IPv4 address is, then my 6to4 address is 2002:d56b:69be::. You can calculate this automatically using this command:

ipv6calc --ipv4_to_6to4addr --printprefix

So my /etc/network/interfaces file now has an extra entry for sit0, which is the tunnel device, plus commands to add some routes once it is up. We allocate a temporary address in the 3ffe: range but the /etc/add6to4tun script changes this. It would be nice if dhclient3 could do all this work in future, but we have hacky scripts for now:

iface sit0 inet6 static
        address 3ffe:ffff::1
        netmask 48
        down ip -6 route del 2000::/3
        down /etc/del6to4tun
        up   ip -6 route add 2000::/3 via ::
        up   /etc/add6to4tun
        up   ip -6 addr  del 3ffe:ffff::1/48 dev sit0

Okay, so now we have a sit0 device. The /etc/add6to4tun is a simple shell script:

# /etc/myip contain my current IP address obtained by
# grepping through the DHCP lease file. Yes, it's a hack.
# It would be nice to cat /proc/net/ipv4/eth0/ipaddress really.
myip=`cat /etc/myip`
6to4=`ipv6calc --ipv4_to_6to4addr --printprefix $myip`
ip addr add ${6to4}::/48 dev sit0
ip addr add ${6to4}:5678::/64 dev eth0

In my case, my internal 10.x.x.x network also has an IPv6 equivalent of {6to4}:5678::/64, so in my case, my internal network is 2002:d56b:69be:5678::/64. If you want automatic configuration of IPv6 addresses, you'll need to configure the radvd daemon to hand out addresses in this range, and usually the MAC address of an ethernet card will be appended to generate an IPv6 address in the /64 subnet. My /etc/radv.conf file has these contents:

interface eth0
   AdvSendAdvert on;
   MaxRtrAdvInterval 30;  # Advertise at least every 30 seconds

   prefix 0:0:0:5678::/64 # The 0:0:0 will be filled in below
       AdvOnLink on;
       AdvAutonomous on;
       Base6to4Interface eth0; # Fill in 0:0:0 with 2002:x:x from eth0
Okay. You'll also need to allow 6to4 packets through your firewall (I use iptables), so my /etc/firewall has a couple of lines that say:
# IPv6 accept; actual firewalling is done in /etc/firewall.ipv6
-A INPUT  -p ipv6 -j ACCEPT
-A OUTPUT -p ipv6 -j ACCEPT

You will want to configure your ip6tables firewall, although I don't think you're like to be hacked on IPv6 just yet. Final proof of the pudding, try ping6 and traceroute6, from both Linux and Windoze:

16:34:35 ~ on ratty$ ping6
PING 56 data bytes
64 bytes from icmp_seq=1 ttl=55 time=91.4 ms
64 bytes from icmp_seq=2 ttl=55 time=89.2 ms
Administrator@watervole ~
$ tracert6

Tracing route to [2001:5c0:0:2::24]
over a maximum of 30 hops:

 1   <1 ms  <1 ms  <1 ms [2002:d56b:69be:5678::]
 2   20 ms  24 ms  22 ms  2002:c058:6301::
 3   21 ms  80 ms  21 ms [2001:7b8:3:4f:290:6900:4fc6:d81f]
 4   25 ms  34 ms  22 ms [2001:7b8::205:8500:120:7c1f]
 5   21 ms  20 ms  21 ms [2001:7f8:1::a500:3265:1]
 6   53 ms  76 ms  53 ms [2001:7f8:1::a500:3549:1]
 7  214 ms 212 ms 212 ms  2001:450:1:1::22
 8  176 ms 176 ms 189 ms [3ffe:80a::10]
 9  198 ms 199 ms 200 ms  2001:5c0:0:2::1
10  209 ms 201 ms 199 ms  2001:5c0:0:2::24

Don't forget to go to uk6x to check you're running IPv6 okay. You should see a message such as the following:

IP Address: 2002:d56b:69be::
Via: (none)
User Agent: ELinks/0.9.2rc4 (textmode; Linux 2.6.9 i686; 124x48)
HTTP Protocol: HTTP/1.1

You are using IPv6 - cool :-)