From a11b90b7218e1e2d218da307554a5bd99eaca2f9 Mon Sep 17 00:00:00 2001 From: Frederik Lindenaar <frederik@lindenaar.nl> Date: Mon, 5 Aug 2019 20:58:32 +0200 Subject: [PATCH] small improvements + configurable DNSDomain - fixed handling of expiry - fixed calculation of expiry period - reduced CNAME checks / lookups to when really needed --- dyndns.cfg.dist | 8 ++++++++ dyndns.pl | 56 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/dyndns.cfg.dist b/dyndns.cfg.dist index bcb9446..955be56 100644 --- a/dyndns.cfg.dist +++ b/dyndns.cfg.dist @@ -6,6 +6,14 @@ # DNS Settings #dns_server = 192.168.1.1 # DNS Server to communicate with (use IP!) +dns_domain = ?, !, 1 # DNS Domain to support, match hostname with: + # '?' - take domain name from parameter 'domain' + # '!' - take domain name from virtualhost name + # positive number - last # parts from hostname + # negative number - last # parts from virtualhost + # any other string - use if hostname ends on this + + #expand_cnames = 1 # CNAME levels to expand (0 to disable) #require_rr = # Require existing record of this type to update #replace_rr = A, AAAA, TXT # Records types to replace (clear) during update diff --git a/dyndns.pl b/dyndns.pl index a3e83b3..c0971dd 100755 --- a/dyndns.pl +++ b/dyndns.pl @@ -31,6 +31,12 @@ my $ConfigFile = 'optional'; # hardcoded, either optional, required or ignore ############################## # Configuration section (defaults, can be set in config file) my $DNSServer = '192.168.1.1'; # DNS Server to communicate with (use IP!) +my @DNSDomain = ( '?', '!', 0 ); # DNS Domain to support, matches hostname with: + # '?' - take domain name from parameter 'domain' + # '!' - take domain name from virtualhost name + # positive number - last # parts from hostname + # negative number - last # parts from virtualhost + # any other string - use if hostname ends on this my $ExpandCNAMEs = 1; # CNAME levels to expand (0 to disable) my $AllowDebugKey = 'off'; # Debuging, 'off' to disable, '' for always on # and other values to enable with debug= param. @@ -63,8 +69,8 @@ sub periodSeconds($) { my ($number, $units) = ($_[0]=~/^(\d+)([smhdw])?$/); if($number && $units && $units cmp 's') { $number *= ($units eq 'm') ? 60 # Seconds per minute - : ($units cmp 'h') ? 3600 # Seconds per hour - : ($units cmp 'd') ? 86400 # Seconds per day + : ($units eq 'h') ? 3600 # Seconds per hour + : ($units eq 'd') ? 86400 # Seconds per day : 604800; # Seconds per week } return $number; @@ -222,8 +228,9 @@ sub DNS_Update($$$$$$$) { ############################## # Handlers for the different requests -sub handle_update($$$$$) { - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; +sub handle_update($$$$) { + my ($mode, $host, $dnsdomain, $debug) = @_; + my $dnshost = expand_CNAME($host); my ($signer, $key) = get_authinfo($cgi, $host); # perform the action @@ -251,8 +258,8 @@ sub handle_update($$$$$) { } -sub handle_expire($$$$$) { - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; +sub handle_expire($$$$) { + my ($mode, $host, $dnsdomain, $debug) = @_; my ($signer, $key) = get_authinfo($cgi, $host); my $debugmsg = ($debug) ? "\n" : ''; @@ -269,7 +276,7 @@ sub handle_expire($$$$$) { if($rr->type eq 'TXT' && $rr->txtdata=~/$UpdateTXT(.*\d\d:\d\d:\d\d \d{4})$/){ if(my $lastupdate = parse_localtime($1)) { - DNS_Update($dnsdomain, $dnshost, undef, undef, $signer, $key, $debug) + DNS_Update($dnsdomain, $rr->name, undef, undef, $signer, $key, $debug) unless($lastupdate > $validafter); if($debug) { $debugmsg .= ($lastupdate > $validafter) ? 'Keeping ' : 'Expiring '; @@ -286,8 +293,9 @@ sub handle_expire($$$$$) { } } -sub handle_view($$$$$) { - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; +sub handle_view($$$$) { + my ($mode, $host, $dnsdomain, $debug) = @_; + my $dnshost = expand_CNAME($host); my $title = "DynDNS Updater - $host"; print $cgi->header(-status=>200), $cgi->start_html(-title => $title), @@ -310,8 +318,8 @@ sub handle_view($$$$$) { print $cgi->end_html(); } -sub handle_list($$$$$) { - my ($mode, $host, $dnshost, $dnsdomain, $debug) = @_; +sub handle_list($$$$) { + my ($mode, $host, $dnsdomain, $debug) = @_; my $title = "DynDNS Updater - $dnsdomain"; print $cgi->header(-status=>200), @@ -345,7 +353,8 @@ if ($ConfigFile cmp 'ignore') { $CFGFile =~ s/(\.pl)?$/.cfg/; if (open (CONFIG, $CFGFile)) { my %CONFIG = ( - allow_debug_key => \$AllowDebugKey, dns_server => \$DNSServer, + allow_debug_key => \$AllowDebugKey, + dns_server => \$DNSServer, dns_domain => \@DNSDomain, expand_cnames => \$ExpandCNAMEs, auth_mode => \$AuthMode, static_signer => \$StaticSigner, static_key => \$StaticKey, require_rr => \$RequireRR, replace_rr => \@ReplaceRR, @@ -399,6 +408,20 @@ foreach my $rrtype (@ReplaceRR) { my $mode = $cgi->path_info || $cgi->param('mode') || 'view'; $mode=~s/^\/([^\/]+)(\/(.*))?/$1/; my $host = $cgi->param('host') || $3; +my $dnsdomain; +foreach my $d (@DNSDomain) { + if ($d eq '!') { $d = $cgi->virtual_host; } + elsif ($d eq '?') { $d = $cgi->param('domain'); } + elsif ($d =~ /-?\d+/) { + if ($d <0) { $d = join('.', splice([ split(/\./, $cgi->virtual_host) ], $d)); } + else { $d = join('.', splice([ split(/\./, $host) ], ($d) ? -$d : 1)); } + } + $dnsdomain = $d if ($host && length($host) == length($d)+rindex($host,$d)); + last if $dnsdomain; +} +fail($PE, "No host name to act on specified", 400) + unless $host || $mode eq 'list' || $mode eq 'expire'; +fail($PE, "No host or domain name to act on specified", 400) unless $dnsdomain; ############################## @@ -410,13 +433,8 @@ my %handlers = ( list => \&handle_list, expire => \&handle_expire, ); -if($host eq '' and $mode cmp 'list' and $mode cmp 'expire') { - fail($PE, "No host name to act on specified", 400); -} elsif(my $handler = $handlers{$mode}) { - # Replace provided host with that of a CNAME it points to and determine domain - my $dnshost = ($host) ? expand_CNAME($host) : undef; - my $dnsdomain = $cgi->param('domain') || ($dnshost=~/\.(.*)$/)[0]; - $handler->($mode, $host, $dnshost, $dnsdomain, $debug); +if(my $handler = $handlers{$mode}) { + $handler->($mode, $host, $dnsdomain, $debug); } else { fail("File Not Found", "Invalid Mode '$mode' specified", 404); } -- libgit2 0.22.2