Dynamic DNS for NSD
Go to file
Michael Clemens c787670297
Merge pull request #2 from chrisb86/master
Made shebang more portable.
2018-10-05 21:36:03 +02:00
README.md Updated README 2018-06-03 01:19:14 +02:00
dyndns.conf-dist first commit 2018-04-29 20:39:07 +02:00
dyndns.sh Made shebang more portable. 2018-10-05 21:19:43 +02:00




nsd-dyndns is a simple script that adds dynamic DNS dunctionality to NSD (authoritative DNS name server).


The following is required or suggested:

  • OpenBSD (or another BSD or some Linux distro) with HTTPD and NSD installed (pkg_add nsd), configured and running
  • (sub-)domain for your webserver. Needed for updating the NS record of your actual DynDNS domain.
    • In this example: update.example.com
  • (sub-)domain that is updated dynamically.
    • In this example: dyn.example.com
  • A router capable of sending custom GET-requests to your DynDNS server.
    • In this example: A FritzBox


Configure your web server


Add the following new virtual host to your /etc/httpd.conf:

server "update.example.com" {
        listen on $ext_addr port 80
        root "/htdocs/dyndns"
        log access dyndns.log


Add the following to your nginx.conf. The "access" log format isn't avaliable by default so you have to define it.

http {
    log_format access '$host $remote_addr - $remote_user [$time_local] '
                               '"$request" $status $body_bytes_sent '
                               '"$http_referer" "$http_user_agent" "$gzip_ratio"';

    server {
        listen 80;

        server_name update.example.com;

        root /htdocs/dyndns;
        access_log /var/www/logs/dyndns.log access;


Create an empty update.html:

# mkdir /var/www/htdocs/dyndns/
# touch /var/www/htdocs/dyndns/update.html

After reloading webserver, try to access http://update.example.com/update.html The request should show up in /var/www/logs/dyndns.log

Create a zone file for dyn.example.com

Create a new zone file (e.g. at /var/nsd/zones/dyn.example.com.zone) with the following content

$ORIGIN example.com.
$TTL 300
@       IN      SOA     ns1.example.com.      admin.example.com. (
                        300                     ; refresh
                        900                     ; retry
                        1209600                 ; expire
                        1800                    ; ttl
; Name servers
                    IN      NS      ns1.example.com.
                    IN      NS      ns2.example.com.

; A records
@ IN A
update IN A
dyn IN A

Don't forget to set your own domain names, name servers and ip addresses Furthermore, add this zone file to your /var/nsd/etc/nsd.conf

Configure and Install nsd-dyndns

  • Copy dyndns.conf-dist to /etc/dyndns.conf
    • # cp dyndns.conf-dist /etc/dyndns.conf
  • Edit /etc/dyndns.conf to your needs
  • Copy dyndns.sh to /usr/local/bin/dyndns.sh
    • # cp dyndns.sh /usr/local/bin/dyndns.sh
  • Make the script executable:
    • # chmod u+x /usr/local/bin/dyndns.sh
  • Add /usr/local/bin/dyndns.sh to your crontab

Configure your router

Configure your router to query the following URL:


Don't forgert to set your own domain name and to replace the string after "?" with the password you configured in the config file.

What it does

When your router gets a new IP and therefore sends an HTTP request to your server, a similar entry should appear in your /var/www/logs/dyndns.log:

update.example.com - - [29/Apr/2018:20:48:19 +0200] "GET /update.html?qwertzuiop1234567890 HTTP/1.1" 200 6

When the script is executed e.g. via cron, the following happens:

  • It greps the last line of /var/www/logs/dyndns.log where the correct password was found and extracts the requesting IP address
  • It checks if this IP is the same than the last time
  • If it's a new IP, then it replaces the forth line in your zone file - the line with the version number - with a new version (current unix time stamp)
  • As a second step, it updates the A record of you DynDNS domain (dyn.example.com in our example)
  • It then stores the new IP in the file /tmp/last_dyndns_ip.txt
  • Finally it reloads NSD