This document explains how to set up a DDNS zone and explains how to
let a client update its dynamic IP address using the nsupdate utility.
For this to work, you need at least Bind v9 on both server and client.
So Red Hat 7 would be ok ;-)
- You can only set keys for a zone-file. This means if you want to have several
dynamic entries for one domain, you need to delegate them to seperate zone-files.
First you need to create TSIG keys to ensure the communication between the client and
the DNS server is secure. You can do:
dnssec-keygen -a HMAC-MD5 -b 128 -n zone key-test
The TSIG key is redundantly stored in two separate files. This is a consequence
of nsupdate using the DST library for its cryptographic operations, and may change
in future releases. (eg Bind >= 9.2 uses .key-file)
-rw-r--r-- 1 root root 52 Jan 16 16:58 Kkey-test.+157+02315.key
-rw------- 1 root root 81 Jan 16 16:58 Kkey-test.+157+02315.private
A security-bug in older Bind version causes one of the files to be world-readable.
You should change the permissions by doing:
chmod og= Kkey*
Both files will hold a shared secret that you need to configure in your /etc/named.conf
key "key-test." {
algorithm hmac-md5;
secret "v9BhsbwDu4q95g/Gf/EiXA==";
};
If this is defined, you can start using this shared secret (between the server and the client)
in the definition of your zone-files.
zone "ddns.test.be" {
type master;
file "master/db.ddns.test.be";
allow-update { key "key-test."; };
};
Once this is defined, you can have everything in the zone-file being updated by the client.
We define something like this in /var/named/master/db.ddns.test.be.
$TTL 86400 ; 1 minute
@ IN SOA ddns.test.be. dag.wieers.com. (
2001072010 ; serial
10800 ; refresh (3 hours)
3600 ; retry (1 hour)
1814400 ; expire (3 weeks)
86400 ; minimum (1 day)
)
@ NS ns.test.be.
hostname 60 IN A 10.11.12.13
The next step is to make sure the client updates the zone-file everytime
its IP address changes. I have a configuration for pump and ppp or ADSL.
ntpdate from Bind < 9.2 uses Kkey-test.+157+02315.private,
newer versions use Kkey-test.+157+02315.key.
So be careful which file you supply.
Since Red Hat is deprecating the use of pump, I suggest to use this script:
/etc/dhcpcd/dhcpcd-eth0.exe
with contents:
#!/bin/bash
### Copyright 2001-2002 - Dag Wieers <dag@wieers.com>
### http://dag.wieers.com/howto/
### Local settings, must be changed
KEY="/etc/Kkey-test.+157+02315.private"
SERVER="ns.test.be"
ZONE="ddns.test.be"
NTPSERVERS="ntp.belnet.be brussels.belnet.be leuven.belnet.be"
### Default settings, may be changed
IF="eth0"
HOSTNAME="$(hostname | cut -d. -f1)"
LOGFILE="/var/log/nsupdate.log"
### Start of script
INFOFILE=${1:-/etc/dhcpcd/dhcpcd-$IF.info}
STATUS=${2:-new}
(
echo "$(date) Running $0 with arguments \"$*\""
echo "--------------"
if [ -r "$INFOFILE" ]; then
source "$INFOFILE"
else
echo "File $INFOFILE cannot be read."
echo "=============="
exit 98
fi
case "$STATUS" in
(up|new)
/usr/sbin/ntpdate -s -b $NTPSERVERS
cat "$INFOFILE"
echo "--------------"
cat <<EOF | nsupdate -d -k "$KEY"
server $SERVER
zone $ZONE
update delete $HOSTNAME
update add $HOSTNAME 60 A $IPADDR
send
EOF
RC=$?
echo
;;
(*)
RC=99
esac
if [ $RC != 0 ]; then
echo "--------------"
echo "$(date) Updating $HOSTNAME.$ZONE failed. (RC=$RC)"
fi
echo "=============="
) >>$LOGFILE 2>&1
exit $RC
For pump, I use the following configuration.
Add this before any device configuration blocks:
script /etc/pump.script
And add the following script as /etc/pump.script:
#!/bin/bash
### Copyright 2001-2002 - Dag Wieers <dag@wieers.com>
### http://dag.wieers.com/howto/
### Local settings, must be changed
KEY="/etc/Kkey-test.+157+02315.private"
SERVER="ns.test.be"
ZONE="ddns.test.be"
NTPSERVERS="ntp.belnet.be brussels.belnet.be leuven.belnet.be"
### Default settings, may be changed
HOSTNAME="$(hostname | cut -d. -f1)"
LOGFILE="/var/log/nsupdate.log"
### Start of script
STATUS=${1:-new}
IF=${2:-eth0}
IPADDR=${3:-1.2.3.4}
(
echo "$(date) Running $0 with arguments \"$*\""
echo "--------------"
case "$STATUS" in
(up|new)
/usr/sbin/ntpdate -s -b $NTPSERVERS
echo "IP address: $IPADDR"
echo "--------------"
cat <<EOF | nsupdate -d -k "$KEY"
server $SERVER
zone $ZONE
update delete $HOSTNAME
update add $HOSTNAME 60 A $IPADDR
send
EOF
RC=$?
echo
;;
(*)
RC=99
esac
if [ $RC != 0 ]; then
echo "--------------"
echo "$(date) Updating $HOSTNAME.$ZONE failed. (RC=$RC)"
fi
echo "=============="
) >>$LOGFILE 2>&1
exit $RC
For a ppp or adsl-connection, you could use /etc/ppp/ip-up.local much the same way.
Here is a modified script:
#!/bin/bash
### Copyright 2001-2002 - Dag Wieers <dag@wieers.com>
### http://dag.wieers.com/howto/
### Local settings, must be changed
KEY="/etc/Kkey-test.+157+02315.private"
SERVER="ns.test.be"
ZONE="ddns.test.be"
NTPSERVERS="ntp.belnet.be brussels.belnet.be leuven.belnet.be"
### Default settings, may be changed
HOSTNAME="$(hostname | cut -d. -f1)"
LOGFILE="/var/log/nsupdate.log"
### Start of script
IF=${1:-ppp0}
TTY=$2
SPEED=$3
IPADDR=${4:-1.2.3.4}
(
echo "$(date) Running $0 with arguments \"$*\""
echo "--------------"
/usr/sbin/ntpdate -s -b $NTPSERVERS
echo "IP address: $IPADDR"
echo "--------------"
cat <<EOF | nsupdate -d -k "$KEY"
server $SERVER
zone $ZONE
update delete $HOSTNAME
update add $HOSTNAME 60 A $IPADDR
send
EOF
RC=$?
echo
if [ $RC != 0 ]; then
echo "--------------"
echo "$(date) Updating $HOSTNAME.$ZONE failed. (RC=$RC)"
fi
echo "=============="
) >>$LOGFILE 2>&1
exit $RC