DynDNS provides an account level key which can be used to update DNS hosts instead of our HTTP-based DNS Update API. You can generate and obtain your key from your TSIG account settings page. Your account must be a paid account to use this mechanism.
TSIG updates are a mechanism to transport zone updates over a secured
mechanism. This feature is available for paid accounts (Account Upgrades
and Custom DNS) and can be used with nsupdate or with
dhcpd. For more information on this mechanism, please see
RFC 2845 and the
Wikipedia page for TSIG.
TTL values are only respected for Custom DNS hosts.
To update a DNS Server dynamically using TSIG for authorization, run nsupdate by doing the following:
$ nsupdate -d > server update.dyndns.com > zone $ZONE > key $KEY_NAME $KEY_HMAC > update add $HOST.$ZONE 60 A 10.0.0.1 > send > quit
For dynamic DNS hosts, $ZONE should be the third level DNS name like myhost.dyndns.org
You can also use this sample Perl script using Net::DNS as an example for your applications to perform updates.
#!/usr/bin/perl
use warnings;
use strict;
use MIME::Base64;
use Net::DNS;
use Net::DNS::Update;
use Net::DNS::Resolver;
# Your account info
my $key_name = "";
my $key_hmac = "";
my $host = "";
# DynDNS server information
my $tsig_server = 'update.dyndns.com';
my $tsig_server_pt = '53';
# Create update packet, only updates are permitted
my $update = Net::DNS::Update->new($host);
$update->push("update", rr_add("$host A 1.2.3.4"));
### End Configuration ###
$update->sign_tsig($key_name, $key_hmac);
my $res = Net::DNS::Resolver->new(
port => $tsig_server_pt,
nameservers => [ $tsig_server ],
debug => 0,
);
my $pack = Net::DNS::Packet->new(\($update->data));
my $mac = $pack->{additional}[-1]->mac;
my $mac_size = $pack->{additional}[-1]->mac_size;
my $time = $pack->{additional}[-1]->time_signed;
my $reply = $res->send($update);
if ($reply) {
if ($reply->header->rcode eq 'NOERROR') {
print "Update succeeded, verifying source.\n";
my $tsigRR = $reply->{additional}[0];
delete $reply->{additional};
$reply->sign_tsig($key_name, $key_hmac);
# Net::DNS::RR::TSIG should be handling this for us...
my $size = unpack("H*", pack('n', $mac_size));
$reply->{additional}[-1]->{request_mac} = $size . $mac;
$reply->{additional}[-1]->{time_signed} = $time;
my $packet = Net::DNS::Packet->new(\($reply->data));
if ($packet->{additional}[-1]->{mac} eq $tsigRR->{mac}) {
print "Verified!\n";
} else {
print "Failed! Potential man in the middle attack!\n";
}
} else {
print 'Update failed: ', $reply->header->rcode, $reply->{additional}[-1]->{error}, "\n";
}
} else {
print 'Update failed: ', $res->errorstring, "\n";
}