How to run DynDNS - DDNS yourself
Me being the way I am, that is always looking for a good challenge and also running a web development and hosting company it looked kind of silly to me to depend upon services like dyndns.com for dynamic dns. But ever since I started running my own DNS using PowerDNS it was lingering at the back of my head how little it needs to be done to have my own dyndns.
Finally I got to it this week and when I did it took me a total of 20 minutes to set it all up. So you might call it trivial. My idea was to use SSH key authentication to execute domain update script remotely. The only other thing I needed to solve independently of all of the online services was how to detect my public IP. Finally I resorted to using PHP since my dedicated server runs LAMP anyways.
So, without further poetry, here is the result of my hard labor:
The public IP detection PHP script
$ cat whatismyip.php
<?php echo $_SERVER['REMOTE_ADDR']; ?>
That's a neat script. I don't want to hear anything other than words of praise for this achievement.
Now comes the script that resides on the server where PowerDNS is running and is used to update the ddns database.
The database update BASH script
$ cat powerdns-dynamic.sh
mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -h $MYSQL_HOST powerdns -e \
"UPDATE records SET CONTENT=\"$1\", CHANGE_DATE=\"`date +%s`\" WHERE name=\"$2\""
As you can see this one is also a marvelous development achievement. If you don't understand it I suggest you don't mess with any of this stuff.
But now comes the hard part. A script that is running on the client machine. That is the machine for which you want a domain that is dynamically updated.
Client update BASH script
$ cat powerdns-update.sh
IP=`wget -qO- abraham.evorion.hr/whatismyip.php`
ssh firstname.lastname@example.org "/home/vlatko/bin/powerdns-dynamic.sh $IP $DOMAIN"
This script is run by the cron process using an entry like this:
$ cat /etc/crontab
# Update dynamic DNS for david.evorion.hr
* * * * * vlatko /home/vlatko/bin/powerdns-update.sh
You need to pay attention to the fact that this crontab line works due to the fact that I have established an SSH key authentication between my two machines so that the line: ssh email@example.com "/home/vlatko/bin/powerdns-dynamic.sh $IP $DOMAIN" does not require password input.
So the whole workflow goes like this:
- Every minute crontab starts a script on the client machine. That is the machine for which you want a dyndns domain.
- The script determines the public IP address of the client machine by calling the whatismyip.php script using wget.
- Once the IP is determined the client machine executes a domain update script via SSH line that performs the actual update of the PowerDNS database completing the full workflow.
There is one more thing worth noting. The dynamic domain that you are updating needs to have a very short TTL in order to have it propagate quickly enough through the DNS network. If you don't understand what DNS propagation is you can learn more by reading an excellent article at DevShed: What is DNS propagation and why does it take so long?
I know you guys have a ton of improvements on these lines of mine. I would love to have them in the comments section below. No login, just punch your ideas in and let's see how we can improve upon this peace of software.
DynDNS for BIND
Stephen Milton made the same thing for BIND. Check it out here: http://sacrifunk.milton.com/index.php/2007/02/18/diy_dynamic_dns
I have also created a Dynamic DNS system running on top of PowerDNS/MySQL, which uses a web interface rather than SSH (more accessible, and would be more secure if I bothered to test it properly). It allows creation, updating and deletion of dynamic hosts, and may be found on github:
To script an update via the web interface, use "curl" on Linux/Unix, or hand-craft a HTTP GET command and feed it into "telnet" on Windows.