dudders — home router HOWTO

This page explains how to set up a BIND 9 server and dudders on your home router to dynamically update a DNS record.

Contents

Background

This section explains at a basic level the technologies dudders uses, and why you might want to use dudders. Skip this section if you already know how DNS UPDATE works.

A computer on the internet is identified by an IP address. For home networks, this address is assigned to a router or modem by an ISP (the telecommunications company you pay for internet access). Many ISPs frequently change the particular IP address they assign to a home connection: this practice is often described as assigning a dynamic IP address.

You may wish to connect directly to your home network from a remote location: for example, to upload a file to a home server. Accessing your home network through the internet requires you to know the dynamic IP address assigned by your ISP. Some ISPs make it available via their websites, or you could write it down, or even just remember it as you leave the house. However, if your home connection drops temporarily, it's possible the address could change!

An IP address is just a number, such as 192.0.32.10. Most people on the internet are used to accessing machines using the Domain Name System. A type of DNS record called an A record associates a domain name (e.g. home​.dynamic.net) to an IP address. If you have registered your own domain name (e.g. dynamic.net), it may be convenient to set up a subdomain like "home" to point to your home address. This is easier to remember than a 4-octet IP address, but it still doesn't solve the problem of being up-to-date. You need your home modem or router to update the A record whenever your home connection gets a new address.

Dudders is a program with a command-line interface that allows your computer (or router) to securely update a domain name to point to a dynamic IP address. Your home router sends a DNS packet to the DNS server responsible for your domain with your home's new address, whenever your router reconnects to the internet. This lets you connect to your home computers from anywhere in the world, using an easy-to-remember domain name like home​.dynamic.net.

Dudders uses an extension to the DNS protocol that allows a DNS zone to be updated. This extension, DNS UPDATE, was standardised by the IETF, the same group that publishes the DNS protocol. The DNS UPDATE extension is secure, efficient, and supported by BIND, one of the most popular DNS server implementations.

HOWTO

Suppose you own the domain dynamic.net, and its DNS is hosted using BIND. This HOWTO assumes you have access to that DNS server, and a computer with BIND's tools such as nsupdate and dnssec-keygen.

Key generation

You need to generate a key for SIG(0), using the RSA/MD5 algorithm. You can generate it with the dnssec-keygen program distributed with BIND. We generate a key that "belongs" to the router called "myrouter" in the example.

dnssec-keygen -a RSAMD5 -T KEY -n HOST -b 512 myrouter.dynamic.net.

This will produce two files, something like Kmyrouter​.dynamic.net​.+001+32086​.key and Kmyrouter​.dynamic.net​.+001+32086​.private (the 32086 part may be different).

You can read about generating keys in the BIND manual.

BIND configuration

Suppose you own the domain dynamic.net, and its DNS is hosted using BIND on the server ns1​.dynamic.net. The BIND configuration will be in a file similar to /etc/named.conf or /etc/bind/named.conf, or possibly a file included by one of those two. The zone statement in that file will be similar to:

zone "dynamic.net" IN {
  type master;
  file "db.dynamic.net";
};

You should edit the zone statement to include an update-policy statement:

zone "dynamic.net" IN {
  type master;
  file "db.dynamic.net";
  update-policy {
    # allow "myrouter" to update the A record of "home"
    grant myrouter.dynamic.net. name home.dynamic.net. A;
  };
};

You can read more in the BIND administrator's manual about dynamic updates.

Zone configuration

You need to add the A record for your home domain name, and the KEY record for your key to your zone. The appropriate zone entry for the KEY record is contained in the Kmyrouter​.dynamic.net​.+001+32086​.key generated earlier. After adding the entries, the file db​.dynamic.net should look something like:

$TTL 86400
dynamic.net.  IN SOA  ns1.dynamic.net. me.dynamic.net. (
  2010082601 ; serial
  86400      ; refresh (1 day)
  7200       ; retry (2 hours)
  4838400    ; expire (8 weeks)
  10800      ; minimum (3 hours)
  )
; existing NS, MX, A and other records...

home.dynamic.net.     IN A 127.0.0.2
myrouter.dynamic.net. IN KEY 512 3 1 AwEAAbVKdizHlpi3k4f/p/yDblpSwcb32Ti9FhEIwk5wvI1pC4RU56m0 vJYKKQxmAbt54YfWGQnV4/lmkIiDhTl9VtM=

Testing with nsupdate

Before using dudders, you may wish to test your configuration with nsupdate. nsupdate is distributed with BIND but some OS distributions package it separately; e.g. in debian, it is called dnsutils, in gentoo it is called bind-tools. You should force BIND to reload its configuration file after the changes above. Then run:

nsupdate -k Kmyrouter.dynamic.net.+*.private << EOF
server ns1.dynamic.net.
zone dynamic.net.
update delete home.dynamic.net A
update add home.dynamic.net 86400 A 127.0.0.3
send
EOF

You should then be able to query the new A record

 host home.dynamic.net ns1.dynamic.net

Using domain server:
Name: ns1.dynamic.net
Address: 10.0.0.1#53
Aliases: 

home.dynamic.net has address 127.0.0.3

Updating with dudders

If nsupdate worked, you should be able to use dudders too!

If you haven't already, download the latest version of dudders from the GitHub releases page. There may be a pre-built binary for your platform, or you can build from source.

Once dudders is installed, try running it with your new keys:

dudders -k Kmyrouter.dynamic.net.+*.private -m ns1.dynamic.net -z dynamic.net home.dynamic.net 86400 127.0.0.14

If dudders exits with status 0 and no output, it has successfully updated the record.

Automatically running dudders when your IP address changes

If your router is assigned a dynamic IP address every time it reconnects to a network, you should run dudders every time the network interface is brought up, or every time the daemons responsible for obtain the IP address are executed.

Unfortunately this is very distribution-specific. Most distributions have a directory containing scripts that are run after network interfaces are brought up; it may be something like /etc/hotplug.d, /etc/network/if-up.d, or /etc/ppp/ip-up.d. You should drop a shell-script into the appropriate directory that runs dudders as above (with the appropriate IP address, of course). One caveat is that dudders should be run after the system has acquired the correct time, e.g. after ntpdate or similar NTP clients.

If you use OpenWRT, the official OpenWRT dudders package comes with its own hotplug script, so all you have to do is edit /etc/config/dudders.

PPP

If you have a DSL, cable, or dialup modem, it probably establishes a connection using PPP. In this case, the dynamic IP address is re-assigned via IPCP every time the PPP connection is established.

pppd by default runs /etc/ppp/ip-up with the remote IP address as the 5th parameter. You can read more about PPPd's ip-up script in the pppd(8) manual. A script such as the following could be used:

TTL=86400
SERVER=ns1.dynamic.net
ZONE=dynamic.net
HOSTNAME=home.dynamic.net
KEYFILE=/path/to/Kmyrouter.dynamic.net.+001+32086.private
        
if [ -n "$5" ] ; then
  dudders -k $KEYFILE -m SERVER -z $ZONE $HOSTNAME $TTL $5
fi
    

DHCP

If your IP is assigned via DHCP as opposed to IPCP, you can call dudders from the DHCP client's exit hook. The ubiquitous dhclient DHCP client executes the file /etc/dhclient-exit-hooks with the new_ip_address set in the environment. You can therefore use a script like:

TTL=86400
SERVER=ns1.dynamic.net
ZONE=dynamic.net
HOSTNAME=home.dynamic.net
KEYFILE=/path/to/Kmyrouter.dynamic.net.+001+32086.private
        
if [ -n "$new_ip_address" ] ; then
  dudders -k $KEYFILE -m SERVER -z $ZONE $HOSTNAME $TTL $new_ip_address
fi
    

You can read more about dhclient's hooks in the dhclient-script(8) manual page.

Determining the Internet address

When using hooks for PPPd or dhclient, your script will be fortunate enough to have the IP address available as an environment variable or command-line parameter. However, in some cases it may be necessary (or even more reliable) to infer the dynamic IP address from routing information.

Usually on a modem/router, the default route is the internet IP address assigned by the ISP. One trick to get the IP address from a shell-script is to process the output of route -n (to get the interface) and ifconfig (to get the address) with awk or similar. However, beware that this output is not standardised! Here's how it works on OpenWRT:

# get the network interface from the default route:
interface=$(route -n 2>&- |grep '^0.0.0.0' |sed -e 's/.* \([^ ]\+\)$/\1/')
# get the IP address:
ifconfig "$interface" |grep -o 'addr:[^ ]\+' |sed -e 's/addr://'