Weekend Project: Transition to IPv6


This is our third article in the Weekend Project series. Our recent Linux.com survey results told us that you want more tutorials on the site, so this series is running on Fridays and includes longer tutorials to provide Linux users with a fun project to embark upon over the weekend. Please share with your friends and colleagues and have fun with it! And, as always, let us know if it’s useful and what other topics you would like to see in this series.

Transitioning to IPv6

Internet Protocol version 4 (IPv4) has certainly served the world well over the past few decades, but that’s no reason to cling to it until the bitter end. You can start using its replacement IPv6 on your Linux machines and home network today.

Know Your Protocols

If you haven’t worked with IPv6 before, you might have only heard one fact about it: that its expand, 128-bit address space is so much larger than IPv4’s 32-bit space that it will never need to be expanded again. The curmudgeons may mutter, “never say never” at that claim, but it is true that the last unreserved IPv4 address blocks are predicted to be used up by September of 2011, at which point ISPs and businesses will be forced to start using IPv6 in order to roll out new networks.

Still, if you are reading this Weekend Project, then you are connected to the Internet, so IPv4’s address depletion hasn’t hit you yet. But there is a lot more to IPv6 than just its large address space. IPv6 has built-in IPSec security features that are optional in IPv4 (and thus, rarely offered to consumers by ISPs), larger packet payloads called jumbograms that increase network efficiency, built-in support for mobile networking devices that move from one connection point to another as they travel, simplified routing and address autoconfiguration.

Some of those niceties are available to IPv4 networks through other means, of course. DHCP is commonly used to allow automatic address assignment — IPv6 builds the same functionality right into the IP protocol.  Because it is a low-layer protocol, applications (with very rare exceptions) don’t care whether or not they are running on top of IPv4 or v6.

Getting started with IPv6 starts with understanding IPv6 addresses. Many of IPv6’s new functions are possible because the protocol uses the 128-bits more intelligently; essentially, there is so much space available that the protocol uses the address to embed hierarchical information about the network, not just assign a unique string of bits to each host.

This is possible because each network interface can have multiple addresses assigned to it, with different prefixes. For example, the prefix “fe80::” indicates that an address is link local. Routers do not forward link-local address traffic; it is valid only on the immediate Ethernet segment (or equivalent). A device can use its link local address to broadcast requests for site-wide or global addresses, and only the nearest router will respond, greatly simplifying configuration. The prefix “2002::” indicates that an address is a 6to4 transition address. 6to4 is a mechanism with which IPv6 nodes can tunnel traffic through incompatible, IPv4-only network segments. The address structure also includes other special multicast and “anycast” address types to implement other features.

Because IPv6 addresses encapsulate routing and network information in this manner, how best to roll out IPv6 on your Linux machine depends in part on how your network is set up — particularly on whether or not you are only worried about a single box, or want to set up multiple boxes — and how you connect to the Internet upstream.  Getting started, however, begins in the same place: the kernel.

The Linux Kernel and Utilities

The Linux kernel has supported IPv6 since the very beginning, around 1996, and has adapted to keep up with the revisions and enhancements of IPv6-related RFCs over the years. Today, virtually no Linux distribution ships a kernel that does not include the IPv6 module compiled and loaded by default. You can test for its presence in several ways, though. The simplest is to look inside the /proc/net/ directory; if /proc/net/if_inet6 (and other entries) are present, the IPv6 module is loaded. If not, you can load it with modprobe ipv6.

Next up is to examine your network interfaces and see if they are configured for IPv6.  Run ip -6 addr show dev eth0 (as root); the output will list all IPv6 addresses assigned to the eth0 network interface (if you use eth1 or another interface, just substitute it in the preceding command). You will at least see an fe80:: link-local address. If you have additional IPv6 addresses already assigned, then you are already up and running, and the remainder of this guide will not be of much use. For everyone just getting started, though, the link local address is likely the only one reported by ip.

The other major obstacle to an IPv6 transition is DNS lookup. While IPv6 addresses may be reachable directly, most user programs operate on DNS records, and by default some DNS servers do not try IPv6’s distinct “AAAA” records first. This was the source of a well-publicized bug in Ubuntu several releases ago.  To see whether or not you can look up IPv6 hostnames, run host -t AAAA ipv6.google.com. You can attempt to lookup any hostname this way, but it must be one with an IPv6 record, hence you should choose a known-to-be-on-IPv6 target. If the request fails, the easiest fix is to choose new DNS servers — most of the free, publicly-available servers now support IPv6 lookups; you are likely to encounter trouble only if you are using your ISP’s default DNS servers.

Finally, if you are behind a firewall, be sure that it is not configured to block IPv6 packets; they are IP protocol number 41 and are not the same as IPv4 packets. How to do this depends on the firewall that you run, however, all Linux firewalls in regular usage support it.

Getting Around the LAN

As mentioned above, if your IPv6 network stack is running, your Ethernet or WiFi interface should automatically grab a link local address. But to connect to other hosts, you will need an additional address.  As with IPv4, you can assign an address yourself with a command line tool like ifconfig, provided that you choose a valid address. For testing purposes, such as between two boxes on your home network, this is an acceptable method — even though you will want a more permanent solution further down the road.

You can assign a unique local address (ULA) yourself without fear of colliding with another IPv6 host. They begin with the prefix “fc00::” and are supposed to contain a randomly-generated string, although there is currently no canonical way to select this. For testing purposes, you can assign one with ifconfig eth0 inet6 add fc00:XXXX::1/64. If you wish, you can register your random ULA prefix with the unofficial index at SixXS.net, although this is not required.

Once you set up two or more IPv6 hosts on the same network, you can test whether they are reachable from each other using ping6, an IPv6-only implementation of ping. Simply run ping6 fc00:XXXX::1, substituting the appropriate prefix in place of XXXX.

You may find references to site local addresses (as opposed to link local) in some reference materials; this is a type of address with the prefix “fec0:” and it is now deprecated; ULAs are the replacement.

Connecting to the Rest of the Internet

Two hosts on the same network being able to ping6 one another is nice, but it’s nothing to write home about. Your transition also has to account for connecting your IPv6-capable hosts to the IPv6-connected Internet writ large. How best to pursue that depends on your network connection point.

If your machine has a static IP address, you can use a free 6to4 tunnel broker (such as Hurricane Electric or SixXS), which will allow you to route IPv6 traffic even through uncooperative IPv4-only ISPs using 6to4 “relay routers.”  6to4 addresses use the prefix 2002: followed by the IPv4 address of the host, such as 2002:A.B.C.D:: — it is because of this scheme that a 6to4 host must have a reachable IPv4 address; a NAT address such as is not unique.

Once you have registered with a 6to4 tunnel broker, setting up the tunnel is as simple as running a few configuration commands. Start with ip tunnel add my6to4 mode sit remote any local A.B.C.D, followed by ip link set dev my6to4 up. This creates a new virtual network interface named my6to4, then activates it. You will then need to assign the 6to4 address to the tunnel device, with a command like ip addr add 2002:A.B.C.D::1/16 dev my6to4 — but remember to first convert the A.B.C.D IPv4 address to its hexadecimal form.  Finally, ip -6 route add ::/0 via :: dev my6to4 metric 1026 adds the appropriate routing information — sending all IPv6 traffic through the my6to4 interface.

A far, far simpler solution for most basic setups is to skip 6to4 and use the Teredo protocol instead.  Like 6to4, Teredo is an official IPv4-to-IPv6 “transition mechanism,” but it is entirely automatic, and better still, it works even for those hosts that do not have a static IPv4 address (which includes most ISP customers).  The downside is that Teredo grabs a new IPv6 address on each restart, making persistent connections and running servers impossible.

The Linux implementation of the protocol is called Miredo. Most distributions package it; if yours does not you can fetch it from the project site. Once installed, just run miredo as root; the service spawns in the background and retrieves an IPv6 address. That’s all there is to it. You can test its effectiveness by running ping6 ipv6.google.com (or ping6’ing another IPv6 host).

As simple as it sounds, most other Linux applications work fine over IPv6 with no additional steps required.  You can test whether or not Firefox or another Web browser is correctly connecting over any of the above IPv6 configurations by visiting www.kame.net. The site responds differently depending on whether or not you reach it via IPv4 or IPv6. On IPv4, you will see a static PNG image of a turtle at the top of the page.  On IPv6, you will see an animation of the turtle swimming instead.

By and large, the rest of the Internet will not seem more special or magical on IPv6; you can access Google’s IPv6-only search engine, which might be faster, and some users who run their own web and mail servers report drastically lower incidents of spammers and denial-of-service attacks, but the real fun is found in the improved routing and autoconfiguration; it’s easy to get used to.

Further Work

Both of the tunneling techniques described above (6to4 and Teredo) work well for single machines, but if you intend to run an IPv6 network at home or in your office, neither is ideal. For that, your best option is to set up one host or router on your network as the local endpoint of a 6to4 tunnel, and use IPv6’s stateless autoconfiguration for all of the other computers.

For this, you will need to designate one machine as a “router advertiser” (presumably the gateway). This machine will listen for router solicitation requests broadcast over the local network by IPv6 clients using their link local addresses, then respond to each of them, assigning unique address. This is akin to the behavior of a DHCP server with IPv4.

On Linux, the preferred package to perform this task is the router advertisement daemon, radvd. Setup is not complicated, but there are a few options, such as working with or without 6to4. If you segment your network, you may also need to take special steps to ensure that clients on one link can reach the radvd server — remember, the clients use link local addresses to try and discover the server, so they must be on the same network segment. This could even affect WiFi clients, if the router in question keeps the WiFi and wired sides of the LAN separate.

Once you’ve gotten familiar with basic radvd, though, there is still more in IPv6 to learn — we have not even touched on Mobile IPv6 or IPSec, both of which are interesting topics in their own right. If you’re interested in a Weekend Project tutorial on Mobile IPv6 or IPSec vote with your comments in the section below!