Using an IPv6 tunnel broker

01 Nov 2019 - tsp
Last update 01 Nov 2019
Reading time 11 mins

What is IPv6 and what is a tunnel broker

IPv6 is the current version of the internet protocol which has been standardized by the IETF back in 1998. It is the direct successor of the version 4 (IPv4). One of the main modifications was to expand IP adresses from 32 bits to 128 bits. This was a necessary change since the IPv4 pools have nearly all been already allocated to network operators - so we basically ran out of IPv4 adresses. This lead to an emerging of circumvention strategies like using network address translation (NAT). This brought a whole bunch of problems like not offering a real IP network connection.

To see where the problem with NAT comes from one has to realize that in an IP network there is no distinction between different types of devices connected. There is no notation of server or client. There are just nodes connected to the network. They can initiate connections, they can accept connections. The whole network is built agnostic about the content transferred by these nodes - and also agnostic about the direction this data takes. The whole network is a bunch of autonomous systems loosely held together by routing protocols by which every autonomous network announces for which IP subnets it’s responsible or is capable of routing traffic to (and also with which metric - i.e. a link cost thats influenced by bandwidth and hop count as well as latency). That way all routers on the network learn how to reach each subnet on the whole internet via which physical routes. All autonomous systems normally run an open and cost neutral peering policy - they simply take any traffic form anyone and route it everywhere independent of source, destination and content. That’s the key concept of net neutrality that’s really required to hold the whole internet together. In fact there is no destinction between a network and the often used notation of an internet service provider or access provider. They are just networks with a bunch of nodes and normally operate some kind of network cabling (like the TV cable networks, DSL lines, optical networks, etc.) as a backhault to transfer data from the users to their own network - i.e. it’s all about the long cable to your home. Wireless access is a little bit different though (and because of this normally exepmted from net neutrality - the main difference is the roaming feature of mobile networks that makes it just unpredictable where how many clients want to join and also makes the prediction of network load nearly impossible; on the other hand these networks have been built primarily for isochronous services with quality of service like voice that’s also prioritized).

The main problem now arrises when one runs out of IP adresses. Normally every node has to have an IP adress so it can receive data by any other side (either requested or as a service provided, etc.). The main solution used here had been network address translation (NAT). In this case the nodes only get assigned a private IP adress (i.e. an adress that is never routed onto the internet). The NAT device then tries to translate connection information for TCP and UDP by remembering which internal device requested a connection to which external device at which port combination and opens itself a connection on a random port. It remembers the combination of client IP, client port, destination IP, destination port, public IP used, public port used and rewrites the source address and source port fields of each UDP or TCP packet to match it’s choosen public IP and port fields. First this makes it impossible to choose source ports. On the other hand inbound connections are not possible - a connection has to be established always from the inside so that the NAT device is capable of learning the connection data (which it forgets after a given timeout). There is a whole bunch of problems with this:

There have been some techniques that try to make use of characteristics of many NAT implementations to establish connections between devices behind NAT (like STUN and STUNT) which work to a given degree under some circumstances but these solutions are also just hacks. And there has been the major misconception that NAT might be a security feature - it really is not! Never mistake a NAT device as a firewall or security device.

IPv6 solves the whole NAT problem by extending the IP adress range from 32 bits to 128 bits which should be enough to assign every device a worldwide unique address. Subnetting is supported but there are some differences to IPv4. At IPv4 you could freely choose the prefix length and some network operators even assigned up to /29 or /30 for small subnets. Since IPv6 also changes the way autoconfiguration works - one does not need DHCP any more - subnetting also changed a little bit. Each IPv6 address is separated into the network part (upper 64 bit) and a local part (lower 64 bit) - the longest prefix that can be announced on a network is /64. Longer prefixes violate the IPv6 RFC. IP address assignment via stateless address autoconfiguration (SLAAC) work by letting the router announce the subnets on each of it’s interfaces. Everytime a node sees such an advertisment it takes the advertised subnet and appends a value derived from the worldwide unique ethernet MAC address at the lower 64 bit of the address - and has it’s address assigned. Note that this of course means that you should never manipulate your MAC addresses / they have to be unique at least in the same IP subnet.

To assign DNS servers like previously done via DHCP one can use rddns in the same advertisement. If one really requires other configuration options there is DHCPv6 which supplies this configuration information but should never be used to configure IP addresses, SLAAC should be used for that.

There have been a few other changes with IPv6 like mobility extensions (that allow a backhaul of mobile devices into your local network via mechanisms known to the router), etc. Note that ICMP is still an integral part of IP and is even more important with IPv6 so it should not be blocked by a firewall.

Since the worldwide transition to IPv6 should be as flawless and easy as possibe dual stack operation was established, that means every host gets his IPv4 address as known before and also enabled IPv6 operation. Whenever possible hosts use IPv6, when not possible they fall back to IPv4 connectivity. There are other mechanisms like NAT64 or 4in6 mappings that allow one to operate a clean IPv6 only network and still don’t loose connection to legacy IPv4 networks but that’s out of scope for this short article.

In general all modern networks should support IPv6 and ISPs should normally delegate a /48 prefix to each user as specified by the IPv6 RFC, the shortest prefix they should every announce to a home network is a /64 (but as stated by the RFC they should at least provide a /48 on request without any charge). If your ISP is also still living in the stoneages of the internet and not providing IPv6 routing there are some parts of the internet that are unreachable even tody - to circumvent this one can use a tunnel provider. This is simply an network operator that allows you to build up an tunnel over IPv4 and route all your IPv6 traffic via this tunnel to one of their points of presence from which on the traffic will be routed as usualy inside the internet. Normally these tunnel providers use a generic route encapsulation tunnel (GRE) or similar mechanisms to transfer data between networks.

Registering your tunnel at hurricane electric

One of the major tunnel providers is Hurricane Electric. It allows one to freely register an account. After registration you are free to create a new tunnel. Choose a point of presence that has the best network connection to you (do not choose based on geographic location, measure via ICMP echo, look at peering information between the networks, etc. - a short topological distance as well as low latency and high bandwidth connection is desired). The tunnel creation also requires your current public IPv4 address so you have to have a publically reachable tunnel endpoint. Enter the static IP address assigned to your gateway (that we will configure in the next step) or your currently dynamically assigned public IP address for the local part.

After tunnel creation HE shows you the tunnel configuration:

Network configuration (gif, interfaces, router advisory, DNS)

Now one can simply enable the tunnel by configuring the gif interface. On FreeBSD one can temporarily do this via

ifconfig gif0 create
ifconfig gif0 tunnel ${YOUR_PUBLIC_IPV4} ${POP_IPV4}
ifconfig gif0 inet6 ${CLIENT_IPV6} ${POP_IPV6} prefixlen 128
route -n add -inet6 default ${POP_IPV6}
ifconfig gif0 up

That’s all that’s required to bring the interface up. One can then test the IPv6 connection via

ping6 ${POP_IPV6}

If this doesn’t work one might be missing a firewall rule for icmp-v6.

To make that change persistent the following entries are required in /etc/rc.conf:

gifconfig_gif0="${YOUR_PUBLIC_IPV4} ${POP_IPV4}"
ifconfig_gif0="inet6 ${CLIENT_IPV6} ${POP_IPV6} prefixlen 128"

Now one wants to advertise the assigned prefix into the local network. To do that one uses the router advisory daemon. This is configured via /etc/rtadvd.conf. One just configured the interface facing the local network (in the following example that will be re0) with the prefix and prefixlen. The following example also includes an rdnss entry that autoconfigures DNS servers:


Now one can enable rtadvd in /etc/rc.conf via rtadvd_enable="YES" and launch via

/etc/rc.d/rtadvd start

After that clients should get IPv6 addresses assigned. Eventually one has to enable forwarding if this hasn’t been done until now:

sysctl net.inet6.ip6.forwarding=1

and make that change persistent in /etc/sysctl.conf or inside ones firewall script.

The last thing to do is to configure reverse DNS. One simply configures the reverse zone on one’s DNS server and enters the DNS server name itself into the tunnel configuration. There are two approaches for this: Wildcard reverse DNS just responds with a generic response for each reverse DNS client or one only configures for specific clients (which leads to clients using privacy extensions having no reverse name). I’d personally choose the second approach since I normally want to have a specific name for specific clients and no wildcard approach.

Dynamic IP considerations (update script)

When one has a dynamically assigned external IPv4 address there might be a problem with the tunnel configuration thoug. On has to update the public tunnel endpoint whenever the local IP changes. One might use the following shellscript to periodically (for example via cron) check if the external IP has changed and in case trigger the update process. One might also use dhclient hooks to be notified of v4 address changes and run the script:

This article is tagged:

Data protection policy

Dipl.-Ing. Thomas Spielauer, Wien (

This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support