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 
#!/usr/bin/env bash

MYSQL_USER=powerdns
MYSQL_PASSWORD=YourPowerDNSMySQLPassword
MYSQL_HOST=localhost

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
#!/usr/bin/env bash

IP=`wget -qO- abraham.evorion.hr/whatismyip.php`
DOMAIN=david.evorion.hr
ssh vlatko@abraham.evorion.hr "/home/vlatko/bin/powerdns-dynamic.sh $IP $DOMAIN"

This script is run by the cron process using an entry like this:

$ cat /etc/crontab
SNIP
# 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 vlatko@abraham.evorion.hr "/home/vlatko/bin/powerdns-dynamic.sh $IP $DOMAIN" does not require password input.

So the whole workflow goes like this:

  1. Every minute crontab starts a script on the client machine. That is the machine for which you want a dyndns domain.
  2. The script determines the public IP address of the client machine by calling the whatismyip.php script using wget.
  3. 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

Your thoughts

steve, 26-06-11 08:37
If you want to give some other services a try other than dyndns there are tons more to choose from such as those listed at http://dnslookup.me/dynamic-dns/
dokma, 11-03-11 17:12
You failed to read the last sentence of the article. There is your answer for BIND... I'm totally unfamiliar with BIND so it's best for you to take Stephen's word on it.
Brian, 11-03-11 14:10
I use a DynDNS service and had always wondered how I might accomplish doing this myself. What would be the command in "powerdns-dynamic.sh" to update BIND?

I assume instead of this line:

mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -h $MYSQL_HOST powerdns -e \
"UPDATE records SET CONTENT=\"$1\", CHANGE_DATE=\"`date +%s`\" WHERE name=\"$2\""
dokma, 19-12-10 15:18
That would require the time I don't have right now. But it's not such a far fetched idea. I think I read somewhere that PowerDNS crew plans to implement DynDNS properly so I guess it would be a waste of time...
frankster, 02-12-10 09:58
This is really simple and it works. Did you think of implementing a real DynDNS interface for PowerDNS with user login and stuff?

Add comment

* - required field

*




CAPTCHA image for SPAM prevention
If you can't read the word, click here.
*
*