From de9fee6eec828e95ff39469efc77a5121609c6bd Mon Sep 17 00:00:00 2001 From: Daniel Roethlisberger Date: Sun, 27 Apr 2014 20:03:38 +0200 Subject: [PATCH] Add nsupdate(1) support The 'nsupdate' protocol is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server using the 'nsupdate' command line utility part of ISC BIND. Dynamic DNS updates allow resource records to be added or removed from a zone configured for dynamic updates through DNS requests protected using TSIG. BIND ships with 'ddns-confgen', a utility to generate sample configurations and instructions for both the server and the client. See nsupdate(1) and ddns-confgen(8) for details. --- README.md | 1 + ddclient | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/README.md b/README.md index a9a345c..d7eb970 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Dynamic DNS services currently supported include: Freedns - See http://freedns.afraid.org/ for details ChangeIP - See http://www.changeip.com/ for details dtdns - See http://www.dtdns.com/ for details + nsupdate - See nsupdate(1) and ddns-confgen(8) for details DDclient now supports many of cable/dsl broadband routers. diff --git a/ddclient b/ddclient index 0acc8eb..1b9d3ef 100755 --- a/ddclient +++ b/ddclient @@ -429,6 +429,10 @@ my %variables = ( 'login' => setv(T_LOGIN, 0, 0, 0, 'unused', undef), 'client' => setv(T_STRING, 0, 1, 1, $program, undef), }, + 'nsupdate-common-defaults' => { + 'ttl' => setv(T_NUMBER, 0, 1, 0, 600, undef), + 'zone' => setv(T_STRING, 1, 1, 1, '', undef), + }, ); my %services = ( 'dyndns1' => { @@ -573,6 +577,16 @@ my %services = ( $variables{'service-common-defaults'}, ), }, + 'nsupdate' => { + 'updateable' => undef, + 'update' => \&nic_nsupdate_update, + 'examples' => \&nic_nsupdate_examples, + 'variables' => merge( + { 'login' => setv(T_LOGIN, 1, 0, 1, '/usr/bin/nsupdate', undef), }, + $variables{'nsupdate-common-defaults'}, + $variables{'service-common-defaults'}, + ), + }, ); $variables{'merged'} = merge($variables{'global-defaults'}, $variables{'service-common-defaults'}, @@ -3765,6 +3779,108 @@ sub nic_dtdns_update { } } +###################################################################### +## nic_nsupdate_examples +###################################################################### +sub nic_nsupdate_examples { + return < ## fully qualified hostname to update + +Example ${program}.conf file entries: + ## single host update + protocol=nsupdate \\ + server=ns1.example.com \\ + password=/etc/${program}/dyn.example.com.key \\ + zone=dyn.example.com \\ + ttl=3600 \\ + myhost.dyn.example.com + +EoEXAMPLE +} + +###################################################################### +## nic_nsupdate_update +## by Daniel Roethlisberger +###################################################################### +sub nic_nsupdate_update { + debug("\nnic_nsupdate_update -------------------"); + + ## group hosts with identical attributes together + my %groups = group_hosts_by([ @_ ], [ qw(login password server zone) ]); + + ## update each set of hosts that had similar configurations + foreach my $sig (keys %groups) { + my @hosts = @{$groups{$sig}}; + my $hosts = join(',', @hosts); + my $h = $hosts[0]; + my $binary = $config{$h}{'login'}; + my $keyfile = $config{$h}{'password'}; + my $server = $config{$h}{'server'}; + my $zone = $config{$h}{'zone'}; + my $ip = $config{$h}{'wantip'}; + delete $config{$_}{'wantip'} foreach @hosts; + + info("setting IP address to %s for %s", $ip, $hosts); + verbose("UPDATE:","updating %s", $hosts); + + ## send separate requests for each zone with all hosts in that zone + my $instructions = <