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