update-serial
branchhs12
changeset 39 8b46e7c48995
parent 38 d50f6874b7ab
child 40 512e12c40389
--- a/update-serial	Fri Dec 03 16:42:12 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,549 +0,0 @@
-#!/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 (<CONFIG>) {
-        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
-    ## <zone>.signed-datei den zeitpunkt in $time mit dem ablaufdatum der
-    ## signatur, welcher aus der datei <zone>.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 = <ZONE>;
-            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 = <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 (<SER>) {
-            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 <FROM>;
-        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 = <INDEXZONE>;
-    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 = <FILE>;
-            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 = <FILE>;
-            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"};
-}
-
-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 = <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>;
-        $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 = <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 {
-    # die funktion fugt alle schluessel in eine zonedatei
-    our $master_dir;
-    my $zone = $_[0];
-    my $zpf = "$master_dir/$zone";
-    my @old_content;
-    my @new_content = ();
-
-    open(ZONEFILE, "<$zpf/$zone");
-    @old_content = <ZONEFILE>;
-    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 = <INDEX>;
-    close(INDEX);
-    open (INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n";
-    push @keylist, <INDEX>;
-
-    # 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 = <INDEX>;
-        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
-    &sign_zone; # zone signieren
-}
-
-&file_entry;  # bearbeitet die file-eintraege der konfigurations-datei
-&mk_zone_conf; # konfiguration zusammenfuegen
-&server_reload; # server neu laden