Wednesday, January 4, 2012

Create your own Dynamic DNS Service using PowerDNS and MySQL

Dynamic DNS services can be very useful for sites or servers with dynamic IP addresses. Most residential Internet providers will only provide you with a dynamic IP address, making it quite difficult to manage systems remotely. This problem can be remedied with the use of Dynamic DNS where a software client updates the DNS server with the latest IP address of the site. Many providers already exist which provide this service such as No-IP.com or DyDNS.com. These are good, but unfortunately not all of their features are free and they require you to log in every once in a while to make sure that your account doesn’t get deactivated. In this article, I’m going to show you how you can setup your own Dynamic DNS service using PowerDNS and MySQL to update your dynamic sites’ IP in your own DNS server.


Instructions

These instructions assume that you have a domain name (purchased from a provider such as GoDaddy or otherwise) and you have the ability to point your domain to your own name servers.




Step 1

Install PowerDNS and its dependencies for MySQL.

Ubuntu / Debian

sudo apt-get install pdns-server pdns-backend-mysql mysql-server

CentOS / RHEL / Fedora


yum install pdns pdns-backend-mysql mysql-server



Step 2

Configure PowerDNS with your MySQL details.

sudo nano /etc/powerdns/pdns.d/pdns.local

# Here come the local changes the user made, like configuration of
# the several backends that exist.

gmysql-host=127.0.0.1
gmysql-user=<mysql user>
gmysql-password=<mysql password>
gmysql-dbname=<powerdns database>



Step 3 (Optional)

You can optionally install a web frontend to manage your domains. I recommend PowerDNS Administrator.
http://code.google.com/p/pdnsadministrator/downloads/list



Step 4

Configure the update script to update the DNS record in the database.

sudo mkdir -p /opt/dynamic-dns

sudo nano /opt/dynamic-dns/update.php

<?php

$ip = $argv[1];
$domain = $argv[2];


// Make MySQL Connection
mysql_connect("localhost", "powerdns", "a4031b869c") or die(mysql_error());
mysql_select_db("powerdns") or die(mysql_error());

// Update record in database.
$result = mysql_query("UPDATE records SET content='$ip' WHERE name='$domain' and type='A';")

?>


Step 5

Install openssh-server and openssh-client in both servers.

sudo apt-get install openssh-server
sudo apt-get install openssh-client

Configure SSH Keys on the dynamic host for passwordless authentication to the DNS server. Be sure to change the <user> and <powerdns ip>
to the correct values.

ssh-keygen (Accept all the default values.)

cat ~/.ssh/id_rsa.pub | ssh username@hostname 'cat >> .ssh/authorized_keys'



Step 6

Configure the client script/cron job to fetch the dynamic host’s current IP address and update the DNS database. Be sure to update the bold values with the appropriate values.

sudo nano /etc/cron.hourly/dynamic-dns.cron && sudo chmod +x /etc/cron.hourly/dynamic-dns.cron

#!/bin/bash
IP=`curl -s http://www.whatismyip.org`
DOMAIN=<dynamic dns domain>
ssh -C <user>@<powerdns ip> php /opt/dynamic-dns/update.php $IP $DOMAIN
echo “`date` $DOMAIN – Updated IP to $IP” >> /var/log/dynamic-dns.log