EdgeRouter configuration example for a Hurricane Electric IPv6 tunnel


Hurricane Electric provide an IPv6 Tunnel Broker service, allowing a connection to the IPv6 internet across the IPv4 internet backbone.  Generally you would only want to use this if your own ISP does not provide native IPv6 connectivity.


From HE’s Tunnel Broker configuration site, when you create your tunnel, you will be provided with a few different IP addresses that you need to use:

  1. The HE destination IPv4 address to use for tunnel encapsulation (Server IPv4 Address).
  2. The internal address for your side of the IPv6-in-IPv4 tunnel.  This is allocated out of a /64 subnet,  ending in ::2, with ::1 being the address at the Hurricane Electric end of the tunnel (Client and Server IPv6 addresses)
  3. A /64 prefix that they will route towards your tunnel. You would use this for your internal network, assuming you only need a single subnet behind our router (Routed /64).
  4. Optionally, a /48 prefix that they will route towards your tunnel. You would use this for your internal networks, assuming you need more than one (Routed /48).

Note that although a /64 seems quite large to those used to IPv4 addressing, it’s the only size that works for Stateless Address Autoconfiguration. So practically you would never go below a /64 subnet on a LAN.

In the below examples, the following addresses and prefixes are used. Note that in your own configuration you will have to replace these examples with the values you have been given by the HE Tunnel Broker configuration site:

  1.  HE’s Server IPv4 address
  2. 2001:470:1111:2222::2 /64  Client IPv6 Address
  3. 2001:470:f000:0000:: /64  Routed /64
  4. 2001:470:f001::/48  Routed /48

In order to successfully configure your tunnel, the external IPv4 address of your router will need to be pingable by HE’s server, so your IPv4 WAN_LOCAL firewall rule will need to allow this. You may need to renumber the rule below to fit into your existing configuration.

name WAN_LOCAL {

    default-action drop

    description "WAN to router"


    rule 20 {

        action accept

        description "ICMP to router"

        icmp {

            type 8


        log disable

        protocol icmp

        state {

            established enable

            invalid disable

            new enable

            related disable





Tunnel interface definition

The firewall entries can be left out of the interface definition until basic connectivity has been proven.

tunnel tun0 {
       address 2001:470:1111:2222::2/64
       description "HE Tunnel"
       encapsulation sit
       firewall {
           in {
               ipv6-name ipv6-fw
           local {
               ipv6-name ipv6-fw
       multicast disable
       ttl 255

Once the tunnel is configured, you should be able to ping the other end using IPv6:

admin@ubnt:~$ ping6 2001:470:1111:2222::2

PING 2001:470:1111:2222::2(2001:470:1111:2222::2) 56 data bytes

64 bytes from 2001:470:1111:2222::2: icmp_seq=1 ttl=64 time=0.370 ms

64 bytes from 2001:470:1111:2222::2: icmp_seq=2 ttl=64 time=0.300 ms

If this doesn’t work, ensure you can ping the remote IP

admin@ubnt:~$ ping

PING ( 56(84) bytes of data.

64 bytes from icmp_req=1 ttl=59 time=9.01 ms

64 bytes from icmp_req=2 ttl=59 time=8.57 ms

Then follow HE’s troubleshooting guide, or ask in their forum.

Now you have basic connectivity, add the IPv6 firewall definition, and interface entries and re-check the IPv6 ping.  This simple set of rules allows all incoming ICMPv6 (e.g. as a simple way to allow Path MTU discovery to work). It’s possible to be more restrictive if you prefer.

I also prefer to apply MSS clamping for IPv6 traffic to ensure that TCP packets will fit within the IPv4 encapsulation, with no need to rely on Path MTU Discovery.

firewall {

    ipv6-name ipv6-fw {

        default-action drop

        description "IPv6 firewall"

        rule 10 {

            action accept

            log disable

            protocol icmpv6


        rule 20 {

            action accept

            state {

                established enable

                related enable




   options {

        mss-clamp6 {

            mss 1420




Notes on client address configuration

Client machines on your network can be configured in a few ways:

It’s important to know that Android does not support DHCPv6, because the key technical authority at Google does not believe it’s a good idea. This has been the case for many years, and presumably will remain the case at least until he is no longer responsible for it.  This reduces the usefulness of DHCPv6 for many networks.

First Internal Subnet

Add a default route for IPv6, pointing to the tunnel:

protocols {

    static {

        interface-route6 ::/0 {

            next-hop-interface tun0 {




Using the Routed /64 provided by HE, this is a sample configuration for a dual stack LAN interface, with client’s IPv6 addresses being configured using Stateless Address Autoconfiguration (no DHCPv6 required).

DNS is set to point to Google Public DNS via the “name-server” option just to illustrate how it’s done via SLAAC - whether you want to do this or not is dependent on your own DNS requirements. You don’t need to access DNS via IPv6, in order to look up IPv6 addresses.

interfaces {

    ethernet eth4 {


        address 2001:470:f000:0000::1/64

        description "Interface with IPv4 and IPv6"

        duplex auto

        ipv6 {

            dup-addr-detect-transmits 1

            router-advert {

                cur-hop-limit 64

                link-mtu 1420

                managed-flag false

                max-interval 600

                min-interval 180

                name-server 2001:4860:4860::6464

                other-config-flag false

                prefix 2001:470:f000:0000::/64 {

                    autonomous-flag true

                    on-link-flag true

                    valid-lifetime 2592000


                reachable-time 0

                retrans-timer 0

                send-advert true



        speed auto


Additional Subnets

If HE provided you with a Routed /48, you simply allocate further /64 subnets out of this block. So additional LAN interfaces would be configured as above, but with addresses such as: