First let me acknowledge that there are many ways to accomplish this. An easy solution for me would have been to simply use dyndns.com, no-ip.com, or one of the other commercial DDNS services supported by my router. For various reasons, I decided not to use one of those. Actually I did use duckdns.org for a while, but there were occasional issues that I got tired of dealing with.
I’m currently using Porkbun for DNS. They’re cheap, reliable, and have a decent user interface. They, like many other DNS services, also provide an API to make changes programmatically, without needing to log into their web site and make manual changes.
In my case, I have a shell script that runs as a cron job every 5 minutes. It checks my router for the WAN address and compares it to the last recorded address. If the two are not the same, it emails me and runs a Python script to update DNS.
I realize that some of this is pretty specific to my setup. Still, it might be a useful starting point. I found the Python script to update Porkbun DNS on their web site. The command to check the WAN IP address at the router may work for yours, or you may need to take a different approach.
#!/bin/bash
# Read the old IP address from a file. The EOL will go into a variable we don't use. This is necessary.
read OldIP b < /home/dale/myipaddress.txt
# Get our curent IP address from the router.
OUTFILE=~/myipstatus.txt
MyIP=`ssh -o StrictHostKeyChecking=no [username]@[router.ip] "ifconfig eth0 \
| grep inet | sed -e 's/.*addr:\([^ ]*\) .*/\1/'"`
while [[ $MyIP == "" || $MyIP == "192.168."* ]] ; do
sleep 10
MyIP=`ssh -o StrictHostKeyChecking=no [username]@[router.ip] "ifconfig eth0 \
| grep inet | sed -e 's/.*addr:\([^ ]*\) .*/\1/'"`
done
if [ "$OldIP" != "$MyIP" ] ; then
echo "`date`" > $OUTFILE
echo "Found new IP $MyIP, which is different from our previous $OldIP!" >> $OUTFILE
echo "Updating Porkbun DNS entries..." >> $OUTFILE
python3 ~/porkbun/porkbun-ddns.py ~/porkbun/config.json <mydomain.com> <hostname> >> $OUTFILE
mail -s "IP address change detected" <myemail@domain.com> < $OUTFILE
echo $MyIP > ~/myipaddress.txt
else
echo -n "." >> $OUTFILE
fi
In practice, this can result in a 5-10 minute lag between the time your IP address changes and the time your DNS is updated. If your ISP changes your IP address frequently, it may be too long. In my case, our ISP only changes our IP on rare occasions — typically less than once a year.
Again, there are other approaches, but most will not update DNS entries in your own domain. You can get around this to a certain extent by using CNAME entries, but this was the best way that I found to update my own domain’s DNS.