DIY Dynamic DNS with DigitalOcean

Background

Lately I've been looking into setting up a VPN to access my home network when I'm away. I wanted to use a subdomain of one of the domains I've registered, so it's easy for me to remember. The straightforward way to do this would be to get a static IP and setup a subdomain that way. However, I didn't really want to spend the $25 per month my ISP charges for that, nor did I want to pay for a dynamic DNS service to let me use my own domain. Since I won't run anything that's critical to access outside home off a home server (I'll use a VPS for that), I'm willing to accept some downtime if the IP changes but the DNS record hasn't updated yet.

Thinking through this, I realized my NAS is constantly running, which gives me an always on Linux system.
Then I checked to see how easy the DigitalOcean API would be to use, since I already have an account where my domain's DNS settings are managed, and found they have a CLI tool (doctl) that can do this. After that, it turned out to be easy to setup, so I documented what I did for this post.

Some notes:

  • This guide assumes you already have a DigitalOcean account managing a domain name you own.
  • You don't need a synology NAS specifically for this, it's just convenient for me as I already have it running. Any always-on system could be set up with a cronjob or similar.

Install doctl

Create Access Token

Follow the official DigitalOcean directions to generate an access token. I recommend making it unique to just this project, so if needed it can be revoked without breaking services using other tokens.

Setup Home Directories on NAS

Since we'll need somewhere to store doctl's config, enable home directories on the NAS. Open Control Panel -> User & Group -> User Home and enable Enable user home service. After applying the setting, SSH into the NAS and check that the directory is created by running cd ~ && pwd and making sure it outputs your home directory (mine is under /var/services/home).

Install doctl On NAS

Luckily, DigitalOcean provides pre-built Linux binaries for doctl. On the install and configure documentation there's instructions on how to download the binary releases from GitHub. Make sure to check the releases page linked from there to make sure you get the latest version. When I installed it, the instructions showed v1.101 in the example, but v1.103 was the actual latest. Also pay attention to the OS and architecture. My NAS uses an Intel CPU, but other models may use an ARM architecture CPU instead. While SSHed into the NAS, run the commands, accounting for version number and CPU architecture.

Create The DNS Record

Now that doctl is setup, we can now create the DNS record with the current IP address. DigialOcean has documentation on managing DNS records with doctl. Since doctl is already setup, we can skip to step 4. To add an A record (which we want for IPv4), run doctl compute domain records create YOUR_DOMAIN_NAME --record-name SUBDOMAIN --record-ttl 3600 --record-type A --record-data CURRENT_IP, adjusting the arguments for your case. Make sure the domain entry is created by running doctl compute domain records list DOMAIN, and note the ID for the record that we'll be updating, as it's needed in the next section.

Setup Synology Task

Since the "dynamic" part of dynamic DNS means we need to update the record with the network's public IP, we need a way to programmatically find out what it is. There are a few ways to do this, but for this guide we'll use curl with AWS' IP reporting service. Test this works on the NAS by running curl https://checkip.amazonaws.com and verifying it returns your public IP. Then in your home directory, create a file named diy-dynamic-dns.sh with the line doctl compute domain records update YOUR_DOMAIN_NAME --record-id ID --record-data $(curl https://checkip.amazonaws.com), with your record's ID filled in.

In the Synology NAS web interface, create a new task by going to Control Panel -> Task Scheduler -> Create -> Scheduled Task -> User-defined script. I set the task name to diy-dynamic-dns, it to run daily, every hour with start time 00:00 and end time 23:00 (to match the DNS TTL). For the task's run command, use full path names per the Synology docs. For my case, this means the command is /bin/bash /var/services/homes/thomas/diy-dynamic-dns.sh.

Finshing Up

Now that everything is setup, it's time to make sure it updates the DNS record. If you have email support setup on the NAS, set the task to send you an email when it runs so you know when to check the DNS record, at least for the first time. Then make sure the DNS settings in DigitalOcean are what you expect.

One important note is that there can be a lag of up to an hour between an IP change and the DNS record being updated. If that can cause significant issues, then using a static IP is a much better option. But for the low subscription cost of free, this seems good enough for many uses.