Protest against software patents

Getting IPv6 connectivity under Linux

Despite being an elegant and technologically sound solution, I think IPv6 will be adopted universally within a few years. — Anonymous

This document describes how to get a public, globally routable IPv6 address on a GNU/Linux system.

Summary for Debian and Ubuntu users

I should also mention we use uTP on platforms which are not Windows. Those platforms need to get their collective Teredo asses in gear — alus

# apt-get install miredo
$ sleep 10
$ ping6 -c5 huponomos.wifi.pps.jussieu.fr

That's it. You no longer need to read this page.

Preliminaries

You will need to have IPv6 support in your kernel. You can check whether this is the case by typing
$ ifconfig lo
If this prints
inet6 addr: ::1/128 Scope:Host
you're all set. If not, try typing
# modprobe ipv6
and check again.

You can make this change permanent by adding the line

ipv6
to the file /etc/modules.

Native IPv6 connectivity

If you're lucky, your network may already have native IPv6 connectivity. If this is the case, your machine should automatically grab a globally routable IPv6 address using a mechanism known as stateless autoconfiguration.

You may check whether this is the case by typing

$ ifconfig eth0
If this prints an IPv6 address in 2000::/3 (i.e. one that starts with a 2 or a 3), you've got native IPv6 connectivity. (Ignore any addresses in fe80::/64 – these are link-local addresses.)

Try

$ ping6 huponomos.wifi.pps.jussieu.fr
If this works, your IPv6 connectivity is working fine.

Une note pour les français : si vous êtes chez Free, vous pouvez obtenir une connectivité native si vous le demandez. Allez dans l'interface de configuration de votre Freebox, et cliquez ce qu'il faut.

Eupalinos Tunnel

6to4

If you don't have native IPv6, but you've got a globally routable static IPv4 address (not one in 192.168.0.0/16, 172.16.0.0/12 or 10.0.0.0/8), and your firewall lets through IPv4 packets with protocol 41, you can use 6to4 tunnelling to get global IPv6 connectivity.

Create a file 6to4.sh with the following shell script:

#!/bin/sh

set -e

ip4=$1
echo "$ip4" | grep -q '^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$' || \
{ echo 'Syntax: $0 a.b.c.d'; exit 1; }

prefix=$(printf '%02x%02x:%02x%02x\n' $(echo $ip4 | sed 's/\./ /g'))

ip tunnel add 6to4 mode sit remote any local $ip4
ip link set dev 6to4 up
ip addr add 2002:$prefix::1/16 dev 6to4
ip -6 route add ::/0 via ::192.88.99.1 dev 6to4 metric 1026

Then type

$ sh 6to4.sh xxx.xxx.xxx.xxx
where xxx.xxx.xxx.xxx is your globally routable IPv4 address. This will create a pseudo-interface 6to4 with a global IPv6 address; the prefix (/64) will depend on your IPv4 address, and the host number will be 1.

Note that 6to4 gives you a whole /48 to play with (that's 65 thousand networks of /64 each), so if you're running a network, only the edge router needs to have a 6to4 tunnelling interface. See multiple hosts below.)

Try typing

$ ping6 huponomos.wifi.pps.jussieu.fr
If this fails, there's probably a firewall in the way that blocks protocol 41.

Teredo connectivity

If you're still reading, you're probably behind a NAT box, or behind a firewall that you cannot configure to let protocol 41 through. In that case, you'll need to use the Teredo protocol.

First, install the Miredo daemon (if you're under Debian, just apt-get install miredo). Then, simply type

# miredo
If you type ifconfig, you should see a pseudo-tunnelling interface called teredo. After a few seconds, this interface should get an address in 2001::/32.

Try both of these:

$ ping6 huponomos.wifi.pps.jussieu.fr
$ ping6 www.kame.net
If both fail, you're either behind a symmetric NAT, which Teredo cannot cross, or your firewall is too restrictive. If only one of these fails, then the Teredo prefix is undergoing one of its regularly scheduled partial blackholes.

(The quality of Teredo connectivity is improving, especially in Europe. However, 6to4 will probably give you better service if you can use it.)

Configured tunnelling

6to4 and Teredo are automatic tunnelling techniques: the tunnel endpoints are chosen automatically by the routing infrastructure. While this is convenient, and, in the presence of sufficient relays, gives near-optimal routing, it is next to impossible to debug: if connectivity fails, it is very difficult to find out what the problem is. Additionally, Teredo (but not 6to4) carries some overhead designed to work around NATs.

If you'd like to avoid these problems, you may want to consider configured tunnelling, where the tunnel endpoints are explicitly configured. While it is possible to configure such a tunnel manually (and some parts of our mesh network are in fact configured that way), it is easier to use software that can contact a server called a tunnel broker to automatically configure a tunnel for you.

The simplest solution is to use a tunnel broker provided by Hexago (freenet6). Hexago don't require registration, and their tunnel broker client will configure a tunnel for you without any manual configuration. They will give you a full /48 if your register. Use the tspc tunnel broker client for accessing the Hexago tunnel broker (under Debian, simply apt-get install tspc).

Unfortunately, Hexago may give you poor latency if you're not in the US. If you are in Europe, you may experiment with SixXS which has brilliant connectivity but, unfortunately, requires registration for all users. In order to automatically establish a tunnel with SixXS, you'll want to use the aiccu tunnel broker client (apt-get install aiccu under Debian), which you'll need to configure with information about your SixXS account.

A note about servers

Whichever technique you use, the IPv6 address you will get is globally routable, and there should be no problem running a server or peer-to-peer application on it. Note, however, that in the case of 6to4, the address will embed your IPv4 address; hence, if your IPv4 address is dynamic, your IPv6 address will vary over time. In the case of Teredo, expect your IPv6 address to change randomly whenever the Miredo daemon is restarted or your NAT hiccups.

To make your IPv6 server accessible by name, you will want to add one or more AAAA records into your DNS. Here's the zone file entry for one of my machines:

huponomos       IN      A       134.157.168.121
                IN      AAAA    2001:660:3301:8061:290:27ff:feac:7980
                IN      AAAA    2001:660:3301:8063::1

You will additionally want to run a Teredo relay on your server in order to improve connectivity for Teredo clients. Simply put the following in your /etc/miredo.conf:

RelayType cone
and run Miredo normally. Unless you want to muck around with IPv6 routing, this should be done on every one of your IPv6 servers.

Multiple hosts

Packets between two 6to4 hosts use end-to-end tunnelling, so the issue doesn't occur if you have multiple 6to4 hosts. However, it will be more efficient to have just one 6to4 router and use native IPv6 between your hosts. This is also necessary if any of your hosts use NATed addresses.

The situation is slightly worse with Teredo. If two of your hosts behind the same NAT use Teredo, communication will go through the NAT if the NAT supports hairpinning. If the NAT doesn't, communication will fail (Miredo doesn't support local discovery).

Finally, if you use configured tunnelling, packets between two of your hosts with configured tunnels will, by default, follow the tunnel. Twice. The performance of your local connectivity will be horrible.

A native local network

In order to solve these problems, you will want to configure a tunnel on just one of your hosts and use it as a default router for a native IPv6 local network. You will need to get at least a /64 prefix; this is automatic with 6to4, possible with all tunnel brokers known to me, and impossible with Teredo.

You will then want to set up a router advertisement daemon on the router you have chosen. You may either use the standalone radvd daemon, or, if you're using Quagga, you may use its built-in support for router advertisements.

If you've got multiple links, you will need to choose a separate /64 prefix for each of them. Since 6to4 and most tunnel brokers give you a massive /48 to play with (65536 networks of /64 each), you should not have a problem finding enough net numbers.

If your tunnel endpoint is connected to all of your links, just set it up to multicast router advertisements on all of them. If this is not the case, you will need to set up native IPv6 routing on your network, using either static routing, or a dynamic routing protocol such as RIPng (using e.g. Quagga, or, under BSD, route6d) or Babel. (I don't recommend OSPFv3. If you've got a dozen routers in a simple topology, RIPng should work just fine. If you've got a hundred routers in a complex topology, Babel should cope just fine. If you've got more than a few thousand routers, you shouldn't be reading this page in the first place.)

Back to my software page, retour à wifi.pps.jussieu.fr.

Juliusz Chroboczek, <jch@pps.jussieu.fr>