1#!/bin/sh 2# update-anchor.sh, update a trust anchor. 3# Copyright 2008, W.C.A. Wijngaards 4# This file is BSD licensed, see doc/LICENSE. 5 6# which validating lookup to use. 7ubhost=unbound-host 8 9usage ( ) 10{ 11 echo "usage: update-anchor [-r hs] [-b] <zone name> <trust anchor file>" 12 echo " performs an update of trust anchor file" 13 echo " the trust anchor file is overwritten with the latest keys" 14 echo " the trust anchor file should contain only keys for one zone" 15 echo " -b causes keyfile to be made in bind format." 16 echo " without -b the file is made in unbound format." 17 echo " " 18 echo "alternate:" 19 echo " update-anchor [-r hints] [-b] -d directory" 20 echo " update all <zone>.anchor files in the directory." 21 echo " " 22 echo " name the files br.anchor se.anchor ..., and include them in" 23 echo " the validating resolver config file." 24 echo " put keys for the root in a file with the name root.anchor." 25 echo "" 26 echo "-r root.hints use different root hints. Strict option order." 27 echo "" 28 echo "Exit code 0 means anchors updated, 1 no changes, others are errors." 29 exit 2 30} 31 32if test $# -eq 0; then 33 usage 34fi 35bindformat="no" 36filearg='-f' 37roothints="" 38if test X"$1" = "X-r"; then 39 shift 40 roothints="$1" 41 shift 42fi 43if test X"$1" = "X-b"; then 44 shift 45 bindformat="yes" 46 filearg='-F' 47fi 48if test $# -ne 2; then 49 echo "arguments wrong." 50 usage 51fi 52 53do_update ( ) { 54 # arguments: <zonename> <keyfile> 55 zonename="$1" 56 keyfile="$2" 57 tmpfile="/tmp/update-anchor.$$" 58 tmp2=$tmpfile.2 59 tmp3=$tmpfile.3 60 rh="" 61 if test -n "$roothints"; then 62 echo "server: root-hints: '$roothints'" > $tmp3 63 rh="-C $tmp3" 64 fi 65 $ubhost -v $rh $filearg "$keyfile" -t DNSKEY "$zonename" >$tmpfile 66 if test $? -ne 0; then 67 rm -f $tmpfile 68 echo "Error: Could not update zone $zonename anchor file $keyfile" 69 echo "Cause: $ubhost lookup failed" 70 echo " (Is the domain decommissioned? Is connectivity lost?)" 71 return 2 72 fi 73 74 # has the lookup been DNSSEC validated? 75 if grep '(secure)$' $tmpfile >/dev/null 2>&1; then 76 : 77 else 78 rm -f $tmpfile 79 echo "Error: Could not update zone $zonename anchor file $keyfile" 80 echo "Cause: result of lookup was not secure" 81 echo " (keys too far out of date? domain changed ownership? need root hints?)" 82 return 3 83 fi 84 85 if test $bindformat = "yes"; then 86 # are there any KSK keys on board? 87 echo 'trusted-keys {' > "$tmp2" 88 if grep ' has DNSKEY record 257' $tmpfile >/dev/null 2>&1; then 89 # store KSK keys in anchor file 90 grep '(secure)$' $tmpfile | \ 91 grep ' has DNSKEY record 257' | \ 92 sed -e 's/ (secure)$/";/' | \ 93 sed -e 's/ has DNSKEY record \([0-9]*\) \([0-9]*\) \([0-9]*\) /. \1 \2 \3 "/' | \ 94 sed -e 's/^\.\././' | sort >> "$tmp2" 95 else 96 # store all keys in the anchor file 97 grep '(secure)$' $tmpfile | \ 98 sed -e 's/ (secure)$/";/' | \ 99 sed -e 's/ has DNSKEY record \([0-9]*\) \([0-9]*\) \([0-9]*\) /. \1 \2 \3 "/' | \ 100 sed -e 's/^\.\././' | sort >> "$tmp2" 101 fi 102 echo '};' >> "$tmp2" 103 else #not bindformat 104 # are there any KSK keys on board? 105 if grep ' has DNSKEY record 257' $tmpfile >/dev/null 2>&1; then 106 # store KSK keys in anchor file 107 grep '(secure)$' $tmpfile | \ 108 grep ' has DNSKEY record 257' | \ 109 sed -e 's/ (secure)$//' | \ 110 sed -e 's/ has DNSKEY record /. IN DNSKEY /' | \ 111 sed -e 's/^\.\././' | sort > "$tmp2" 112 else 113 # store all keys in the anchor file 114 grep '(secure)$' $tmpfile | \ 115 sed -e 's/ (secure)$//' | \ 116 sed -e 's/ has DNSKEY record /. IN DNSKEY /' | \ 117 sed -e 's/^\.\././' | sort > "$tmp2" 118 fi 119 fi # endif-bindformat 120 121 # copy over if changed 122 diff $tmp2 $keyfile >/dev/null 2>&1 123 if test $? -eq 1; then # 0 means no change, 2 means trouble. 124 cat $tmp2 > $keyfile 125 no_updated=0 126 echo "$zonename key file $keyfile updated." 127 else 128 echo "$zonename key file $keyfile unchanged." 129 fi 130 131 rm -f $tmpfile $tmp2 $tmp3 132} 133 134no_updated=1 135if test X"$1" = "X-d"; then 136 tdir="$2" 137 echo "start updating in $2" 138 for x in $tdir/*.anchor; do 139 if test `basename "$x"` = "root.anchor"; then 140 zname="." 141 else 142 zname=`basename "$x" .anchor` 143 fi 144 do_update "$zname" "$x" 145 done 146 echo "done updating in $2" 147else 148 # regular invocation 149 if test X"$1" = "X."; then 150 zname="$1" 151 else 152 # strip trailing dot from zone name 153 zname="`echo $1 | sed -e 's/\.$//'`" 154 fi 155 kfile="$2" 156 do_update $zname $kfile 157fi 158exit $no_updated 159