Rob Sears bio photo

Rob Sears

       

Rocket scientist. Computer hacker. Geek before it was cool.

BTC Donations:
1AU9qGkSubhR24r8Y4WEoV8bccZjeT2dKg

Filed under “reinventing the wheel,” I recently needed to update a part of my home lab that broke when Dropbox changed a security policy. Dropbox was a component of a system I made allowing me to access my home network remotely, and it had been working flawlessly for about a decade. The breaking change they rolled out was a pain in the ass to fix and I didn’t want to deal with a new layer of complexity in my solution.

While researching alternatives for managing remote connections to a home lab, I discovered that what I’d actually wanted to implement ~10 years ago has a name: Dynamic DNS. And apparently not one other f*cking person on the planet has ever abused Dropbox for it.

What is Dynamic DNS?

DNS – Domain Name System – is kind of like the Internet’s phone book. See, computers don’t understand “google.com” as anything meaningful. The internet is built on top of a networking system in which computers in the network are assigned a machine-readable address called an IP address.

This system works great for computers communicating with each other efficiently, but the addresses – like phone numbers – can be cumbersome, hard to remember, and inscrutible to humans. “68.157.32.256” maps to some machine, somewhere, but a given person isn’t going to have a clue what it is. Humans do much better with readable descriptors like “google.com”

Enter DNS. It’s an open, global service that maps human-readable names like “google.com” to machine-readable IP addresses. Dynamic DNS is simply a process for automatically updating the IP address associated to a domain, if that IP address changes.

What Problem Does DDNS Solve?

Let’s say you have a home server or something that you want to connect to remotely. To do that, you have to know your home’s public IP address. When you connect to the Internet via your service provider (ISP), you’re issued one such address. The thing is, the IP address your ISP provides is part of a pool of IP addresses it controls. So, for any number of reasons, your public IP address can change at any time.

With DNS, you can register a domain name and associate it to your public IP address, so you don’t need to memorize your home IP address to access your home server. This way, requests to this domain name get directed to your home router, where you (ideally) have some kind of firewall to keep out unwanted traffic. But you still need to know if/when your public IP address changes so you can update DNS records accordingly. And if your home’s public IP address changes while you’re offsite, then… buddy I don’t know what to tell you.

Dynamic DNS solves this issue by having some kind of home-based server that continuously checks its public IP address, and if it’s different from the one associated to your domain name, then it will automatically update DNS records through an API. Thus, the random and spontaneous changes to your public IP address are incorporated into DNS records automatically.

DDNS in Practice

DDNS isn’t software you can download and run, it’s a methodology for solving a common problem. Thus there are quite a few boilerplate ways to implement it. Broadly though, you have some computer/system on your home network that is regularly polling your home’s public IP address, and updating public DNS records if it detects a change.

A few home routers support DDNS out of the box, others can support it with flashed firmware, like OpenWrt. PFSense supports it too. Alternatively, Linux/Mac devices can utilize cron to run such a script on a schedule. Windows users probably have something similar. But it all works the same: check every X minutes to see if the public IP address has changed, and update DNS records if it has.

On the DNS side, you can use a service like DuckDNS, where you get a subdomain like myhomerouter.duckdns.org and an API key for updating the IP address. This is nice because it’s free and you don’t need to register a domain name. If you want a domain name, you can register something like “myhomeserver.com”, and configure a service like CloudFlare to manage the nameservers for the domain name. You’d get an API key from CloudFlare that allows you to make DNS changes as needed.

In any case, your script needs to have API access to whomever is managing the DNS records for you.

Implementing DDNS with Dropbox

Back in the day that I implemented this, around 2012-ish, I didn’t know what DDNS was; all I knew was I had a home system that I occasionally needed remote access to, and it was annoying as shit to keep track of my public IP address that kept changing. But I had Dropbox set up on both my desktop and laptop.

So I just set up a script on the desktop that determined my public IP address every minute or so, and updated a single file in the Dropbox folder. Then I wrote another script that ran on my laptop, which checked the file created by the desktop machine, and updated a line in the laptop’s /etc/hosts file. Something like this:

Add a line to the /etc/hosts file on the laptop:

# This line tells the computer that qwert.qwert is located at a given IP address
142.250.190.132 qwert.qwert

Then add this to the crontab on the desktop:

crontab -e

# Runs on the desktop at home:
# Update the desktop.ip file every minute
*/1 * * * * /usr/bin/sh -c 'curl -s https://ipv4.icanhazip.com/ > /path/to/dropbox/folder/desktop.ip

Last, add this to the crontab on the laptop:

# Update the hosts file every 2 minutes
*/2 * * * * /usr/bin/sed -ri "s/^(\S+) .*qwert\.qwert/$(cat /path/to/dropbox/folder/desktop.ip) qwert\.qwert/" /etc/hosts

Done! Now as far as the laptop was concerned, the desktop could always be reached at qwert.qwert, which simplified life a lot. And if the IP address changed, the desktop would only be unreachable for about 2 minutes at most.

How’d It Go?

It wasn’t pretty but it worked, and was actually kind of awesome. One of the downsides with DNS is that the global servers often cache records for an hour or more, and changes take time to propagate. So if your public IP address changes, even if your home server detects it and issues an update via some API right away, it could take an hour or more for your remote machine to be able to access the home server again. And you may even need to flush your local DNS caches to make it work.

Also, if you can’t reach your home server when you’re remote, you have no way of knowing whether the issue is DNS related or not, because you can’t be sure what your home server’s public IP address is. Perhaps the server is offline (power outage), or your IP checking script failed, or maybe everything is working and the DNS changes haven’t propagated yet. You can’t rule anything out without consulting the home server, which you can’t access, because you can’be sure of its IP address.

With my approach, changes to my public IP address were incorporated into my remote machine within 2 minutes or less. And I could always inspect the desktop.ip file to see when the IP address was last updated. That way, if I couldn’t connect to the desktop, I could determine whether the issue was DNS-related, or whether the desktop was offline for some reason.

Basically, it was faster and made troubleshooting easier than the boilerplate DDNS solutions, which are far from perfect, and potentially slow to propagate changes.

The main downside was that it could be buggy, due the Dropbox Linux daemon (which often created multiple versions of a file). I eventually migrated to the Dropbox CLI tool (dbxcli). That was stable for years, until Dropbox went to a short-lived token approach. Now I need to regularly refresh access tokens to keep the system functioning, which is one layer of complexity more than I care to manage.

Now What?

I guess I’ll shell out for a proper domain name and use a service like CloudFlare or Route53 to power DDNS. I can always configure my laptop to use CloudFlare’s DNS servers instead of whatever is provided by a connected access point. That would mitigate the impact of propagation issues. It’s still like $12/year more than my older solution, but it’s probably going to be more flexible in the long run.