IPv6

IPv6, or Internet Protocol version 6, is the basis of the "new Internet". It is the next standardized version of IP (currently we run IPv4). It has several advantages over IPv4, but most notably, it has an enormous address space, which promises to get us out of the current IP address crunch, and eliminate the need for NAT.

I had the pleasure of collaborating with Mark G. Sobell on the Sixth Edition of A Practical Guide to Fedora and Red Hat Enterprise Linux, writing about four pages on IPv6 (pp. 373-376). It's a start.

Why?

You might be asking yourself, "Why do we need IPv6? Why should I run IPv6?" I'll answer these two questions separately.

Why do we need IPv6?

Because we're running out of IPv4 addresses. Update 03Feb2011: The IANA free pool is depleted. All reasonable projections are that the unallocated IPv4 address space will be depleted in 2012. Getting more IPv4 addresses at that point will likely involve a sort of "free market" approach, and it could get ugly, or at least very expensive. And it isn't sustainable; there just aren't enough addresses to meet the demand. The mathematical number of IPv4 addresses, 2^32, is a very different thing than the practical number of usable addresses. IPv6 gives us 2^128 addresses, which should satisfy any appetite.

Here's a grandma-friendly explanation (tailor as needed to each "grandma"): Consider street addresses. We "waste" addresses so that it is easy to find the block you are looking for. You may have a "100" block, and then a "200" block; that's 100 possible addresses on each block. But we aren't compelled to use up all possible 100 addresses; we use only what we need to number the houses and businesses on that block, "wasting" the rest of the numbers. If we numbered blocks in tens instead of hundreds, we might be able to use up more numbers, but what if we had a block with 11 houses on it? We need to have ordered ranges of addresses per block so we can find an address, and that means having to skip numbers. The Internet works the same way; computers are addressed like street addresses, and the networks they are on are like block numbers. Most networks out there don't use up all their numbers, just like we don't use up all the street addresses on a block, and that's OK. But unlike street addresses, where you can just add more digits as the road is extended into the suburbs, we have a fixed number of digits in computer addresses, and we're running out of "block numbers" to give people. We need a new system with more digits, and that's what IPv6 does.

There are other improvements, but the address space is the pressing need.

Why should I run IPv6?

    1. The best reason any geek has to do anything: Because you can. It may seem reasonable to assume that you can't participate meaningfully in IPv6 unless your ISP gives it to you. But that is actually not the case. It is surprisingly easy to get started with IPv6 and talk to the greater IPv6 Internet, even on an IPv4 connection.

    2. The you-know-what is going to hit the fan soon when the addresses run out, and you should be prepared. Having the skills ahead of the crushing demand will be a good career move for anyone in IT.

    3. Kiss NAT goodbye. Gone is the need for port forwarding and STUN protocols and all that nonsense. We've gotten comfy under our NAT blankets over the years, but it should be remembered that you can implement the same security policy without NAT that you can with NAT.

Basics

It is advisable to read (or at least skim) the Wikipedia article on IPv6. But here are the highlights:

128-bit addressing

In contrast to IPv4's 32-bit addressing, this gives us so much address space that we can be truly wasteful. It opens the door to simplifying network provisioning, both in terms of sizing networks and autoconfiguration.

IPv6 addresses are represented in hexadecimal, with each two bytes (i.e. four hex digits) separated by colons. Leading zeros can be omitted, and running zeros can be abbreviated with the use of a double-colon. For instance, here is an address returned for ipv6.google.com:

2001:4860:800e::63

This expands to:

2001:4860:800e:0000:0000:0000:0000:0063

If you think about it, you'll realize that double-colons can only be used once. And they can be used on either end of the address; for example, the network address for that host would be:

2001:4860:800e::

We can also put the netmask component on network addresses:

2001:4860:800e::/64

One-size-fits-all networks

Subnetting is a thing of the past. All networks are /64; i.e., the first 64 bits are always the network address, and the last 64 bits are always the host address. For example, an allocation of /48 is really 65536 /64 networks. There is no reason one would need to provision a network on a subnet larger than a /64, as a /64 by itself can contain four billion times the total addressing capacity of the v4 Internet! Furthermore, there are still plenty of networks available for allocation; consider that a /48, which is a standard "extra-small" allocation of 65536 networks, is similar in function to a IPv4 /8 "extra-large" allocation of 65536 class-C networks.

Autoconfiguration

Because of the enormous and standardized 64-bit host component address size, much liberty can be taken with how addresses are constructed. One common way to construct a host address is for the host itself to use a deterministic algorithm to produce a globally unique address based on its MAC address. Therefore host addresses can be the same on any network on IPv6; only the network part of the address must change. This makes a lot of network maintenance tasks much easier, as you don't have to renumber a network if its prefix changes or if networks are merged. It also opens possibilities for Mobile IPv6. Host addresses can still be statically assigned without interfering with this algorithm if that is desired.

Furthermore, IPv6 defines extensions to ICMP that allow routers to announce themselves via a link-local multicast address, and announce the network address. Hosts can use this information to configure their interfaces and routes. This is built into the protocol stack; DHCP is not necessary (but available). This means that you can fire up an IPv6 network on your LAN, and all IPv6-enabled hosts will suddenly start talking IPv6 without any configuration whatsoever.

It is also standard for hosts to assign themselves link-local addresses, similar in nature to the IPv4 169.254.0.0/16 range. This is implemented in the protocol stack, so it requires no support from a daemon process and is guaranteed to be available. This allows ad-hoc networks to be very practical.

Dual Stack

As a migration feature, almost all systems implement a "dual stack" of IPv4 and IPv6, using both simultaneously. Some systems have separate stacks, and some implement both in the same stack; the distinction may be academic. Running both stacks will be necessary as long as IPv4 addresses need to be reached; the community doesn't seem to like doing NAT between IPv6 and IPv4, and efforts such as NAT-PT have been riddled with difficulty.

Ubiquity

A surprising number of operating systems and distributions have IPv6 enabled by default. If you see one of these link-local addresses assigned to an interface, you know it is on and working. And most major network software is already able to talk IPv6, such as web browsers and OpenSSH.

Getting Started

Getting started with IPv6 is surprisingly easy. Here are several ways of participating:

Getting an IPv6 allocation from your ISP is likely to be a tricky feat at this juncture, but worth a shot. Comcast is starting a pilot program which will be using 6rd, a method similar to 6to4 (discussed below). Verizon has also announced a pilot program.

Automatic tunneling is a good place to start, as it is easy and quick to setup. Teredo tunneling is almost trivial to setup, and may be fun to try first just to get going, but it isn't as flexible. It will, however, poke through most firewalls and NATs, so it is useful to setup on portable computers.

If you use DD-WRT, there are instructions in this document for how to get these configuration items into it. I have made the following "Getting Started" instructions as general as possible, and it should be directly applicable to DD-WRT; it is reasonable to go straight to DD-WRT as your first endeavor if that's convenient to you.

Common Commands

As you start with this, you'll surely want to use some common tools to test that things are working. Many tools append a "6" to the end to differentiate themselves (although not all):

    • ping6

    • traceroute6

    • ip6tables

Other tools "just work". Occasionally you have to put addresses in square brackets to differentiate them from hostnames (not with the aforementioned "6" tools). And for very special link-local addresses, you may have to affix the interface name, either with a "%" delimiter in the address, or with a switch (-I for ping6).

Automatic Tunneling

It may come as a surprise to you, but if you have an IPv4 public address, you already have a /48 IPv6 allocation! The 2002::/16 address space is reserved for this. Each IPv4 address has the allocation 2002:xxxx:xxxx::/48, where the x's are the hexadecimal representation of your IPv4 address.

Traffic is routed to you via the IPv4 Internet using 6to4 tunneling. This is nothing more than embedding an IPv6 packet inside of an IPv4 packet (proto 41), similar to IP-in-IP (proto 4). There are 6to4 gateways (too few, I might add) scattered throughout which advertise their ability to route to 2002::/16. They see traffic sent to these special network addresses and send an IPv4-encapsulated IPv6 packet to the IPv4 address embedded in the destination IPv6 address. Similarly, encapsulated return traffic can be sent to any one of these gateways. As an added convenience, they advertise to the IPv4 world via BGP their ability to route to the well-known anycast address of 192.88.99.1, which you can use as the default gateway for IPv6 traffic. This (hopefully) means that return traffic will always take the shortest route to the nearest 6to4 gateway. You can also use the gateway's unicast address if you know better. However, any traffic from your machine bound for 2002::/16 does not use the default route, but rather is delivered directly to the embedded address. This means that when 2002::/16 networks are communicating directly with each other they will take the most efficient route through the IPv4 Internet rather than being bottlenecked on a 6to4 gateway.

Here's the recipe for getting your Linux box up and running with automatic tunneling:

# Replace WANIF with your WAN interface name

WANIF="eth0"

# Get your WAN IP address

WANIP=$(ip -4 addr show dev $WANIF | awk '/inet / {print $2}' | cut -d/ -f1)

if [ -n $WANIP ]; then

# Deduce your IPv6 network address

V6PREFIX=$(printf '2002:%02x%02x:%02x%02x' $(echo $WANIP | tr . ' '))

# And the real magic...

ip tunnel add tun6to4 mode sit ttl 255 remote any local $WANIP

ip link set tun6to4 mtu 1280

ip link set tun6to4 up

ip addr add $V6PREFIX:0::1/16 dev tun6to4

ip -6 route add 2000::/3 via ::192.88.99.1 dev tun6to4

fi

If you want to create a local network that can talk IPv6 (and I'm sure you do), you'll need to allocate one and put an address on the LAN interface. Easy enough... just add this somewhere in the aforementioned recipe (I put the "ip addr" commands together):

# Replace with your LAN interface name

LANIF="eth1"

ip addr add $V6PREFIX:1::1/64 dev $LANIF

You can now either statically assign IPv6 addresses on your various machines, or configure radvd for autoconfiguration (highly recommended).

You can even do reverse DNS for 6to4 addresses! Just visit this link from any host on your 6to4 network to setup the delegation.

Automatic Configuration

IPv6 is great because of its automatic configuration abilities. But it does need some hints. There's a daemon called the Router Advertisement Daemon, or "radvd", that uses the IPv6-intrinsic methods for announcing the router and the network prefix. It is easy to get going. The config file is usually /etc/radvd.conf (there's a form field for it in the DD-WRT GUI). Here's a configuration for those using automatic tunneling (replace WANIF with your WAN interface name, and LANIF with your LAN interface name):

interface LANIF {

MinRtrAdvInterval 3;

MaxRtrAdvInterval 10;

AdvLinkMTU 1280;

AdvSendAdvert on;

prefix 0:0:0:1::/64 {

AdvOnLink on;

AdvAutonomous on;

AdvValidLifetime 86400;

AdvPreferredLifetime 86400;

Base6to4Interface WANIF;

AdvRouterAddr on;

};

};

This config will deduce your network prefix from your IPv4 address, giving you the form 2002:xxxx:xxxx:1::/64 (the "1" comes from the line "prefix"), and advertise that to your LAN, suggesting that machines may autonomously give themselves addresses. This prefix assumes you have set up an interface address on your router per the instructions in this document.

All you should have to do is fire up the daemon, and voila, your IPv6-enabled machines will instantly be addressed and able to route! Try going to http://ipv6.google.com to test it out!

RTFM for details on what all the options mean. You can actually do with much less, but it is advisable at least to set the lifetime values to avoid addresses sticking around for a REALLY long time on all your devices, especially in this early stage when you're fiddling.

Teredo Tunneling

The purpose of Teredo tunneling is to provide a way for machines to get on the IPv6 Internet when they are trapped behind NAT, which precludes the use of 6to4 tunneling. Teredo is implemented with UDP, since many NATs can't handle traffic that isn't TCP or UDP. Also, the addresses given to hosts encode the particulars of what Teredo relay you're using, as well as what your NAT's public IPv4 address is, which allow the protocol to work via NAT while being stateless on the relay.

Not only does Teredo give you the ability to get on the IPv6 Internet, but it also makes it possible for Teredo clients to communicate using IPv6 directly without going through a relay, even if both clients are behind NAT. To understand the finer details on how all this is accomplished, read Microsoft's overview.

A common Linux Teredo implementation is Miredo. There is a Debian package for it. If you just install it, it'll start working, and you'll instantly be on the IPv6 Internet! Crazy, huh? Try going to http://ipv6.google.com to see if it works! Miredo is also available for the Mac.

Teredo is built-in to all Windows platforms at least as far back as Windows XP SP2. See the instructions near the bottom of Microsoft's Teredo overview for XP instructions on how to get IPv6 turned on and Teredo working.

This is safe (from a correctness standpoint) to leave running all the time. The tunnel route is given a less favorable metric, so if there is a more proper way of getting on the IPv6 Internet, that will be preferred. Of course, bringing the whole IPv6 Internet into your computer with no firewall is not especially safe. Caveat Emptor.

IPv6 Rapid Deployment

If you're lucky enough that your service provider is rolling out IPv6 natively, there's a good chance they're using IPv6 Rapid Deployment (6rd). Comcast has announced plans to roll this out. This is similar in nature to the 6to4 "automatic tunneling" method mentioned before, but instead of using these special 2002::/16 addresses, you get a real 2001::/16 "native" address from your ISP, and they manage getting your traffic to and from the native IPv6 Internet. This is essentially the same as getting native IPv6 service from your provider, but they can roll it out easier by using the existing IPv4 infrastructure as a virtual link layer just like 6to4 effectively does. In fact, 6to4 can be seen as a special case of 6rd.

The "sit" tunnel driver in Linux has been updated in 2.6.33 to support 6rd. Hopefully the "iproute" package has been updated to support the new ioctls.

The disadvantage to this method is the continued overhead of the encapsulation.

DD-WRT Particulars

Surely many of you want to do this on DD-WRT. There is a great tutorial on the DD-WRT website. Here is the condensed version. It can all be done via the GUI.

    1. Under Administration->Management, turn on IPv6 and likely also radvd. If you use radvd, place your radvd config in the text field.

    2. Place your IPv6 networking startup script (i.e. the commands from previous sections used to setup IPv6) into Administration->Commands, and click "Save Startup". You'll need to make these important changes from the configs mentioned in this document:

      • WANIF should ordinarily be vlan1

      • LANIF should ordinarily be br0

      • Prefix with this to ensure the ipv6 module is loaded:

        • insmod ipv6; sleep 5

      • If you're using radvd (highly recommended), suffix with this to ensure that it runs:

        • radvd

That's it! DD-WRT makes these hand-configurations surprisingly easy. Firewall configs can be stored similarly using the "Save Firewall" button; they'll be applied idempotently without precipitating a restart.

Hurricane Electric

This is an easy way to get a Hurricane Electric tunnel setup on your DD-WRT installation.

Security

Security is going to be the big deal with IPv6. As you can see, tunneling makes it easy to bring in the whole IPv6 Internet to your machine or your whole network, and with most modern OSes and distros defaulting to having IPv6 on, it is rather easy to circumvent security policies. At the very least, you're going to want to protect yourself from undesirables coming in via your purposely configured IPv6 network.

ip6tables

Like so many Linux IPv6 tools, the number "6" is involved in the name of the IPv6-enabled iptables, but this one is a bit unusual that it is in the middle of the name and not a suffix. ip6tables has basically the same semantics as iptables, but it is a completely separate set of configurations from IPv4, so you MUST configure your firewall if you want to protect yourself! Here's a reasonable configuration allowing one network in and disallowing others, while permitting established connections to work:

ip6tables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

ip6tables -A FORWARD -s 2001:470:1f07:6c0::/64 -m comment --comment "Richie's 4 billion Internets" -j ACCEPT

ip6tables -A FORWARD -i tun6to4 -j REJECT --reject-with icmp6-port-unreachable

Salt to taste. Your interface names and addresses may vary. You might consider setting the default policy to DROP or REJECT. Ordinary security sense applies.

6to4

RFC 3964 discusses security issues specific to 6to4 tunneling. Read the wiki page on 6to4 for a synopsis. If you provide public addresses to your hosts, but you need to enforce policy, you may want to block protocol 41 at your firewall.

Teredo Tunneling

While Teredo tunneling is useful, it can violate security policies at organizations. Therefore such organizations should take at least basic precautions to disallow it. It should be as easy as firewalling off the UDP port 3544. Of course, the user could setup his own Teredo relay on a different port, but then you're just playing a game of chase to prevent a motivated user from getting around your policies, which doesn't end well.

Throwing Users a Bone

Such organizations should consider offering IPv6 access without the need for 6to4 or Teredo. This will dissuade users from violating policies by giving them most of what they want (e.g. access to their home machines from work which are hard to get to via IPv4), while giving you the ability to implement proper policy on your firewall. If you can reduce the advantage gained by circumventing policy without compromising security, everyone wins.

Notes

This section contains miscellaneous notes that perhaps could be better organized, but are useful enough to go ahead and document.

IPv6-enabled Sites

Here are some popular or interesting sites that are IPv6-enabled.

I read on this blog that the .org domain servers are 100% IPv6-enabled.

Here you can get a list of the top 50 IPv6-enabled sites, updated automatically and periodically.

IPv6-enabled ISPs

Here are some ISPs who are participating in IPv6.

    • I have witnessed that Verizon's LTE (aka 4G) network issues IPv6, at least on the Samsung Galaxy Nexus.

    • XS4ALL, a large consumer ISP in the Netherlands, has announced opt-in native IPv6 for all its customers. This is likely the first large-scale residential deployment anywhere (not counting "walled gardens").

    • Comcast has announced IPv6 trials to consumers, and I hear that some people are already getting 6RD-capable routers.

    • T-Mobile is looking for folks to help test their mobile IPv6 offerings.

    • The entire campus of UC Berkeley is IPv6 ready. Users of campus DHCP are assigned IPv6 addresses along with IPv4.

Disabling Autoconfiguration

In Linux, there are numerous options for IPv6 here:

/proc/sys/net/ipv6

You can disable autoconfiguration of IPv6 address (router-announced network prefix) like so:

# echo 0 > /proc/sys/net/ipv6/conf/all/autoconf

You can disable autoconfiguration of default route (router announcement) like so:

# echo 0 > /proc/sys/net/ipv6/conf/all/accept_ra

You can replace "all" with the name of a specific interface. In fact, I tried to do this to "all", and it seemed to have no effect; doing it on the specific interface worked.

Finding All IPv6 Hosts

It would take approximately forever to nmap an entire /64 network, so that method of discovering hosts is impractical. Luckily, the equivalent of a broadcast ping is rarely disabled in IPv6 (in fact, the option doesn't exist in Linux; it would have to be implemented with a firewall configuration). IPv6 doesn't have the concept of broadcast like IPv4 does, but it makes great use of multicast. There is a link-local "all-hands" multicast address that you can ping: ff02::1. Since this is link-local, you have to provide the interface in question. For example, here are two ways to use ping6:

$ ping6 ff02::1 -I eth0

$ ping6 ff02::1%eth0

The percent sign is common nomenclature to specify the interface when necessary, and is likely to work across programs.

If your network is setup with autonomous address assignment, this trick is especially useful. The ping will return the link-local address (i.e. prefixed with fe80::), but the algorithm for assigning the host component of the address does not depend on the network component, so all you have to do to get the host's global address is replace the network prefix returned in the ping with your local network's global prefix.

Disabling random identifiers in Windows

At least in Windows 7, the host address component of an IPv6 address will be generated randomly by default rather than with the MAC of the host interface. If this behavior is not desired it can be disabled with the following command line:

netsh interface ipv6 set global randomizeĀ­identifiers=disabled

Windows 7 will also configure a "Temporary IPv6 Address" that it will use as its source address by default. Likely you'll want to disable that too if you ran the above command. You can do so with this command line:

netsh interface ipv6 set privacy state=disabled

For more information, see IPv6 Autoconfiguration in Windows Vista.

External Links

RFCs

    • RFC 4291 - IPv6 Addressing Architecture

    • RFC 4966 - Reasons to Move NAT-PT (RFC 2766) to Historic Status

    • RFC 3484 - Default Address Selection for IPv6