From c550b1ee735130b031ad3890faf4f98f466732a6 Mon Sep 17 00:00:00 2001
From: Svenne Krap <svenne@krap.dk>
Date: Mon, 11 Jan 2010 00:06:53 +0100
Subject: [PATCH] initial import

---
 conf/settings.sample  | 16 +++++++++++++++
 disable-zone.sh       | 15 ++++++++++++++
 edit-zone.sh          | 18 ++++++++++++++++
 list-keys.sh          | 24 ++++++++++++++++++++++
 list-retired-keys.sh  | 24 ++++++++++++++++++++++
 make-ksk.sh           | 13 ++++++++++++
 make-zsk.sh           | 13 ++++++++++++
 prepare-zone.sh       | 43 ++++++++++++++++++++++++++++++++++++++
 purge-retired-keys.sh | 26 +++++++++++++++++++++++
 refresh-signatures.sh |  7 +++++++
 reinstate-key.sh      | 18 ++++++++++++++++
 retire-key.sh         | 18 ++++++++++++++++
 sign-zone.sh          | 48 +++++++++++++++++++++++++++++++++++++++++++
 trash/readme          |  3 +++
 update-zone-conf.sh   | 29 ++++++++++++++++++++++++++
 zones/readme          |  1 +
 16 files changed, 316 insertions(+)
 create mode 100644 conf/settings.sample
 create mode 100755 disable-zone.sh
 create mode 100755 edit-zone.sh
 create mode 100755 list-keys.sh
 create mode 100755 list-retired-keys.sh
 create mode 100755 make-ksk.sh
 create mode 100755 make-zsk.sh
 create mode 100755 prepare-zone.sh
 create mode 100755 purge-retired-keys.sh
 create mode 100755 refresh-signatures.sh
 create mode 100755 reinstate-key.sh
 create mode 100755 retire-key.sh
 create mode 100755 sign-zone.sh
 create mode 100644 trash/readme
 create mode 100755 update-zone-conf.sh
 create mode 100644 zones/readme

diff --git a/conf/settings.sample b/conf/settings.sample
new file mode 100644
index 0000000..143f3b5
--- /dev/null
+++ b/conf/settings.sample
@@ -0,0 +1,16 @@
+signzone=/usr/sbin/dnssec-signzone
+keygen=/usr/bin/dnssec-keygen
+salt_length=32
+resign_days=10
+
+num_nameservers=2
+
+ns1_public_name="ns1.example.com"
+ns1_ssh_access="root@ns1.example.com"
+ns1_conf_path="/opt/bind/etc/"
+ns1_rndc_path="/opt/bind/sbin/rndc"
+
+ns2_public_name="ns2.example.com"
+ns2_ssh_access="root@ns2.example.com"
+ns2_conf_path="/opt/bind/etc/"
+ns2_rndc_path="/opt/bind/sbin/rndc"
diff --git a/disable-zone.sh b/disable-zone.sh
new file mode 100755
index 0000000..4f54d1a
--- /dev/null
+++ b/disable-zone.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then
+    echo "$0 <zone>"
+    exit
+fi
+if [ ! -d zones/$1 ] ; then
+    echo "$1 does not exist"
+    exit
+fi
+
+mv zones/$1 trash/
+./update-zone-conf.sh
diff --git a/edit-zone.sh b/edit-zone.sh
new file mode 100755
index 0000000..599cd8f
--- /dev/null
+++ b/edit-zone.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then 
+    echo "$0 <zone>"
+    exit
+fi
+
+if [ ! -f zones/$1/$1 ] ; then
+    echo "$1 does not exist or is not prepared"
+    exit
+fi
+
+$EDITOR zones/$1/$1
+
+echo "You might want to run update-zone-conf or sign-zone scripts"
+
diff --git a/list-keys.sh b/list-keys.sh
new file mode 100755
index 0000000..cef2f2d
--- /dev/null
+++ b/list-keys.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then
+	echo "$0 <domain.tld>"
+	exit
+fi 
+if [ ! -d zones/$1 ] ; then
+    echo "zone $1 does not exists"
+    exit
+fi
+
+echo "Listing keys for $1"
+for ksk in $( find . -name "*.key" -exec grep -q " 257 " {} \; -exec ls {} \; ) ; do 
+    ksk=$(basename $ksk .key)
+    date=$(date -r zones/$1/${ksk}.key +%Y-%m-%d  )
+    echo " ... found KSK $ksk modified $date"
+done
+for zsk in $( find . -name "*.key" -exec grep -q " 256 " {} \; -exec ls {} \; ) ; do 
+    zsk=$(basename $zsk .key)
+    date=$(date -r zones/$1/${zsk}.key +%Y-%m-%d  )
+    echo " ... found ZSK $zsk modified $date"
+done
diff --git a/list-retired-keys.sh b/list-retired-keys.sh
new file mode 100755
index 0000000..bd746b9
--- /dev/null
+++ b/list-retired-keys.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then
+	echo "$0 <domain.tld>"
+	exit
+fi 
+if [ ! -d zones/$1 ] ; then
+    echo "zone $1 does not exists"
+    exit
+fi
+
+echo "Listing keys for $1"
+for ksk in $( find . -name "*.oldkey" -exec grep -q " 257 " {} \; -exec ls {} \; ) ; do 
+    ksk=$(basename $ksk .oldkey)
+    date=$(date -r zones/$1/${ksk}.oldkey +%Y-%m-%d  )
+    echo " ... found KSK $ksk modified $date"
+done
+for zsk in $( find . -name "*.oldkey" -exec grep -q " 256 " {} \; -exec ls {} \; ) ; do 
+    zsk=$(basename $zsk .oldkey)
+    date=$(date -r zones/$1/${zsk}.oldkey +%Y-%m-%d  )
+    echo " ... found ZSK $zsk modified $date"
+done
diff --git a/make-ksk.sh b/make-ksk.sh
new file mode 100755
index 0000000..3fbd512
--- /dev/null
+++ b/make-ksk.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then
+    echo "$0 <zone>";
+    exit;
+fi
+if [ ! -d zones/$1 ] ; then
+    mkdir zones/$1;
+fi
+cd zones/$1
+$keygen -f KSK -a NSEC3RSASHA1 -b 2048 -n ZONE $1
diff --git a/make-zsk.sh b/make-zsk.sh
new file mode 100755
index 0000000..274bb51
--- /dev/null
+++ b/make-zsk.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then
+    echo "$0 <zone>";
+    exit;
+fi
+if [ ! -d zones/$1 ] ; then
+    mkdir zones/$1;
+fi
+cd zones/$1
+$keygen -a NSEC3RSASHA1 -b 2048 -e -n ZONE $1
diff --git a/prepare-zone.sh b/prepare-zone.sh
new file mode 100755
index 0000000..da37890
--- /dev/null
+++ b/prepare-zone.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 2 ] ; then
+    echo "prepare-zone.sh <domain.tld> <maintainer.mail>"
+    exit
+fi
+if [ -d zones/$1 ] ; then
+    echo "Zone $1 already exists ... did you want to use edit-zone ? "
+    exit
+fi
+mainmail=$(echo $2 | tr @ . )
+mkdir zones/$1
+cat > zones/$1/$1 <<EOF
+\$TTL 1h
+
+@       IN      SOA     $ns1_public_name. $mainmail. (
+                        1      ; serial
+                        1h      ; refresh
+                        30m     ; retry
+                        7d      ; expiration
+                        1h )    ; minimum
+
+EOF
+
+for i in `seq $num_nameservers`  ; do 
+    ns=ns$i
+    eval public_name=\$${ns}_public_name
+
+    echo "        NS      $public_name." >> zones/$1/$1
+done
+
+echo "Generatign KSK and ZSK keys... "
+echo 
+echo "This uses a LOT of random data and may take quiet a while..."
+echo 
+echo "If you are anticipating to do this often, consider acquireing a fast h/w random number generator"
+
+./make-ksk.sh $1
+./make-zsk.sh $1
+
+echo "To finalize your zone use edit-zone and then sign-zone and finally update-zone-conf."
diff --git a/purge-retired-keys.sh b/purge-retired-keys.sh
new file mode 100755
index 0000000..326ec3d
--- /dev/null
+++ b/purge-retired-keys.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then
+	echo "$0 <domain.tld>"
+	exit
+fi 
+if [ ! -d zones/$1 ] ; then
+    echo "zone $1 does not exists"
+    exit
+fi
+
+echo "Removing retired keys for $1"
+for ksk in $( find . -name "*.oldkey" -exec grep -q " 257 " {} \; -exec ls {} \; ) ; do 
+    ksk=$(basename $ksk .oldkey)
+    date=$(date -r zones/$1/${ksk}.oldkey +%Y-%m-%d  )
+    rm zones/$1/${ksk}.oldkey
+    echo " ... removed KSK $ksk modified $date"
+done
+for zsk in $( find . -name "*.oldkey" -exec grep -q " 256 " {} \; -exec ls {} \; ) ; do 
+    zsk=$(basename $zsk .oldkey)
+    date=$(date -r zones/$1/${zsk}.oldkey +%Y-%m-%d  )
+    rm zones/$1/${zsk}.oldkey
+    echo " ... removed ZSK $zsk modified $date"
+done
diff --git a/refresh-signatures.sh b/refresh-signatures.sh
new file mode 100755
index 0000000..6836350
--- /dev/null
+++ b/refresh-signatures.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+source `dirname $0`/conf/settings 
+cd `dirname $0`
+
+for zone in `find . -name "*.signed" -mtime $resign_days -exec basename {} .zone.signed \;`  ; do 
+    ./sign-zone.sh $zone
+done
diff --git a/reinstate-key.sh b/reinstate-key.sh
new file mode 100755
index 0000000..483468a
--- /dev/null
+++ b/reinstate-key.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 2 ] ; then
+	echo "$0 <domain.tld> <key>"
+	exit
+fi 
+if [ ! -d zones/$1 ] ; then
+    echo "zone $1 does not exists"
+    exit
+fi
+
+if [ -f zones/$1/$2.oldkey -a -f zones/$1/$2.oldprivate ] ; then
+    echo "Re-instate key $2 for $1"
+    mv zones/$1/$2.oldkey zones/$1/$2.key
+    mv zones/$1/$2.oldprivate zones/$1/$2.private
+fi
diff --git a/retire-key.sh b/retire-key.sh
new file mode 100755
index 0000000..25a0df4
--- /dev/null
+++ b/retire-key.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 2 ] ; then
+	echo "$0 <domain.tld> <key>"
+	exit
+fi 
+if [ ! -d zones/$1 ] ; then
+    echo "zone $1 does not exists"
+    exit
+fi
+
+if [ -f zones/$1/$2.key -a -f zones/$1/$2.private ] ; then
+    echo "Retire key $2 for $1"
+    mv zones/$1/$2.key zones/$1/$2.oldkey
+    mv zones/$1/$2.private zones/$1/$2.oldprivate
+fi
diff --git a/sign-zone.sh b/sign-zone.sh
new file mode 100755
index 0000000..4667c63
--- /dev/null
+++ b/sign-zone.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+if [ $# -ne 1 ] ; then
+	echo "$0 <domain.tld>"
+	exit
+fi 
+if [ ! -d zones/$1 ] ; then
+    echo "zone $1 does not exists"
+    exit
+fi
+
+function gen_salt { 
+    # gen_salt function copied and adapted from advanced bash scripting guide
+    LENGTH=$1
+    MATRIX="0123456789ABCDEF"
+
+    while [ "${n:=1}" -le "$LENGTH" ]
+    do
+        SALT="$SALT${MATRIX:$(($RANDOM%${#MATRIX})):1}"
+        let n+=1
+    done
+    return 0;
+}
+
+cd zones/$1 
+
+echo "=== zone $1"
+echo "... adding keys"
+cat $1 K$1*.key > $1.zone
+cat $1 K$1*.oldkey >> $1.zone
+
+echo "... signing"
+gen_salt $salt_length
+$signzone -A -a  -3 $SALT -N unixtime -o $1 $1.zone
+
+for i in `seq $num_nameservers`  ; do 
+    ns=ns$i
+
+    echo "... uploading to $ns"
+    eval ssh_access=\$${ns}_ssh_access
+    eval conf_path=\$${ns}_conf_path
+    eval rndc_path=\$${ns}_rndc_path
+
+    scp -q $1.zone.signed $ssh_access:$conf_path
+    ssh -q $ssh_access  "$rndc_path reload"
+done
diff --git a/trash/readme b/trash/readme
new file mode 100644
index 0000000..76717e3
--- /dev/null
+++ b/trash/readme
@@ -0,0 +1,3 @@
+this file containes "deleted" domains.
+
+they can be removed when you are sure, they are unneeded.
diff --git a/update-zone-conf.sh b/update-zone-conf.sh
new file mode 100755
index 0000000..5716c8d
--- /dev/null
+++ b/update-zone-conf.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+source `dirname $0`/conf/settings
+cd `dirname $0`
+
+rm -f zones/zone.conf
+
+for d in zones/* ; do 
+    zone=`basename $d` 
+cat >> zones/zone.conf <<EOF 
+zone "$zone." in {
+        type master;
+        file "$zone.zone.signed";
+};
+
+EOF
+done
+
+
+for i in `seq $num_nameservers`  ; do 
+    ns=ns$i
+
+    echo "running $ns"
+    eval ssh_access=\$${ns}_ssh_access
+    eval conf_path=\$${ns}_conf_path
+    eval rndc_path=\$${ns}_rndc_path
+
+    scp zones/zone.conf $ssh_access:$conf_path
+    ssh $ssh_access  "$rndc_path reload"
+done
diff --git a/zones/readme b/zones/readme
new file mode 100644
index 0000000..8cdc628
--- /dev/null
+++ b/zones/readme
@@ -0,0 +1 @@
+this folder contains production zones
-- 
2.36.1