Homebrew Dynamic DNS

Niall Deakin
19 Jul 19

A little history

I run a Gitlab server from home. It’s quite cost-effective as the hardware requirements are rather low, and I can easily upgrade the storage space as and when I need it.
It’s also a lot cheaper than hosting a server or VPS elsewhere.

However, the problem lies in accessing the server from somewhere outside of my home. My work takes me all across the country, and that means needing access to the repos remotely.

What I usually did was get the server’s public IP and either use that, or update DNS records manually.

Using DigitalOcean, I set up an A Record with the public IP so I can access the server via a subdomain; it’s quite handy, but the record would need to be updated whenever my IP changes at home (because a static IP is very costly).

So I created a nice little bash script to run whenever I’ve lost access due to the IP changing.

The script

#!/bin/bash
IP=$(curl https://ipinfo.io/ip)

curl -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer [API KEY]" -d '{"data":"'"${IP}"'"}' "https://api.digitalocean.com/v2/domains/[DOMAIN]/records/[RECORD ID]" 

To begin with, that’s the whole code.
All you need to do is copy that, create a new .sh file (I’ve called mine DynDNS.sh) and make a few changes, including setting the permissions to 744.

You need your API Key, Domain and Record ID for this script to work. Simply switch out the values (e.g. “[DOMAIN]” would become “classicniall.co.uk”).

Getting API Key

It’s very straight forward. Go to DigitalOcean API Tokens, and generate a new Token. I’d recommend saving it in a secure file somewhere.
Copy the Token and replace [API KEY] with it.

Getting Domain

I think it’s rather straight forward, it’s your domain that is used for the subdomain. So, if you want “repo.domain.com”, then enter in here “domain.com”.

Getting the Record ID

Okay, this one is not so straight forward.
Just run this command:

curl -X GET -H 'Content-Type: application/json' -H 'Authorization: Bearer [API KEY]' "https://api.digitalocean.com/v2/domains/[DOMAIN]/records"

That will spit out all the records for the selected domain. What you need to do is find the A Record for your subdomain, and copy the id field (yes, it’s lowercase).

NB: I ran this code in Git Bash, so the results weren’t formatted, but it’s the only way I knew how to get the ID for the record.

If you don’t have an A Record for the subdomain, you will need to manually create the A Record first (if you want to follow my guide), and run the command again.

Running the command

So now that the script has been created, modified and with the correct permissions, you should be able to run it by calling the file itself. In this instance, I simply use “./DynDNS.sh” to run the command, and it executes rather quickly (probably about a second).
I’ve tested it quite a few times, and it always grabs the correct public IP and updates the record.

Creating a Bash Command

To make things easier, you may want to create a Command in order to run the script. Sure, it may not take much to type out the command above, but it would be easier to type in a single word for the command. I use DynDNS.

Go into your .bash_alias file and simply add:

alias DynDNS="./DynDNS.sh"

alias marks it out as an alias, DynDNS is the command word, and everything between the speech marks is the command itself. Running DynDNS basically says “run this file”.

Save it, log out of the server/session and log back in. The alias will now work (or you could manually force the update to take place).

Taking things further

There is definitely room for improvement here.
For starters, this still requires to be manually ran whenever there is a change in the home server’s public IP. What we need to do is to make it more dynamic to check if there is a change.

One way is to set up a Cron job or scheduled task to run the file at a set interval, but that wouldn’t be very efficient (although it would be an automated process), or we could take things further and run a check to see if the public IP has changed (because it could happen at any moment).

If it changes, then run DynDNS.

However, I don’t know how to do this, but it is on my radar.

A Records, Bash, DigitalOcean, DNS, Dynamic DNS, Gitlab, home server, Remote Access