my failed projects

RFC2136 DDNS, BIND & DNSSEC for Home Router Dynamic DNS

  • You have: a BIND that already does DNSSEC; a home router
  • You want: a hostname myhost in your domain example.org that tracks your home router’s IP

BIND setup

The six53 DNSSEC reference card has been very helpful. A Netlink article covers some of the content as well. IPAM explains the update-policy options.

Generate asymmetric DNSSEC key for nsupdate on myhost:

1
dnssec-keygen -C -r /dev/urandom -a RSASHA256 -b 2048 -n HOST -T KEY myhost.example.org

This will generate two files, Kmyhost.example.org.*.{key,private}. Copy both files to myhost.

Add the host key to the zone file db.example.org:

1
$include "/path/of/Kmyhost.example.org.*.key"

This will add a KEY resource record (RR) for myhost.example.org. In the next step we will refer to this key.

Set up BIND for automatic zone signing:

1
2
3
4
5
6
7
8
9
10
11
zone "example.org" {
        type master;
        key-directory "/etc/bind";
        auto-dnssec maintain;
        sig-validity-interval 30;       // days
        update-policy {
                grant local-ddns zonesub ANY;
                grant myhost.example.org. self dummy A AAAA TXT SSHFP;
        };
        file "/etc/bind/db.example.org";
};

This configures BIND to accept dynamic updates of the zone and automatically keeps the zone signed. It also allows updates to myhost.example.org’s A, AAAA, TXT, and SSHFP RRs, as long as the updater is in possession of the private key matching the KEY RR of myhost.example.org.

Make sure that BIND can write to the directory the zone file is in, because it will create a journal and also update the zone file itself.

Now reload the BIND config with rndc reload. Check for error messages in /var/log/messages.

Home router setup

Put the generated key files from above in a convenient location, e.g. /etc/ddns. The following shell script can then be used from various hooks, e.g. /etc/ddns/ddns-update.sh A 172.17.1.2

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

HOST=myhost.example.org
CONFDIR=$(dirname "$0")

exec nsupdate -k $CONFDIR/K$HOST*.private -- - <<__END__
update delete $HOST $1
update add $HOST ${TTL:-300} $@
show
send
__END__

Hook the update script into ppp by creating the following shell script as /etc/ppp/ip-up.d/ddns. Remember to +x all scripts.

1
2
3
4
5
#!/bin/sh

# IPv4 update script for RFC2136 DDNS

/etc/ddns/ddns-update.sh A $PPP_LOCAL

If an IPv6 network is announced to the home network, hook it in dhcp6c’s /etc/wide-dhcpv6/dhcp6c.conf:

1
2
3
4
5
profile default
{
...
        script "/etc/wide-dhcpv6/update-ipv6.sh";
};

Update the IP from /etc/wide-dhcpv6/update-ipv6.sh for the network on MYIFACE:

1
2
3
4
5
6
MYIFACE=br0
(
sleep 2
myipv6=$(ip addr show dev $MYIFACE | sed -ne's/^.*inet6 \([^ ]*\)\/.*$/\1/;T;p;q;')
/etc/ddns/ddns-update.sh AAAA $myipv6
) &

Regexp courtesy of SuperUser.