If you have a dynamic IPv4, are using a Hurricane Electric IPv6 Tunnel, but are behind a double-NAT (home router behind another home router), I have the solution for you.
In this guide, I’ll focus on OpenWrt, but this will work with anything that can run cronjobs/curl or supports dynamic DNS.
The Problem
When you have a dynamic IPv4 and no IPv6, you might want to use an IPv6 tunnel. However, the tunnel broker needs to know your current IPv4 address. In the case of a dynamic address, this means the tunnel would eventually break.
If you have normal NAT (i.e. no double-NAT), and are running OpenWrt, this is quite straightforward as you can simply enable dynamic updates for he.net directly in the interface settings.
The problem with double-NAT is that OpenWrt expects the public IPv4 to be directly on the WAN interface, and it will share this IPv4 with the tunnel broker. In the case of double-NAT, the IPv4 on the WAN interface is a private IPv4 address, however. So, the built-in updater can’t be used with double-NAT.
The Solution
If you log in to your Hurricane Electric tunnel account at tunnelbroker.net, you can click on your tunnel in the list and then go to the “Advanced” tab.
Under that tab, you’ll find “Example Update URL”. This is the actual update URL you can call as is with curl, and it will use the current IPv4 from where you’re connecting from to update the IPv4 address. This means you don’t even have to use any IPv4 lookup service or anything, and things will be handled automagically.
Generic solution
Now, the simplest way to do this would be to run a cronjob which calls curl with the provided update URL.
However, we can also use our router’s dynamic DNS feature, by specifying “custom” provider and passing this URL.
Router solution
Most routers nowadays support dynamic DNS, which you can use to update the tunnel IP by passing a custom URL.
To be clear, we’re not actually doing dynamic DNS here, we’re just using the dynamic DNS function to achieve the IP update in the same way.
OpenWrt-specific solution (DDNS)
First thing you’ll have to do is install dynamic DNS in OpenWrt, either through the GUI or SSH:
opkg update
opkg install luci-app-ddns
Now refresh the web interface, go to Services > Dynamic DNS.
Create a new service, choose IPv4, call it he_net_v4 or whatever and choose “custom” provider.
Lookup hostname: tunnelbroker.net (this is simply because it needs *something* to look up, doesn’t actually matter what you put in here as long as it exists)
Custom update URL:
https://[USERNAME]:[PASSWORD]@ipv4.tunnelbroker.net/nic/update?hostname=[DOMAIN]
Domain: You’ll put the tunnel ID here (that’s a number, copy it from the original URL).
Username: That’s simply your Hurricane Electric username.
Password: This is the “Update Key” from the “Advanced” tab.
Check the box “Use HTTP Secure”, and if you’re on OpenWrt 21.02 or newer, specify this path to the CA-Certificate: “/etc/ssl/certs/ca-certificates.crt”
Now, in the DDNS Advanced Settings, choose IP Address Source: “URL” and specify URL to detect: “https://checkip.synology.com”. We’re not actually going to use the resulting IP, but the DDNS scripts demand a valid public IPv4. Make sure to also check the box “Force IP version”.
In the DDNS Timer Settings, choose check interval 5 minutes and force interval 15 minutes. You can also adjust this to your liking, depending on how often your ISP changes your IP.
Keep in mind that it will actually update on every check because we have no real DDNS domain to look up. This DDNS script is actually far too complex for our simple update needs, but it works.
Now save, save and apply, and then restart DDNS or reload the specific service.
Wait a minute or so, then click edit on the service you just created, go onto the “Log File Viewer” tab, press the button “Read / Reread Log File”. If the logs say the update was successful, you’re good to go.
Phew! Now that was something.
Conclusion
If you have double-NAT, you might think at first you won’t be able to run a tunnel, but using a cronjob with curl, dynamic DNS in your generic router, or specifically DDNS in OpenWrt, you can solve this problem effortlessly!
I run this blog in my not-so-free time. If I helped you out, consider donating a coffee. (:
I’m also in a similar situation where My ISP only offers CGNAT-based service. I tried the HE tunnel, and I was able to ping remote hosts, but I could not establish any IPv6 TCP connections. Any suggestions? Could my router or the ISP somehow block the tunnel? I tested this on a Debian 11 machine behind the router provided by the ISP.
I don’t have CG-NAT, though! I simply have two routers behind each other due to funny circumstances, by which I mean ISPs and their devices being shitty…
I’m also in the same situation: CG-NAT (in the 192.168.xx.xx range, so improperly done) and no IPv6, and clients get a global v6 address, but they can’t connect to anything using v6. I’m using OpenWrt.
There is also a parallel issue with the DDNS script returning uclient-fetch error 8 and nslookup 1 which I also couldn’t fix.