In previous articles I’ve covered the basics of configuring IPv6 on your Linux host. Knowing how to enable and configure IPv6 is valuable but this knowledge is not very useful if you can’t use it to connect to anything. At present most people are not connected to the IPv6 Internet because their ISP lacks support for the protocol. In time this will change, but how can you make use of IPv6 right now?
In this article we’ll dive in to setting up and using a tunnel broker to access the IPv6 Internet. We’ll cover this topic in two articles. First we’ll go over the basics of what a tunnel broker is, configuring a tunnel and managing issues created by having a dynamic IPv4 address. In part two we’ll go over how to route IPv6 to your internal network, use router advertisements to assign IPv6 addresses to all of your internal hosts and add some security using ip6tables. In addition I’ll share some scripts to automate tunnel setup, configuration and maintenance.
About Tunnel Brokers
IPv6 Tunnel brokers have been around for quite a while now with some serving users since the late 1990s when the IPv6 protocol was standardized in RFC2460. All tunnel brokers provide the same basic service, they allow you to connect to the IPv6 Internet by tunneling IPv6 inside of IPv4. The services offered by tunnel brokers can vary, some provide a single IPv6 address giving a single host connectivity while others allocate an entire /56 or even a /48 of IPv6 addresses allowing you to route multiple subnets over the tunnel. Some tunnel brokers support DNS delegation, BGP and multicast. Others work well with NAT while some do not. A list of IPv6 tunnel brokers which details the features they support and services they offer is available at Wikipedia.
How Tunnel Brokers Work
There are numerous ways to establish IPv6 connectivity by encapsulating IPv6 inside of another protocol. The most common method is the 6in4 protocol which is defined in RFC4213. 6in4 is supported natively in Linux, the various flavors of BSD, Cisco and Juniper routers as well as other devices. The protocols broad support makes it ideal for use in many situations. 6in4 does have some drawbacks though. For example, it does not work well behind a NAT. It can be made to work by forwarding packets or using “DMZ” settings available on some home routers but generally getting it to work behind a NAT is prone to problems. 6in4 also requires that each end of the tunnel be configured with the public IP address of the other side which means that dynamic IPv4 addresses can be a problem. There are ways to deal with dynamic addresses which we will explore later in this article.
There are other protocols available for tunneling IPv6 in IPv4 as well. For example AYIAY, the Anything in Anything protocol and TSP, the Tunnel Setup Protocol, which is defined in RFC 5572, are both protocols that allow for tunnels to work over NATs. However these protocols have limited support across operating systems and often require specialized software to be installed in order to work properly. If you are behind a NAT or want IPv6 support on your laptop as you travel they may be your best choice and are worth looking in to.
This article will focus on using 6in4. It is the most widely used IPv6 tunneling protocol with support from all of the tunnel brokers listed on wikipedia as well as broad support among operating systems and devices.
Choosing a Tunnel Broker
Over the years I’ve tried all of the popular tunnel brokers and they all perform very well in my experience. You should choose a tunnel broker based on the features that you require and your level of comfort with the system configuration. If you are looking for a way to get a single host or laptop connected to the IPv6 Internet Gogo6 and SixXS both offer client software that will establish an IPv6 tunnel from behind NATs and make getting IPv6 connectivity very easy. Their client software makes IPv6 for road warriors simple. If you want to configure BGP to announce your own IPv6 allocation Hurricane Electric has an option for you with their tunneling service. If you need multicast support SixXS has you covered. All of the major tunnel brokers will allocate you a block of addresses in order to IPv6 enable entire subnets. A matrix of features is available in the wikipedia article mentioned above.
In this article we are going to use the tunnelbroker.net service provided by Hurricane Electric. The primary reason for this is that I have been using their service for the last few years and have developed tools that make managing their tunnels easy in a Linux environment. The tunnelbroker.net service also offers a free IPv6 educational program that makes use of their tunnel service to help system administrators and others learn how to integrate IPv6 with their network. Going through some of the certification drills is a great way to test out your newly provisioned IPv6 tunnel. With that said just about any tunnel broker will work, the techniques contained in this article can be applied to any service that supports the 6in4 protocol.
Configuring Your Tunnel
For the rest of this article it is assumed that you have created an account at tunnelbroker.net and created a regular tunnel by defining your IPv4 address (endpoint) and selecting a tunnel server. Once you have done this you should know the IPv4 address of the far end of your tunnel (the tunnel server), the IPv6 address (client IPv6 address) allocated to you by tunnelbroker.net and the IPv6 address of the tunnel server. For example, here is the information for a tunnel I have configured using the tunnelbroker.net service:
My IPv4 address: 70.164.19.160
My assigned IPv6 address: 2001:470:1f06:56f::2/64
Server IPv4 address: 209.51.161.14
Server IPv4 address: 2001:470:1f06:56f::1/64
I will use the above information throughout the examples in this article (Remember to use the addresses that you are allocated, not the addresses from the examples!). In order to configure IPv6 on your host issue the following commands:
sudo modprobe ipv6
sudo ip tunnel add he-ipv6 mode sit remote 209.51.161.14 local 70.164.19.160 ttl 255
sudo ip link set he-ipv6 up
sudo ip addr add 2001:470:1f06:56f::2/64 dev he-ipv6
sudo ip route add ::/0 dev he-ipv6
Here is an explanation of what each of these commands do.
“modprobe ipv6″ loads the IPv6 kernel module. IPv6 is enabled by default on most Linux distributions but just in case it is not we will issue this command.
“ip tunnel add he-ipv6 mode sit remote 209.51.161.14 local 70.164.19.160 ttl 255″ configures a new 6in4 tunnel device named he-ipv6 with a remote endpoint of 209.51.161.14 and a local endpoint of 70.164.19.160 with a TTL of 255. TTL refers to the IP TTL and is set on packets traversing the tunnel. Remember to use your IP addresses!
“ip link set he-ipv6 up” bring the tunnel on line by setting the interface he-ipv6 to the up state.
“ip addr add 2001:470:1f06:56f::2/64 dev he-ipv6″ assigns the tunnelbroker.net assign IPv6 address to our local tunnel device.
“ip route add ::/0 dev he-ipv6″ sets the default route for IPv6 to the tunnel interface.
After entering the commands from above you should now have access to the IPv6 Internet from this host. You can test this by visiting a number of different sites that tell you your IPv6 address. One example is the homepage for ARIN, http://www.arin.nethttp://www.arin.net, which will display your IPv6 or IPv4 address at the very top of each page.
Troubleshooting
Having problems? Here are some things to try:
1) Can you ping the IPv4 address of the far side of the tunnel?
matt@zoidberg:~$ ping 209.51.161.14
PING 209.51.161.14 (209.51.161.14) 56(84) bytes of data.
64 bytes from 209.51.161.14: icmp_req=1 ttl=58 time=13.8 ms
64 bytes from 209.51.161.14: icmp_req=2 ttl=58 time=9.79 ms
If you can’t ping the IPv4 address of the remote tunnel end point try configuring a different tunnel end point using the management interface at tunnelbroker.net
2) Can you ping the IPv6 address of the far side of the tunnel?
matt@zoidberg:~$ ping6 2001:470:1f06:56f::2
PING 2001:470:1f06:56f::2(2001:470:1f06:56f::2) 56 data bytes
64 bytes from 2001:470:1f06:56f::2: icmp_seq=1 ttl=255 time=0.030 ms
64 bytes from 2001:470:1f06:56f::2: icmp_seq=2 ttl=255 time=0.036 ms
If you can’t ping the IPv6 address of the far side of the tunnel try clearing your tunnel configuration and re-applying the configuration.
sudo ip route del ::/0 dev he-ipv6
sudo ip addr del 2001:470:1f06:56f::2/64 dev he-ipv6
sudo ip tunnel del he-ipv6 mode sit remote 209.51.161.14 local 70.164.19.160 ttl 255
3) Can you ping a remote IPv6 address?
matt@zoidberg:~$ ping6 www.arin.net
PING www.arin.net(www.arin.net) 56 data bytes
64 bytes from www.arin.net: icmp_seq=1 ttl=55 time=23.7 ms
64 bytes from www.arin.net: icmp_seq=2 ttl=55 time=23.3 ms
If you can ping the IPv6 address of the far side of the tunnel but not a remote IPv6 address take a look at your default gw.
matt@zoidberg:~$ ip -6 route sh
2001:470:1f06:56f::/64 via :: dev he-ipv6 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
fe80::/64 via :: dev he-ipv6 proto kernel metric 256
default dev he-ipv6 metric 1024
If you don’t see “default” listed try re-adding the default route.
sudo ip route add ::/0 dev he-ipv6
If ICMP packets traverse the tunnel properly but HTTP and other types of packets do not it may be caused by having too large of an MTU on the tunnel interface. Tunneling IPv6 over IPv4 carries some overhead which limits MTU size. You can try setting the MTU of your tunnel interface to something lower than the default (1480 in most cases) using the following command:
ip link set he-ipv6 mtu 1280
If none of the steps above help to get your tunnel working you can visit the tunnelbroker.net forums (http://www.tunnelbroker.net/forums/http://www.tunnelbroker.net/forums/) and ask for help. There are many people there who can help you figure out what is wrong.
Making Things Permanent
We could just take the commands we used earlier and dump them in to /etc/rc.local to make the tunnel come up on boot but that is pretty lazy! Both Debian and Red Hat have support for tunnels in their network initialization scripts. Many distributions are derived from Redhat and Debian so understanding the configuration on each will take you a long way. It is also worth knowing how to initialize a tunnel using a custom script for cases where your Linux distribution does not conform to the Debian or Redhat way. Or perhaps you have special requirements that these built in support does not address. Using rc.local works too of course but there are definitely better ways.
Debian Configuration
Configuration in Debian and its derivatives is very straight forward. The /etc/network/interfaces file supports a special network device type called 6in4. You configure this device much like any other network device. There are some special directives you pass to the device but the syntax should be very familiar to anyone that has setup networking on Debian based systems in the past. Here’s an example using the values we’ve used throughout this article.
auto 6in4
iface 6in4 inet6 v4tunnel
address 2001:470:1f06:56f::2
netmask 64
endpoint 209.51.161.14
gateway 2001:470:1f06:56f::1
ttl 255
Here’s an explanation of what these parameters mean. The first line, “auto 6in4” tells the ifup command (used to bring up network devices) that the the device should be brought up automatically. “iface 6in4 inet6 v4tunnel” defines a new network interface named 6in4 which supports the IPv6 address family and is of the v4tunnel type. The “address” parameter is the IPv6 address of the 6in4 interface and “netmask” is the IPv6 netmask for the local IPv6 address. Next comes the definition for the tunnel brokers IPv4 address, this is defined with the “endpoint” parameter. “gateway” defines the IPv6 default gateway and “ttl” defines the tunnels default time to live value.
Adding a configuration like the example above (using the addresses assigned to you by tunnelbroker.net) to your /etc/network/interfaces file will cause your IPv6 tunnel to come up at boot.
Redhat configuration
Like Debian, Redhat’s network initialization scripts support provisioning an IPv6 tunnel at startup. If you’re familiar with the Redhat way of configuring network devices this should look very familiar to you. Redhat systems store configuration information for network interfaces in /etc/sysconfig/network-scripts/. Adding a new interface for an IPv6 tunnel requires that you make a new file in this directory called “ifcfg-sit0”. Here’s what a typical ifcfg-tun0 file looks like:
TYPE=sit
DEVICETYPE=sit
ONBOOT=yes
DEVICE=sit0
BOOTPROTO=none
IPV6INIT=yes
IPV6ADDR=2001:470:1f06:56f::2/64
IPV6TUNNELIPV4=209.51.161.14
IPV6TUNNELIPV4LOCAL= 70.164.19.160
You also need to make sure that you have a default IPv6 route. On Redhat systems this is done in a separate file called /etc/sysconfig/network-scripts/route6-sit0. This file should contain the following:
::/0 dev sit0
Now for an explanation of what this all means. The /etc/sysconfig/network-scripts/ifcfg-sit0 file contains quite a few parameters but they should look pretty familiar to you. “TYPE” and “DEVICETYPE” refer to the type of interface / device which in this case is “sit” which stands for “Simple Internet Transition” and refers to the 6in4 protocol. “ONBOOT” tells the system to bring the interface up at boot. “BOOTPROTO” is none because we are configuring static addresses. “IPV6INIT” tells the system to initialize the IPv6 subsystem of the kernel. “IPV6ADDR” is the local IPv6 address for the tunnel interface. IPV6TUNNELIPV4 and IPV6TUNNELIPV4LOCAL are the remote and local IPv4 addresses for the tunnel.
A Custom Configuration
Of course you may be using something other than Redhat or Debian that does not use these network initialization scripts. In this case it is probably easier to write your own initialization script and have the system call it at boot. Another advantage to using a custom solution is that it allows us to easily deal with dynamic IPv4 addresses.
Here’s a very simple init script that should work on most Linux distributions.
#!/bin/bash
# Public Facing Interface
ETH=”eth0”
# Get the Public IPv4 address
if [ -z $2 ]
then
LocalIPv4=`/sbin/ifconfig $ETH | /usr/bin/awk '/inet addr/ { sub(/inet addr:/, ""); print$1}'`
else
LocalIPv4=$2
fi
# Remote IPv4 of the the tunnel
TunnelIPv4=” 209.51.161.14”
# Local IPv6 adress
LocalIPv6=”2001:470:1f06:56f::2/64”
start () {
echo -n "Starting IPv6 Tunnel: "
/sbin/ip tunnel add he-ipv6 mode sit remote $TunnelIPv4 local $LocalIPv4 ttl 255
/sbin/ip link set he-ipv6 up
/sbin/ip addr add $LocalIPv6 dev he-ipv6
/sbin/ip -6 route add ::/0 dev he-ipv6
echo done
}
stop () {
echo -n "Stopping IPv6 Tunnel: "
/sbin/ip -6 route del ::/0 dev he-ipv6
/sbin/ip addr del $LocalIPv6 dev he-ipv6
/sbin/ip link set he-ipv6 down
/sbin/ip tunnel del he-ipv6 mode sit remote $TunnelIPv4 local $LocalIPv4 ttl 255
echo done
}
case "$1" in
start)
start
;;
stop)
stop
;;
*)
echo $"Usage: $0 {start|stop}"
esac
Copy this script to /etc/init.d/ipv6-tunnel and then symlink it to /etc/rc2.d (or /etc/rc3.d in some cases). Don’t forget to make it executable. It is also a good idea to initialize it early in the init cycle so that any capable network daemons listen on the IPv6 address. For example:
ln -s /etc/init.d/ipv6-tunnel /etc/rc2.d/S10ipv6-tunnel
This script will take the either the current IPv4 address from eth0 or and address passed as a argument and use it to setup a tunnel using the remote tunnel server IPv4 address, the IPv6 address assigned to you as well as your current IPv4 address. Dynamically grabbing the IPv4 address and / or reading the address from an argument allows us to deal with an IPv4 address that is dynamically assigned by our ISP.
Dealing with Dynamic Addresses
Dynamically assigned IPv4 address can be a problem. If your DHCP lease expires and your ISP decides to assign you a new IPv4 address your tunnel will stop working properly. Luckily tunnelbroker.net has a solution for this using a simple web based auto-configuration service. All you need to do is detect when your Ipv4 address changes and let tunnelbroker.net know about your new address. Here’s a simple script that compares the current IPv4 address of an interface to the address assigned the last time the script ran:
#!/bin/bash
# Public Facing Interface
ETH=”eth0”
CURRENTIP=`/sbin/ifconfig $ETH | /usr/bin/awk '/inet addr/ { sub(/inet addr:/, "");
print$1}'`LASTIP=`/bin/cat /var/tmp/lastip`
# Vars for tunnelbroker.net setup
IPV4ADDR="$CURRENTIP"
# md5 hash of your tunnelbroker.net password
# echo -n PASSWORD | md5sum
MD5PASS="[md5sum of your tunnelbroker.net password"
# Your tunnelbroker.net userid is locate on the main login page
# it looks like a md5 hash
USERID="[USERID from your tunnelbroker.net homepage]"
# Your tunnel ID is listed on the tunnel detail page on tunnelbroker.net
TUNID="[tunnel ID for the tunnel you are updating]"
if [ "$CURRENTIP" = "$LASTIP" ]; then
exit
else
# update the tunnelbroker.net configuration
/usr/bin/curl -k https://ipv4.tunnelbroker.net/ipv4_end.php?ipv4b=$IPV4ADDR&pass=$MD5PASS&user_id=$USERID&tunnel_id=$TUNID
sleep 5
# Restart the tunnel
/etc/init.d/ipv6-tunnel stop $LASTIP
sleep 5
/etc/init.d/ipv6-tunnel start $CURRENTIP
Place this script somewhere, make it executable and setup a cron job to run every minute. If your IPv4 address changes your tunnelbroker.net configuration will be updated and the ipv6-tunnel script we created earlier will be called to re-configure the tunnel on your host.
Conclusion
We’ve covered a lot of ground in this article! Hopefully there is enough information here to get you started with IPv6 using a tunnel provider. In the next article we’ll build upon what we’ve done so far to IPv6 enable entire networks. If you have questions, problems or suggestions on how to make this article better please leave a comment. Enjoy playing with this stuff and please come back soon for part two!
{ 4 comments… read them below or add one }
Most of the links in the article are broken.
The links should be fixed now. Thanks for letting us know…
HE’s service is a fantastic service with one exception….Level3 does not route to them O_o
For debian/ubuntu users in combination with sixxs. Just do : sudo aptitude install aiccu .
{ 1 trackback }