http://andrwe.org/doku.php/linux/own-ddns HOW-TO: be your own DDNS provider Summary This how-to explains a way to build your own dynamic DNS server. Main Hi, since some time my DDNS provider has problems which cause the loss of the connection to my home server. To prevent this loss I've read some manpages and build my own DDNS server. Requirements: own server with static IP own domain resolving (e.g.: example.org) subdomain delegated to to your server (e.g.: dyndns.example.org) php5 webserver supporting PHP (I use Lighttpd, but any will do) bind>=9 dnsutils Configurations You have to change all 'dyndns.example.org' to your domain. bind the bind user requires write-access to bind working directory: // named.conf options { ... ; working directory of bind directory "/var/named"; ... }; chmod 770 /var/named/ we generate a TSIG-key in a new directory which is used to verify the server and client: mkdir -p /etc/named/ cd /etc/named/ dnssec-keygen -a hmac-sha512 -b 512 -n HOST dyndns.example.org # webserver-group needs read access to file containing TSIG-key chown root: /etc/named/Kdyndns.example.org*.private chmod 640 /etc/named/Kdyndns.example.org*.private # get and remember the key grep Key /etc/named/Kdyndns.example.org*.private create zone in named.conf key mykey { algorithm hmac-sha512; secret "the-generated-key"; }; zone "dyndns.example.org" IN { type master; file "dyndns.example.org.zone"; allow-query { any; }; allow-transfer { none; }; allow-update { key mykey; }; }; create zone-file /var/named/dyndns.example.org.zone $ORIGIN . $TTL 86400 ; 1 day dyndns.example.org IN SOA localhost. root.localhost. ( 52 ; serial 3600 ; refresh (1 hour) 900 ; retry (15 minutes) 604800 ; expire (1 week) 86400 ; minimum (1 day) ) NS localhost. $ORIGIN dyndns.example.org. Webserver Create a subdomain (dyndns.example.org) and a vhost for the updating script. For security purpose and compatibility of the php-script the vhost has to be protected by http-authentication. For Lighttpd you can use the script provided here to generate the users. Save this PHP-script in the vhost-directory: index.php array('subdomain','sub2'), 'user2' => array('sub4') ); $dyndns = "dyndns.example.org"; $subdomain = $_POST['DOMAIN']; $ip = $_SERVER['REMOTE_ADDR']; $user = $_SERVER['REMOTE_USER']; if ( isset($subdomain) && isset($ip) && isset($user) && count($_POST) == 1 ) { if ( preg_match_all("/(\d{1,3}\.){3}\d{1,3}/", $ip, $matches) ) { unset($matches); if ( preg_match_all("/[\w\d-_\.\*]+/", $subdomain, $matches) ) { unset($matches); foreach ( $user_domain[$user] as $domain ) { if ( $subdomain == $domain ) { if ( $subdomain != "-" ) $subdomain = $subdomain . '.'; else $subdomain = ''; // using an absolute path for the private-key file is faster shell_exec("/usr/bin/nsupdate -k /etc/named/K$dyndns*.private < Usage If you've configured all correctly you can update domains using this command: wget --no-check-certificate --http-user="user" --http-passwd="password" --post-data "DOMAIN=example" -q https://dyndns.example.com Some examples: Script configuration: $user_domain = array( 'user' => array('subdomain') ); $dyndns = "dyndns.example.org" Result: The user 'user' can update the IP for the domain subdomain.user.dyndns.example.org. Script configuration: $user_domain = array( 'user' => array('subdomain'), 'user2' => array('test', 'foobar') ); $dyndns = "dyndns.example.org" Result: The user 'user' can update the IP for the domain subdomain.user.dyndns.example.org. The user 'user2' can update the IP for the domains test.user2.dyndns.example.org and foobar.user2.dyndns.example.org. Script configuration: $user_domain = array( 'user' => array('*'), 'user2' => array('test', 'foobar') ); $dyndns = "dyndns.example.org" Result: The user 'user' can update the IP for the wildcard domain *.user.dyndns.example.org which means all subdomains of user.dyndns.example.org are resolved to the IP set for *. The user 'user2' can update the IP for the domains test.user2.dyndns.example.org and foobar.user2.dyndns.example.org. Script configuration: $user_domain = array( 'user' => array('-','subdomain'), 'user2' => array('test', 'foobar') ); $dyndns = "dyndns.example.org" Result: The user 'user' can update the IP for the domains subdomain.user.dyndns.example.org and user.dyndns.example.org. The user 'user2' can update the IP for the domains test.user2.dyndns.example.org and foobar.user2.dyndns.example.org. Sources http://www.bind9.net/manuals http://www.oceanwave.com/technical-resources/unix-admin/nsupdate.html This blog post was created on 2011-01-31 at 20:06 and last modified on 2011-01-31 at 20:25 by Andrwe Lord Weber. It is tagged with ddns linux . Comments 1 Great article! I think the examples would apply to a few other providers with some very minor tweaks as well. When all else fails, you can always use a free service to try to accomplish something similar such as some of the others at http://dnslookup.me/dynamic-dns/ ddns 2011/06/26 18:09