Skip to content

Instantly share code, notes, and snippets.

@Juul
Last active March 21, 2022 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Juul/f52255d6170dc3dcd93ced8723c34eb0 to your computer and use it in GitHub Desktop.
Save Juul/f52255d6170dc3dcd93ced8723c34eb0 to your computer and use it in GitHub Desktop.
How to use ddns on OpenWRT using Digital Ocean's API and skibish's daemon

Digital Ocean has an API that, among other things, allows DNS changes.

A github user called skibish maintains a small daemon written in go that implements DDNS using this API.

This guide shows you how to make this work on OpenWRT.

DNS records

Let's say you want the subdomain home.example.org to point to your home router. You can either use Digital Ocean's DNS servers for the entire example.org domain or you can add the following records to your existing DNS server to let Digital Ocean only handle the subdomain:

home  NS  ns1.digitalocean.com.
home  NS  ns2.digitalocean.com.
home  NS  ns3.digitalocean.com.

Note that the dot at the end of .com. is important.

Now go to Digital Ocean's DNS admin, add your subdomain as a managed domain and create an A record for some IP address with a very short TTL. Which IP isn't important as it will be overwritten shortly.

Compiling the ddns daemon for OpenWRT

Now if you're using an arm or x86 router you can simply use one of the pre-compiled binaries from the github releases page, but if not then you can easily cross-compile. Here's how I did it for MIPS Little Endian OpenWRT router.

On your desktop/laptop:

wget https://go.dev/dl/go1.18.linux-amd64.tar.gz
tar xvzf go1.18.linux-amd64.tar.gz
git clone https://github.com/skibish/ddns
cd ddns/
GOOS=linux GOARCH=mipsle GOMIPS=softfloat ../go/bin/go build main.go
mv main ddns

To list possible operating systems and architectures use ../go/bin/go tool dist list

Now copy the binary to your router:

scp ddns root@my-router:/usr/bin

Configuring the daemon

SSH into your router: ssh root@my-router.

You will need to generate a Digital Ocean API token on their website. Then you can create /etc/ddns.yml which is documented in the ddns daemon's github README file.

Mine looks something like this:

# DDNS configuration file.

# Mandatory, DigitalOcean API token.
# It can be also set using environment variable DDNS_TOKEN.
token: <my_token>

checkPeriod: "5m"

requestTimeout: "10s"

ipv6: false

# List of domains and their records to update.
domains:
  home.example.org:
  - type: "A"
    name: "@"
    ttl: 1800

Now you can test the daemon by running:

cd /etc
ddns

The next step is to create a new user so the ddns daemon doesn't run as root:

opkg update
opkg install shadow # note that this install many tools related to user management

useradd -s /bin/false ddns
mkdir -p /home/ddns
chown root.ddns /etc/ddns.yml
chmod 640 /etc/ddns.yml

Now we need an init script to start the daemon on boot. Create the file /etc/init.d/ddns with the content:

#!/bin/sh /etc/rc.common

START=100

start() {

  cd /etc
  echo "Starting ddns daemon"
  start-stop-daemon -S -c ddns -b -x /usr/bin/ddns

}

stop() {
  echo "Stopping ddns daemon"
  start-stop-daemon -K -c ddns -b -x /usr/bin/ddns
}

Make it executable:

chmod 755 /etc/init.d/ddns

Then test it:

/etc/init.d/ddns start
ps | grep ddns | grep -v grep

If it works, enable it so it auto-starts on boot:

/etc/init.d/ddns enable

That's it!

If it doesn't work, you can try troubleshooting by changing the /bin/false at the end of the ddns line in /etc/password to /bin/sh (remember to change it back later) and then becoming the ddns user with su -l ddns. Then you can try running:

cd /etc
ddns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment