Table of Contents 1 Foreword 2 Links 3 Why ? 4 How ? 4.1 Getting Linux ready for IPv6 4.2 Connecting the router to the 6Bone 4.3 Testing IPv6 connectivity to the router 5 Understanding IPv6 addresses 5.1 Notation 5.2 Link-local vs. global unicast 5.3 Recognizing types of addresses 6 Communicating within the LAN 6.1 Setting up the router's LAN interface 6.1.1 Why set it up manually ? 6.1.2 Set the address 6.2 Setting up the stateless autoconfiguration server 6.2.1 What is stateless autoconfiguration ? 6.2.2 Setting up the advertisement daemon 6.2.3 How autoconfigured addresses are built 6.3 Getting the router to route 7 Observing the whole thing happen 8 Do something useful with your IPv6 connected hosts 9 Finding a better IPv6 provider 10 Contributors 11 Todo
|
|
Send comments, suggestions, criticism, money and death threats to Jean-Marc Liotier.
Dancing turtles for all... Actually, it's swimming rather than dancing, but anyway here is a short guide to global IPv6 connectivity for all hosts on your LAN. It is heavily Debian biased, but I guess Debian users will consider that a bonus. Others will pardon the idiosyncrasies and adapt accordingly or switch to Debian.
In this guide, I try to take you by the hand to tell you what I know in my own way (which I hope you'll find didactic), but my knowledge is very thin so if you want the authoritative reference for all things Linux+IPv6 you need Peter Bieringer's HOWTO : http://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/.
http://www.hs247.com/ is a grab bag of IPv6 stuff.
http://www.deepspace6.net/ describes itself as an IPv6 portal.
http://www.kame.net/ the dancing turtle !
Let's consider :
A Linux host with global IPv4 connectivity.
Other hosts on the LAN behind the Linux host.
The only solution available to provide Internet access to the hosts on the LAN was to use a private non routable subnet and to masquerade it behind the edge router. NAT also allowed some of these hosts to expose services to the outside world. But this solution has a major drawback : it breaks end to end connectivity and thus complicates the offering of many services that the Internet was meant for. Used like that, NAT is an evil kludge.
IPv6 provides a way out. There certainly are many other advantages in the use of IPv6, but end to end connectivity for the masses is what I am primarily interested in.
Let's get on to the actual step by step guide. No guarantees, your mileage may vary. At least it worked for me.
Start with enabling the ipv6 option in the kernel. I found that I also had to enable netlink device emulation in order to use the tools in the iproute package.
Install the freenet6 package :
apt-get install freenet6
Go to http://www.freenet6.net/register.shtml and create an account. Accounts are mandatory on Freenet6 if you want an authenticated tunnel or a /48 IPv6 prefix delegation – and you want both. The authenticated tunnel provides one single and permanent IPv6 address to a node in spite of Ipv4 address changes. The /48 IPv6 prefix delegation is how you get a bunch of addresses for those hosts inside your LAN.
Edit /etc/freenet6/tspc.conf :
Make sure that the values assigned to userid and passwd are the ones that you got by mail from Freenet6. Also add the following options :
host_type=router
prefixlen=48
Execute '/etc/init.d/freenet6 restart'
Execute ifconfig and among the output you should see something like that :
sit1 Link encap:IPv6-in-IPv4 inet6 addr: 3ffe:b80:3:1a91::2/128 Scope:Global inet6 addr: fe80::a00:1/10 Scope:Link inet6 addr: fe80::c0a8:8b01/10 Scope:Link inet6 addr: fe80::3e04:1236/10 Scope:Link UP POINTOPOINT RUNNING NOARP MTU:1472 Metric:1 RX packets:4648 errors:0 dropped:0 overruns:0 frame:0 TX packets:5403 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1093435 (1.0 MiB) TX bytes:660564 (645.0 KiB)
sit1 is the interface of the IPv6-in-IPv4 tunnel that runs between your edge node and the IPv6 connected node that provides you with connectivity. Congratulation, you have IPv6 connectivity !
Install the packages that contain ping6 and traceroute6 :
apt-get install iputils-tracepath apt-get install iputils-ping
Use them like the usual ping and traceroute :
ping6 -c 2 3ffe:b80:3:1a91::2 PING 3ffe:b80:3:1a91::2(3ffe:b80:3:1a91::2) 56 data bytes 64 bytes from 3ffe:b80:3:1a91::2: icmp_seq=1 ttl=64 time=0.079 ms 64 bytes from 3ffe:b80:3:1a91::2: icmp_seq=2 ttl=64 time=0.037 ms --- 3ffe:b80:3:1a91::2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.037/0.058/0.079/0.021 ms traceroute6 3ffe:4013:0:2::2 traceroute to 3ffe:4013:0:2::2 (3ffe:4013:0:2::2) from 3ffe:b80:3:1a91::2, 30 hops max, 16 byte packets 1 3ffe:b80:3:1a91::1 (3ffe:b80:3:1a91::1) 263.556 ms 285.743 ms 197.612 ms 2 inode-gw-parcr1.fr.ndsoftwarenet.net (3ffe:4013:f:3::2) 185.702 ms 181.589 ms 177.661 ms 3 edt-viagenie.ipv6.edisontel.it (3ffe:8170:1:11::1) 335.552 ms 415.807 ms 319.105 ms 4 tun61-0-parcr1.fr.ndsoftwarenet.net (2001:7a8:1:f004::2) 728.48 ms 394.493 ms 465.463 ms 5 eth0-1-parcr2.fr.ndsoftwarenet.net (3ffe:4013:0:1::2) 518.149 ms 425.007 ms 441.383 ms
You can also test your IPv6 connectivity from one of the numerous Web interfaces to traceroute6, ping6 and friends. There is a list of sites with such tools at http://www.traceroute6.org/
Before going any further, some degree of familiarity with IPv6 addresses is needed. Here is the skinny on them; if you want more information you can go read http://www.taclug.org/documents/ipv6/x444.htm
Leading zeros can be dropped and consecutive strings of zeros can be compressed. So :
3ffe:ffff:0100:f101:0000:0000:0000:0001 becomes 3ffe:ffff:100:f101:0:0:0:1 or 3ffe:ffff:100:f101::1
The largest reduction is seen by the ipv6 localhost address :
localhost is 0000:0000:0000:0000:0000:0000:0000:0001 and becomes ::1
There is also a short for anyhost (the equivalent of 0.0.0.0 in ipv4) :
0000:0000:0000:0000:0000:0000:0000:0000 becomes ::
Like IPv4, IPv6 uses netmasks and the CIDR notation. Just remember there are 128 bits now instead of 32.
What you need to know right now is the difference between two types of addresses that will certainly confuse you. Take a look at this section of ifconfig's output :
eth1 Link encap:Ethernet HWaddr 00:10:5A:66:DC:33 inet addr:192.168.139.1 Bcast:192.168.139.255 Mask:255.255.255.0 inet6 addr: fe80::210:5aff:fe66:dc33/10 Scope:Link inet6 addr: 3ffe:b80:17e2::1/64 Scope:Global
eth1 obviously has two IPv6 addresses. But they don't have the same function. The last one has a global scope. It is the global unicast address and draws a direct parallel to the Ipv4 addresses you are certainly already familiar with. The other is a link-local and that is an IPv6 novelty : it is an administrative addresses that only requires an IPv6 enabled kernel to bring itself up. It is only used for administrative communications between neighbors. Link-Local addresses are for use during auto-configuration and for when no routers are present. Using it as a destination would never pass through a router. It is used for link communications such as “is anyone else here on this link ?” or “is anyone here with a special address” (looking for routers). So don't try to ping6 or traceroute6 nor connect to a link-local address because it will get you nowhere.
Link local addresses begin with fe8, fe9, fea, and feb; but you will probably only see examples beginning with fe8, such as the one above.
The beginning of an address provides useful information. Apart from the link local prefixes, here are a few others :
3FFE is the prefix of a 6Bone address. The 6Bone provides addresses and connectivity to whoever wants to experiment with IPv6.
2002 is the prefix of a 6-to-4 address. 6to4 is an optional method of connecting IPv6 domains via IPv4 clouds. It provides a mechanism for assigning of an IPv6 address prefix to a machine that has a global IPv4 address.
2001 is the prefix of the first block of production addresses. http://www.dfn.de/service/ipv6/ipv6aggis.html lists block assignations.
FEC0 is the prefix of a site local address. Site local addresses are the equivalent of a private IPv4 address.
FF02::1 is address that multicasts to all nodes on the LAN.
FF02::2 is address that multicasts to all routers on the LAN.
If you encounter an address whose nature you wish to know more about, Peter Bieringer's ipv6calc will tell you everything. The Debian package's name is ipv6calc, you know the drill. Here is an example of ipv6calc showing the properties of a global unicast address that a LAN station set on its Ethernet interface after stateless autoconfiguration :
ipv6calc -i 3ffe:b80:17e2:0:210:5aff:fef1:e854 Address type: unicast 6bone Address type has SLA: 0000 Interface identifier: 0210:5aff:fef1:e854 Interface identifier is an EUI-64 generated from EUI-48 (MAC): 00:10:5a:f1:e8:54 MAC is a global unique one
And here is another example of ipv6calc giving information about the link-local address on the same node :
ipv6calc -i fe80::210:5aff:fef1:e854 Address type: unicast link-local Interface identifier: 0210:5aff:fef1:e854 Interface identifier is an EUI-64 generated from EUI-48 (MAC): 00:10:5a:f1:e8:54 MAC is a global unique one
No shell access or too lazy to install the package ? Point your IPv6 enabled browser to http://ipv6to4.aerasec.de/index2.html.en and you will see what ipv6calc has to say about your address.
It's all nice and dandy to have your router part of the IPv6 world, but what you really want is to bring this connectivity to your users on the LAN. Let's do it !
To perform stateless autoconfiguration, a host needs a router running radvd. But the IPv6 network must be bootstrapped at some point. So routers must know their own address without the need for another host to tell them. That's why we must set the router's LAN interface's address by means other than autoconfiguration.
That does not mean that it can't be done automatically : on getting the delegated /48, Freenet6's scripts are supposed to be able to set your LAN interface's address for you. But I have not found out how to do that yet, and since setting the fixed address in /etc/network/interfaces once and for once is not much more complicated, that's the way I will show you how to do it. And doing it manually once in your life will bring you a little bit of understanding of how things actually happen, and that never hurts.
Very easy : take the prefix you got from the
IPv6 connectivity provider. In my case it is 3ffe:0b80:17e2::
and append a unique identifier. Simple. If you want to be
absolutely sure that the identifier is unique to your prefix, you
can use the same algorithm I describe for building an address
during stateless autoconfiguration, but an arbitrary identifier
should be OK in about all cases.
Since this host is my LAN's main router, I thought '1' would be a suitable identifier. Appended at the end of '3ffe:0b80:17e2::' it becomes '3ffe:b80:17e2::1' and that's going to be the router's LAN interface's address - global unicast of course. If you wanted to subnet your prefix, the the :: between the prefix and the identifer could be changed to whatever subnet you wanted to use. Remembering you have 16 bits for subnetting you can set it to anything from :: to :FFFF:
But for now I am content with just one big subnet so I added the following to /etc/network/interfaces :
iface eth1 inet6 static address 3ffe:b80:17e2::1 netmask 64 gateway 3ffe:b80:3:1a91::1
The gateway's address is the tunnel server's. In the output of 'grep type=\"ipv6\" /var/log/syslog' you will find something like “<server> <address type="ipv4">206.123.31.114</address> <address type="ipv6">3ffe:0b80:0003:1a91:0000:0000:0000:0001</address> </server>”. 3ffe:0b80:0003:1a91:0000:0000:0000:0001 is the IPv6 address of the tunnel server and that's your default gateway.
Hosts on a LAN have the capability to autoconfigure as defined in RFC2462 : they automatically create a unique link-local addresse for each LAN interface that appear to be Ethernet, and they use that address to receive router advertisement messages to automatically configure the following parameters :
A default router.
The default setting for the Hop Limit field in the IPv6 header.
The timers used in the neighbor discovery processes.
The maximum transmission unit (MTU) of the local link.
The list of network prefixes that are defined for the link. Each network prefix contains both the IPv6 network prefix and its valid and preferred lifetimes. If indicated, a network prefix is combined with the interface identifier to create a stateless IPv6 address configuration for the receiving interface. A network prefix also defines the range of addresses for nodes on the local link.
So now we need a router that advertises the needed parameters. Aboard the router, radvd (Router Advertisement Daemon) is the piece of software that provides this information to other hosts on the LAN. So first, install radvd :
apt-get install radvd
Then edit /etc/radvd.conf
Mine looks like that :
interface eth1 { AdvSendAdvert on; prefix 3ffe:0b80:17e2:: /64 { AdvAutonomous on; AdvOnLink on; AdvRouterAddr on; }; };
The critical part is the prefix that radvd advertises. You can find it in your logs, for exemple by trying the following command :
grep type=\"ipv6\" /var/log/syslog
The output will be something like :
Dec 18 21:35:54 Kisangani TSPClient: ExtractPayload: 200 Undefined <tunnel action="info" type="v6v4" lifetime="129600"> <server> <address type="ipv4">206.123.31.114</address> <address type="ipv6">3ffe:0b80:0003:1a91:0000:0000:0000:0001</address> </server> <client> <address type="ipv4">62.4.18.54</address> <address type="ipv6">3ffe:0b80:0003:1a91:0000:0000:0000:0002</address> <address type="dn">ruwenzori.tsps1.freenet6.net</address> <router> <prefix length="48">3ffe:0b80:17e2:0000:0000:0000:0000:0000</prefix> </router> </client> </tunnel>
<prefix length="48">3ffe:0b80:17e2:0000:0000:0000:0000:0000</prefix> is the critical part : from that you know that the prefix given by Freenet6 is 3ffe:0b80:17e2:: /48. If you just want a single subnet, substitute /64 for the /48 and you have the prefix that radvd will advertise. But you could also cut your /48 in multiple /64 subnets by using the last 16 bits for subnetting. For example you could have 3ffe:0b80:17e2:1: /64, 3ffe:0b80:17e2:2: /64, 3ffe:0b80:17e2:3: /64 and so on : 16 bits give you up to 65536 /64 subnets (with 2^64 hosts each...). Configuring a few more subnets to which your router is connecter is probably just a matter of adding a few more interface ethx... stanzas in radvd.conf but I have never done it myself.
I just want one subnet, and my prefix is therefore 3ffe:0b80:17e2:: /64. So in radvd.conf the line that begins with “prefix” will be :
prefix 3ffe:0b80:17e2:: /64
Execute '/etc/init.d/radvd restart' and radvd is ready to serve and the other hosts on the LAN will configure themselves at kernel boot time with no intervention from your part.
Freenet6 is supposed to take care of configuring radvd by writing radvd.conf for you and restarting radvd automatically. The problem is that Andreas Rottmann, the Debian maintainer of the radvd decided that it should not let Freenet6 rewrite the entire configuration file lest manual modifications by the administrator be overwritten. He asked if it would be possible to have a way for freenet6 to change the advertised prefix of radvd without rewriting the whole config file. But Nathan Lutchansky answered in substance that administrator who do not want to risk their modifications overwritten should handle radvd.conf manually. I believe it is true that configurations more complex than the simple automatically manageable case are indeed rare, but in typical Debian fashion Andreas Rottman probably believes he is better safe than sorry, and so he commented out the parts of /etc/freenet6/setup.sh that deal with rewriting radvd.conf. If you feel adventurous you can uncomment them, see what happen and tell me. Right now I'm happy with my manually configured radvd.conf and too lazy to try anything else...
So you have a router that advertises your 48 bit prefix. You certainly wonder how the LAN host ends up with a 128 bit address. Read on and you shall soon know...
The last 64 bits of an IPv6 address are the interface identifier that is unique to the prefix. RFC2464 states that the interface identifier is based on the EUI-64 identifier. The IEEE EUI-64 address represents a new standard for network interface addressing. It supersedes the MAC addressing, also known as IEEE 802. The company ID is still 24-bits in length, but the extension ID is 40 bits instead of only 24 in the MAC address, creating a much larger address space for a network adapter manufacturer. So since the Ethernet adapter you most probably use on your computer use is certainly identified by a good old 48 bit MAC address, we'll need to map it to a 64 bit IEEE-64. And that's where the magic ingredient comes in : just add some padding. RFC2464 says “The fourth and fifth octets of the EUI are set to the fixed value FFFE hexadecimal” .
So, to create an EUI-64 address from a MAC address, the 16 bits of 11111111 11111110 (0xFFFE) are inserted into the IEEE 802 address between the company ID and the extension ID. For example :
- The MAC address : |
|
- The padding : |
|
- The resulting almost EUI-64 address : |
|
At this point you certainly wonder what the hell an "almost EUI-64 address" is. It simply means that from where we are we need to set the lowest order bit in the first octet (00 is the first octet of my example) from 0 to 1 for a globally unique IPv6 interface identifer. In my example, the first byte in binary form is 00000000. When the seventh bit is complemented, it becomes 00000010 (0x02). That gives us a first octet as 02 giving making the EUI-64 interface 0000:0210:5aff:fe66:dc33
Now, I have my prefix (3ffe:b80:17e2::) and a EUI-64 identifier (210:5aff:fe66:dc33). I concatenate the two... Lo and behold the 128 bit splendor : 3ffe:b80:17e2::210:5aff:fe66:dc33 is the LAN interface's IPv6 global unicast address.
Now boot a host on the LAN and you will see it get an IP address automatically. 'ip -6 route neigh show' will show you his neighbours. You can even touch the router. But not yet the outside world : the router and the outside node don't know where to send packets destined to the LAN. To tell the router that the subnet whose 48 bit prefix the IPv6 connectivity provider gave you lies on the inside LAN, you can use something like he following command :
ip -6 route add 3ffe:0b80:17e2::/48 dev eth1
That's where it pays to have enabled the netlink device emulation : the command fails without it. To manage the route automatically, you can add the following two lines to /etc/network/interfaces :
up ip -6 route add 3ffe:0b80:17e2::/48 dev eth1 down ip -6 route del 3ffe:0b80:17e2::/48 dev eth1
As a result, some section of your /etc/network/interfaces should look somewhat like that :
iface eth1 inet6 static address 3ffe:b80:17e2::1 netmask 64 gateway 3ffe:b80:2:adee::3e04:1236 up ip -6 route add 3ffe:0b80:17e2::/48 dev eth1 down ip -6 route del 3ffe:0b80:17e2::/48 dev eth1
Now, 'ip -6 route' should output something like that :
3ffe:b80:17e2:fffe::/64 dev eth1 proto kernel metric 256 mtu 1500 advmss 1440 2000::/3 dev sit1 metric 1 mtu 1472 advmss 1412 fe80::/10 dev eth1 proto kernel metric 256 mtu 1500 advmss 1440 fe80::/10 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440 fe80::/10 via :: dev sit1 proto kernel metric 256 mtu 1472 advmss 1412 ff00::/8 dev eth1 proto kernel metric 256 mtu 1500 advmss 1440 ff00::/8 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440 ff00::/8 dev sit1 proto kernel metric 256 mtu 1472 advmss 1412 default dev sit1 metric 1 mtu 1472 advmss 1412 unreachable default dev lo metric -1 error -101
Your work has born its fruits : you can now inform your amazed users of the availability of the dancing turtle at http://www.kame.net/. Isn't IPv6 wonderful ? Of course only users of IPv6 enabled browsers such as Mozilla on IPv6 enabled hosts will enjoy the sight of the mythical animal. It may seem obvious, but when it comes to users, nothing is obvious.
If you want to have a look at the passing packets, ethereal is a good GUI choice. Enter 'ipv6' (without the quotes !) as a display filter and enjoy the view. If you prefer a simpler tool, tethereal works well in the console.
Connectivity is nice, but doing something useful with it is even better. So bring on the apps !
The standard Debian distribution comes with some degree of IPv6 support, but it is actually still patchy. IPv6 is a continuing goal of the Debian project, but a few hurdles make widespread IPv6 support throughout the distribution a non-trivial task. First, IPv6's specifications having long been a moving target does not make implementation particularily easy. Then even when IPv6 is implemented in the upstream package it is often disabled by the Debian package's maintainer. The reason is that enabling IPv6 by default seems to have often generated various breakages that convinced maintainers that a conservative configuration was preferable. Luckily you will find under the Debian-IPv6 banner a group of motivated individuals that are pushing IPv6 support in the distribution. Until the day when all their work is merged in the mainstream distribution, you can find their IPv6 enabled packages. Once the packages hit the main Debian archive they are removed from this archive.
The packages are provided in a central apt-getable repository. They provide a list of mirrors. Just keep in mind that those are experimental packages, so the usual warnings apply.
A few Internet access providers now offer /48 subnets to their customers who can then enjoy radically lower latency for their IPv6 traffic. The long way across the tunnel to the endpoint and then to the destination and back the same way make for barely tolerable latency. An endpoint right across the DSL link will really make IPv6 usable for the common folk.
In France, Nerim http://www.nerim.net/ proposes such a service to subscribers for free, although it is not standard and you have to ask for it specifically. If you are a customer, send your polite request to ipv6@nerim.net.
There are certainly other providers with such offerings. Please notify me if you encounter one and I will list him here as an encouragement to the others.
Jean-Marc Liotier is the original
author and the current maintainer.
David
Goodenough was the first to spot a typo in an
example address. But the error was apparently much deeper than a
typo and
Jeremy T.
Bouse sent me a heavy erratum for former section
6.2 "Setting up the router's LAN interface". Turns out I had not
understood correctly how to produce an address. As a result, I
rewrote sections 6.1 "Setting up the router's LAN interface" and
6.2 "Setting up the stateless autoconfiguration server". Writing a
howto is a good way to make sure you really understand the
subject...
Complete rewrite of several portions to reflect the state of the art.
This is ruwenzori.net.