Skip to content

Instantly share code, notes, and snippets.

@bgrewell
Last active March 29, 2025 01:55
Show Gist options
  • Save bgrewell/faee67342085fb8fe98b446feeb10ced to your computer and use it in GitHub Desktop.
Save bgrewell/faee67342085fb8fe98b446feeb10ced to your computer and use it in GitHub Desktop.
This gist explains how to set up IPv6 connectivity on your Ubiquiti UDM Pro or similar Ubiquiti devices using a Hurricane Electric (TunnelBroker) tunnel. Enable free IPv6 access to your network without relying on ISP support.

Setup IPv6 Tunnel on Unifi Dream Machine Pro

In order to use IPv6 via a Hurricane Electric tunnel you need to sign up for their free Tunnel Broker service at https://tunnelbroker.net/

Setup Address Allocation

Navigate to https://unifi.ui.com and go to your network management page. Navigate to Settings -> Networks and select the network you wish to enable IPv6 on such as Default then click on the IPv6 button.

  1. Select static for interface type
  2. Under Gateway IP/Subnet enter your Routed IPv6 Prefix from the HE management page
  3. Under Advanced select manual
  4. Under Client Address Assignment select DHCPv6

The rest of the defaults should be fine.

Unifi OS v4 - Configure Dream Machine Over SSH

Use the following instructions to setup an IPv6 tunnel with Hurricane Electric if you have version 4+ of Unifi OS running on your router. You will need the following information to setup the tunnel which you can get from your hurricane electric tunnel management page.

  • IPv4 Server Address
  • IPv4 Client Address
  • IPv6 Client Address
  1. Create the setup script in /persistent/system/setup-he-ipv6.sh
#!/bin/bash

# Configuration Variables
TUNNEL_IFACE="he-ipv6"
HE_IPv4="<he_ipv4_server_addr>"
LOCAL_IPv4="<he_ipv4_client_addr>"
HE_IPv6_ADDR="<he_ipv6_client_addr>"
CHECK_INTERVAL=3600

# Function to check if the tunnel interface exists
interface_exists() {
    ip link show "$TUNNEL_IFACE" &> /dev/null
}

# Function to check if the interface is up
interface_is_up() {
    ip link show "$TUNNEL_IFACE" | grep -q "UP,LOWER_UP"
}

# Function to check if the IPv6 address is assigned
ipv6_addr_assigned() {
    ip -6 addr show dev "$TUNNEL_IFACE" | grep -q "$HE_IPv6_ADDR"
}

# Function to check if the default route exists
default_route_exists() {
    ip -6 route show default dev "$TUNNEL_IFACE" | grep -q "default"
}

# Function to set up the tunnel
setup_tunnel() {
    echo "$(date): Checking tunnel status..."

    # Add the IPv6 tunnel if it doesn't exist
    if ! interface_exists; then
        echo "$(date): Adding tunnel interface $TUNNEL_IFACE..."
        ip tunnel add "$TUNNEL_IFACE" mode sit remote "$HE_IPv4" local "$LOCAL_IPv4" ttl 255
    else
        echo "$(date): Tunnel interface $TUNNEL_IFACE already exists."
    fi

    # Bring the tunnel interface up if it's not already up
    if ! interface_is_up; then
        echo "$(date): Bringing up interface $TUNNEL_IFACE..."
        ip link set "$TUNNEL_IFACE" up
    else
        echo "$(date): Interface $TUNNEL_IFACE is already up."
    fi

    # Assign the IPv6 address if it's not already assigned
    if ! ipv6_addr_assigned; then
        echo "$(date): Assigning IPv6 address $HE_IPv6_ADDR to $TUNNEL_IFACE..."
        ip addr add "$HE_IPv6_ADDR" dev "$TUNNEL_IFACE"
    else
        echo "$(date): IPv6 address $HE_IPv6_ADDR is already assigned to $TUNNEL_IFACE."
    fi

    # Add the default IPv6 route if it doesn't exist
    if ! default_route_exists; then
        echo "$(date): Adding default IPv6 route via $TUNNEL_IFACE..."
        ip route add ::/0 dev "$TUNNEL_IFACE"
    else
        echo "$(date): Default IPv6 route via $TUNNEL_IFACE already exists."
    fi

    echo "$(date): Tunnel status check complete."
}

# Infinite loop to monitor and maintain the tunnel
while true; do
    setup_tunnel
    sleep "$CHECK_INTERVAL"
done

After you create the script make sure it's executable chmod +x /persistent/system/setup-he-ipv6.sh

  1. Setup a systemd service to start the script on boot in /lib/systemd/system/he-ipv6.service
[Unit]
Description=Set up Hurricane Electric IPv6 tunnel after network is online
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/persistent/system/setup-he-ipv6.sh
Restart=always
RestartSec=10
User=root

[Install]
WantedBy=multi-user.target
  1. Enable and Start the service
systemctl enable he-ipv6.service
systemctl start he-ipv6.service
  1. Ensure that the tunnel is functional by pinging Google’s IPv6 address
ping6 2001:4860:4860::8888
  1. You should be able to verify functionality by checking http://test-ipv6.com/index.html.en_US

Unifi OS v2 - Configure Dream Machine Over SSH

The instructions below are legacy from an older version of Unifi OS and are most likely not needed anymore but are kept just in case anyone needs them.

SSH to your UDM

ssh root@<udm ip address>
<enter the password you set when prompted>

Configure the IPv6 Tunnel - You get the addresses from the Tunnel Details page on TunnelBroker

ip tunnel add he-ipv6 mode sit remote <server ipv4 address> local <client ipv4 address> ttl 255
ip link set he-ipv6 up
ip addr add <client ipv6 address> dev he-ipv6
ip route add ::/0 dev he-ipv6
ip -f inet6 addr

Test Connectivity from UDM

ping6 2001:4860:4860::8888
@janneurocny
Copy link

It works perfectly! But I had a permission error so I had to run chmod +x /persistent/system/setup-he-ipv6.sh

@bgrewell
Copy link
Author

bgrewell commented Jan 6, 2025

Thanks, I forgot to add that to the steps. I have updated the gist to include that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment