From 72530d2f9c88ffeb0ce9b2da1b023e1f7a55357b Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 26 Oct 2022 09:51:21 +0200 Subject: [PATCH 1/2] Add new upforwd system test Add a new upforwd system test that checks if update forwarding still works if the first primary is badly configured. We cannot reuse the 'example.' zone for this test because that checks if update forwarding works for DoT. What transport is used in the new test is of no relevance. Update the system test to use different known good file names for the different zones that are being tested. --- bin/tests/system/upforwd/CA/CA.pem | 29 ++++ .../system/upforwd/knowngood.after1.example3 | 10 ++ .../system/upforwd/knowngood.before.example3 | 8 ++ bin/tests/system/upforwd/ns1/example3.db | 18 +++ bin/tests/system/upforwd/ns1/named.conf.in | 6 + bin/tests/system/upforwd/ns2/named.conf.in | 6 + bin/tests/system/upforwd/ns3/named.conf.in | 17 ++- bin/tests/system/upforwd/tests.sh | 128 ++++++++++++++---- 8 files changed, 191 insertions(+), 31 deletions(-) create mode 100644 bin/tests/system/upforwd/CA/CA.pem create mode 100644 bin/tests/system/upforwd/knowngood.after1.example3 create mode 100644 bin/tests/system/upforwd/knowngood.before.example3 create mode 100644 bin/tests/system/upforwd/ns1/example3.db diff --git a/bin/tests/system/upforwd/CA/CA.pem b/bin/tests/system/upforwd/CA/CA.pem new file mode 100644 index 0000000000..1f725dbb8a --- /dev/null +++ b/bin/tests/system/upforwd/CA/CA.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE3TCCA0WgAwIBAgIUeZPKrvbGEBZaRc2jNczlIsJXyPYwDQYJKoZIhvcNAQEL +BQAwfTELMAkGA1UEBhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4G +A1UEBwwHS2hhcmtpdjEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0 +aXVtMRwwGgYDVQQDDBNjYS50ZXN0LmV4YW1wbGUuY29tMCAXDTIyMDEyNDEyNDA1 +NFoYDzIwNTIwMTE3MTI0MDU0WjB9MQswCQYDVQQGEwJVQTEYMBYGA1UECAwPS2hh +cmtpdiBPYmxhc3QnMRAwDgYDVQQHDAdLaGFya2l2MSQwIgYDVQQKDBtJbnRlcm5l +dCBTeXN0ZW1zIENvbnNvcnRpdW0xHDAaBgNVBAMME2NhLnRlc3QuZXhhbXBsZS5j +b20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCi6hEegBzpUKbE1NTo +Z7uz7EMUY7TBckkiw/7ydTLKNa8YI4JpBguFvWQsDY0dGFJIoVwyHyNx3seW/LoI +B5zWPZ2xbOvLLceA+t2NZpbc98E7jUOVS123yED+nqlfZjCq9Zt0r/ezwnQtjnFF +ko1mcU4H9Jvg8aIgnU2AxE78zciU9CY8799pFFNThIjbooI8oVbfjbzbpmLzxjA5 +3rDmZBTh+ySTlMa2U2oT4WPjRltZWnJVegRRLpG95GnTbQ1fkJAbj1Iu10XTkCee +wBOqaA1UJem0a6pby5odE414Y7c0ETKcmaJtYENQyO0IJwZWDKtVe5OTIAklakia +eyFTCAw1h5tHCYLaJW/Yu2wlLl5RNQcRZ9+cWXnldTY+TI1iBjfmADjLdKJYUlhX +z7kWJtTi63Sdv6WYcEXxaWpxT+R3e2kaR/R7GOo4gdkWpX1siGlRteHHH2/36CSQ +ZD2etcTUpGW+KDHFR4grnEfL1rt9UgvCjpa4KcssmZtWSSUCAwEAAaNTMFEwHQYD +VR0OBBYEFHyJ6Fzr5R9ySATFj/uSCJz1YCY5MB8GA1UdIwQYMBaAFHyJ6Fzr5R9y +SATFj/uSCJz1YCY5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggGB +AF3y0hvzyZWtmuG1JwIcOcc1aPl1KdRy8bao/5iHYGYYrsdDgcO5/e+y9S/izalc +TdW7SKB5iBOCiE8fBNtToCvGP+fxNxHijpAmTr37G5sWuSo1T1VYFizHWL+df/Ig +TcSvDrEjSnAwaEdNJUWtjoIC4VzNKTLtZf16QIATTzTZa3bfgSetpWS7LhLQbHod +CSGI2QB1LRbqGC+a1Y85QxHv81jWzPWPzXYvnOLrDdQyBMOBcxDzrN4b6zg+5Itz +qGYt+IS71jAH0IhxAyD/U5n1jGJv02BnSq0ynLEOD6gsnZjqAwPbt/PM9pGbtbXO +70Q9rxr+vQc1IISKAEiH3txaEPi10wU98d6LbInJvQrmgHo/ntet8skWNYuxlEzS +wvynuE9KvvQtOTodWt5AePtKrhHdxu527a4CHVp59nYUjKSdMKjvmhMRXM1cNjFE +rA/pyyhozR47w3RzHMJVHw2GJ2B/HeqmxpXr1CmJjoRP38QCR7N+mqiZy85Fq2j2 +8Q== +-----END CERTIFICATE----- diff --git a/bin/tests/system/upforwd/knowngood.after1.example3 b/bin/tests/system/upforwd/knowngood.after1.example3 new file mode 100644 index 0000000000..c37ca2f2ac --- /dev/null +++ b/bin/tests/system/upforwd/knowngood.after1.example3 @@ -0,0 +1,10 @@ +example3. 3600 IN SOA n1.example3. hostmaster.ns1.example3. 2 3600 1200 604800 7200 +example3. 3600 IN NS ns2.example3. +example3. 3600 IN NS ns3.example3. +ns1.example3. 3600 IN A 10.53.0.1 +ns2.example3. 3600 IN A 10.53.0.2 +ns3.example3. 3600 IN A 10.53.0.3 +updated.example3. 600 IN TXT "Foo" +updated.example3. 600 IN A 10.10.10.1 +example3. 3600 IN SOA n1.example3. hostmaster.ns1.example3. 2 3600 1200 604800 7200 + diff --git a/bin/tests/system/upforwd/knowngood.before.example3 b/bin/tests/system/upforwd/knowngood.before.example3 new file mode 100644 index 0000000000..f47a88e510 --- /dev/null +++ b/bin/tests/system/upforwd/knowngood.before.example3 @@ -0,0 +1,8 @@ +example3. 3600 IN SOA n1.example3. hostmaster.ns1.example3. 1 3600 1200 604800 7200 +example3. 3600 IN NS ns2.example3. +example3. 3600 IN NS ns3.example3. +ns1.example3. 3600 IN A 10.53.0.1 +ns2.example3. 3600 IN A 10.53.0.2 +ns3.example3. 3600 IN A 10.53.0.3 +example3. 3600 IN SOA n1.example3. hostmaster.ns1.example3. 1 3600 1200 604800 7200 + diff --git a/bin/tests/system/upforwd/ns1/example3.db b/bin/tests/system/upforwd/ns1/example3.db new file mode 100644 index 0000000000..e32614cb68 --- /dev/null +++ b/bin/tests/system/upforwd/ns1/example3.db @@ -0,0 +1,18 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +@ 3600 SOA n1.example3. hostmaster.ns1.example3. ( + 1 3600 1200 604800 7200 ) + NS ns2.example3. + NS ns3.example3. +ns1 A 10.53.0.1 +ns2 A 10.53.0.2 +ns3 A 10.53.0.3 diff --git a/bin/tests/system/upforwd/ns1/named.conf.in b/bin/tests/system/upforwd/ns1/named.conf.in index dad7b2ffbf..a2ae56448c 100644 --- a/bin/tests/system/upforwd/ns1/named.conf.in +++ b/bin/tests/system/upforwd/ns1/named.conf.in @@ -41,3 +41,9 @@ zone "example2" { file "example2.db"; allow-update { key sig0.example2.; }; }; + +zone "example3" { + type primary; + file "example3.db"; + allow-update { key update.example.; 10.53.0.3; }; +}; diff --git a/bin/tests/system/upforwd/ns2/named.conf.in b/bin/tests/system/upforwd/ns2/named.conf.in index dd2de8b6ef..34d6d52047 100644 --- a/bin/tests/system/upforwd/ns2/named.conf.in +++ b/bin/tests/system/upforwd/ns2/named.conf.in @@ -34,3 +34,9 @@ zone "example2" { file "example2.bk"; primaries { 10.53.0.1; }; }; + +zone "example3" { + type secondary; + file "example3.bk"; + primaries { 10.53.0.1; }; +}; diff --git a/bin/tests/system/upforwd/ns3/named.conf.in b/bin/tests/system/upforwd/ns3/named.conf.in index abb6770c09..ed4f421537 100644 --- a/bin/tests/system/upforwd/ns3/named.conf.in +++ b/bin/tests/system/upforwd/ns3/named.conf.in @@ -35,11 +35,16 @@ controls { inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; }; +tls tls-example-primary { + remote-hostname "srv01.crt01.example.com"; // enable Strict TLS + ca-file "../CA/CA.pem"; +}; + zone "example" { type secondary; file "example.bk"; allow-update-forwarding { any; }; - primaries { 10.53.0.1 port @TLSPORT@ tls ephemeral; }; + primaries { 10.53.0.1 tls ephemeral; }; }; zone "example2" { @@ -49,6 +54,16 @@ zone "example2" { primaries { 10.53.0.1; }; }; +zone "example3" { + type secondary; + file "example3.bk"; + allow-update-forwarding { any; }; + primaries { + 10.53.0.1 tls tls-example-primary; // bad + 10.53.0.1; // good + }; +}; + zone "noprimary" { type secondary; file "noprimary1.db"; diff --git a/bin/tests/system/upforwd/tests.sh b/bin/tests/system/upforwd/tests.sh index 33227c363d..7aeaa4a746 100644 --- a/bin/tests/system/upforwd/tests.sh +++ b/bin/tests/system/upforwd/tests.sh @@ -39,12 +39,12 @@ echo_i "waiting for servers to be ready for testing ($n)" for i in 1 2 3 4 5 6 7 8 9 10 do ret=0 - $DIG +tcp -p ${PORT} example. @10.53.0.1 soa > dig.out.ns1 || ret=1 - grep "status: NOERROR" dig.out.ns1 > /dev/null || ret=1 - $DIG +tcp -p ${PORT} example. @10.53.0.2 soa > dig.out.ns2 || ret=1 - grep "status: NOERROR" dig.out.ns2 > /dev/null || ret=1 - $DIG +tcp -p ${PORT} example. @10.53.0.3 soa > dig.out.ns3 || ret=1 - grep "status: NOERROR" dig.out.ns3 > /dev/null || ret=1 + $DIG +tcp -p ${PORT} example. @10.53.0.1 soa > dig.out.ns1.$n || ret=1 + grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1 + $DIG +tcp -p ${PORT} example. @10.53.0.2 soa > dig.out.ns2.$n || ret=1 + grep "status: NOERROR" dig.out.ns2.$n > /dev/null || ret=1 + $DIG +tcp -p ${PORT} example. @10.53.0.3 soa > dig.out.ns3.$n || ret=1 + grep "status: NOERROR" dig.out.ns3.$n > /dev/null || ret=1 test $ret = 0 && break sleep 1 done @@ -54,28 +54,28 @@ n=`expr $n + 1` echo_i "fetching primary copy of zone before update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.1 axfr > dig.out.ns1 || ret=1 + @10.53.0.1 axfr > dig.out.ns1.example.before || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "fetching secondary 1 copy of zone before update ($n)" $DIG $DIGOPTS example.\ - @10.53.0.2 axfr > dig.out.ns2 || ret=1 + @10.53.0.2 axfr > dig.out.ns2.example.before || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "fetching secondary 2 copy of zone before update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.3 axfr > dig.out.ns3 || ret=1 + @10.53.0.3 axfr > dig.out.ns3.example.before || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "comparing pre-update copies to known good data ($n)" ret=0 -digcomp knowngood.before dig.out.ns1 || ret=1 -digcomp knowngood.before dig.out.ns2 || ret=1 -digcomp knowngood.before dig.out.ns3 || ret=1 +digcomp knowngood.before dig.out.ns1.example.before || ret=1 +digcomp knowngood.before dig.out.ns2.example.before || ret=1 +digcomp knowngood.before dig.out.ns3.example.before || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "checking update forwarding of a zone (signed) (Do53 -> DoT) ($n)" @@ -95,28 +95,28 @@ sleep 15 echo_i "fetching primary copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.1 axfr > dig.out.ns1 || ret=1 + @10.53.0.1 axfr > dig.out.ns1.example.after1 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "fetching secondary 1 copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.2 axfr > dig.out.ns2 || ret=1 + @10.53.0.2 axfr > dig.out.ns2.example.after1 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "fetching secondary 2 copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.3 axfr > dig.out.ns3 || ret=1 + @10.53.0.3 axfr > dig.out.ns3.example.after1 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "comparing post-update copies to known good data ($n)" ret=0 -digcomp knowngood.after1 dig.out.ns1 || ret=1 -digcomp knowngood.after1 dig.out.ns2 || ret=1 -digcomp knowngood.after1 dig.out.ns3 || ret=1 +digcomp knowngood.after1 dig.out.ns1.example.after1 || ret=1 +digcomp knowngood.after1 dig.out.ns2.example.after1 || ret=1 +digcomp knowngood.after1 dig.out.ns3.example.after1 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "checking update forwarding of a zone (signed) (DoT -> DoT) ($n)" @@ -136,28 +136,28 @@ sleep 15 echo_i "fetching primary copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.1 axfr > dig.out.ns1 || ret=1 + @10.53.0.1 axfr > dig.out.ns1.example.after2 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "fetching secondary 1 copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.2 axfr > dig.out.ns2 || ret=1 + @10.53.0.2 axfr > dig.out.ns2.example.after2 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "fetching secondary 2 copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.3 axfr > dig.out.ns3 || ret=1 + @10.53.0.3 axfr > dig.out.ns3.example.after2 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "comparing post-update copies to known good data ($n)" ret=0 -digcomp knowngood.after2 dig.out.ns1 || ret=1 -digcomp knowngood.after2 dig.out.ns2 || ret=1 -digcomp knowngood.after2 dig.out.ns3 || ret=1 +digcomp knowngood.after2 dig.out.ns1.example.after2 || ret=1 +digcomp knowngood.after2 dig.out.ns2.example.after2 || ret=1 +digcomp knowngood.after2 dig.out.ns3.example.after2 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "checking 'forwarding update for zone' is logged twice ($n)" @@ -195,27 +195,95 @@ sleep 15 echo_i "fetching primary copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.1 axfr > dig.out.ns1 || ret=1 + @10.53.0.1 axfr > dig.out.ns1.example.after3 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "fetching secondary 1 copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.2 axfr > dig.out.ns2 || ret=1 + @10.53.0.2 axfr > dig.out.ns2.example.after3 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi n=`expr $n + 1` echo_i "fetching secondary 2 copy of zone after update ($n)" ret=0 $DIG $DIGOPTS example.\ - @10.53.0.3 axfr > dig.out.ns3 || ret=1 + @10.53.0.3 axfr > dig.out.ns3.example.after3 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi echo_i "comparing post-update copies to known good data ($n)" ret=0 -digcomp knowngood.after3 dig.out.ns1 || ret=1 -digcomp knowngood.after3 dig.out.ns2 || ret=1 -digcomp knowngood.after3 dig.out.ns3 || ret=1 +digcomp knowngood.after3 dig.out.ns1.example.after3 || ret=1 +digcomp knowngood.after3 dig.out.ns2.example.after3 || ret=1 +digcomp knowngood.after3 dig.out.ns3.example.after3 || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi + +echo_i "fetching primary copy of zone before update, first primary fails ($n)" +ret=0 +$DIG $DIGOPTS example3.\ + @10.53.0.1 axfr > dig.out.ns1.example3.before || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi +n=`expr $n + 1` + +echo_i "fetching secondary 1 copy of zone before update, first primary fails ($n)" +$DIG $DIGOPTS example3.\ + @10.53.0.2 axfr > dig.out.ns2.example3.before || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi +n=`expr $n + 1` + +echo_i "fetching secondary 2 copy of zone before update, first primary fails ($n)" +ret=0 +$DIG $DIGOPTS example3.\ + @10.53.0.3 axfr > dig.out.ns3.example3.before || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi +n=`expr $n + 1` + +echo_i "comparing pre-update copies to known good data, first primary fails ($n)" +ret=0 +digcomp knowngood.before.example3 dig.out.ns1.example3.before || ret=1 +digcomp knowngood.before.example3 dig.out.ns2.example3.before || ret=1 +digcomp knowngood.before.example3 dig.out.ns3.example3.before || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi + +echo_i "checking update forwarding of a zone (signed) (Do53 -> DoT) ($n)" +ret=0 +$NSUPDATE -y "${DEFAULT_HMAC}:update.example:c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K" -- - < dig.out.ns1.example3.after1 || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi +n=`expr $n + 1` + +echo_i "fetching secondary 1 copy of zone after update, first primary fails ($n)" +ret=0 +$DIG $DIGOPTS example3.\ + @10.53.0.2 axfr > dig.out.ns2.example3.after1 || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi + +echo_i "fetching secondary 2 copy of zone after update, first primary fails ($n)" +ret=0 +$DIG $DIGOPTS example3.\ + @10.53.0.3 axfr > dig.out.ns3.example3.after1 || ret=1 +if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi +n=`expr $n + 1` + +echo_i "comparing post-update copies to known good data, first primary fails ($n)" +ret=0 +digcomp knowngood.after1.example3 dig.out.ns1.example3.after1 || ret=1 +digcomp knowngood.after1.example3 dig.out.ns2.example3.after1 || ret=1 +digcomp knowngood.after1.example3 dig.out.ns3.example3.after1 || ret=1 if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi if $FEATURETEST --enable-dnstap From 218c661b41dc7d5d052b0158641a60cb6b4d03a1 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Wed, 26 Oct 2022 10:02:36 +0200 Subject: [PATCH 2/2] Fix update forwarding bug The wrong tls configuration was picked here. It should be of the primary that is selected by forward->which, not zone->curprimary. This bug may cause BIND to select the wrong primary when retrieving the TLS settings, or cause a crash in case the wrongly selected primary has no TLS settings. --- lib/dns/zone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 2b5f860713..83f5aac850 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -18354,7 +18354,7 @@ sendtoprimary(dns_forward_t *forward) { zone->primarytlsnames[forward->which] != NULL) { dns_view_t *view = dns_zone_getview(zone); - dns_name_t *tlsname = zone->primarytlsnames[zone->curprimary]; + dns_name_t *tlsname = zone->primarytlsnames[forward->which]; result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, &forward->transport);