1#!/bin/sh 2 3# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 4# 5# SPDX-License-Identifier: MPL-2.0 6# 7# This Source Code Form is subject to the terms of the Mozilla Public 8# License, v. 2.0. If a copy of the MPL was not distributed with this 9# file, you can obtain one at https://mozilla.org/MPL/2.0/. 10# 11# See the COPYRIGHT file distributed with this work for additional 12# information regarding copyright ownership. 13 14set -e 15 16SYSTEMTESTTOP=.. 17export ALGORITHM_SET="ecc_default" 18#shellcheck source=conf.sh 19. "$SYSTEMTESTTOP/conf.sh" 20 21dig_with_opts() ( 22 "$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "${PORT}" "$@" 23) 24 25delv_with_opts() ( 26 "$DELV" -a ns1/trusted.conf -p "${PORT}" "$@" 27) 28 29rndccmd() ( 30 "$RNDC" -c "$SYSTEMTESTTOP/common/rndc.conf" -p "${CONTROLPORT}" -s "$@" 31) 32 33mkeys_reconfig_on() ( 34 nsidx=$1 35 rndccmd "10.53.0.${nsidx}" reconfig . | sed "s/^/ns${nsidx} /" | cat_i 36) 37 38mkeys_reload_on() ( 39 nsidx=$1 40 nextpart "ns${nsidx}"/named.run > /dev/null 41 rndc_reload "ns${nsidx}" "10.53.0.${nsidx}" 42 wait_for_log 20 "loaded serial" "ns${nsidx}"/named.run || return 1 43) 44 45mkeys_loadkeys_on() ( 46 nsidx=$1 47 nextpart "ns${nsidx}"/named.run > /dev/null 48 rndccmd "10.53.0.${nsidx}" loadkeys . | sed "s/^/ns${nsidx} /" | cat_i 49 wait_for_log 20 "next key event" "ns${nsidx}"/named.run || return 1 50) 51 52mkeys_refresh_on() ( 53 nsidx=$1 54 nextpart "ns${nsidx}"/named.run > /dev/null 55 rndccmd "10.53.0.${nsidx}" managed-keys refresh | sed "s/^/ns${nsidx} /" | cat_i 56 wait_for_log 20 "Returned from key fetch in keyfetch_done()" "ns${nsidx}"/named.run || return 1 57) 58 59mkeys_sync_on() ( 60 # No race with mkeys_refresh_on() is possible as even if the latter 61 # returns immediately after the expected log message is written, the 62 # managed-keys zone is already locked and the command below calls 63 # dns_zone_flush(), which also attempts to take that zone's lock 64 nsidx=$1 65 nextpart "ns${nsidx}"/named.run > /dev/null 66 rndccmd "10.53.0.${nsidx}" managed-keys sync | sed "s/^/ns${nsidx} /" | cat_i 67 wait_for_log 20 "dump_done" "ns${nsidx}"/named.run || return 1 68) 69 70mkeys_status_on() ( 71 # No race with mkeys_refresh_on() is possible as even if the latter 72 # returns immediately after the expected log message is written, the 73 # managed-keys zone is already locked and the command below calls 74 # mkey_status(), which in turn calls dns_zone_getrefreshkeytime(), 75 # which also attempts to take that zone's lock 76 nsidx=$1 77 rndccmd "10.53.0.${nsidx}" managed-keys status 78) 79 80mkeys_flush_on() ( 81 nsidx=$1 82 rndccmd "10.53.0.${nsidx}" flush | sed "s/^/ns${nsidx} /" | cat_i 83) 84 85mkeys_secroots_on() ( 86 nsidx=$1 87 rndccmd "10.53.0.${nsidx}" secroots | sed "s/^/ns${nsidx} /" | cat_i 88) 89 90original=$(cat ns1/managed.key) 91originalid=$(cat ns1/managed.key.id) 92 93status=0 94n=1 95 96rm -f dig.out.* 97 98echo_i "check for signed record ($n)" 99ret=0 100dig_with_opts +norec example. @10.53.0.1 TXT > dig.out.ns1.test$n || ret=1 101grep "^example\.[[:space:]]*[0-9]*[[:space:]]*IN[[:space:]]*TXT[[:space:]]*\"This is a test\.\"" dig.out.ns1.test$n > /dev/null || ret=1 102grep "^example\.[[:space:]]*[0-9]*[[:space:]]*IN[[:space:]]*RRSIG[[:space:]]*TXT[[:space:]]" dig.out.ns1.test$n > /dev/null || ret=1 103if [ $ret != 0 ]; then echo_i "failed"; fi 104status=$((status+ret)) 105 106n=$((n+1)) 107echo_i "check positive validation with valid trust anchor ($n)" 108ret=0 109dig_with_opts +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 110grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 111grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1 112if [ $ret != 0 ]; then echo_i "failed"; fi 113status=$((status+ret)) 114 115n=$((n+1)) 116ret=0 117echo_i "check positive validation using delv ($n)" 118delv_with_opts @10.53.0.1 txt example > delv.out$n || ret=1 119grep "; fully validated" delv.out$n > /dev/null || ret=1 # redundant 120grep "example..*TXT.*This is a test" delv.out$n > /dev/null || ret=1 121grep "example..*.RRSIG..*TXT" delv.out$n > /dev/null || ret=1 122if [ $ret != 0 ]; then echo_i "failed"; fi 123status=$((status+ret)) 124 125n=$((n+1)) 126echo_i "check for failed validation due to wrong key in managed-keys ($n)" 127ret=0 128dig_with_opts +noauth example. @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 129grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 130grep "example..*.RRSIG..*TXT" dig.out.ns3.test$n > /dev/null && ret=1 131grep "opcode: QUERY, status: SERVFAIL, id" dig.out.ns3.test$n > /dev/null || ret=1 132if [ $ret != 0 ]; then echo_i "failed"; fi 133status=$((status+ret)) 134 135n=$((n+1)) 136echo_i "check new trust anchor can be added ($n)" 137ret=0 138standby1=$($KEYGEN -a ${DEFAULT_ALGORITHM} -qfk -K ns1 .) 139mkeys_loadkeys_on 1 || ret=1 140mkeys_refresh_on 2 || ret=1 141mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 142# there should be two keys listed now 143count=$(grep -c "keyid: " rndc.out.$n) || true 144[ "$count" -eq 2 ] || ret=1 145# two lines indicating trust status 146count=$(grep -c "trust" rndc.out.$n) || true 147[ "$count" -eq 2 ] || ret=1 148# one indicates current trust 149count=$(grep -c "trusted since" rndc.out.$n) || true 150[ "$count" -eq 1 ] || ret=1 151# one indicates pending trust 152count=$(grep -c "trust pending" rndc.out.$n) || true 153[ "$count" -eq 1 ] || ret=1 154if [ $ret != 0 ]; then echo_i "failed"; fi 155status=$((status+ret)) 156 157n=$((n+1)) 158echo_i "check new trust anchor can't be added with bad initial key ($n)" 159ret=0 160mkeys_refresh_on 3 || ret=1 161mkeys_status_on 3 > rndc.out.$n 2>&1 || ret=1 162# there should be one key listed now 163count=$(grep -c "keyid: " rndc.out.$n) || true 164[ "$count" -eq 1 ] || ret=1 165# one line indicating trust status 166count=$(grep -c "trust" rndc.out.$n) || true 167[ "$count" -eq 1 ] || ret=1 168# ... and the key is not trusted 169count=$(grep -c "no trust" rndc.out.$n) || true 170[ "$count" -eq 1 ] || ret=1 171if [ $ret != 0 ]; then echo_i "failed"; fi 172status=$((status+ret)) 173 174n=$((n+1)) 175echo_i "remove untrusted standby key, check timer restarts ($n)" 176ret=0 177mkeys_sync_on 2 || ret=1 178t1=$(grep "trust pending" ns2/managed-keys.bind) || true 179$SETTIME -D now -K ns1 "$standby1" > /dev/null 180mkeys_loadkeys_on 1 || ret=1 181# Less than a second may have passed since the last time ns2 received a 182# ./DNSKEY response from ns1. Ensure keys are refreshed at a different 183# timestamp to prevent false negatives caused by the acceptance timer getting 184# reset to the same timestamp. 185sleep 1 186mkeys_refresh_on 2 || ret=1 187mkeys_sync_on 2 || ret=1 188t2=$(grep "trust pending" ns2/managed-keys.bind) || true 189# trust pending date must be different 190[ -n "$t2" ] || ret=1 191[ "$t1" = "$t2" ] && ret=1 192if [ $ret != 0 ]; then echo_i "failed"; fi 193status=$((status+ret)) 194 195n=$((n+1)) 196ret=0 197echo_i "restore untrusted standby key, revoke original key ($n)" 198t1=$t2 199$SETTIME -D none -K ns1 "$standby1" > /dev/null 200$SETTIME -R now -K ns1 "$original" > /dev/null 201mkeys_loadkeys_on 1 || ret=1 202# Less than a second may have passed since the last time ns2 received a 203# ./DNSKEY response from ns1. Ensure keys are refreshed at a different 204# timestamp to prevent false negatives caused by the acceptance timer getting 205# reset to the same timestamp. 206sleep 1 207mkeys_refresh_on 2 || ret=1 208mkeys_sync_on 2 || ret=1 209mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 210# two keys listed 211count=$(grep -c "keyid: " rndc.out.$n) || true 212[ "$count" -eq 2 ] || ret=1 213# two lines indicating trust status 214count=$(grep -c "trust" rndc.out.$n) || true 215[ "$count" -eq 2 ] || ret=1 216# trust is revoked 217count=$(grep -c "trust revoked" rndc.out.$n) || true 218[ "$count" -eq 1 ] || ret=1 219# removal scheduled 220count=$(grep -c "remove at" rndc.out.$n) || true 221[ "$count" -eq 1 ] || ret=1 222# trust is still pending on the standby key 223count=$(grep -c "trust pending" rndc.out.$n) || true 224[ "$count" -eq 1 ] || ret=1 225# pending date moved forward for the standby key 226t2=$(grep "trust pending" ns2/managed-keys.bind) || true 227[ -n "$t2" ] || ret=1 228[ "$t1" = "$t2" ] && ret=1 229if [ $ret != 0 ]; then echo_i "failed"; fi 230status=$((status+ret)) 231 232n=$((n+1)) 233ret=0 234echo_i "refresh managed-keys, ensure same result ($n)" 235t1=$t2 236# Less than a second may have passed since the last time ns2 received a 237# ./DNSKEY response from ns1. Ensure keys are refreshed at a different 238# timestamp to prevent false negatives caused by the acceptance timer getting 239# reset to the same timestamp. 240sleep 1 241mkeys_refresh_on 2 || ret=1 242mkeys_sync_on 2 || ret=1 243mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 244# two keys listed 245count=$(grep -c "keyid: " rndc.out.$n) || true 246[ "$count" -eq 2 ] || ret=1 247# two lines indicating trust status 248count=$(grep -c "trust" rndc.out.$n) || true 249[ "$count" -eq 2 ] || ret=1 250# trust is revoked 251count=$(grep -c "trust revoked" rndc.out.$n) || true 252[ "$count" -eq 1 ] || ret=1 253# removal scheduled 254count=$(grep -c "remove at" rndc.out.$n) || true 255[ "$count" -eq 1 ] || ret=1 256# trust is still pending on the standby key 257count=$(grep -c "trust pending" rndc.out.$n) || true 258[ "$count" -eq 1 ] || ret=1 259# pending date moved forward for the standby key 260t2=$(grep "trust pending" ns2/managed-keys.bind) || true 261[ -n "$t2" ] || ret=1 262[ "$t1" = "$t2" ] && ret=1 263if [ $ret != 0 ]; then echo_i "failed"; fi 264status=$((status+ret)) 265 266n=$((n+1)) 267ret=0 268echo_i "restore revoked key, ensure same result ($n)" 269t1=$t2 270$SETTIME -R none -D now -K ns1 "$original" > /dev/null 271mkeys_loadkeys_on 1 || ret=1 272$SETTIME -D none -K ns1 "$original" > /dev/null 273mkeys_loadkeys_on 1 || ret=1 274# Less than a second may have passed since the last time ns2 received a 275# ./DNSKEY response from ns1. Ensure keys are refreshed at a different 276# timestamp to prevent false negatives caused by the acceptance timer getting 277# reset to the same timestamp. 278sleep 1 279mkeys_refresh_on 2 || ret=1 280mkeys_sync_on 2 || ret=1 281mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 282# two keys listed 283count=$(grep -c "keyid: " rndc.out.$n) || true 284[ "$count" -eq 2 ] || ret=1 285# two lines indicating trust status 286count=$(grep -c "trust" rndc.out.$n) || true 287[ "$count" -eq 2 ] || ret=1 288# trust is revoked 289count=$(grep -c "trust revoked" rndc.out.$n) || true 290[ "$count" -eq 1 ] || ret=1 291# removal scheduled 292count=$(grep -c "remove at" rndc.out.$n) || true 293[ "$count" -eq 1 ] || ret=1 294# trust is still pending on the standby key 295count=$(grep -c "trust pending" rndc.out.$n) || true 296[ "$count" -eq 1 ] || ret=1 297# pending date moved forward for the standby key 298t2=$(grep "trust pending" ns2/managed-keys.bind) || true 299[ -n "$t2" ] || ret=1 300[ "$t1" = "$t2" ] && ret=1 301if [ $ret != 0 ]; then echo_i "failed"; fi 302status=$((status+ret)) 303 304echo_i "reinitialize trust anchors, add second key to bind.keys" 305stop_server --use-rndc --port "${CONTROLPORT}" ns2 306rm -f ns2/managed-keys.bind* 307keyfile_to_initial_ds ns1/"$original" ns1/"$standby1" > ns2/managed.conf 308nextpart ns2/named.run > /dev/null 309start_server --noclean --restart --port "${PORT}" ns2 310 311n=$((n+1)) 312echo_i "check that no key from bind.keys is marked as an initializing key ($n)" 313ret=0 314wait_for_log 20 "Returned from key fetch in keyfetch_done()" ns2/named.run || ret=1 315mkeys_secroots_on 2 || ret=1 316grep '; initializing' ns2/named.secroots > /dev/null 2>&1 && ret=1 317if [ $ret != 0 ]; then echo_i "failed"; fi 318status=$((status+ret)) 319 320echo_i "reinitialize trust anchors, revert to one key in bind.keys" 321stop_server --use-rndc --port "${CONTROLPORT}" ns2 322rm -f ns2/managed-keys.bind* 323mv ns2/managed1.conf ns2/managed.conf 324nextpart ns2/named.run > /dev/null 325start_server --noclean --restart --port "${PORT}" ns2 326 327n=$((n+1)) 328echo_i "check that standby key is now trusted ($n)" 329ret=0 330wait_for_log 20 "Returned from key fetch in keyfetch_done()" ns2/named.run || ret=1 331mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 332# two keys listed 333count=$(grep -c "keyid: " rndc.out.$n) || true 334[ "$count" -eq 2 ] || ret=1 335# two lines indicating trust status 336count=$(grep -c "trust" rndc.out.$n) || true 337[ "$count" -eq 2 ] || ret=1 338# both indicate current trust 339count=$(grep -c "trusted since" rndc.out.$n) || true 340[ "$count" -eq 2 ] || ret=1 341if [ $ret != 0 ]; then echo_i "failed"; fi 342status=$((status+ret)) 343 344n=$((n+1)) 345echo_i "revoke original key, add new standby ($n)" 346ret=0 347standby2=$($KEYGEN -a ${DEFAULT_ALGORITHM} -qfk -K ns1 .) 348$SETTIME -R now -K ns1 "$original" > /dev/null 349mkeys_loadkeys_on 1 || ret=1 350mkeys_refresh_on 2 || ret=1 351mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 352# three keys listed 353count=$(grep -c "keyid: " rndc.out.$n) || true 354[ "$count" -eq 3 ] || ret=1 355# one is revoked 356count=$(grep -c "REVOKE" rndc.out.$n) || true 357[ "$count" -eq 1 ] || ret=1 358# three lines indicating trust status 359count=$(grep -c "trust" rndc.out.$n) || true 360[ "$count" -eq 3 ] || ret=1 361# one indicates current trust 362count=$(grep -c "trusted since" rndc.out.$n) || true 363[ "$count" -eq 1 ] || ret=1 364# one indicates revoked trust 365count=$(grep -c "trust revoked" rndc.out.$n) || true 366[ "$count" -eq 1 ] || ret=1 367# one indicates trust pending 368count=$(grep -c "trust pending" rndc.out.$n) || true 369[ "$count" -eq 1 ] || ret=1 370# removal scheduled 371count=$(grep -c "remove at" rndc.out.$n) || true 372[ "$count" -eq 1 ] || ret=1 373if [ $ret != 0 ]; then echo_i "failed"; fi 374status=$((status+ret)) 375 376n=$((n+1)) 377echo_i "revoke standby before it is trusted ($n)" 378ret=0 379standby3=$($KEYGEN -a ${DEFAULT_ALGORITHM} -qfk -K ns1 .) 380mkeys_loadkeys_on 1 || ret=1 381mkeys_refresh_on 2 || ret=1 382mkeys_status_on 2 > rndc.out.1.$n 2>&1 || ret=1 383# four keys listed 384count=$(grep -c "keyid: " rndc.out.1.$n) || true 385[ "$count" -eq 4 ] || { echo_i "keyid: count ($count) != 4"; ret=1; } 386# one revoked 387count=$(grep -c "trust revoked" rndc.out.1.$n) || true 388[ "$count" -eq 1 ] || { echo_i "trust revoked count ($count) != 1"; ret=1; } 389# two pending 390count=$(grep -c "trust pending" rndc.out.1.$n) || true 391[ "$count" -eq 2 ] || { echo_i "trust pending count ($count) != 2"; ret=1; } 392$SETTIME -R now -K ns1 "$standby3" > /dev/null 393mkeys_loadkeys_on 1 || ret=1 394mkeys_refresh_on 2 || ret=1 395mkeys_status_on 2 > rndc.out.2.$n 2>&1 || ret=1 396# now three keys listed 397count=$(grep -c "keyid: " rndc.out.2.$n) || true 398[ "$count" -eq 3 ] || { echo_i "keyid: count ($count) != 3"; ret=1; } 399# one revoked 400count=$(grep -c "trust revoked" rndc.out.2.$n) || true 401[ "$count" -eq 1 ] || { echo_i "trust revoked count ($count) != 1"; ret=1; } 402# one pending 403count=$(grep -c "trust pending" rndc.out.2.$n) || true 404[ "$count" -eq 1 ] || { echo_i "trust pending count ($count) != 1"; ret=1; } 405$SETTIME -D now -K ns1 "$standby3" > /dev/null 406mkeys_loadkeys_on 1 || ret=1 407if [ $ret != 0 ]; then echo_i "failed"; fi 408status=$((status+ret)) 409 410n=$((n+1)) 411echo_i "wait 20 seconds for key add/remove holddowns to expire ($n)" 412ret=0 413sleep 20 414mkeys_refresh_on 2 || ret=1 415mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 416# two keys listed 417count=$(grep -c "keyid: " rndc.out.$n) || true 418[ "$count" -eq 2 ] || ret=1 419# none revoked 420count=$(grep -c "REVOKE" rndc.out.$n) || true 421[ "$count" -eq 0 ] || ret=1 422# two lines indicating trust status 423count=$(grep -c "trust" rndc.out.$n) || true 424[ "$count" -eq 2 ] || ret=1 425# both indicate current trust 426count=$(grep -c "trusted since" rndc.out.$n) || true 427[ "$count" -eq 2 ] || ret=1 428if [ $ret != 0 ]; then echo_i "failed"; fi 429status=$((status+ret)) 430 431n=$((n+1)) 432echo_i "revoke all keys, confirm roll to insecure ($n)" 433ret=0 434$SETTIME -D now -K ns1 "$original" > /dev/null 435$SETTIME -R now -K ns1 "$standby1" > /dev/null 436$SETTIME -R now -K ns1 "$standby2" > /dev/null 437mkeys_loadkeys_on 1 || ret=1 438mkeys_refresh_on 2 || ret=1 439mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 440# two keys listed 441count=$(grep -c "keyid: " rndc.out.$n) || true 442[ "$count" -eq 2 ] || ret=1 443# both revoked 444count=$(grep -c "REVOKE" rndc.out.$n) || true 445[ "$count" -eq 2 ] || ret=1 446# two lines indicating trust status 447count=$(grep -c "trust" rndc.out.$n) || true 448[ "$count" -eq 2 ] || ret=1 449# both indicate trust revoked 450count=$(grep -c "trust revoked" rndc.out.$n) || true 451[ "$count" -eq 2 ] || ret=1 452# both have removal scheduled 453count=$(grep -c "remove at" rndc.out.$n) || true 454[ "$count" -eq 2 ] || ret=1 455if [ $ret != 0 ]; then echo_i "failed"; fi 456status=$((status+ret)) 457 458n=$((n+1)) 459echo_i "check for insecure response ($n)" 460ret=0 461mkeys_refresh_on 2 || ret=1 462dig_with_opts +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 463grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 464grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 465grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1 466if [ $ret != 0 ]; then echo_i "failed"; fi 467status=$((status+ret)) 468 469n=$((n+1)) 470echo_i "reset the root server ($n)" 471ret=0 472$SETTIME -D none -R none -K ns1 "$original" > /dev/null 473$SETTIME -D now -K ns1 "$standby1" > /dev/null 474$SETTIME -D now -K ns1 "$standby2" > /dev/null 475$SIGNER -Sg -K ns1 -N unixtime -o . ns1/root.db > /dev/null 2>/dev/null 476copy_setports ns1/named2.conf.in ns1/named.conf 477rm -f ns1/root.db.signed.jnl 478mkeys_reconfig_on 1 || ret=1 479mkeys_reload_on 1 || ret=1 480if [ $ret != 0 ]; then echo_i "failed"; fi 481status=$((status+ret)) 482 483echo_i "reinitialize trust anchors" 484stop_server --use-rndc --port "${CONTROLPORT}" ns2 485rm -f ns2/managed-keys.bind* 486nextpart ns2/named.run > /dev/null 487start_server --noclean --restart --port "${PORT}" ns2 488 489n=$((n+1)) 490echo_i "check positive validation ($n)" 491ret=0 492wait_for_log 20 "Returned from key fetch in keyfetch_done()" ns2/named.run || ret=1 493dig_with_opts +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 494grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 495grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1 496if [ $ret != 0 ]; then echo_i "failed"; fi 497status=$((status+ret)) 498 499n=$((n+1)) 500echo_i "revoke key with bad signature, check revocation is ignored ($n)" 501ret=0 502revoked=$($REVOKE -K ns1 "$original") 503rkeyid=$(keyfile_to_key_id "$revoked") 504rm -f ns1/root.db.signed.jnl 505# We need to activate at least one valid DNSKEY to prevent dnssec-signzone from 506# failing. Alternatively, we could use -P to disable post-sign verification, 507# but we actually do want post-sign verification to happen to ensure the zone 508# is correct before we break it on purpose. 509$SETTIME -R none -D none -K ns1 "$standby1" > /dev/null 510$SIGNER -Sg -K ns1 -N unixtime -O full -o . -f signer.out.$n ns1/root.db > /dev/null 2>/dev/null 511cp -f ns1/root.db.signed ns1/root.db.tmp 512BADSIG="SVn2tLDzpNX2rxR4xRceiCsiTqcWNKh7NQ0EQfCrVzp9WEmLw60sQ5kP xGk4FS/xSKfh89hO2O/H20Bzp0lMdtr2tKy8IMdU/mBZxQf2PXhUWRkg V2buVBKugTiOPTJSnaqYCN3rSfV1o7NtC1VNHKKK/D5g6bpDehdn5Gaq kpBhN+MSCCh9OZP2IT20luS1ARXxLlvuSVXJ3JYuuhTsQXUbX/SQpNoB Lo6ahCE55szJnmAxZEbb2KOVnSlZRA6ZBHDhdtO0S4OkvcmTutvcVV+7 w53CbKdaXhirvHIh0mZXmYk2PbPLDY7PU9wSH40UiWPOB9f00wwn6hUe uEQ1Qg==" 513# Less than a second may have passed since ns1 was started. If we call 514# dnssec-signzone immediately, ns1/root.db.signed will not be reloaded by the 515# subsequent "rndc reload ." call on platforms which do not set the 516# "nanoseconds" field of isc_time_t, due to zone load time being seemingly 517# equal to master file modification time. 518sleep 1 519sed -e "/ $rkeyid \./s, \. .*$, . $BADSIG," signer.out.$n > ns1/root.db.signed 520mkeys_reload_on 1 || ret=1 521mkeys_refresh_on 2 || ret=1 522mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 523# one key listed 524count=$(grep -c "keyid: " rndc.out.$n) || true 525[ "$count" -eq 1 ] || { echo_i "'keyid:' count ($count) != 1"; ret=1; } 526# it's the original key id 527count=$(grep -c "keyid: $originalid" rndc.out.$n) || true 528[ "$count" -eq 1 ] || { echo_i "'keyid: $originalid' count ($count) != 1"; ret=1; } 529# not revoked 530count=$(grep -c "REVOKE" rndc.out.$n) || true 531[ "$count" -eq 0 ] || { echo_i "'REVOKE' count ($count) != 0"; ret=1; } 532# trust is still current 533count=$(grep -c "trust" rndc.out.$n) || true 534[ "$count" -eq 1 ] || { echo_i "'trust' count != 1"; ret=1; } 535count=$(grep -c "trusted since" rndc.out.$n) || true 536[ "$count" -eq 1 ] || { echo_i "'trusted since' count != 1"; ret=1; } 537if [ $ret != 0 ]; then echo_i "failed"; fi 538status=$((status+ret)) 539 540n=$((n+1)) 541echo_i "check validation fails with bad DNSKEY rrset ($n)" 542ret=0 543mkeys_flush_on 2 || ret=1 544dig_with_opts +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 545grep "status: SERVFAIL" dig.out.ns2.test$n > /dev/null || ret=1 546if [ $ret != 0 ]; then echo_i "failed"; fi 547status=$((status+ret)) 548 549n=$((n+1)) 550echo_i "restore DNSKEY rrset, check validation succeeds again ($n)" 551ret=0 552rm -f "${revoked}".key "${revoked}".private 553rm -f ns1/root.db.signed.jnl 554$SETTIME -D none -R none -K ns1 "$original" > /dev/null 555$SETTIME -D now -K ns1 "$standby1" > /dev/null 556# Less than a second may have passed since ns1 was started. If we call 557# dnssec-signzone immediately, ns1/root.db.signed will not be reloaded by the 558# subsequent "rndc reload ." call on platforms which do not set the 559# "nanoseconds" field of isc_time_t, due to zone load time being seemingly 560# equal to master file modification time. 561sleep 1 562$SIGNER -Sg -K ns1 -N unixtime -o . ns1/root.db > /dev/null 2>/dev/null 563mkeys_reload_on 1 || ret=1 564mkeys_flush_on 2 || ret=1 565dig_with_opts +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 566grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 567grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1 568if [ $ret != 0 ]; then echo_i "failed"; fi 569status=$((status+ret)) 570 571if [ ! "$CYGWIN" ]; then 572 n=$((n+1)) 573 echo_i "reset the root server with no keys, check for minimal update ($n)" 574 ret=0 575 # Refresh keys first to prevent previous checks from influencing this one. 576 # Note that we might still get occasional false negatives on some really slow 577 # machines, when $t1 equals $t2 due to the time elapsed between "rndc 578 # managed-keys status" calls being equal to the normal active refresh period 579 # (as calculated per rules listed in RFC 5011 section 2.3) minus an "hour" (as 580 # set using -T mkeytimers). 581 mkeys_refresh_on 2 || ret=1 582 mkeys_status_on 2 > rndc.out.1.$n 2>&1 || ret=1 583 t1=$(grep 'next refresh:' rndc.out.1.$n) || true 584 stop_server --use-rndc --port "${CONTROLPORT}" ns1 585 rm -f ns1/root.db.signed.jnl 586 cp ns1/root.db ns1/root.db.signed 587 nextpart ns1/named.run > /dev/null 588 start_server --noclean --restart --port "${PORT}" ns1 589 wait_for_log 20 "all zones loaded" ns1/named.run || ret=1 590 mkeys_refresh_on 2 || ret=1 591 mkeys_status_on 2 > rndc.out.2.$n 2>&1 || ret=1 592 # one key listed 593 count=$(grep -c "keyid: " rndc.out.2.$n) || true 594 [ "$count" -eq 1 ] || ret=1 595 # it's the original key id 596 count=$(grep -c "keyid: $originalid" rndc.out.2.$n) || true 597 [ "$count" -eq 1 ] || ret=1 598 # not revoked 599 count=$(grep -c "REVOKE" rndc.out.2.$n) || true 600 [ "$count" -eq 0 ] || ret=1 601 # trust is still current 602 count=$(grep -c "trust" rndc.out.2.$n) || true 603 [ "$count" -eq 1 ] || ret=1 604 count=$(grep -c "trusted since" rndc.out.2.$n) || true 605 [ "$count" -eq 1 ] || ret=1 606 t2=$(grep 'next refresh:' rndc.out.2.$n) || true 607 [ "$t1" = "$t2" ] && ret=1 608 if [ $ret != 0 ]; then echo_i "failed"; fi 609 status=$((status+ret)) 610fi 611 612n=$((n+1)) 613echo_i "reset the root server with no signatures, check for minimal update ($n)" 614ret=0 615# Refresh keys first to prevent previous checks from influencing this one 616mkeys_refresh_on 2 || ret=1 617mkeys_status_on 2 > rndc.out.1.$n 2>&1 || ret=1 618t1=$(grep 'next refresh:' rndc.out.1.$n) || true 619stop_server --use-rndc --port "${CONTROLPORT}" ns1 620rm -f ns1/root.db.signed.jnl 621cat ns1/K*.key >> ns1/root.db.signed 622nextpart ns1/named.run > /dev/null 623start_server --noclean --restart --port "${PORT}" ns1 624wait_for_log 20 "all zones loaded" ns1/named.run || ret=1 625# Less than a second may have passed since the last time ns2 received a 626# ./DNSKEY response from ns1. Ensure keys are refreshed at a different 627# timestamp to prevent minimal update from resetting it to the same timestamp. 628sleep 1 629mkeys_refresh_on 2 || ret=1 630mkeys_status_on 2 > rndc.out.2.$n 2>&1 || ret=1 631# one key listed 632count=$(grep -c "keyid: " rndc.out.2.$n) || true 633[ "$count" -eq 1 ] || ret=1 634# it's the original key id 635count=$(grep -c "keyid: $originalid" rndc.out.2.$n) || true 636[ "$count" -eq 1 ] || ret=1 637# not revoked 638count=$(grep -c "REVOKE" rndc.out.2.$n) || true 639[ "$count" -eq 0 ] || ret=1 640# trust is still current 641count=$(grep -c "trust" rndc.out.2.$n) || true 642[ "$count" -eq 1 ] || ret=1 643count=$(grep -c "trusted since" rndc.out.2.$n) || true 644[ "$count" -eq 1 ] || ret=1 645t2=$(grep 'next refresh:' rndc.out.2.$n) || true 646[ "$t1" = "$t2" ] && ret=1 647if [ $ret != 0 ]; then echo_i "failed"; fi 648status=$((status+ret)) 649 650n=$((n+1)) 651echo_i "restore root server, check validation succeeds again ($n)" 652ret=0 653rm -f ns1/root.db.signed.jnl 654$SIGNER -Sg -K ns1 -N unixtime -o . ns1/root.db > /dev/null 2>/dev/null 655mkeys_reload_on 1 || ret=1 656mkeys_refresh_on 2 || ret=1 657mkeys_status_on 2 > rndc.out.$n 2>&1 || ret=1 658dig_with_opts +noauth example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 659grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 660grep "example..*.RRSIG..*TXT" dig.out.ns2.test$n > /dev/null || ret=1 661if [ $ret != 0 ]; then echo_i "failed"; fi 662status=$((status+ret)) 663 664n=$((n+1)) 665echo_i "check that trust-anchor-telemetry queries are logged ($n)" 666ret=0 667grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/NULL" ns2/named.run > /dev/null || ret=1 668if [ $ret != 0 ]; then echo_i "failed"; fi 669status=$((status+ret)) 670 671n=$((n+1)) 672echo_i "check that trust-anchor-telemetry queries are received ($n)" 673ret=0 674grep "query '_ta-[0-9a-f][0-9a-f]*/NULL/IN' approved" ns1/named.run > /dev/null || ret=1 675if [ $ret != 0 ]; then echo_i "failed"; fi 676status=$((status+ret)) 677 678n=$((n+1)) 679echo_i "check 'rndc-managed-keys destroy' ($n)" 680ret=0 681rndccmd 10.53.0.2 managed-keys destroy | sed 's/^/ns2 /' | cat_i 682mkeys_status_on 2 > rndc.out.1.$n 2>&1 || ret=1 683grep "no views with managed keys" rndc.out.1.$n > /dev/null || ret=1 684mkeys_reconfig_on 2 || ret=1 685check_root_trust_anchor_is_present_in_status() { 686 mkeys_status_on 2 > rndc.out.2.$n 2>&1 || return 1 687 grep "name: \." rndc.out.2.$n > /dev/null || return 1 688 return 0 689} 690retry_quiet 5 check_root_trust_anchor_is_present_in_status || ret=1 691if [ $ret != 0 ]; then echo_i "failed"; fi 692status=$((status+ret)) 693 694n=$((n+1)) 695echo_i "check that trust-anchor-telemetry queries contain the correct key ($n)" 696ret=0 697# convert the hexadecimal key from the TAT query into decimal and 698# compare against the known key. 699tathex=$(grep "query '_ta-[0-9a-f][0-9a-f]*/NULL/IN' approved" ns1/named.run | awk '{print $6; exit 0}' | sed -e 's/(_ta-\([0-9a-f][0-9a-f]*\)):/\1/') || true 700tatkey=$($PERL -e 'printf("%d\n", hex(@ARGV[0]));' "$tathex") 701realkey=$(rndccmd 10.53.0.2 secroots - | sed -n "s#.*${DEFAULT_ALGORITHM}/\([0-9][0-9]*\) ; .*managed.*#\1#p") 702[ "$tatkey" -eq "$realkey" ] || ret=1 703if [ $ret != 0 ]; then echo_i "failed"; fi 704status=$((status+ret)) 705 706n=$((n+1)) 707echo_i "check initialization fails if managed-keys can't be created ($n)" 708ret=0 709mkeys_secroots_on 4 || ret=1 710grep '; initializing managed' ns4/named.secroots > /dev/null 2>&1 || ret=1 711grep '; managed' ns4/named.secroots > /dev/null 2>&1 && ret=1 712grep '; trusted' ns4/named.secroots > /dev/null 2>&1 && ret=1 713if [ $ret != 0 ]; then echo_i "failed"; fi 714status=$((status+ret)) 715 716n=$((n+1)) 717echo_i "check failure to contact root servers does not prevent key refreshes after restart ($n)" 718ret=0 719# By the time we get here, ns5 should have attempted refreshing its managed 720# keys. These attempts should fail as ns1 is configured to REFUSE all queries 721# from ns5. Note that named1.args does not contain "-T mkeytimers"; this is to 722# ensure key refresh retry will be scheduled to one actual hour after the first 723# key refresh failure instead of just a few seconds, in order to prevent races 724# between the next scheduled key refresh time and startup time of restarted ns5. 725stop_server --use-rndc --port "${CONTROLPORT}" ns5 726nextpart ns5/named.run > /dev/null 727start_server --noclean --restart --port "${PORT}" ns5 728wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for '.':" ns5/named.run || ret=1 729wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for 'sub.tld':" ns5/named.run || ret=1 730wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for 'sub.foo':" ns5/named.run || ret=1 731# ns5/named.run will contain logs from both the old instance and the new 732# instance. In order for the test to pass, both must attempt a fetch. 733count=$(grep -c "Creating key fetch" ns5/named.run) || true 734[ "$count" -lt 2 ] && ret=1 735if [ $ret != 0 ]; then echo_i "failed"; fi 736status=$((status+ret)) 737 738n=$((n+1)) 739echo_i "check 'rndc managed-keys' and islands of trust root unreachable ($n)" 740ret=0 741mkeys_sync_on 5 742mkeys_status_on 5 > rndc.out.$n 2>&1 || ret=1 743# there should be three keys listed now 744count=$(grep -c "keyid: " rndc.out.$n) || true 745[ "$count" -eq 3 ] || ret=1 746# three lines indicating trust status 747count=$(grep -c "trust" rndc.out.$n) || true 748[ "$count" -eq 3 ] || ret=1 749# one indicates current trust 750count=$(grep -c "trusted since" rndc.out.$n) || true 751[ "$count" -eq 1 ] || ret=1 752if [ $ret != 0 ]; then echo_i "failed"; fi 753status=$((status+ret)) 754 755n=$((n+1)) 756echo_i "check key refreshes are resumed after root servers become available ($n)" 757ret=0 758stop_server --use-rndc --port "${CONTROLPORT}" ns5 759# Prevent previous check from affecting this one 760rm -f ns5/managed-keys.bind* 761# named2.args adds "-T mkeytimers=2/20/40" to named1.args as we need to wait for 762# an "hour" until keys are refreshed again after initial failure 763cp ns5/named2.args ns5/named.args 764nextpart ns5/named.run > /dev/null 765start_server --noclean --restart --port "${PORT}" ns5 766wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for '.': failure" ns5/named.run || ret=1 767wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for 'sub.tld': failure" ns5/named.run || ret=1 768wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for 'sub.foo': success" ns5/named.run || ret=1 769mkeys_secroots_on 5 || ret=1 770grep '; initializing managed' ns5/named.secroots > /dev/null 2>&1 || ret=1 771# ns1 should still REFUSE queries from ns5, so resolving should be impossible 772dig_with_opts +noauth example. @10.53.0.5 txt > dig.out.ns5.a.test$n || ret=1 773grep "flags:.*ad.*QUERY" dig.out.ns5.a.test$n > /dev/null && ret=1 774grep "example..*.RRSIG..*TXT" dig.out.ns5.a.test$n > /dev/null && ret=1 775grep "status: SERVFAIL" dig.out.ns5.a.test$n > /dev/null || ret=1 776# Allow queries from ns5 to ns1 777copy_setports ns1/named3.conf.in ns1/named.conf 778rm -f ns1/root.db.signed.jnl 779nextpart ns5/named.run > /dev/null 780mkeys_reconfig_on 1 || ret=1 781wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for '.': success" ns5/named.run || ret=1 782wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for 'sub.tld': success" ns5/named.run || ret=1 783wait_for_log_peek 20 "Returned from key fetch in keyfetch_done() for 'sub.foo': success" ns5/named.run || ret=1 784mkeys_secroots_on 5 || ret=1 785grep '; managed' ns5/named.secroots > /dev/null || ret=1 786# ns1 should not longer REFUSE queries from ns5, so managed keys should be 787# correctly refreshed and resolving should succeed 788dig_with_opts +noauth example. @10.53.0.5 txt > dig.out.ns5.b.test$n || ret=1 789grep "flags:.*ad.*QUERY" dig.out.ns5.b.test$n > /dev/null || ret=1 790grep "example..*.RRSIG..*TXT" dig.out.ns5.b.test$n > /dev/null || ret=1 791grep "status: NOERROR" dig.out.ns5.b.test$n > /dev/null || ret=1 792if [ $ret != 0 ]; then echo_i "failed"; fi 793status=$((status+ret)) 794 795n=$((n+1)) 796echo_i "reinitialize trust anchors, add unsupported algorithm ($n)" 797ret=0 798stop_server --use-rndc --port "${CONTROLPORT}" ns6 799rm -f ns6/managed-keys.bind* 800nextpart ns6/named.run > /dev/null 801start_server --noclean --restart --port "${PORT}" ns6 802# log when an unsupported algorithm is encountered during startup 803wait_for_log 20 "ignoring initial-key for 'unsupported.': algorithm is unsupported" ns6/named.run || ret=1 804if [ $ret != 0 ]; then echo_i "failed"; fi 805status=$((status+ret)) 806 807n=$((n+1)) 808echo_i "ignoring unsupported algorithm in managed-keys ($n)" 809ret=0 810mkeys_status_on 6 > rndc.out.$n 2>&1 || ret=1 811# there should still be only two keys listed (for . and island.) 812count=$(grep -c "keyid: " rndc.out.$n) || true 813[ "$count" -eq 2 ] || ret=1 814# two lines indicating trust status 815count=$(grep -c "trust" rndc.out.$n) || true 816[ "$count" -eq 2 ] || ret=1 817 818n=$((n+1)) 819echo_i "introduce unsupported algorithm rollover in authoritative zone ($n)" 820ret=0 821cp ns1/root.db ns1/root.db.orig 822ksk=$(cat ns1/managed.key) 823zsk=$(cat ns1/zone.key) 824cat "ns1/${ksk}.key" "ns1/${zsk}.key" ns1/unsupported.key >> ns1/root.db 825grep "\.[[:space:]]*IN[[:space:]]*DNSKEY[[:space:]]*257 3 255" ns1/root.db > /dev/null || ret=1 826$SIGNER -K ns1 -N unixtime -o . ns1/root.db "$ksk" "$zsk" > /dev/null 2>/dev/null || ret=1 827grep "DNSKEY.*257 3 255" ns1/root.db.signed > /dev/null || ret=1 828cp ns1/root.db.orig ns1/root.db 829if [ $ret != 0 ]; then echo_i "failed"; fi 830status=$((status+ret)) 831 832n=$((n+1)) 833echo_i "ignoring unsupported algorithm in rollover ($n)" 834ret=0 835mkeys_reload_on 1 || ret=1 836mkeys_refresh_on 6 || ret=1 837mkeys_status_on 6 > rndc.out.$n 2>&1 || ret=1 838# there should still be only two keys listed (for . and island.) 839count=$(grep -c "keyid: " rndc.out.$n) || true 840[ "$count" -eq 2 ] || ret=1 841# two lines indicating trust status 842count=$(grep -c "trust" rndc.out.$n) || true 843[ "$count" -eq 2 ] || ret=1 844# log when an unsupported algorithm is encountered during rollover 845wait_for_log 20 "Cannot compute tag for key in zone .: algorithm is unsupported" ns6/named.run || ret=1 846if [ $ret != 0 ]; then echo_i "failed"; fi 847status=$((status+ret)) 848 849n=$((n+1)) 850echo_i "check 'rndc managed-keys' and views ($n)" 851ret=0 852rndccmd 10.53.0.7 managed-keys refresh in view1 > rndc.out.ns7.view1.test$n || ret=1 853grep "refreshing managed keys for 'view1'" rndc.out.ns7.view1.test$n > /dev/null || ret=1 854lines=$(wc -l < rndc.out.ns7.view1.test$n) 855[ "$lines" -eq 1 ] || ret=1 856rndccmd 10.53.0.7 managed-keys refresh > rndc.out.ns7.view2.test$n || ret=1 857lines=$(wc -l < rndc.out.ns7.view2.test$n) 858grep "refreshing managed keys for 'view1'" rndc.out.ns7.view2.test$n > /dev/null || ret=1 859grep "refreshing managed keys for 'view2'" rndc.out.ns7.view2.test$n > /dev/null || ret=1 860[ "$lines" -eq 2 ] || ret=1 861if [ $ret != 0 ]; then echo_i "failed"; fi 862status=$((status+ret)) 863 864n=$((n+1)) 865echo_i "check 'rndc managed-keys' and islands of trust now that root is reachable ($n)" 866ret=0 867mkeys_sync_on 5 868mkeys_status_on 5 > rndc.out.$n 2>&1 || ret=1 869# there should be three keys listed now 870count=$(grep -c "keyid: " rndc.out.$n) || true 871[ "$count" -eq 3 ] || ret=1 872# theee lines indicating trust status 873count=$(grep -c "trust" rndc.out.$n) || true 874[ "$count" -eq 3 ] || ret=1 875# three indicates current trust 876count=$(grep -c "trusted since" rndc.out.$n) || true 877[ "$count" -eq 3 ] || ret=1 878if [ $ret != 0 ]; then echo_i "failed"; fi 879status=$((status+ret)) 880 881echo_i "exit status: $status" 882[ $status -eq 0 ] || exit 1 883