Skip to main content

Updating Cloudflare DDNS On Ubiquiti UDM-Pro

I’ve been somewhat pulling my hair out (ok, that’s a lie – I have none) figuring out a way to update a Cloudflare A name using the UDM-Pro. There’s a long list of reasons you’d want to do this, but for my purposes in this instance I want to setup a VPN endpoint. Of course, static IP addresses aren’t something that are common for small business users, and especially not so for home users. Setting manual DNS entries will work for all of a few days and users need something easy to remember that will update whenever the public IP address of the UDM-Pro gets updated (which could be days, weeks, or even months apart). 

Ubiquiti’s firmware allows DDNS updates natively within it, but the providers are quite limited, and despite Cloudflare being arguably the most requested one in the forums, they’ve yet to add it. I suspect this is because it’s not as simple as a quick URL call with some variables like DynDNS used to be. There’s some tricky ways to do this using DNSoMatic, but I’m going to be setting this up for a long list of clients, and I also really don’t want to rely on yet another middleware service.  

Previously I did this on my Synology NAS which I posted about here, but I wanted something more permanent. This solution graciously utilizes the work of a few people I’d like to credit, specifically boostchicken and timothymiller. To give you some context, the UDM-Pro runs Debian as a core OS, then it basically runs the Unifi-OS within a container. That means we can run other containers alongside the Unifi-OS container and do whatever the hell we want in there. Granted, it’ll chew into the system resources the Unifi-OS uses from the hardware, but this is super minor so we’re not all that worried here. Let’s get going.

  1. First you’ll want to SSH into your UDM-Pro. I suggest using PuTTy.
  2. We’ll install the UDM-boot script from here : This more or less allows us to run a bunch of things on startup (so, if the UDM-Pro reboots, does a firmware upgrade, or whatever, our customizations will stick). As we’re already SSH’d in… 
    1. Drop into the Unifi-OS Shell
      unifi-os shell
    2. Download the boot scripts to the UDM-Pro
      curl -L -o udm-boot_1.0.5_all.deb dpkg -i udm-boot_1.0.5_all.deb exit​
      Make sure to exit out of the Unifi-OS shell, which we did above with “exit”.
  3. Excellent. Let’s move on and add in the Cloudflare script 
    1. Make a directory to store the Cloudflare scripts
      mkdir -p /mnt/data/cloudflare-ddns​
    2. Create a config.json file. Just toss it in with VI…  vi config.json, then insert this (command : I), and then save by hitting ESC a few times, then typing :wq! – I’ve supplied my config.json file below, but I’ve fudged some of the variable values.
      { "cloudflare": [ { "authentication": { "api_token": "Qjlkjs9sWKzQhE983ks0k30s0ab2e9s8ZxATX0tAAaz", "api_key": { "api_key": "83661alks93kd09ks8kpsk0dgb75c087wP", "account_email": "[email protected]" } }, "zone_id": "142d77681af781e09lacddc888dcbdf9fb8d61", "subdomains": [ "testsubdomain" ], "proxied": false, "ttl": 120 } ] }​
    3. Of course, edit up the values as you see fit. Here’s what you’ll want to replace: 
      API TOKEN – Create one with edit privileges on the zone you’re looking to edit. You’ll likely need to create a new API Key.
      API KEY – Get from your Cloudflare dashboard under API. It’ll be the global key.
      ACCOUNT EMAIL – The full email address of your CloudFlare account
      ZONE ID – Go to the zone in question, get the ID from Overview on the right side panel
      SUBDOMAINS – Enter the subdomain name. If you want, you can add multiples if you separate them with a comma. For example “test1”, “test2”, “test3” – and ensure the last entry does NOT have a comma at the end.
    4. Change your directory, and go to the boot directory
      cd /mnt/data/on_boot.d​
    5. Create a file. Just toss it in with VI…  vi, then insert this (command : I), and then save by hitting ESC a few times, then typing :wq!
      #!/bin/sh CONTAINER=cloudflare-ddns # Starts a cloudflare ddns container that is deleted after it is stopped. # All configs stored in /mnt/data/cloudflare-ddns if podman container exists "$CONTAINER"; then podman start "$CONTAINER" else podman run -i -d --rm \ --net=host \ --name "$CONTAINER" \ --security-opt=no-new-privileges \ -v /mnt/data/cloudflare-ddns/config.json:/config.json \ timothyjmiller/cloudflare-ddns:latest fi​
    6. CHMOD the file accordingly 
      chmod 744​
    7. Run the damn file from the command line..
  4. To check to ensure everything is running smoothly, you can check your various podman instances.
    1. This will show any of the containers running:#
      podman ps
      c09d3eea6b9d python -u /cloudf... 40 minutes ago Up 40 minutes ago cloudflare-ddns
      3643198165d5 localhost/unifi-os:latest /sbin/init 2 months ago Up 22 hours ago
      unifi-os # 
    2. The script runs via CRON job every 5 minutes, so after you’ve gone and poured yourself a coffee for the job well done, check to see what’s going on: 
      # podman logs cloudflare-ddns
      ⚙️ Individually disable IPv4 or IPv6 with new config.json options. Read more about it here:
      ?️ Updating IPv4 (A) & IPv6 (AAAA) records every 5 minutes
      ? IPv6 not detected
      ? Updating record {'type': 'A', 'name': 'testsubdomain', 'content': '123.456.789.10', 'proxied': False, 'ttl': 300}
      # ​

And that’s about that. It’s pretty straightforward stuff, but if you’re not familiar with using tools such as an SSH client, vi, or just generally working in a *nix shell, this is likely going to feel pretty intimidating. If that’s the case, I would welcome you to reach out and I’m sure I can give you a hand.