I’m a big supporter of the effort to bring native IPv6 connectivity to all networks. A significant amount of service providers around the world aren’t yet providing it to their customers. That leaves most people with the option of bringing IPv6 to their network by using a tunnel broker which tunnels the IPv6 traffic over existing IPv4 connectivity. I’ve always been hesitant to do this, mostly because I thought performance and stability just wouldn’t be there, but after taking the time to learn and implement, I’ve proven myself wrong.
Today, I don’t have native IPv6 connectivity, but using Hurricane Electric’s Tunnel Broker service, my networks talk to IPv6 hosts seamlessly and performance and stability is impressive.
The setup I detail here was performed on a FreeBSD 9.0-RC2 installation with a standard residential cable modem connection.
The first thing you should do is read all about IPv6. There are tons of good articles and resources on the web that help you understand all about it. There are LOTS of great resources at tunnelbroker.net and they also have a FREE certification program that tests what you have learned and lets you ensure your IPv6 connectivity is implemented properly. The FreeBSD handbook also has a nice IPv6 which is available at:
I suggest you do a lot of reading and get comfortable with the concepts. As you setup your tunnel in FreeBSD, it will all come together.
Create a Tunnel Broker Account
The first thing you need to do is create an account at tunnelbroker.net. Registration is quick and free. You can setup up to 5 tunnels each with a routed /64 and /48.
Create a New Regular Tunnel
You’ll need to create a new tunnel once you have logged into tunnelbroker.net. On the left hand menu, you’ll see an option to “Create Regular Tunnel”. The first thing you will need to enter is your FreeBSD router’s public IP address, which must be reachable via ICMP. Once you put in your public IP address, it will run a check to make sure it is reachable and eligible to be a tunnel endpoint. If ICMP is being blocked, it will inform you of which remote address requires the ability to reach your public IP address via ICMP so that you may configure your firewall appropriately. It will also automatically recommend a remote endpoint for your tunnel based on your location.
Once your tunnel is created, you’ll be able to see both endpoints configuration as well as the /64 that was assigned to you. A /48 isn’t automatically assigned, so if you require this, click on “Assign /48″. Here is what my tunnel configuration looks like at tunnelbroker.net:
The server and client addresses are used in the FreeBSD GIF(4) tunnel that you will create, and the routed /64 are the addresses that you will be able to assign out to devices on your network.
Configure the Tunnel in FreeBSD
Now that the tunnel is created at tunnelbroker.net, you can configure the GIF(4) interface on your FreeBSD router. Of course, you don’t have to configure the tunnel at the router, but it’s the easiest place to configure it and extend the IPv6 connectivity to the rest of your network. Here is what I added to /etc/rc.conf which will enable IPv6 and configure the gif0 interface at boot:
ifconfig_gif0_ipv6=”inet6 2001:470:c:12f4::2 2001:470:c:12f4::1 prefixlen 128″
After rebooting, you will see a newly create interface called gif0 that should look something like:
gif0: flags=8051metric 0 mtu 1280
tunnel inet 220.127.116.11 –> 18.104.22.168
inet6 fe80::222:3fff:fef1:ee91%gif0 prefixlen 64 scopeid 0xb
inet6 2001:470:c:12f4::2 –> 2001:470:c:12f4::1 prefixlen 128
nd6 options=21 options=1
My first instinct was to ping the remote endpoint’s IPv6 address using ping6 to see if its working, but it timed out. I quickly realized I needed to allow the new setup through my firewall before it would function. IPv6 traffic will need to be configured in the firewall just as IPv4 does. I utilize PF for my firewall and added the following to /etc/pf.conf, which enables ICMP on the new gif0 interface so I can test connectivity using ping6:
pass quick on gif0 proto icmp6 all keep state
After issuing a pfctl -f /etc/pf.conf to reload my rules, I was able to use ping6 to ping the remote endpoint’s IPv6 address:
PING6(56=40+8+8 bytes) 2001:470:c:12f4::2 –> 2001:470:c:12f4::1
16 bytes from 2001:470:c:12f4::1, icmp_seq=0 hlim=64 time=25.047 ms
16 bytes from 2001:470:c:12f4::1, icmp_seq=1 hlim=64 time=22.629 ms
16 bytes from 2001:470:c:12f4::1, icmp_seq=2 hlim=64 time=21.922 ms
— 2001:470:c:12f4::1 ping6 statistics —
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 21.922/23.199/25.047/1.338 ms
I also used ping6 to ping www.freebsd.org and ipv6.google.com and was also successful. At this stage, your router will have connectivity to the IPv6 world.
Enable IPv6 Connectivity on Entire Network
Now that your router is IPv6 aware, you can extend IPv6 connectivity to your entire network. Each device on your network can be configured with an address in your routed /64 and then talk to other IPv6 hosts. This is where you have to start thinking outside of the box. We’re all used to DHCP and NAT, but IPv6 doesn’t necessarily work the same way. While DHCP can still be used with IPv6, it doesn’t have to be, and NAT doesn’t need to be used because addresses assigned from your /64 to devices on your network are publicly routed addresses. For this reason, you should ensure you firewall is filtering traffic according to your security policies so that devices obtaining IPv6 addresses aren’t all of a sudden open on the Internet. Based on the PF rule we defined above, only ICMP would be enabled on any device behind the router that receives an IPv6 address.
The first thing you need to do is configure your internal network interface with an IPv6 address from your routed /64. This enables devices that are behind the router to connect through the internal network interface, and then through gif0. The address you assign to the internal interface becomes the default gateway for IPv6 hosts behind the router. My internal interface is re1, and I added the following to /etc/rc.conf:
Now you have two options… You can statically assign IPv6 configurations to your devices that are behind the router, or you can configure your devices to automatically get its IPv6 configuration by configuring the router to advertise available IPv6 addresses using rtadvd. To do so, add the following to /etc/rc.conf:
You can start the rtadvd daemon by issuing the command /etc/rc.d/rtadvd start. When bringing up an IPv6 enabled device on your network, it should be automatically configured with IPv6 connectivity. You can test IPv6 connectivity on your hosts being using ICMP, or by visiting websites that are only IPv6 enabled, such as ipv6.google.com. Other sites, like ipv6.he.net, will show you the remote address that is being used. If a host is configured with both an IPv4 and IPv6 address, IPv6 will usually be used first, and then IPv4 if that fails. That behavior is dependent on the client, but is generally followed.
At this point you should have an IPv6 enabled router that allows network devices behind it to communicate with IPv6 hosts on the Internet. I challenge you to make this only the start of your IPv6 adventure. Complete the IPv6 certification which will force you to learn about DNS, Reverse DNS, and utilizing IPv6 in real life scenarios. Contact your local ISP and find out when IPv6 connectivity will be available. Learn how IPv6 should be secured in your firewall. After your done, you’ll feel good knowing your prepared for the IPv6 era.