dnssec-creatkey
changeset 19 2c3bcb280768
parent 13 4844031fc55e
child 20 5b52190d8750
--- a/dnssec-creatkey	Thu Jul 22 12:44:14 2010 +0200
+++ b/dnssec-creatkey	Tue Jul 27 09:48:25 2010 +0200
@@ -1,104 +1,174 @@
-#!/bin/bash
-set -e
+#!/usr/bin/perl -w
+
+use strict;
 
-#import aus der dnstools.conf
-source dnstools.conf
-master_dir=$MASTER_DIR
-key_counter_end=$KEY_COUNTER_END
+my $master_dir="/etc/bind/master";	# verzeichnis fuer bind
+my $key_counter_end="2";		# ablauf des schluessels
+my @zones = `ls $master_dir`;	# alle verwalteten zonen
+my @change;			# liste abgelaufener zonen
+my @manu;			# liste manuell eingegebener zonen aus ARGV
+my @index;
+my $zone;
+my $keyname;
+
+# prueft ob eingaben in ARGV domains sind und gibt sie in die liste @manu
+foreach (@ARGV) {
+	chomp ($zone = `idn --quiet "$_"`);
 
+	if (-e "$master_dir/$zone") {
+		push (@manu, $zone);
+	} else {
+		print " $zone ist keine verwaltete zone \n ";
+	}
+}
+	
+# gibt alle zonen mit abgelaufenen keycounter in die liste @change
+foreach (@zones) {
+	chomp ($zone = $_);
+	my $key;
 
-# gibt alle zonen ohne zsk in die standard-ausgabe
-function test_zsk_new {
-	for zone in $master_dir/*
-	do
-		test -f $zone/${zone##*/}.signed || continue
-		test -f $zone/.index.zsk || echo ${zone##/*/}
-	done
+	if (-e "$master_dir/$zone/.keycounter") {
+
+		open (KEY, "$master_dir/$zone/.keycounter");
+		$key = <KEY>;
+		close (KEY);
+
+		if ($key_counter_end < $key) {
+			push (@change, $zone);
+		}
+	}
 }
 
+#erzeugt zsks
+foreach (@change, @manu) {
+	$zone = $_;
 
-# gibt alle zonen ohne ksk in die standard-ausgabe
-function test_ksk_new {
-	for zone in $master_dir/*
-	do
-		test -f $zone/${zone##*/}.signed || continue
-		test -f "$zone/.index.ksk" || echo ${zone##/*/}
-	done
+	chdir "$master_dir/$zone" or die "chdir nach / nicht moeglich: $1";
+	$keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`;
+
+	if (-e ".index.zsk") {
+		open (INDEX, ".index.zsk");
+		@index = <INDEX>;
+		close (INDEX);
+	} else {
+		@index = ();
+	}
+
+	push @index, $keyname;
+	if (@index > 2){
+		shift (@index);
+	}
+
+	open (INDEX, ">.index.zsk");
+	print INDEX @index;
+	close (INDEX);
+
+	chomp ($keyname);
+	print "$keyname (ZSK) erzeugt fuer $zone \n";
+
+	open (KC, ">.keycounter");
+	print KC "0";
+	close (KC);
 }
 
+#erzeugt ksks
+foreach (@manu) {
+	$zone = $_;
 
-# gibt alle zonen mitabgelaufenen keycounter in die standardausgabe
-function test_zsk_time {		# prueft den keycounter
-	for zone in $master_dir/*
-	do
-		test -f $zone/${zone##*/}.signed || continue
-		test -f $zone/keycounter || echo 0 > $zone/keycounter
-		key_counter=`< $zone/keycounter`
-	
-		if [ $key_counter_end -le $key_counter ]
-		then
-			echo ${zone##/*/} 
-		fi
-	done
+	chdir "$master_dir/$zone" or die "chdir nach / nicht moeglich: $1";
+	$keyname = `dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`;
+
+	if (-e ".index.ksk") {
+		open (INDEX, ".index.ksk");
+		@index = <INDEX>;
+		close (INDEX);
+	} else {
+		@index = ();
+	}
+
+	push @index, $keyname;
+	if (@index > 2){
+		shift (@index);
+	}
+
+	open (INDEX, ">.index.ksk");
+	print INDEX @index;
+	close (INDEX);
+
+	chomp ($keyname);
+	print "$keyname (KSK) erzeugt fuer $zone \n";
 }
 
 
-#prueft die eingegebnen domains und erstellt eine liste
-for utf8domain in $@
-do
-        domain=$(idn --quiet "$utf8domain")
+# loescht alle unbenoetigten schluessel, fuegt die schluessel in
+# die zone-datei
+foreach (@change, @manu) {
+	$zone = $_;
+	my @old_zone_content = ();
+	my @new_zone_content = ();
+	my @keylist = ();
+	my $file = ();
 
-        if [ -d $master_dir/$domain ]
-        then
-                zsk_manuell="$zsk_manuell $domain"
-        else
-                echo $domain ist keine verwaltete Zone
-        fi
-done
+	open (INDEX, "$master_dir/$zone/.index.zsk");
+	@keylist = <INDEX>;
+	close (INDEX);
 
+	open (INDEX, "$master_dir/$zone/.index.ksk");
+	push @keylist, <INDEX>;
+	close (INDEX);
 
-# gibt die standard-ausgabe aus den funktionen in listen
-zsk_time=`test_zsk_time`
-zsk_new=`test_zsk_new`
-ksk_new=`test_ksk_new`
-
+	open (ZONE, "$master_dir/$zone/$zone");
+	@old_zone_content = <ZONE>;
+	close (ZONE);
 
-# erstellt zsks
-for NEW_ZSK_ZONE in $zsk_time $zsk_manuell
-do
-	cd $master_dir/$NEW_ZSK_ZONE
-	echo "erzeugt zsk fuer" $NEW_ZSK_ZONE
-	dnssec-keygen -a RSASHA1 -b 512 -n ZONE $NEW_ZSK_ZONE >> .index.zsk
-	INDEX_ZSK=$( tail -n2 .index.zsk )
-	echo $INDEX_ZSK | fmt -w1 > .index.zsk
+	# kuerzt die schluessel-bezeichnung aus der indexdatei auf die id um sie
+	# besser vergleichen zu koennen.
+	foreach (@keylist) {
+		chomp;
+		s#K.*\+.*\+(.*)#$1#;
+	}
+
+	# filtert alle schluessel aus der zonedatei
+	# old_zone_content ==> new_zone_content
+	foreach (@old_zone_content) {
+		unless (/IN\sDNSKEY/) {
+			push @new_zone_content, $_;
+		}
+	}
 
-	echo 0 > keycounter	
-done
-
+	# 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;
 
-# erstellt ksks
-for NEW_KSK_ZONE in $zsk_manuell
-do	
-	cd $master_dir/$NEW_KSK_ZONE
-	echo "erzeugt ksk fuer" $NEW_KSK_ZONE
-	dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $NEW_KSK_ZONE >> .index.ksk
-	INDEX_KSK=$( tail -n2 .index.ksk )
-	echo $INDEX_KSK | fmt -w1 > .index.ksk
-done
+		foreach (@keylist) {
 
+			if ($file =~ /$_/) {
+				$rm_count = 0;
 
-# fuegt die schluessel in die zone-datei
-for zone in $zsk_time $zsk_manuell
-do
-	cd $master_dir/$zone
-
-	#loescht alle Schluessel die nicht in der indexdatei stehen
-	rm $(ls K*[key,private] | grep -v "`cat .index.zsk`" | grep -v "`cat .index.ksk`") 2>/dev/null || true
+				# 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;
+				}
+			}
+		}
 
-	#erzeugt ein backup und entfernt alle schluessel aus der zonedatei
-	mv $zone .$zone
-	grep -v 'DNSKEY' .$zone >> $zone
+		#loescht alle unbenoetigten schluessel
+		if ($rm_count == 1) {
+			print `rm -f $file`;
+		}
+	}
 
-	#fuegt die existirenden schluessel in die zonedatei ein
-	cat K$zone.*key >> $zone
-done
+	open (ZONE, ">$master_dir/$zone/$zone");
+	print ZONE @new_zone_content;
+	close (ZONE);
+	
+	print "$master_dir/$zone/$zone wurde neu erstellt \n";
+}