You need IPv6 now and here's how to get it

The Internet is dead! Long live the Internet (v6)! You need IPv6. I need you to have IPv6 so you can view this website over the next generation Internet Protocol. If you and I both had IPv6, we would be able to forget about such inconveniences as NAT. We could video chat without having to have a separate server. We could share files directly. We could do a whole lot of really cool stuff.

Now, the question is: how do you get IPv6? Here is one way using SixXS and a Raspberry Pi.

This is my current method, since it is low cost and requires no special router setup. Basically, IPv6 packets are encapsulated into IPv4+UDP via the Anything-in-Anything protocol. UDP traverses NAT boundaries fairly easily and SixXS provides a very nice service so that you don't have to manually tell them that your public IP has changed. Using this setup, I've basically created a generic IPv6 tunnel endpoint and router that I can connect to almost any LAN and it would automagically enable IPv6 on that network. Let me show you how:

Step 1. Obtain a Raspberry Pi and install Linux on it. This is beyond the scope of this post, and documented well elsewhere. You can also use any other always-on device on your network, but I will assume you will get a Raspberry Pi for the purpose here.

Step 2. Get an account with SixXS. This is a multi-step process where some steps require manual approval, but it goes pretty quickly. Once you have your account, request a tunnel and a subnet. For the reason, state something like "I want to get my local network IPv6 enabled", but with more detail. Make sure to select the AYIYA type of tunnel.

Step 3. Set your Raspberry Pi as a router:

echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Step 4. Set up your firewall:

ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
ip6tables -A INPUT -s 2001:4830:xxxx:xxx::/64 -j ACCEPT
ip6tables -A INPUT -s 2001:4830:xxxx:Yxxx::/64 -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
ip6tables -A INPUT -j DROP
ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -p tcp -m tcp --dport 22 -j ACCEPT
ip6tables -A FORWARD -s 2001:4830:xxxx:Yxxx::/64 -j ACCEPT
ip6tables -A FORWARD -p ipv6-icmp -j ACCEPT
ip6tables -A INPUT -j DROP

Note that we are letting two IPv6 subnets through: 2001:4830:xxxx:xxx::/64 and 2001:4830:xxxx:Yxxx::/64. The one with the Yxxx is going to be the routed subnet. That's the one that the rest of the devices on your network will use. The one with just the xxx will only have two addresses on it: ::1 (the remote end of your tunnel) and ::2 (your Raspberry Pi).

Step 5. Make sure your firewall is enabled at boot time. This is easy:

Put the following into /etc/network/if-pre-up.d/ip6tables-load, and make it executable ($ sudo chmod 755 /etc/network/if-pre-up.d/ip6tables-load)

ip6tables-restore < /etc/ip6tables.rules
exit 0

Now, put the following into /etc/network/if-post-down.d/ip6tables-save and make it executable ($ sudo chmod 755 /etc/network/if-post-down.d/ip6tables-save)

ip6tables-save -c > /etc/ip6tables.rules
if [ -f /etc/ip6tables.downrules ]; then
   ip6tables-restore < /etc/ip6tables.downrules
exit 0

For good measure, execute $ sudo /etc/network/if-post-down.d/ip6tables-save

Step 6. Now that you are firewalled off, let's bring up the IPv6 tunnel. All this takes is:

sudo apt-get install aiccu

Answer the questions about your login and password, then let the install finish. Check that you have IPv6 connectivity:

sit0      Link encap:IPv6-in-IPv4  
          inet6 addr: :: Scope:Unknown
          inet6 addr: :: Scope:Compat
          UP RUNNING NOARP  MTU:1480  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

sixxs     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet6 addr: fe80::4830:xxxx:xxx:2/64 Scope:Link
          inet6 addr: 2001:4830:xxxx:xxx::2/64 Scope:Global
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0 MiB)  TX bytes:0 (0 MiB)

$ ping6
PING 56 data bytes
64 bytes from icmp_seq=1 ttl=53 time=44.2 ms
64 bytes from icmp_seq=2 ttl=53 time=47.1 ms
--- ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 44.231/45.715/47.199/1.484 ms

Step 7. Start using your IPv6 routed subnet. First, you will want to edit your /etc/aiccu.conf file. Here is the diff:

-#setupscript /usr/local/etc/
+setupscript /usr/local/etc/

Now, create an executable script at /usr/local/etc/ with the following content:

ip addr add 2001:4830:xxxx:Yxxx::1/64 dev eth0

Then restart aiccu: $ sudo /etc/init.d/aiccu restart. Now, your eth0 will have its own IPv6 address in the routed (Yxxx) subnet.

Step 8. Enable IPv6 for the rest of your LAN. This step is also very easy. We will install radvd ($ sudo apt-get install radvd) and configure it to advertise your routed network prefix. Create a file at /etc/radvd.conf with the following content:

interface eth0 { 
        AdvSendAdvert on;
        MinRtrAdvInterval 3; 
        MaxRtrAdvInterval 10;

        prefix 2001:4830:xxxx:Yxxx::/64 { 
                AdvOnLink on; 
                AdvAutonomous on; 
                AdvRouterAddr on;

        AdvValidLifetime 30;
        AdvPreferredLifetime 20;

Now restart radvd: $ sudo /etc/init.d/radvd restart. Now the rest of your LAN is IPv6 enabled. Enjoy.