What's new

Tutorial IPv6 DDNS (noip.com) and VPN server for CG-NAT IPv4

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

AurelM

Regular Contributor
Hi,

First a bit of background for this tutorial: I have a AsusWRT-Merlin router and want to use OpenVPN to create a site-to-site VPN network to another AsusWRT-Merlin router in another city. I used the WebUI to create a OpenVPN server on my end and a OpenVPN client on the remote one, and since the ISP asssing IPs dynamically I setup DDNS on both. I've done this by using a remote desktop software (teamviewer) to access a pc connected to the remote router.
After the initial successful setup, because I wanted to further tinker with the settings for the site-to-site and not wanting to use the remote desktop software, I decided to enable a OpenVPN server on the remote router and connect to it while doing changes to the OpenVPN client. This worked wonderfully and I made some changes which made the site-to-site unusable so another way to access the router was definitely a good idea.
After some time however, both our ISP accounts were assigned to carrier-grade NAT pool so the VPN server could no longer be accessed using the IPv4. I asked the ISP for an internet routable IPv4 address for me, but I had no reason to do the same for the other account account so I let it that way. This is still the situation to this day.

One time I started to think about using IPv6 to once again make the remote VPN server accessible so I started to look into if this thing is possible and how to do it if it is. First thing is if the ISP offers IPv6 services; the second is if OpenVPN supports IPv6; the third is if DDNS supports IPv6; last but not least how to make it all work in AsusWRT-Merlin firmware. The ISP offers it, OpenVPN supports it, the ddns service I use (noip.com) supports it and AsusWRT-Merlin does as well, but not by default using the WebUI, but by using scripts to manage all the necessary steps.

I used many resources, like AsusWRT-Merlin's Wiki on github and of course searches on the internet, since I'm not a very proficient script writer and there may very well be major bugs in them (since minor ones are almost a certainty), but from the testing I've done it works, so I decided to share with others by writing this post.

Lastly before I begin, this tutorial assumes one has at least a medium understanding of using the router, such as setting up DDNS and OpenVPN from the WebGUI, enabling scripts, setting up SSH (or at least telnet) and connecting to it, creating and editing files from the terminal.
__________________________________________________
Making the VPN Server use IPv6 instead of IPv4 is actually pretty easy, one just havs to specify it in the proto statement as indicated by the manual (For forcing IPv4 or IPv6 connection suffix tcp or udp with 4/6 like udp4/udp6/tcp4/tcp6.), however there isn't a way to make the change in the WebUI, so the openvpn-event script has to handle this.
After some trials I found that I need to open the port set for the VPN Server in the firewall. This script adds this rule in the firewall before the last line (which is to drop all packets) when the server is started (i.e. script type is up) and deletes every instance if there are more of them in all other scenarios.

Notes:
- I use UDP as the protocol, change PROTO variable to tcp at the beginning of the script if one wants to use this protocol;
- I use OpenVPN Server 1, change VPN_SERVER variable to 2 at the beginning of the script if one wants to use this server.

Of course, all clients that want to connect to this server must use IPv6 as well, so in their configuration file one must use the same proto as in the server (either tcp6 or udp6).
__________________________________________________
The DDNS script is more complex since the only information one needs to set in the WebUI is the Server set to Custom and the Host Name, with everything else handled by the script.
Since I use noip.com the script is only valid for this ddns service provider because I use their rules for sending the request and interpreting the response. Based on these I decided to use two new nvram variables, ddns_last_update_code and ddns_last_update_time for deciding if the request should be sent or not on this execution of the script. So make sure the router has a bit of nvram space available; check in WebUI -> Tools page-> Sysinfo tab-> Internal Storage section -> NVRAM usage entry.

First, the script checks if the time is synchronized (using nvram variable ntp_ready), and if not, by default waits 50 seconds for it to synchronize (10 retries of 5 seconds each). One can change these by modifying the variables TRIES and SLEEP in the beginning of the wait_for_ntp_sync procedure.
Second it checks the last update code, last update time and current time and based on these and the previously mentioned rules for sending the request and interpreting the respone, the script decides whether to move on or exit.
Then it gets the host name, WAN interface, IPv4 address and IPv6 address of said interface and selects which IP, if any, to update. Only internet routable, private network use (RFC 1918) and carrier-grade NAT (RFC 6598) IPv4 addresses are used by default.
Now it creates the URL to be used for requesting the update, after which send the URL together with the user agent and trusted certificate store to be used and finally checks the answer and updates the two nvram variables with the relevant information for next time execution of the script.

Notes:
- one has to add one's username and password for the noip account at the beginning of the script. These should have the special characters used by the shell escaped: ` ' $ \ and " should be preceded by \ and % should be preceded by % (e.g. if the password is `'$\"% then one should write PASSWORD="\`\'\$\\\"%%");
- one has to add a user agent acording to noip's rules for sending the request User-Agent: Company NameOfProgram/OSVersion-ReleaseVersion maintainer-contact@example.com;
- one can change the LOG_TAG variable to something one prefer to be passed to the logger program.

If one hasn't done so already, one has to change the hostname to a AAAA (IPv6) record type instead of a DNS Host (A) one on the noip.com website.
__________________________________________________
I cannot attach extensionless files on the forum, so .txt it is. One should rename the files if one intends to transfer them to the router, they should be ddns-start and openvpn-event, and they should be created in the /jffs/scripts folder.
Also, remember to allow the newly created files to be executed by executing chmod a+rx /jffs/scripts/* command at the terminal.

I also have some unknowns, such as which logger level is which? I assumed 0 to be emergency, 1 to be alert ... 7 to be debug.
Another one is: would it be better to use curl instead of wget to send the request?
Also, are the username and password encrypted by https when sending the request? I assume yes, but don't know how to check to be sure. I don't see how wireshark could capture packets generated by the router from my pc.

Constructive criticism is appreciated; obvious problems and solutions to them are more than welcome.
 

Attachments

  • openvpn-event.txt
    884 bytes · Views: 212
  • ddns-start.txt
    12.2 KB · Views: 131
Last edited:
I think OpenVPN does not support IPv6 in Asuswrt and Asuswrt-Merlin. right? @RMerlin

Also, are the username and password encrypted by https when sending the request?
You should not include the password in the URL, because this may reveal your password, you should use a Get request.
 
I was successful to achieve what is asked here. In particular enable OpenVPN with DDNS on no-ip.com using ipv6.
I spend several days researching it so I thought it would be good to share my findings.

My router is RT-AX58U with Merlin firmware 388.2_2 at this moment. You do need Merlin for a custom DDNS inadyn.conf script.

So lets start with DDNS. I assume you have setup a no-ip hostname configured. Made sure the hostname is of type AAAA.
  • Configure your open-ip DDNS (WAN->DDNA). Provide your hostname, username, password etc.
  • Enable IPV6 (IPv6). I use connection type "Passthrough" but I think "Native" would also work.
  • Enable JFFS (Administration -> System). Enable JFFS custom scripts and configs and also format the partition if this is your first time doing so.
  • Enable SSH. You will need to ssh into the router from a terminal. If this is your first time doing that learn more about ssh.
  • Reboot the router.
  • Check your status. You should have an ipv6 (System Log, IPv6).
The next part we use ssh to login into the router.
  • Check the contents of your inadns.conf. You should see all the information you provided in the DDNS router setting.
    cat /etc/inadyn.conf
  • Make a copy of that file into /jffs/configs
    cp /etc/inadyn.conf /jffs/configs/inadyn.conf
  • Edit that copy and add two lines. First inside the brackets after password and second outside.
    checkip-command = "/sbin/ifconfig eth4 | grep 'inet6 addr:.*/64 Scope:Global'"
    }
    allow-ipv6 = true
  • Test your checkip-command from the terminal. You should see the ipv6 you want to advertise. If not modify it to get the correct string. The grep command selects the global ipv6 address (/128 the one without MAC since newest asus merlin firmware RT-AX58U_3004_388.6_2.zip).
    /sbin/ifconfig eth4 | grep 'inet6 addr:.*/128 Scope:Global'
  • Your config file should look something like (added lines in bold)
    provider default@no-ip.com {
    hostname =hhhhhh.hhh.hh
    username = 'xxxxxxx'
    password = 'xxxxxx'
    checkip-command = "/sbin/ifconfig eth4 | 'inet6 addr:.*/128 Scope:Global'"
    }
    allow-ipv6 = true
    iterations = 1
    ca-trust-file = /etc/ssl/certs/ca-certificates.crt
  • Test your config file. If you are lucky the second command will update your no-ip.com ipv4 and ipv6 addresses. Also check your router log.
    inadyn --check-config -f /jffs/configs/inadyn.conf
    inadyn --once -f /jffs/configs/inadyn.conf
  • Reboot your router.
  • Login again with ssh and check your /etc/inadyn.conf. It should contains all the new changes.
    cat /etc/inadyn.conf
Now lets continue with OpenVPN.
  • Configure your OpenVPN server (VPN->VPN Server -> OpenVPN). Configure the server without any special settings. Keep protocol to UDP.
  • Create at least one username.
  • Export the configuration file.
  • Edit the configuration file and modify the following two lines.
    dev tun-ipv6
    proto udp6
  • This is the client profile you will use.
Router behind your internet provider router.
  • If your Merlin ASUS router is behind your service provider router as is my case you need to port-forward.
  • My router is a Vodafone ARIS cable router which does not give me ipv4 address. This is why I need the ipv6 VPN.
  • For that router you need to create a IPv6 Host Exposure entry for VPN port (default is 1194) to your ASUS router.

You are done. You can use an OpenVPN client to connect to your router.
NOTE: Do not use OpenVPN Connect 3.3 on desktop. It has a bug will keep try using upd4. Use the community edition or previous version 2.7
 
Last edited:
Updated instruction is my previous post as I before I was using the local-link ipv6 which does not work with newer version of inadyn.
New instructions use the global ipv6 generated from the MAC scope global dynamic mngtmpaddr.
 
I was successful to achieve what is asked here. In particular enable OpenVPN with DDNS on no-ip.com using ipv6.[...]
I'm glad you were able to do this.

Since it's been two years and two months since the original post and about ten or so firmware versions and a new firmware branch for the Wi-Fi 6 routers, the original post is no longer relevant.

While it was necessary to do all the things for Merlin v.386.2_0, which was the brand new firmware at that date, the newer firmwares gradually made them obsolete, and although it's still necessary to make some changed from a terminal, it no longer requires scripts.
Isn't progress sweet?

We also have to look forward to the next Merlin firmware that includes this change from ASUS RT-AX86 Series(RT-AX86U/RT-AX86S) Firmware version 3.0.0.4.388.23285 -Enabled DynDNS and No-IP DDNS to use IPv6. .

Right now, for 388.2_2 and 386.11, this is what I do to have a working IPv6 OpenVPN server with noip.com DDNS:
  • I have DDNS configured in WebUI to use noip.com server, I no longer use custom;
  • Since selecting IPv6 Update doesn't work , I have the /jffs/configs/inadyn.conf.add file with the following lines:
Code:
allow-ipv6 = true
iface = ppp0

That's it, there's no longer the need to make firewall changes, they are handled by the firmware; inadyn can now be used to update IPv6.

However, inadyn cannot update both IPv4 and IPv6 addresses for noip.com. Where I need this I make inadyn run both with and without allow-ipv6 = true in its configuration by using /jffs/scripts/service-event file to run a different script.

Of course, there are many things needed to have it working from a default settings router, like (not an exhaustive list):
[...]You do need Merlin
[...]Made sure the hostname is of type AAAA.
[...]Enable IPV6 (IPv6)
[...]Enable JFFS (Administration -> System)
[...]Enable SSH
[...]Configure your OpenVPN server[...]
 
WireGuard (which was built with IPv6 in mind as I understand things) is another way (rather than OpenVPN), now that we've routers capable of running it natively (for the most part). There are good threads here if you care to dig in - @Martineau and @ZebMcKayhan have done quite a bit of work on it in the past, before Asus started to look at it due to user demand. Zeb's FAQ on his GitHub is particularly helpful

Another resource I'll put here is Hurricane Electric (he.net) - they offer a DDNS service (tunnelbroker.net - integrated into stock and Merlin firmware), the ability to manage your own DNS records (for your domains A- and AAAA- records), and some IPv6 testing/education at ipv6.he.net/certification...all free upon registration. And did I mention you can claim a /48 delegation from them, also free?

But rather than site-to-site, you might want to consider an Oracle VPS (there is a rather capable free tier) as the midpoint/server for your VPN, and each Merlin machine a client of that. the benefit of this is you can connect to it from anywhere with pretty much any device. Among other things, it should get you past Netflix (et al) password sharing difficulties, geoblocking (depending on where you choose to have it running), provide certain privacy/anonymity benefits...
 
However, inadyn cannot update both IPv4 and IPv6 addresses for noip.com. Where I need this I make inadyn run both with and without allow-ipv6 = true in its configuration by using /jffs/scripts/service-event file to run a different script.
Please, can you detail how to update both ipv6 and ipv4 addresses from noip.com? Thanks.
 
Let me start by saying that in firmwares 3004.388.4, 3004.388.5 and 386.12, inadyn is able to update both IPv4 and IPv6 for noip.com for me, so I no longer have to do add any script files.

I'll leave what I did in previous firmwares, like 388.2 and 386.11:
  • I made a new script file, /jffs/scripts/ddns-update-ipv6, with execution permissions, with the following contents:
Code:
#!/bin/sh
sleep 5
while [ $(/bin/pidof inadyn) ]; do sleep 1 ; done
/bin/cp /etc/inadyn.conf /tmp/inadyn.conf.tmp
/bin/echo "allow-ipv6 = true" >> /tmp/inadyn.conf.tmp
/usr/sbin/inadyn --force -f /tmp/inadyn.conf.tmp
while [ $(/bin/pidof inadyn) ]; do sleep 1 ; done
/bin/rm /tmp/inadyn.conf.tmp
sleep 5
This script would run inadyn two times, once without allow-ipv6 = true in its configuration file to update the IPv4 address and once with it to update IPv6 address.
  • In /jffs/scripts/service-event file I added the following line:
Code:
if ( [ "$2" = "ddns" ] && ( [ "$1" = "start" ] || [ "$1" = "restart" ] ) ); then /jffs/scripts/ddns-update-ipv6 ; fi

Again, I no longer do this, the current firmware is handling it fine on it's own.
 
Again, I no longer do this, the current firmware is handling it fine on it's own.

Nice work - in a perfect world, we would not have to resort to dynamic DNS for IPv6, but the world is rarely perfect..
 
Let me start by saying that in firmwares 3004.388.4, 3004.388.5 and 386.12, inadyn is able to update both IPv4 and IPv6 for noip.com for me, so I no longer have to do add any script files.
How interesting! Many thanks!
 

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top