Dynamic DNS from behind a router

The problem

I need to update my google’s dynamic DNS records, but my current setup doesn’t support it out of the box.

I have Frontier’s router that I can’t put into bridge mode. The bridge mode won’t support its two DSL connections, and will have half of the internet speed otherwise (I tried). It supports dynamic dns, but only with noip.com and dyndns.com.

I have USG router behind Frontier’s router. It supports dynamic DNS with Google, but since it’s behind router, it detects its ‘public’ IP as an IP assigned by Frontier’s router.

Solution, Part1 – the DNS update script.

But there’s still a way! I can run a script that calls google’s dynamic dns APIs directly via cron job. And I can run it on my USG.

Here’s a script I’ve initially found: https://gist.github.com/cyrusboadway/5a7b715665f33c237996.

dig was not available on USG, so I changed the IP detection code to use ‘host’ (from this article).

Here’s my update-dyndns.sh script:
(Raw file here)

USERNAME="my_secret_name"
PASSWORD="my_secret_password"
HOSTNAME="my.domain.com"

# Resolve current public IP
IP=$(host myip.opendns.com resolver1.opendns.com | grep "myip.opendns.com has" | awk '{print $4}')
URL="https://${USERNAME}:${PASSWORD}@domains.google.com/nic/update?hostname=${HOSTNAME}&myip=${IP}"
curl -s ${URL}

/config/scripts folder on USG will hold scripts and will be preserved between provisions. That’s where the script should go.

I use WinSCP to transfer files to cloud key. I copied the script to my home folder, then used ssh to copy from there to /config/scripts, because that folder requires root access and WinSCP can’t handle that:
sudo cp update-dyndns.sh /config/scripts/

Add ‘execute’ permission for the script file with:
sudo chmod +x /config/scripts/update-dyndns.sh

Important note: don’t forget to have Linux line endings in the script, if you’re editing it on Windows. Sigh.

Solution, Part2 – schedule the script

Now we need to run this script every once in a while. Let’s say, every 10 minutes. To do that, we’ll need to update unifi’s user config file.
Here’s an example of how this could be done: https://burgatshow.com/2018/02/12/blocking-ad-sites-on-unifi-usg/

Important note: configuration file is on cloud key, not on USG. I managed to forget this twice and was wondering why my config changes aren’t applied.

Here’s a slightly modified config.gateway.json from a link above:
(Raw file here)

{
  "system": {
    "task-scheduler": {
       "task": {
         "update-dyndns": {
           "crontab-spec": "*/10 * * * *",
           "executable": {
             "path": "/config/scripts/update-dyndns.sh"
           }
         }
       }
     }
   }
}

After this file is put to cloud key, script to USG, and USG is force-provisioned, everything is done!