Here's how to set up BIND to accept a dynamic update from a particular host. We do this at Freelock to provide dynamic DNS service for our clients who need to be able to connect to an office machine on a dynamic IP address.
There are two sides to this: Server side, and Client side. We use a symmetrical key to authenticate the client request before allowing an update. Both sides have the same key--the client stores it in a .private file, the server in the BIND configuration. This key should be kept confidential. It is possible to use assymetrical keys, but that involves reconfiguring the zone for dns security. See http://ops.ietf.org/dns/dynupd/secure-ddns-howto.html for more on this--look for sig[0] signatures.
- Generate a key using dns-keygen. Use the host name for the key name:
[root@foraker root]# dnssec-keygen -a HMAC-MD5 -b 512 -n HOST hunter.freelock.lan.
Khunter.freelock.lan.+157+33318
[root@foraker root]#
[root@foraker root]# cat Khunter.freelock.lan.+157+33318.private
Private-key-format: v1.2
Algorithm: 157 (HMAC_MD5)
Key: GY/VSVYP0SsinjUoycawYhUJlgdiFgKnIItGDfIlqbZfafsHJLm238PxApCH48pPk9tGkt/bs9ctiII+FRsCgA==
[root@foraker root]#
key hunter.freelock.lan. {
algorithm hmac-md5;
secret "GY/VSVYP0SsinjUoycawYhUJlgdiFgKnIItGDfIlqbZfafsHJLm238PxApCH48pPk9tGkt/bs9ctiII+FRsCgA==";
};
-
In the zone definition, add an update-policy for the key:
zone "freelock.lan" {
type master;
file "freelock.lan.hosts";
update-policy {
grant hunter.freelock.lan. self hunter.freelock.lan.;
};
}; - Reload BIND.
-
Create a test action file (nsupdate.action):
server ns.freelock.lan
zone freelock.lan
update delete hunter.freelock.lan. A
update add hunter.freelock.lan. 86400 A 10.10.10.1
show
send -
Test the action:
nsupdate -k Khunter.freelock.lan.+157+33318.private -v nsupdate.action - Now set up the script!
// first, the host name to update dynamically.
define(HOST, 'hunter.freelock.lan');
// The zone to update.
define(NAME_ZONE, 'freelock.lan');
// The authoritative name server for this zone.
define(NAME_SERVER, 'baker.freelock.lan');
// The file that contains the key that allows us to update...
define(NS_KEY_FILE, 'Khunter.freelock.com.+157+33318.private');
// How long should DNS servers cache this record?
define(TIMEOUT, '3600');
// Address to notify on IP address change
$ip_email = 'notice@freelock.com';
// settings below shouldn't need to change much, as long as this
// is stored in the same place (we use /var/www/conf).
/* note: uptime code stripped out of this file--requires db */
// URL that returns our public IP address so this works behind a firewall
define(EZ_CHECK, 'http://baker.freelock.com/up_ip.php');
// set to directory where this script lives.
chdir('/var/www/conf');
// temporary files so we know what happened last time--these should be writable
// by whatever process is running this script, and relative to the directory
// just specified.
define(EZ_FILE, 'status/last_router_ip');
define(NS_ACTION_FILE, 'status/nsupdate.action');
}<br/>
else //file didn't exist<br/>
{<br/>
$changed=true;<br/>
}<br/>
if ($changed && !$get_error)<br/>
{<br/>
// now do the actual update. First, create an action file:<br/>
$fp = fopen(NS_ACTION_FILE,'w');<br/>
fwrite($fp, 'server '.NAME_SERVER.'<br/>
zone '.NAME_ZONE.'
update delete '.HOST.'. A
update add '.HOST.'. '.TIMEOUT.' A '.$currentIP.'
show
send
');
fclose($fp);
$keyfilename = NS_KEY_FILE;
$nsaction = NS_ACTION_FILE;
$out = nsupdate -k $keyfilename -v $nsaction
;
$fp = fopen(EZ_FILE, 'w');<br/>
fwrite($fp, $currentIP);<br/>
fclose($fp);<br/>
mail($ip_email, $host .' IP Address Change', $currentIP. ' -now<br/>
' . $oldIP[0] . ' -before
' . $out);
}<br/>
?>