]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check recovery from spoofed server addresses
authorMark Andrews <marka@isc.org>
Wed, 22 Jan 2025 12:54:53 +0000 (23:54 +1100)
committerMark Andrews <marka@isc.org>
Mon, 3 Feb 2025 00:24:34 +0000 (00:24 +0000)
Named was failing to recover when spoofed nameserver address from
a signed zone for a peer zone were returned to a previous CD=1
query. Validate non-glue interior server addresses before using them.

bin/tests/system/dnssec/ns1/root.db.in
bin/tests/system/dnssec/ns1/sign.sh
bin/tests/system/dnssec/ns2/named.conf.in
bin/tests/system/dnssec/ns2/peer-ns-spoof.db.in [new file with mode: 0644]
bin/tests/system/dnssec/ns2/peer.peer-ns-spoof.db.in [new file with mode: 0644]
bin/tests/system/dnssec/ns2/sign.sh
bin/tests/system/dnssec/ns3/named.conf.in
bin/tests/system/dnssec/ns3/sign.sh
bin/tests/system/dnssec/ns3/target.peer-ns-spoof.db.in [new file with mode: 0644]
bin/tests/system/dnssec/tests.sh
bin/tests/system/dnssec/tests_sh_dnssec.py

index ca72f0ee323729746b4c4f336b5f1e4948035941..4cb21c18266bf7a12abef31fadc17c0b83140d15 100644 (file)
@@ -37,3 +37,5 @@ inprogress.           NS      ns10.inprogress.
 ns10.inprogress.       A       10.53.0.10
 too-many-iterations.   NS      ns2.too-many-iterations.
 ns2.too-many-iterations.       A       10.53.0.2
+peer-ns-spoof          NS      ns2.peer-ns-spoof.
+ns2.peer-ns-spoof.     A       10.53.0.2
index 0247b9d8b49ab1b812030e19b2395466acbf20ff..b649cd4a0959137da01bcb39795408be3482b48f 100644 (file)
@@ -30,6 +30,7 @@ cp "../ns2/dsset-example." .
 cp "../ns2/dsset-in-addr.arpa." .
 cp "../ns2/dsset-too-many-iterations." .
 cp "../ns2/dsset-lazy-ksk." .
+cp "../ns2/dsset-peer-ns-spoof." .
 
 grep "$DEFAULT_ALGORITHM_NUMBER [12] " "../ns2/dsset-algroll." >"dsset-algroll."
 cp "../ns6/dsset-optout-tld." .
index 6e9ccf68a92c32d9af5a6549537638f722c261a2..310b46b3225181cf19e7667a8091f2c56c892e3a 100644 (file)
@@ -214,4 +214,14 @@ zone "lazy-ksk" {
        allow-update { any; };
 };
 
+zone "peer-ns-spoof" {
+       type primary;
+       file "peer-ns-spoof.db.signed";
+};
+
+zone "peer.peer-ns-spoof" {
+       type primary;
+       file "peer.peer-ns-spoof.db.signed";
+};
+
 include "trusted.conf";
diff --git a/bin/tests/system/dnssec/ns2/peer-ns-spoof.db.in b/bin/tests/system/dnssec/ns2/peer-ns-spoof.db.in
new file mode 100644 (file)
index 0000000..10300ad
--- /dev/null
@@ -0,0 +1,24 @@
+; 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.
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2000042407 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns2
+ns2                    A       10.53.0.2
+peer                   NS      ns2.peer
+ns2.peer               A       10.53.0.2
+target                 NS      ns3.peer
diff --git a/bin/tests/system/dnssec/ns2/peer.peer-ns-spoof.db.in b/bin/tests/system/dnssec/ns2/peer.peer-ns-spoof.db.in
new file mode 100644 (file)
index 0000000..5d4d1a7
--- /dev/null
@@ -0,0 +1,22 @@
+; 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.
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2000042407 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns2
+ns2                    A       10.53.0.2
+ns3                    A       10.53.0.3
index 9ac57f776cdcd9af938d7092c0df2a2d5d7b8536..106f67cbebe59227a4e1bca679a853146bcbe63f 100644 (file)
@@ -27,6 +27,8 @@ for subdomain in secure unsupported disabled enabled; do
   cp "../ns3/dsset-$subdomain.trusted." .
 done
 
+cp "../ns3/dsset-target.peer-ns-spoof." .
+
 # Sign the "trusted." and "managed." zones.
 zone=managed.
 infile=key.db.in
@@ -354,3 +356,34 @@ rm "$rm1.key"
 rm "$rm1.private"
 rm "$rm2.key"
 rm "$rm2.private"
+
+#
+# A zone with where the address for peer zone server is modified and signatures
+# stripped.
+#
+zone=peer.peer-ns-spoof
+infile=peer.peer-ns-spoof.db.in
+zonefile=peer.peer-ns-spoof.db
+ksk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone")
+zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
+cat "$infile" "$ksk.key" "$zsk.key" >"$zonefile"
+"$SIGNER" -g -o "$zone" "$zonefile" >/dev/null 2>&1
+"$CHECKZONE" -D -q -i local "$zone" "$zonefile.signed" \
+  | awk '$1 == "ns3.peer.peer-ns-spoof." && $4 == "RRSIG" && $5 == "A" { next }
+        $1 == "ns3.peer.peer-ns-spoof." && $4 == "A" { $5 = "10.53.0.100" }
+        { print }' >"$zonefile.stripped"
+"$CHECKZONE" -D -q -i local "$zone" "$zonefile.signed" \
+  | awk '$4 == "SOA" { $7 = $7 + 1; print; next } { print }' >"$zonefile.next"
+"$SIGNER" -g -o "$zone" -f "$zonefile.next" "$zonefile.next" >/dev/null 2>&1
+cp "$zonefile.stripped" "$zonefile.signed"
+
+#
+# parent zone for peer.peer-ns-spoof
+#
+zone=peer-ns-spoof
+infile=peer-ns-spoof.db.in
+zonefile=peer-ns-spoof.db
+ksk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone")
+zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
+cat "$infile" "$ksk.key" "$zsk.key" >"$zonefile"
+"$SIGNER" -g -o "$zone" "$zonefile" >/dev/null 2>&1
index 293ff2dda8f1d014632e2ae21a732dd804d88d7d..917e2b72993730ac27b17f3b8e041b9a758ba6e6 100644 (file)
@@ -423,6 +423,11 @@ zone "rsasha1-1024.example" {
        file "rsasha1-1024.example.db";
 };
 
+zone "target.peer-ns-spoof" {
+       type primary;
+       file "target.peer-ns-spoof.db.signed";
+};
+
 dnssec-policy "siginterval1" {
        keys {
                ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
index f61ea2838145bb0752cc7a422751cc96dc127ea8..288ee6bc19bbffc86f8b1028668a2270a64df8e6 100644 (file)
@@ -701,3 +701,14 @@ zone=rsasha1-1024.example
 zonefile=rsasha1-1024.example.db
 awk '$4 == "DNSKEY" && $5 == 257 { print }' "$zonefile" \
   | $DSFROMKEY -f - "$zone" >"dsset-${zone}."
+
+#
+#
+#
+zone=target.peer-ns-spoof
+infile=target.peer-ns-spoof.db.in
+zonefile=target.peer-ns-spoof.db
+ksk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone")
+zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
+cat "$infile" "$ksk.key" "$zsk.key" >"$zonefile"
+"$SIGNER" -g -o "$zone" "$zonefile" >/dev/null 2>&1
diff --git a/bin/tests/system/dnssec/ns3/target.peer-ns-spoof.db.in b/bin/tests/system/dnssec/ns3/target.peer-ns-spoof.db.in
new file mode 100644 (file)
index 0000000..2da55f3
--- /dev/null
@@ -0,0 +1,20 @@
+; 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.
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2000042407 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns3.peer.peer-ns-spoof.
index fc70f4c5681b00ac4a75cb47a626837f60e4248b..254ba2a75001b4708e2cce5e801d38b397bd682c 100644 (file)
@@ -184,6 +184,26 @@ n=$((n + 1))
 test "$ret" -eq 0 || echo_i "failed"
 status=$((status + ret))
 
+echo_i "checking recovery from spoofed server addresses ($n)"
+ret=0
+# prime cache with spoofed address records
+dig_with_opts +cd target.peer-ns-spoof @10.53.0.4 a >dig.out.prime.ns4.test$n || ret=1
+grep "status: SERVFAIL" dig.out.prime.ns4.test$n >/dev/null || ret=1
+rndccmd 10.53.0.4 dumpdb | sed 's/^/ns4 /' | cat_i
+mv ns4/named_dump.db ns4/named_dump.db.test$n >/dev/null || ret=1
+grep "10.53.0.100" ns4/named_dump.db.test$n || ret=1
+# reload server with properly signed zone
+cp ns2/peer.peer-ns-spoof.db.next ns2/peer.peer-ns-spoof.db.signed
+nextpart ns2/named.run >/dev/null
+rndccmd 10.53.0.2 reload peer.peer-ns-spoof | sed 's/^/ns2 /' | cat_i
+wait_for_log 5 "zone peer.peer-ns-spoof/IN: loaded serial 2000042408" ns2/named.run || ret=1
+dig_with_opts +noauth test.target.peer-ns-spoof @10.53.0.4 txt >dig.out.ns4.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns4.test$n >/dev/null || ret=1
+grep "flags: qr rd ra ad;" dig.out.ns4.test$n >/dev/null || ret=1
+n=$((n + 1))
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status + ret))
+
 echo_i "checking that 'example/DS' from the referral was used in previous validation ($n)"
 ret=0
 grep "query 'example/DS/IN' approved" ns1/named.run >/dev/null && ret=1
index c7e4d9df7e9e546412b21b55bef6462fafe561cf..e00d160cd7b62f1f3f4173e5eedabcbfd85ecef0 100644 (file)
@@ -55,6 +55,10 @@ pytestmark = pytest.mark.extra_artifacts(
         "ns2/lazy-ksk.db",
         "ns2/managed.db",
         "ns2/nsec3chain-test.db",
+        "ns2/peer-ns-spoof.db",
+        "ns2/peer.peer-ns-spoof.db",
+        "ns2/peer.peer-ns-spoof.db.next",
+        "ns2/peer.peer-ns-spoof.db.stripped",
         "ns2/settime.out.updatecheck-kskonly.secure.ksk",
         "ns2/settime.out.updatecheck-kskonly.secure.zsk",
         "ns2/single-nsec3.db",
@@ -121,6 +125,7 @@ pytestmark = pytest.mark.extra_artifacts(
         "ns3/siginterval.example.db",
         "ns3/split-dnssec.example.db",
         "ns3/split-smart.example.db",
+        "ns3/target.peer-ns-spoof.db",
         "ns3/trusted-future.key",
         "ns3/ttlpatch.example.db",
         "ns3/ttlpatch.example.db.patched",
@@ -136,6 +141,7 @@ pytestmark = pytest.mark.extra_artifacts(
         "ns4/managed.conf",
         "ns4/managed-keys.bind",
         "ns4/named.secroots",
+        "ns4/named_dump.db",
         "ns4/named_dump.db.*",
         "ns5/revoked.conf",
         "ns5/trusted.conf",