dnssec-sign und dnssec-killkey in perl geschrieben
authorasuess@dns.net.schlittermann.de
Wed, 28 Jul 2010 14:14:47 +0200
changeset 20 5b52190d8750
parent 19 2c3bcb280768
child 21 6715f8f9d04c
dnssec-sign und dnssec-killkey in perl geschrieben
dnssec-creatkey
dnssec-killkey
dnssec-sign
--- a/dnssec-creatkey	Tue Jul 27 09:48:25 2010 +0200
+++ b/dnssec-creatkey	Wed Jul 28 14:14:47 2010 +0200
@@ -3,7 +3,7 @@
 use strict;
 
 my $master_dir="/etc/bind/master";	# verzeichnis fuer bind
-my $key_counter_end="2";		# ablauf des schluessels
+my $key_counter_end="10";		# ablauf des schluessels
 my @zones = `ls $master_dir`;	# alle verwalteten zonen
 my @change;			# liste abgelaufener zonen
 my @manu;			# liste manuell eingegebener zonen aus ARGV
--- 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";
+}
--- a/dnssec-sign	Tue Jul 27 09:48:25 2010 +0200
+++ b/dnssec-sign	Wed Jul 28 14:14:47 2010 +0200
@@ -1,71 +1,91 @@
-#!/bin/bash
-#source ./dnstools.conf
-master_dir="/etc/bind/master"
-SIGN_ALERT_TIME="48"
+#!/usr/bin/perl -w
 
-#prüft die eingegebnen domains
-for utf8domain in $@
-do
-	domain=$(idn --quiet "$utf8domain")	
-
-	if [ -d $master_dir/$domain ]
-	then
-		zone_aenderung="$zone_aenderung $master_dir/$domain"
-	else
-		echo $domain ist keine verwaltete Zone
-	fi
-done
-
+use strict;
 
-#gibt zonen mit abgelaufener signatur in die standardausgabe
-function time_out {
-	unowtime=`date +%s`
-	alerttime=`date -d @$[unowtime - $[ 3600 * $SIGN_ALERT_TIME  ] ] +%Y%m%d%H`
+my $master_dir="/etc/bind/master" ;
+my $sign_alert_time="48";		# zeitraum zwischen signierung und ablauf in h
+my $zone;
+my (@manu, @auto);
+my @zone_sig_content;
+my $sig_date;
+my $kc;
 
-	for zone in $master_dir/*
-	do	
-		domain=${zone##/*/}
-		if [ -f $zone/$domain.signed ]
-		then
-			endtime=`cat $zone/$domain.signed | egrep 'DNSKEY' | egrep '[0-9]{14}' | head -n1 | cut -d" " -f5 | cut -c 1-10`
-		fi
-
-		if [ $endtime ]
-		then
-			if [ $alerttime -ge $endtime ]
-			then
-				echo $zone
-			fi
-		fi
-	done
+# prueft zonen aus ARGV und fuegt sie in die liste @manu ein
+foreach (@ARGV) {
+	chomp ($zone = `idn --quiet $_`);
+	if (-e "$master_dir/$zone") {
+		push @manu, $zone;
+	} else {
+		print "$zone ist keine verwaltete zone \n";
+	}
 }
 
+# feststellen des aktuellen zeitpunktes, zuzueglich der $sign_alert_time
+# die ausgabe $time ist im selben format wie in der signed-datei und kann
+# verglichen werden.
+chomp (my $unixtime=`date +%s`);
+$unixtime = $unixtime + (3600 * $sign_alert_time);
+my $time = `date -d \@$unixtime +%Y%m%d%H`;
 
-#gibt zonen mit schluessel aber ohne signatur in die standardausgabe
-function new_sign {
-	for zone in $master_dir/*
-	do
-		if [ -f $zone/.keycounter ]
-		then
-			if [ `< $zone/.keycounter` -le 0 ]
-			then
-				echo $zone
-			fi
-		fi
-	done
+# 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.
+foreach (`ls $master_dir`) {
+	chomp ($zone = $_);
+
+	if (-e "$master_dir/$zone/$zone.signed") {
+
+		open (ZONE, "$master_dir/$zone/$zone.signed");
+		@zone_sig_content = <ZONE>;
+		close (ZONE);
+
+		foreach (@zone_sig_content) {
+			if (m#SOA.*[0-9]{14}#) {
+				s#.*([0-9]{10})([0-9]{4}).*#$1#;
+				if ($_ < $time) {
+					push @auto, $zone;
+				}
+			}
+		}
+	}
 }
 
+#gibt zonen mit schluessel aber ohne signatur in die liste @auto
+foreach (`ls $master_dir`) {
+	chomp ($zone = $_);
 
-#uebergibt die ausgabe der funktionen in listen
-zone_new_sign=`new_sign`
-zone_time_out=`time_out`
+	if (-e "$master_dir/$zone/.keycounter") {
+
+		open (KC, "$master_dir/$zone/.keycounter" );
+		$kc = <KC>;
+		close (KC);
 
+		if ( $kc < 1) {	
+			push @auto, $zone;
+		}
+	}
+}
 
-# signiert alle zonen aus den listen
-for zone in $zone_aenderung $zone_new_sign $zone_time_out
-do
-	cd $zone
-	domain=${zone##/*/}	
-	key_counter=`< .keycounter`
-	dnssec-signzone $domain && echo $[ key_counter + 1 ] > .keycounter
-done
+# signiert alle zonen in @auto und @manu und erhoeht den wert in
+# der keycounter-datei
+foreach (@auto, @manu) {
+	$zone = $_ ;
+
+	chdir "$master_dir/$zone";
+
+	if (`dnssec-signzone $zone 2>/dev/null`) {
+		print "$zone neu signiert \n";
+
+		open (KC, "$master_dir/$zone/.keycounter" );
+		$kc = <KC>;
+		close (KC);
+		$kc += 1;
+		open (KC, ">$master_dir/$zone/.keycounter" );
+		print KC $kc;
+		close (KC);
+
+	} else {
+		print "$zone konnte nicht signiert werden \n";
+	}
+}
+