# HG changeset patch # User asuess@dns.net.schlittermann.de # Date 1291279096 -3600 # Node ID 6847290f115593260499309aebadf128739a0575 # Parent b809ae6c2f5763b046c69b604d837fd86a82b40f added update-serial diff -r b809ae6c2f57 -r 6847290f1155 dnstools.conf --- a/dnstools.conf Fri Oct 15 11:04:37 2010 +0200 +++ b/dnstools.conf Thu Dec 02 09:38:16 2010 +0100 @@ -3,7 +3,7 @@ zone_conf_dir = /etc/bind/zones.d # Verzeichnis für die Zonen-Konfigurationdateien key_counter_end = 40 # Anzahl der Signierungen bis zum Key-Rollover -sign_alert_time = 144 # Warn-Zeitraum vor dem Ablauf einer Zone-Signatur in h +sign_alert_time = 168 # Warn-Zeitraum vor dem Ablauf einer Zone-Signatur in h abl_zeit = 24 # Dauer des Key-Rollover (2 Schluessel) in h secondary = hh.schlittermann.de diff -r b809ae6c2f57 -r 6847290f1155 update-serial --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/update-serial Thu Dec 02 09:38:16 2010 +0100 @@ -0,0 +1,331 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use FindBin; +use File::Basename; + +sub del_double { + # entfernt doppelte eintraege in einer liste + my %all; + grep { $all{$_} = 0 } @_; + return ( keys %all ); +} + +sub read_conf { + # liest die Konfiguration ein + my @configs = ( "$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf" ); + our %config; + + for ( grep {-f} @configs ) { + open( CONFIG, $_ ) or die "Can't open $_: $!\n"; + } + unless ( seek( CONFIG, 0, 0 ) ) { + die "Can't open config (searched: @configs)\n"; + } + while () { + chomp; + s/#.*//; + s/\t//g; + s/\s//g; + + next unless length; + my ( $cname, $ccont ) = split( /\s*=\s*/, $_, 2 ); + $config{$cname} = $ccont; + } + close(CONFIG); +} + +sub add_argv { + # prueft ob zonen aus ARGV verwaltete zonen sind + # und fuegt sie, falls ja in die liste @new_serial ein + our @new_serial; + our $master_dir; + my $zone; + + for (@ARGV) { + chomp( $zone = `idn --quiet "$_"` ); + if ( -e "$master_dir/$zone/$zone" ) { + push @new_serial, $zone; + } + } +} + +sub changed_zone { + our $master_dir; + our @new_serial; + + for (<$master_dir/*>) { + my $zone = basename($_); + + if (-e "$master_dir/$zone/.stamp") { + my $stamptime = (-M "$master_dir/$zone/.stamp"); + my $filetime = (-M "$master_dir/$zone/$zone"); + if ($stamptime > $filetime) { + push @new_serial, $zone; + print " * $zone: zonedatei wurde geaendert\n"; + } + } + else { + print " * $zone: keine .stamp-datei gefunden\n"; # NOCH IN NEW_SERIAL PUSHEN + push @new_serial, $zone; + } + } + +} + +sub sign_end { + our $sign_alert_time; # die zeit zwischen dem ende und der neuen + # signierung (siehe externe konfiguration) + our $master_dir; + our @new_serial; + + # erzeugt $time (die zeit ab der neu signiert werden soll) + chomp( my $unixtime = `date +%s` ); + $unixtime = $unixtime + ( 3600 * $sign_alert_time ); + my $time = `date -d \@$unixtime +%Y%m%d%H`; + + ## vergleicht fuer alle zonen im ordner $master_dir mit einer + ## .signed-datei den zeitpunkt in $time mit dem ablaufdatum der + ## signatur, welcher aus der datei .signed ausgelesen wird. + for (<$master_dir/*>) { + s#($master_dir/)(.*)#$2#; + my $zone = $_; + + if ( -e "$master_dir/$zone/$zone.signed" ) { + open( ZONE, "$master_dir/$zone/$zone.signed" ); + my @zone_sig_content = ; + close(ZONE); + + for (@zone_sig_content) { + if (m#SOA.*[0-9]{14}#) { + s#.*([0-9]{10})([0-9]{4}).*#$1#; + if ( $_ < $time ) { + push @new_serial, $zone; + } + } + } + } + } +} + +sub sign_zone { + # signiert die zonen und erhoeht den wert in der keycounter-datei + our @new_serial; + our $master_dir; + my $zone; + my $kc; + + for ( &del_double( @new_serial ) ) { + $zone = $_; + + unless (-e "$master_dir/$zone/.index.zsk") { + next; + } + + chdir "$master_dir/$zone"; + if (`dnssec-signzone $zone 2>/dev/null`) { + print " * $zone neu signiert \n"; + + # erhoeht den keycounter + if ("$master_dir/$zone/.keycounter") { + open( KC, "$master_dir/$zone/.keycounter" ); + $kc = ; + close(KC); + $kc += 1; + } + else { + $kc = 1; + } + open( KC, ">$master_dir/$zone/.keycounter" ); + print KC $kc; + close(KC); + } + else { print "$zone konnte nicht signiert werden \n"; } + } +} + +sub update_serial { + our $master_dir; + our @new_serial; + chomp (my $date = `date +%Y%m%d`); + my @new_content; + my $sdate; + my $scount; + my $serial; + + for ( &del_double( @new_serial ) ) { + # erhoeht den serial + my $zone = $_; + my $file = "$master_dir/$zone/$zone"; + my @new_content = (); + + open (SER, "<$file") or die "$file: $!\n"; + for () { + if (/^\s+(\d+)(\d{2})\s*;\s*serial/i) { + $sdate = $1; + $scount = $2; + $serial = "$sdate$scount"; + if ( $date eq $sdate ) { + $scount++; + } + else { + $sdate = $date; + $scount = "00"; + } + } + if ($serial) { + s/$serial/$sdate$scount/; + } + push @new_content, $_; + } + close (SER); + + open (RES, ">$file") or die "$file: $!\n"; + print RES @new_content; + close (RES); + print " * $zone: serial erhoeht \n"; + + open(STAMP, ">$master_dir/$zone/.stamp") or die "$master_dir/$zone/.stamp: $!\n"; + close(STAMP); + print " * $zone: stamp aktualisiert \n"; + } +} + +sub mk_zone_conf { + # erzeugt eine named.conf-datei aus den entsprechenden vorlagen. + our $bind_dir; + our $conf_dir; + + open( TO, ">$bind_dir/named.conf.zones" ) + or die "$bind_dir/named.conf.zones: $!\n"; + while (<$conf_dir/*>) { + open( FROM, "$_" ) or die "$_: $! \n"; + print TO ; + close(FROM); + } + close(TO); + print "** zonekonfiguration erzeugt\n"; +} + +sub update_index { + # aktualisiert die indexzone; + our @new_serial; + our $indexzone; + our $master_dir; + my @iz_content_old; + my @iz_content_new; + + open (INDEXZONE, "$master_dir/$indexzone/$indexzone") + or die "$master_dir/$indexzone/$indexzone: $!\n"; + @iz_content_old = ; + close (INDEXZONE); + + for (@iz_content_old) { + unless (m#ZONE::#) { + push @iz_content_new, $_; + } + } + + for my $dir ( glob "$master_dir/*" ) { + my $zone = basename($dir); + my $info_end = "::sec-off"; + + if (-e "$dir/.keycounter") { + $info_end = "::sec-on"; + } + + my $iz_line = "\t\tIN TXT\t\t\"ZONE::$zone$info_end\"\n"; + + push @iz_content_new, $iz_line; + } + + open (INDEXZONE, ">$master_dir/$indexzone/$indexzone") + or die "$master_dir/$indexzone/$indexzone: $!\n"; + print INDEXZONE @iz_content_new; + close (INDEXZONE); + + # fuegt die index-zone in die liste damit der serial erhoet wird + push @new_serial, $indexzone; + + print "** index-zone aktualisiert \n"; +} + +sub file_entry { + # prueft jede domain, die ein verzeichnis in $master_dir hat, ob sie + # dnssec nutzt. + # passt die eintraege in $config_file falls noetig an. + our $master_dir; + our $conf_dir; + + while (<$master_dir/*>) { + s#($master_dir/)(.*)#$2#; + my $zone = $_; + my $zone_file = "$master_dir/$zone/$zone"; + my $conf_file = "$conf_dir/$zone"; + my @c_content; + + unless ( -f "$conf_file" ) { + die "$conf_file: $! \n"; + } + + if ( -e "$master_dir/$zone/.keycounter" ) { + open( FILE, "<$conf_file" ) or die "$conf_file: $!\n"; + @c_content = ; + close(FILE); + for (@c_content) { + if (m{(.*)($zone_file)(";)}) { + print " * zonekonfiguration aktualisiert ($2 ==> $2.signed)\n"; + $_ = "$1$2.signed$3\n"; + } + } + open( FILE, ">$conf_file" ) or die "$conf_file: $!\n"; + print FILE @c_content; + close(FILE); + } + else { + open( FILE, "<$conf_file" ) or die "$conf_file: $!\n"; + @c_content = ; + close(FILE); + for (@c_content) { + if (m{(.*)($zone_file)\.signed(.*)}) { + print " * zonekonfiguration aktualisiert ($2.signed ==> $2)\n"; + $_ = "$1$2$3\n"; + } + } + open( FILE, ">$conf_file" ) or die "$conf_file: $!\n"; + print FILE @c_content; + close(FILE); + } + } +} + +sub server_reload { + if (`rndc reload`) {print "** reload dns-server \n"}; +} + + +&read_conf; + +our %config; +our @new_serial; # liste fuer neuen serial +our $master_dir = $config{master_dir}; +our $bind_dir = $config{bind_dir}; +our $conf_dir = $config{zone_conf_dir}; +our $sign_alert_time = $config{sign_alert_time}; +our $indexzone = $config{indexzone}; + +&add_argv; +&changed_zone; +&sign_end; + +if (@new_serial) { + &update_index; # index zone aktuallisieren + &update_serial; # serial aktuallisieren + &sign_zone; # zone signieren +} + +&file_entry; # bearbeitet die file-eintraege der konfigurations-datei +&mk_zone_conf; # konfiguration zusammenfuegen +&server_reload; # server neu laden +