diff -r 6847290f1155 -r d3158de72598 update-serial --- a/update-serial Thu Dec 02 09:38:16 2010 +0100 +++ b/update-serial Thu Dec 02 16:46:17 2010 +0100 @@ -304,21 +304,239 @@ if (`rndc reload`) {print "** reload dns-server \n"}; } +sub to_begin_ro { + # gibt alle zonen mit abgelaufenen keycounter in die liste @begin_ro_list + our @begin_ro_list; + our $master_dir; + our $key_counter_end; + our @new_serial; + my $zone; + + while (<$master_dir/*>) { + chomp( $zone = $_ ); + my $key; + + unless (-f "$zone/.keycounter" ) {next;} + + open( KEY, "$zone/.keycounter" ) or die "$zone/.keycounter: $!\n"; + $key = ; + close(KEY); + + # vergleicht den wert aus der keycount-datei mit dem wert aus der + #dnstools.conf (key_counter_end) + if ( $key_counter_end <= $key ) { + $zone =~ s#($master_dir/)(.*)#$2#; + push @begin_ro_list, $zone; + } + } +} + +sub to_end_ro { + # funktion ueberprueft ob ein keyrollover fertig ist + # die bedingung dafuer ist das: + # - eine datei .index.zsk vorhanden ist + # - die datei .index.zsk vor mehr x stunden geaendert wurde + # - die datei .index.zsk ueber mehr als zwei zeilen gross ist + our $master_dir; + our @end_ro_list; + our $ablauf_zeit; + chomp( my $now_time = `date +%s` ); + + for (<$master_dir/*>) { + my $zone = $_; + $zone =~ s#($master_dir/)(.*)#$2#; + + my @index = (); + my $index_wc; + my @status; + + # prueft nach der ".index.zsk"-datei und erstellt den zeitpunkt + # an dem das key-rollover endet. - $status[9] + if ( -e "$master_dir/$zone/.index.zsk" ) { + @status = stat("$master_dir/$zone/.index.zsk"); + $status[9] += ( 3600 * $ablauf_zeit ); + } + else { next; } + + # $status[9] ist der zeitpunkt an dem der key-rollover endet + # prueft ob das key-rollover-ende erreicht ist + unless ( $status[9] < $now_time ) { next;} + + # prueft die anzahl der schluessel in der .index.zsk + open( INDEX, "$master_dir/$zone/.index.zsk" ) + or die "$master_dir/$zone/.index.zsk: $!\n"; + @index = ; + $index_wc = @index; + close(INDEX); + if ( $index_wc > 1 ) {push @end_ro_list, $zone;} + } +} + +sub begin_ro { + # anfang des key-rollovers + our @begin_ro_list; + our $master_dir; + our @new_serial; + + for ( &del_double( @begin_ro_list ) ) { + #erzeugt zsks + my $zone = $_; + my $zpf = "$master_dir/$zone"; + my @index; + + chdir "$zpf" or die "$zpf: $!\n"; + my $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`; + + open( INDEX, ".index.zsk" ) or die "$zpf/.index.zsk: $!\n"; + @index = ; + close(INDEX); + + push @index, $keyname; + if ( @index > 2 ) { shift(@index); } + + open( INDEX, ">.index.zsk" ) or die "$zpf/.index.zsk: $!\n"; + print INDEX @index; + close(INDEX); + + chomp($keyname); + print " * $zone: neuer ZSK $keyname erstellt\n"; + + open( KC, ">.keycounter" ) or die "$zpf/keycounter: $!\n"; + print KC "0"; + close(KC); + + &kill_useless_keys($zone); + &key_to_zonefile($zone); + push @new_serial, $zone; + } +} + +sub key_to_zonefile { + our $master_dir; + my $zone = $_[0]; + my $zpf = "$master_dir/$zone"; + my @old_content; + my @new_content = (); + + open(ZONEFILE, "<$zpf/$zone"); + @old_content = ; + close(ZONEFILE); + + for (@old_content) { + unless (m#INCLUDE.*key#) { push @new_content, $_; } + } + + for (<$zpf/*>) { + if (m#(.*\/)(K.*\.key)#) { + push @new_content, "\$INCLUDE \"$2\"\n"; + } + } + open( ZONEFILE, ">$zpf/$zone" ) or die "$zpf/$zone: $!\n"; + print ZONEFILE @new_content; + close(ZONEFILE); +} + +sub kill_useless_keys { + # die funktion loescht alle schluessel die nicht in der index.zsk + # der uebergebenen zone stehen + our $master_dir; + my $zone = $_[0]; + my @keylist = (); + my $zpf = "$master_dir/$zone"; + + open (INDEX, "<$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; + @keylist = ; + close(INDEX); + open (INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; + push @keylist, ; + + # kuerzt die schluessel-bezeichnung aus der indexdatei auf die id um sie + # besser vergleichen zu koennen. + for ( @keylist ) { + chomp; + s#K.*\+.*\+(.*)#$1#; + } + + # prueft alle schluesseldateien (ksk, zsk) ob sie in der jeweiligen + # indexdatei beschrieben sind. wenn nicht werden sie geloescht. + for (`ls $master_dir/$zone/K*[key,private]`) { + chomp; + my $file = $_; + my $rm_count = 1; + my $keyname; + for (@keylist) { + if ( $file =~ /$_/ ) { $rm_count = 0;} + } + if ($rm_count == 1) { + unlink "$file"; + if ($file =~ /$zpf\/(.*\.key)/ ) { + print " * $zone: Schluessel $1 entfernt \n"; + } + } + } +} + +sub end_ro { + our @end_ro_list; + our $master_dir; + our @new_serial; + my @content; + + for (@end_ro_list) { + my $zone = $_; + my $count = 0; + my @content; + my $last_key; + + open (INDEX, "<$master_dir/$zone/.index.zsk"); + @content = ; + close(INDEX); + + for (@content) { + $count++; + $last_key = $_; + } + if ($count > 1) { + open (INDEX, ">$master_dir/$zone/.index.zsk"); + print INDEX $last_key; + close (INDEX); + } + &kill_useless_keys($zone); + &key_to_zonefile($zone); + push @new_serial, $zone; + } +} + &read_conf; our %config; our @new_serial; # liste fuer neuen serial +our @begin_ro_list; # liste mit zonen deren key-rollover beginnt +our @end_ro_list; # liste mit zonen deren key-rollover fertig ist 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}; +our $key_counter_end = $config{key_counter_end}; +our $ablauf_zeit = $config{abl_zeit}; &add_argv; &changed_zone; &sign_end; +&to_begin_ro; # prueft nach beginnenden rollover-verfahren +&to_end_ro; # prueft nach endenden rollover-verfahren + +if (@begin_ro_list) { + &begin_ro; # eine rollover-beginn-sequenz +} + +if (@end_ro_list) { + &end_ro; # eine rollover-end-squenz +} + if (@new_serial) { &update_index; # index zone aktuallisieren &update_serial; # serial aktuallisieren @@ -328,4 +546,3 @@ &file_entry; # bearbeitet die file-eintraege der konfigurations-datei &mk_zone_conf; # konfiguration zusammenfuegen &server_reload; # server neu laden -