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.
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.
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
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