--- a/dnssec-killkey Tue Jul 27 09:48:25 2010 +0200
+++ b/dnssec-killkey Wed Jul 28 14:14:47 2010 +0200
@@ -1,77 +1,150 @@
-#!/bin/bash
+#!/usr/bin/perl -w
-source dnstools.conf
+use strict;
-master_dir=$MASTER_DIR # ordner fuer die einzelnen zonedateiordner
-ablauf_zeit=$ABL_ZEIT # zeit in minuten waehrend der 2 keys verwendet werden / ungefaehr doppelte TTL
+my $master_dir="/etc/bind/master"; # ordner fuer die einzelnen zonedateiordner
+my $ablauf_zeit="48"; # zeit fuer den key-rollover in h
+my $zone;
+my @status;
+my @auto;
+chomp (my $now_time=`date +%s`); # aktuelle unixzeit
+# prueft zonen aus ARGV und loescht das schluesselmaterial
+foreach (@ARGV) {
+ chomp ($zone = `idn --quiet $_`);
+ my $zdir = "$master_dir/$zone";
+ if (-e "$master_dir/$zone") {
-# loescht zu allen manuell eingegeben domains das schluesselmaterial
-for utf8domain in $@
-do
- domain=$(idn --quiet "$utf8domain")
+ if (-e "$zdir/$zone.signed") { `rm $zdir/$zone.signed`}
+ if (-e "$zdir/.keycounter") { `rm $zdir/.keycounter`}
+ if (-e "$zdir/.index.ksk") { `rm $zdir/.index.ksk`}
+ if (-e "$zdir/.index.zsk") { `rm $zdir/.index.zsk`}
+ if (-e "$zdir/dsset-$zone.") { `rm $zdir/dsset-$zone.`}
+ if (-e "$zdir/keyset-$zone.") { `rm $zdir/keyset-$zone.`}
+
+ foreach (`ls $master_dir/$zone/K*[key,private]`){ `rm $_`}
- if [ -d $master_dir/$domain ]
- then
- zdir="$master_dir/$domain"
+ } else {
+ print "$zone ist keine verwaltete zone \n";
+ }
+}
+
+# beendet den key-rollover
+foreach (`ls $master_dir`) {
+ chomp ($zone = $_);
+ my @index = ();
+ my $index_wc;
- [ -f $zdir/$domain.signed ] && rm $zdir/$domain.signed
- [ -f $zdir/keycounter ] && rm $zdir/keycounter
- [ -f $zdir/.index.ksk ] && rm $zdir/.index.ksk
- [ -f $zdir/.index.zsk ] && rm $zdir/.index.zsk
- [ -f $zdir/dsset-$domain. ] && rm $zdir/dsset-$domain.
- [ -f $zdir/keyset-$domain. ] && rm $zdir/keyset-$domain.
+ # 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; }
+
+ # prueft ob das key-rollover-ende erreicht ist
+ unless ($status[9] < $now_time ) {
+ next;
+ }
- for key in $zdir/K$domain*
- do
- rm $key
- done
+ # prueft die anzahl der schluessel in der ".index.zsk"
+ # loescht alte schluessel
+ open (INDEX, "$master_dir/$zone/.index.zsk");
+ @index = <INDEX>;
+ $index_wc = @index;
+ close (INDEX);
+ if ($index_wc > 1) {
+ open (INDEX, ">$master_dir/$zone/.index.zsk");
+ print INDEX $index[1];
+ close (INDEX);
+ push @auto, $zone;
+ }
- echo "Schluesselmaterial fuer $domain entfernt - mkready ausfuehren! "
- else
- echo $domain ist keine verwaltete Zone
- fi
-done
-
-
+ # prueft die anzahl der schluessel in der ".index.ksk"
+ # loescht alte schluessel
+ open (INDEX, "$master_dir/$zone/.index.ksk");
+ @index = <INDEX>;
+ $index_wc = @index;
+ close (INDEX);
+ if ($index_wc > 1) {
+ open (INDEX, ">$master_dir/$zone/.index.ksk");
+ print INDEX $index[1];
+ close (INDEX);
+ push @auto, $zone;
+ }
-cd $master_dir
-for domain in *
-do
+}
+
+# nach abgeschlossenem key-rollover werden fuer die entsprechende zone
+# unbenoetigte schluessel entfernt und die vorhandenen schluessel in die
+# zonedatei geschrieben.
+foreach (@auto) {
+ my $zone = $_;
+ my @old_zone_content = ();
+ my @new_zone_content = ();
+ my @keylist = ();
+ my $file;
- if ( find $master_dir/$domain -name "index*" -mmin +$ablauf_zeit >/dev/null ) # prueft die schluesselindexdateien
- then # auf zeitpunkt der aenderung
+ open (INDEX, "$master_dir/$zone/.index.zsk");
+ @keylist = <INDEX>;
+ close (INDEX);
+
+ open (INDEX, "$master_dir/$zone/.index.ksk");
+ push @keylist, <INDEX>;
+ close (INDEX);
+
+ open (ZONE, "$master_dir/$zone/$zone");
+ @old_zone_content = <ZONE>;
+ close (ZONE);
+
+ # kuerzt die schluessel-bezeichnung aus der indexdatei auf die
+ # id um sie besser vergleichen zu koennen.
+ foreach (@keylist) {
+ chomp;
+ s#K.*\+.*\+(.*)#$1#;
+ }
- cd $master_dir/$domain
- INDEX_FILE=`find . -name ".index*" -mmin +$ablauf_zeit` # schreibt eine liste INDEX_FILE aller
- # dateien die vor ABL_ZEIT erstellt worden
- for INDEX in $INDEX_FILE
- do
-
- if ( wc -l $INDEX | grep ^2 > /dev/null ) # prueft die indexdatei auf anzahl an eintraegen
- then
- INDEX=${INDEX#./}
- echo aktualisiert $INDEX in $domain
-
- DNS_KEY=`tail -n1 $INDEX` # speichert den letzten eintrag aus dem
- # index in die variable DNS_KEY
-
- echo $DNS_KEY > $master_dir/$domain/$INDEX # schreibt nur die variable
- # DNS_KEY in die indexdatei
+ # filtert alle schluessel aus der zonedatei
+ # old_zone_content ==> new_zone_content
+ foreach (@old_zone_content) {
+ unless (/IN\sDNSKEY/) {
+ push @new_zone_content, $_;
+ }
+ }
+
+ # prueft alle schluesseldateien (ksk, zsk) ob sie in der jeweiligen
+ # indexdatei beschrieben sind. wenn nicht werden sie geloescht.
+ foreach (`ls $master_dir/$zone/K*[key,private]`){
+ chomp;
+ $file = $_;
+ my $rm_count = 1;
+
+ foreach (@keylist) {
+
+ if ($file =~ /$_/) {
+ $rm_count = 0;
+
+ # schluessel die in der indexdatei standen, werden an die
+ # zonedatei angehangen.
+ if ($file =~ /.*key/) {
+ open (KEYFILE, "$file");
+ push @new_zone_content, <KEYFILE>;
+ close (KEYFILE);
+
+ last;
+ }
+ }
+ }
+
+ #loescht alle unbenoetigten schluessel
+ if ($rm_count == 1) {
+ print `rm -f $file`;
+ }
+ }
+
+ open (ZONE, ">$master_dir/$zone/$zone");
+ print ZONE @new_zone_content;
+ close (ZONE);
- rm $(ls K*[key,private] | grep -v "`cat .index.zsk`" | \
- grep -v "`cat .index.ksk`") 2> /dev/null # loesche alle schluessel die nicht in der indexdatei
- # stehen
- mv $domain .$domain
- grep -v 'DNSKEY' .$domain >> $domain # erzeugt ein backup und entfernt alle schluessel
- # aus der zonedatei
- cat K$domain.*key >>$domain # schreibt die aktuellen schluessel in die zonedatei
-
- key_counter=`< keycounter`
- dnssec-signzone $domain && echo $[ key_counter + 1 ] > keycounter
- fi
-
-
- done
- fi
-done
+ print "$master_dir/$zone/$zone wurde neu erstellt \n";
+}