#!/bin/sh # update-anchor.sh, update a trust anchor. # Copyright 2008, W.C.A. Wijngaards # This file is BSD licensed, see doc/LICENSE. # which validating lookup to use. setglobal ubhost = 'unbound-host' proc usage { echo "usage: update-anchor [-r hs] [-b] " echo " performs an update of trust anchor file" echo " the trust anchor file is overwritten with the latest keys" echo " the trust anchor file should contain only keys for one zone" echo " -b causes keyfile to be made in bind format." echo " without -b the file is made in unbound format." echo " " echo "alternate:" echo " update-anchor [-r hints] [-b] -d directory" echo " update all .anchor files in the directory." echo " " echo " name the files br.anchor se.anchor ..., and include them in" echo " the validating resolver config file." echo " put keys for the root in a file with the name root.anchor." echo "" echo "-r root.hints use different root hints. Strict option order." echo "" echo "Exit code 0 means anchors updated, 1 no changes, others are errors." exit 2 } if test $Argc -eq 0 { usage } setglobal bindformat = '"no'" setglobal filearg = ''-f'' setglobal roothints = ''"" if test X"$1" = "X-r" { shift setglobal roothints = $1 shift } if test X"$1" = "X-b" { shift setglobal bindformat = '"yes'" setglobal filearg = ''-F'' } if test $Argc -ne 2 { echo "arguments wrong." usage } proc do_update { # arguments: setglobal zonename = $1 setglobal keyfile = $2 setglobal tmpfile = ""/tmp/update-anchor.$Pid"" setglobal tmp2 = "$tmpfile.2" setglobal tmp3 = "$tmpfile.3" setglobal rh = ''"" if test -n $roothints { echo "server: root-hints: '$roothints'" > $tmp3 setglobal rh = ""-C $tmp3"" } $ubhost -v $rh $filearg $keyfile -t DNSKEY $zonename >$tmpfile if test $Status -ne 0 { rm -f $tmpfile echo "Error: Could not update zone $zonename anchor file $keyfile" echo "Cause: $ubhost lookup failed" echo " (Is the domain decommissioned? Is connectivity lost?)" return 2 } # has the lookup been DNSSEC validated? if grep '(secure)$' $tmpfile >/dev/null 2>&1 { : } else { rm -f $tmpfile echo "Error: Could not update zone $zonename anchor file $keyfile" echo "Cause: result of lookup was not secure" echo " (keys too far out of date? domain changed ownership? need root hints?)" return 3 } if test $bindformat = "yes" { # are there any KSK keys on board? echo 'trusted-keys {' > "$tmp2" if grep ' has DNSKEY record 257' $tmpfile >/dev/null 2>&1 { # store KSK keys in anchor file grep '(secure)$' $tmpfile | \ grep ' has DNSKEY record 257' | \ sed -e 's/ (secure)$/";/' | \ sed -e 's/ has DNSKEY record \([0-9]*\) \([0-9]*\) \([0-9]*\) /. \1 \2 \3 "/' | \ sed -e 's/^\.\././' | sort >> "$tmp2" } else { # store all keys in the anchor file grep '(secure)$' $tmpfile | \ sed -e 's/ (secure)$/";/' | \ sed -e 's/ has DNSKEY record \([0-9]*\) \([0-9]*\) \([0-9]*\) /. \1 \2 \3 "/' | \ sed -e 's/^\.\././' | sort >> "$tmp2" } echo '};' >> "$tmp2" } else { #not bindformat # are there any KSK keys on board? if grep ' has DNSKEY record 257' $tmpfile >/dev/null 2>&1 { # store KSK keys in anchor file grep '(secure)$' $tmpfile | \ grep ' has DNSKEY record 257' | \ sed -e 's/ (secure)$//' | \ sed -e 's/ has DNSKEY record /. IN DNSKEY /' | \ sed -e 's/^\.\././' | sort > "$tmp2" } else { # store all keys in the anchor file grep '(secure)$' $tmpfile | \ sed -e 's/ (secure)$//' | \ sed -e 's/ has DNSKEY record /. IN DNSKEY /' | \ sed -e 's/^\.\././' | sort > "$tmp2" } } # endif-bindformat # copy over if changed diff $tmp2 $keyfile >/dev/null 2>&1 if test $Status -eq 1 { # 0 means no change, 2 means trouble. cat $tmp2 > $keyfile setglobal no_updated = '0' echo "$zonename key file $keyfile updated." } else { echo "$zonename key file $keyfile unchanged." } rm -f $tmpfile $tmp2 $tmp3 } setglobal no_updated = '1' if test X"$1" = "X-d" { setglobal tdir = $2 echo "start updating in $2" for x in [$tdir/*.anchor] { if test $[basename $x] = "root.anchor" { setglobal zname = '".'" } else { setglobal zname = $[basename $x .anchor] } do_update $zname $x } echo "done updating in $2" } else { # regular invocation if test X"$1" = "X." { setglobal zname = $1 } else { # strip trailing dot from zone name setglobal zname = $[echo $1 | sed -e 's/\.$//] } setglobal kfile = $2 do_update $zname $kfile } exit $no_updated