Google Domains shutting down. Moving Dynamic DNS to Cloudflare for UniFi Devices. What else?

Google Domains logo on a gravestone

Google Domains has been around for quite some time, beginning life in 2014, and leaving Beta back in March of 2022. Google Domains was both a Domain Registrar, as well as a Hosted DNS product, and happened to be the registrar this website’s domain was born on. Google Domains provided some appealing services such as easy to use Dynamic DNS, DNSSEC, as well as hosted redirections (Such as redirecting www. to your domain’s root), and did so in an easy to use manner. Domains registered within Google Domains also supported easy integration into Google Webmasters, Google Workspace (formerly Google Suite), and Google Cloud.

On June 15, 2023, Google announced the sale of Google Domains to Squarespace, a company well known for their easy to use website builder, and hosted site solutions. Google Domains now joins many other Google products in the Google Graveyard, where paid products with utility and integration with the rest of the Google empire just, seemingly vanish as part of a shift of business plans.

One of the key features of Google Domains as I mentioned before, was the ability to set up Dynamic DNS records. In Google Domains’ implementation, Google would establish an A or AAAA record underneath your root domain (for example, house.googledomains.com), and create a Username and Password combination for updating the record using a utility such as ddclient or inadyn with the dyndns2 protocol, or by submitting information directly to Google’s DNS API directly. I made heavy use of this feature, not only for accessing resources back at home or on my Plex server, but for many other networks and projects I’ve set up and worked on.

While the migration was underway, I decided to sit and wait for a while to see if Google would be handing over the management console and DNS APIs to Squarespace, and ensuring feature parity between Google and Squarespace to make the migration a breeze. Cue an e-mail which was sent by Google recently…

Update Dynamic DNS Records

Hi there,

As previously communicated, Squarespace has purchased all domain name registrations and related customer accounts from Google Domains. Customers are in the process of being moved to Squarespace Domains, but before we migrate your domain <insert domain name here>, we wanted to inform you that a feature you use, Dynamic DNS (DDNS), will not be supported by Squarespace.

After your domain has been migrated, you will no longer be able to update DDNS records using the DDNS service offered by Google Domains. Any active DDNS record will remain as A and/or AAAA records with the last IP addresses provided prior to the migration, but those IP addresses will no longer update automatically. If you leave any DDNS client active, it will receive an error when trying to perform an update.

Action Required

Since Squarespace Domains doesn’t offer DDNS services, you should consider looking for an alternative from another provider and configure that ahead of your domain migration. Your domain will be migrated as soon as 30 days from today, so please act now to ensure your DDNS records will continue to work as you’d like.

You’ll receive another email after your domain migrates successfully to Squarespace Domains.

See you online,

Google Domains

Text output of the screenshot above

This pretty much confirms what I suspected during the long migration process. After spending some time to search around for Dynamic DNS solutions for one of my domains hosted with Google’s DNS infrastructure, I had to make the decision to migrate the domain’s DNS infrastructure out to another provider. I ended up choosing Cloudflare.

But wait! Cloudflare’s DNS isn’t dynamic. How are you solving for that?

This is the question I had while considering DNS providers. I could move over to tailored solutions such as Dyn or FreeDNS, DNS-O-Matic, or any number of other providers out there which support Dynamic DNS Solutions. I also have a lot of network hardware deployed which can’t necessarily perform HTTP API requests or have cron jobs due to being proprietary, closed box appliances. In the very distant past, in another incarnation of this website, I used to make use of DynDNS (Now Dyn), prior to the purchase of Dyn by Oracle. I left Dyn (and went so far as deleting my account!) as they discontinued their Free Dynamic DNS Service prior to the acquisition by Oracle, since at the time I was not an owner of a domain. After leaving Dyn, I set up shop under Afraid DNS and utilized their free service for a period of time, before purchasing this domain in 2017.

So this effectively brings me back to the retirement of Google Domains, and the problem I faced. While searching around for DNS providers and solutions, I came across Cloudflare. Cloudflare is an umbrella of web services such as Hosted DNS, Domain Registrar, WAF (Web Application Firewall), CDN/Caching, and “server-less” computing (Workers). What really gave me confidence in moving my DNS infrastructure to them were the following bits:

  • Their DNS Solution has a Free tier. The Free tier is very flexible, and is more than good enough for what I am using it for. It doesn’t seem to have many strings attached to it at all, such as needing to log in on a weekly basis.
  • They have solid API documentation, and recently published dedicated articles on Dynamic DNS usage [Link 1] [Link 2] with their DNS.
  • The DNS zone can be staged without having to move registrars or pay up first. This allowed me to stage and test ALL of my records prior to swinging the name servers over at the Registrar.
  • I have been wanting to set up this website behind a caching CDN, as well as a WAF (Web Application Firewall) for quite some time now, in order to protect the backend, and to speed it up globally. Cloudflare does this, and often partners with various web hosting companies to make this possible for small websites. My host does not, but that doesn’t mean it can’t be done without some manual work 😀
  • Cloudflare has known levels of reliability, and prides themselves in being one of the fastest DNS providers in the world, next to Google. Which is something I also care about.

So, fine and dandy, right? NO!

It wasn’t quite as simple as migrating my DNS, swinging the name servers over, and updating some information on the various router/network/device appliances I have performing Dynamic DNS updates. Many of these devices are Ubiquiti Networks UniFi Gateways running ddclient (USG 3P, USG 4P) or inadyn (Dream Machines, Next Gen Security Gateways, etc), and the controllers lack Cloudflare support. I needed a solution which works for all devices and can survive updates from Ubiquiti, such as the removal of Podman from the Dream Machines with UniFi OS 3.x, and also works with the legacy EdgeOS / VyOS powered devices such as the USGs. I also wanted something stable, which wouldn’t interfere with the controller following updates (common with config.gateway.json files placed inside of the controllers, or any custom configuration made through SSH).

Cloudflare Workers (and GitHub) to the rescue!

I happened across this GitHub project which solves my needs. Published by the user “workerforce” and called “unifi-ddns,” this project assists with deploying code within Cloudflare’s Workers service which can accept requests made by Dynamic DNS clients using the very common dyndns2 protocol, and translate them into API Calls supported by the Cloudflare API. Getting it working within UniFi itself (or any other device for that matter) is as simple as filling in Dynamic DNS Information. Here’s how I basically did it.

  1. Sign in with Cloudflare Workers.
  2. If you’re enrolling for the first time, select the *FREE* tier (it is more than sufficient) and follow any additional on-boarding steps until you’ve been brought back to the main Cloudflare Dashboard. During this step you may be asked to create a team name. This team name will be important to know for later on.
  3. Visit the GitHub project and select the “Deploy with Workers” button
  4. Follow the page steps to deploy the project to Workers.
    • NOTE: During this step, I ran into some trouble. You’ll be required to fork or clone the project first as part of the deployment. This part works fine. Cloudflare however, encountered an error after the fork for me. The fix for this was found in the Discussions for the project, and is as simple as committing a change to any file, such as the Readme, in your copy of the project. It will automatically deploy at that point to Cloudflare, and appear in the Workers & Pages Dashboard as “unifi-cloudflare-ddns.” There won’t be any need to refresh the deployment page with the error, or make another attempt at a redeploy. You should also see actions appear in the projection’s Actions under GitHub around the same time.
  5. With the Workers instance created, the next step is to create an API Token for the Cloudflare DNS record changes. To do this, these steps should be followed:
    • Go to My Profile –> API Tokens
    • Click Create token and select the “Edit Zone DNS” template
    • The defaults here are generally OK. In my case, I made a change to the template to restrict zone editing access to only the domain holding my Dynamic DNS Records. This is to help guard against unwanted zone edits, if you hold multiple domains in an account.
    • Click Continue to Summary
    • COPY AND SAVE THE API TOKEN SOMEPLACE SAFE.
  6. Next, obtain your Workers’ route. This is effectively a web address. To do this, go to the Cloudflare Dashboard –> select Workers & Pages –> Select the unifi-cloudflare-ddns worker. The route will appear within the Preview pane. It may look something like “unifi-cloudflare-ddns.<teamname>.workers.dev” and you’ll need to note this down!

At this point, everything was in place for updating the UniFi hardware with new Dynamic DNS information. Updating the UniFi Hardware is as simple as this…

  • Open your UniFi Controller to the place where your Dynamic DNS Entries are stored. Most likely this will be Settings –> Internet –> WAN(1/2/3/etc…) –> Dynamic DNS
  • Domain: Enter in the FQDN (Fully Qualified Domain Name) for the record you want to update. For example, office.<mydomain>.com
  • Username: Fill in your base domain name. For example, <mydomain>.com
  • Password: Enter in the Cloudflare API token you generated earlier
    • If you lost your API token, you can refresh/rotate your token within the API Tokens section of your account. But be mindful, if anything is using that token, you’ll need to update those devices or programs with the new one.
  • Server: This part will differ.
    • UniFi Security Gateway 3P/4P/EdgeRouter: These devices use ddclient to update. Enter in your Workers Route into the Server.
      • Example: unifi-cloudflare-ddns.<teamname>.workers.dev
    • UniFi Dream Machine (UDM/UDM-Pro/UDM-SE/UDW/UDR/UX) / Next Generation Gateway (UXG/UXG-Lite: These devices use inadyn to update. Enter in your Workers Route following the example below.
      • unifi-cloudflare-ddns.<teamname>.workers.dev/update?ip=%i&hostname=%h

Once the Dynamic DNS Settings are saved, it’s time to ensure the devices can update records. The best way to accomplish this is using the Cloudflare Audit Log. This is available within your Cloudflare Account Dashboard. Edits to your records will show up as API logs. Showing the details of the update should show the target record which was updated, as well as the information (A record) which was submitted. Note that the API request will originate from a Cloudflare IP due to using a Workers instance, so do not be alarmed if the update didn’t originate from the IP of the device making the request.

By default, UniFi Security Gateway devices and EdgeRouters will make an attempt at performing a Dynamic DNS update with ddclient upon saving your settings / upon provisioning by the controller. Changes to the records by these devices should reflect in Cloudflare pretty much right away. For Ubiquiti’s Linux-based, next generation routers such as the Dream Machines and UXGs, there is an extra set of validation steps. This is because inadyn stores a cache of the last update it made, and it won’t attempt to update the record again until your IP address changes. We can force an update with the steps below:

  1. SSH into your device
  2. Execute the following:
    • $ ps aux | grep inadyn
  3. Look for read-out with the following:
    • /usr/sbin/inadyn -n -s -C -f /run/ddns-eth8-inadyn.conf
  4. Execute the following:
    • $ inadyn -n -1 –force -f /run/ddns-eth8-inadyn.conf
    • Note that the /run/ddns-ethx-inadyn.conf part will vary depending on what your WAN interface actually is. On Dream Machine Pros this is typically eth8. On Dream Machines, this is eth5, and on Next Generation Gateways, this can be eth1 or eth3 by default. However, because Ubiquiti supports Port Remapping, your WAN interface can be something entirely different! Refer to your ps command output for the correct interface name.
    • Note 2: As the command executes, pay attention to the output. Ensure no errors are sent to the terminal by inadyn. An update should take no more than a few seconds. You can also verify the update was successful by checking the Cloudflare Audit Log.
    • Note 3: If you have multiple WAN interfaces configured and Dynamic DNS is running on them, repeat the same steps for each WAN interface. There should be an accompanying inadyn configuration file in the /run/ directory.

At this point, all should be working fine. Anything that isn’t working will likely boil down to a configuration issue with your API Tokens, or a configuration issue in your hardware. I should also note, these Dynamic DNS configuration steps should also work on consumer devices/routers or anything else that supports the dyndns2 protocol, so this setup process shouldn’t be exclusive to Ubiquiti hardware.

What else?

The first part I can get into is with some limitations. I noticed that the Dynamic DNS Workers method for translating dyndns2 requests into something the Cloudflare API understands has a few problems. For example, it only operates with A (IPv4) records, not AAAA (IPv6) records. Updating these will likely require some code changes OR using inadyn/ddclient with the Cloudflare API/Dynamic DNS Service directly, which would be unsupported on many devices and prone to higher maintenance to keep working. The method I described above simply covers a use case for Ubiquiti or Home routers which do not specify Cloudflare as an option.

Other limitations seem to be around pairing each API token with a specific DNS Record to update. Cloudflare at least on the free tier doesn’t seem to have support for restricting API-based record updates to specific records. Rather, it works on entire zones (or domains, to put it more simply for the free tier). It’s possible to break apart your primary DNS zone into sub-zones, although this seems to require a paid or enterprise account to do at this time. In my case, I restrict the API token to a domain I have specifically set up for all of my Dynamic DNS hardware. This is important because the API Token will not be stored in a hashed and salted manner to protect it in the Ubiquiti hardware, or in the controller. You can view it plaintext by catenating the configuration files in a UniFi router or by clicking the “reveal” icon in the password box within the controller while configuring the Dynamic DNS settings. Likewise, this means if that API token is stolen because your hardware is compromised or the controller database is stolen, it can be used to update any record in the zone. Use with care and monitor your audit log!

Other Remarks on the Google Domains Sale / House Keeping

To close out this post, I’d like to remark on Google Domains itself. Using the service from 2017 – 2024, I can’t say that it has ever given me a problem. Google never had a name server outage that impacted the availability of my DNS records to any extent that I had noticed. It always worked fast. Support for Dynamic DNS worked well. It was a Google Product I definitely didn’t mind paying for as it did what it was supposed to, with one catch – DKIM Records!

DKIM was something I struggled to get working under Google Domains. Generally speaking, setting up DKIM requires inserting a public key into your DNS zone where your mail exchange records live, as a TXT Record. Due to the size of modern DKIM Records, I was required to use split records with Google Domains because a single TXT Record couldn’t store the entire public key, for compatibility with UDP-based DNS lookups. I couldn’t even paste a complete DKIM record into the DNS control panel without hitting a character limit. Needless to say, regardless of my attempts at getting DKIM to work right… many services struggle to validate split records correctly. After moving to Cloudflare for my DNS, I was able to insert a full, un-split TXT Record into their DNS Control panel, and DKIM pretty much just worked off the bat. Horray!

Along with the impending shutdown of Google Domains and the migration of information to Squarespace, I also took the time to consolidate my domains to the Cloudflare Registrar. The transfer process was pretty painless. This required that I first disable DNSSEC for my domains, which took a few steps to do in Google’s control panel. Once the DS and DNSKEY records were un-published and an NSEC3 record published, I swung my name servers to the Cloudflare servers. After that, it was just a matter of unlocking the domain, obtaining a transfer token from Google Domains, and following Cloudflare’s steps to transfer a domain to them. This pretty much involved inserting the Transfer Token from Google into Cloudflare’s forms, verifying my WHOIS information for ICANN was correct, and submitting payment. The transfer itself took about 10 minutes total, with approval notifications coming from Google. Once approved, the domain was with Cloudflare, and Google discontinued their DNS Services a few minutes later. With that done, I re-enabled DNSSEC, validated all of my records are good to go and that’s that.

Useful tools:

I should add some tools I used as part of my DNS and Registrar migration.

DNSViz: This resource is a great tool for validating and debugging DNSSEC issues which can cause your domain to fail to resolve on networks which validate DNSSEC. It is also useful to see a real time status of your domain’s DNS Records from the root, all the way down to a common set of records (A/AAAA/MX/TXT/SOA) your domain might have.

DMARCian’s Domain Checker: This tool is great for validating your SPF, DKIM, and DMARC records. I used this to ensure mail deliver-ability to and from my personal domain. During my migration, I erroneously inserted an include: statement into my SPF record which caused infinite recursion to occur on the SPF record lookup. This tool pointed out that error and showed what had exactly happened.