diff options
Diffstat (limited to 'contrib/scripts/dnssec-keyset.sh')
-rw-r--r-- | contrib/scripts/dnssec-keyset.sh | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/contrib/scripts/dnssec-keyset.sh b/contrib/scripts/dnssec-keyset.sh new file mode 100644 index 0000000..f93ac9f --- /dev/null +++ b/contrib/scripts/dnssec-keyset.sh @@ -0,0 +1,210 @@ +#!/bin/sh +# Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +# Original script contributed by Jeffry A. Spain <spainj@countryday.net> + +HELP=" +Generates a set of <count> successive DNSSEC keys for <zone> +Key timings are based on a pre-publication rollover strategy + + <life> (lifetime) is the key active lifetime in days [default 180] + <intro> (introduction time) is the number of days from publication + to activation of a key [default 30] + <ret> (retirement time) is the number of days from inactivation + to deletion of a key [default 30] + +Options: + -a <alg> Cryptographic algorithm. See man dnssec-keygen for defaults. + -b <bits> Number of bits in the key. See man dnssec-keygen for defaults. + -k if present, generate Key Signing Keys (KSKs). Otherwise, + generate Zone Signing Keys (ZSKs). + -3 If present and if -a is not specified, use an NSEC3- + capable algorithm. See man dnssec-keygen for defaults. + -i <date> Inception date of the set of keys, in 'mm/dd/yyyy' format. + The first two keys will be published by this date, and the + first one will be activated. Default is today. + -f <index> Index of first key generated. Defaults to 0. + -K <dir> Key repository: write keys to this directory. Defaults to CWD. + -d Dry run. No actual keys generated if present." + +USAGE="Usage: +`basename $0` [-a <alg>] [-b <bits>] [-k] [-3] [-i <date>] + [-f <index>] [-d] <zone> <count> [<life>] [<intro>] [<ret>]" + +ALGFLAG='' +BITSFLAG='' +KSKFLAG='' +NSEC3FLAG='' +KEYREPO='' +DRYRUN=false +OPTKSK=false +K=0 +INCEP=`date +%m/%d/%Y` + +# Parse command line options +while getopts ":a:b:df:hkK:3i:" thisOpt +do + case $thisOpt in + a) + ALGFLAG=" -a $OPTARG" + ;; + b) + BITSFLAG=" -b $OPTARG" + ;; + d) + DRYRUN=true + ;; + f) + OPTKSK=true + K=$OPTARG + ;; + h) + echo "$USAGE" + echo "$HELP" + exit 0 + ;; + k) + KSKFLAG=" -f KSK" + ;; + K) + KEYREPO=$OPTARG + ;; + 3) + NSEC3FLAG=" -3" + ;; + i) + INCEP=$OPTARG + ;; + *) + echo 'Unrecognized option.' + echo "$USAGE" + exit 1 + ;; + esac +done +shift `expr $OPTIND - 1` + +# Check that required arguments are present +if [ $# -gt 5 -o $# -lt 2 ]; then + echo "$USAGE" + exit 1 +fi + +# Remaining arguments: +# DNS zone name +ZONE=$1 +shift + +# Number of keys to be generated +COUNT=$1 +shift + +# Key active lifetime +LIFE=${1:-180} +[ $# -ne 0 ] && shift + +# Key introduction time (publication to activation) +INTRO=${1:-30} +[ $# -ne 0 ] && shift + +# Key retirement time (inactivation to deletion) +RET=${1:-30} + +# Today's date in dnssec-keygen format (YYYYMMDD) +TODAY=`date +%Y%m%d` + +# Key repository defaults to CWD +if [ -z "$KEYREPO" ]; then + KEYREPO="." +fi + +if $DRYRUN; then + echo 'Dry Run (no key files generated)' +elif [ ! -d "$KEYREPO" ]; then + # Create the key repository if it does not currently exist + mkdir -p "$KEYREPO" +fi + +# Iterate through the key set. K is the index, zero-based. +KLAST=`expr $K + $COUNT` +while [ $K -lt $KLAST ]; do + KEYLABEL="Key `printf \"%02d\" $K`:" + # Epoch of the current key + # (zero for the first key, increments of key lifetime) + # The epoch is in days relative to the inception date of the key set + EPOCH=`expr $LIFE \* $K` + # Activation date in days is the same as the epoch + ACTIVATE=$EPOCH + # Publication date in days relative to the key epoch + PUBLISH=`expr $EPOCH - $LIFE - $INTRO` + # Inactivation date in days relative to the key epoch + INACTIVE=`expr $EPOCH + $LIFE` + # Deletion date in days relative to the key epoch + DELETE=`expr $EPOCH + $LIFE + $RET` + + # ... these values should not precede the key epoch + [ $ACTIVATE -lt 0 ] && ACTIVATE=0 + [ $PUBLISH -lt 0 ] && PUBLISH=0 + [ $INACTIVE -lt 0 ] && INACTIVE=0 + [ $DELETE -lt 0 ] && DELETE=0 + + # Key timing dates in dnssec-keygen format (YYYYMMDD): + # publication, activation, inactivation, deletion + PDATE=`date -d "$INCEP +$PUBLISH day" +%Y%m%d` + ADATE=`date -d "$INCEP +$ACTIVATE day" +%Y%m%d` + IDATE=`date -d "$INCEP +$INACTIVE day" +%Y%m%d` + DDATE=`date -d "$INCEP +$DELETE day" +%Y%m%d` + + # Construct the dnssec-keygen command including all the specified options. + # Suppress key generation progress information, and save the key in + # the $KEYREPO directory. + KEYGENCMD="dnssec-keygen -q$ALGFLAG$BITSFLAG$NSEC3FLAG$KSKFLAG -P $PDATE -A $ADATE -I $IDATE -D $DDATE -K $KEYREPO $ZONE" + echo "$KEYLABEL $KEYGENCMD" + + # Generate the key and retrieve its name + if $DRYRUN; then + KEYNAME="DryRunKey-`printf \"%02d\" $K`" + else + KEYNAME=`$KEYGENCMD` + fi + + # Indicate the key status based on key timing dates relative to today + if [ $TODAY -ge $DDATE ]; then + echo "$KEYLABEL $KEYNAME is obsolete post deletion date." + elif [ $TODAY -ge $IDATE ]; then + echo "$KEYLABEL $KEYNAME is published and inactive prior to deletion date." + elif [ $TODAY -ge $ADATE ]; then + echo "$KEYLABEL $KEYNAME is published and active." + elif [ $TODAY -ge $PDATE ]; then + echo "$KEYLABEL $KEYNAME is published prior to activation date." + else + echo "$KEYLABEL $KEYNAME is pending publication." + fi + + # For published KSKs, generate the required DS records, + # saving them to the file $KEYREPO/DS-$KEYNAME + if $OPTKSK && [ $TODAY -ge $PDATE -a $TODAY -lt $DDATE ]; then + echo "$KEYLABEL $KEYNAME (KSK) requires the publication of DS records in the parent zone." + if $DRYRUN; then + echo "$KEYLABEL No DS-$KEYNAME file created." + else + dnssec-dsfromkey "$KEYREPO/$KEYNAME" > "$KEYREPO/DS-$KEYNAME" + echo "$KEYLABEL See $KEYREPO/DS-$KEYNAME." + fi + fi + K=`expr $K + 1` +done + +exit 0 |