From b234c6d954ef76d9e9ac226ae164bfe31dadc3d3 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 10 Jul 2025 01:03:17 -0700 Subject: [PATCH 1/6] convert filter-aaaa test to python use pytest for the filter-aaaa test. In order to implement this, isctest.mark can now test whether IPv6 is configured by calling testsock6.pl. --- .../conf/{bad1.conf.in => bad1.conf.j2} | 0 .../conf/{bad2.conf.in => bad2.conf.j2} | 0 .../conf/{bad3.conf.in => bad3.conf.j2} | 0 .../conf/{bad4.conf.in => bad4.conf.j2} | 0 .../conf/{bad5.conf.in => bad5.conf.j2} | 0 .../conf/{good1.conf.in => good1.conf.j2} | 0 .../conf/{good2.conf.in => good2.conf.j2} | 0 .../conf/{good3.conf.in => good3.conf.j2} | 0 .../conf/{good4.conf.in => good4.conf.j2} | 0 .../conf/{good5.conf.in => good5.conf.j2} | 0 .../ns1/{named1.conf.in => named.conf.j2} | 21 +- .../system/filter-aaaa/ns1/named2.conf.in | 45 - .../ns2/{named1.conf.in => named.conf.j2} | 18 +- .../system/filter-aaaa/ns2/named2.conf.in | 44 - .../ns3/{named2.conf.in => named.conf.j2} | 18 +- .../system/filter-aaaa/ns3/named1.conf.in | 44 - .../ns4/{named1.conf.in => named.conf.j2} | 18 +- .../system/filter-aaaa/ns4/named2.conf.in | 44 - .../ns5/{named.conf.in => named.conf.j2} | 8 +- bin/tests/system/filter-aaaa/setup.sh | 18 - bin/tests/system/filter-aaaa/tests.sh | 1405 ----------------- .../system/filter-aaaa/tests_filter_aaaa.py | 1401 ++++++++++++++++ .../filter-aaaa/tests_sh_filter_aaaa.py | 32 - bin/tests/system/isctest/mark.py | 14 +- 24 files changed, 1476 insertions(+), 1654 deletions(-) rename bin/tests/system/filter-aaaa/conf/{bad1.conf.in => bad1.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{bad2.conf.in => bad2.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{bad3.conf.in => bad3.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{bad4.conf.in => bad4.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{bad5.conf.in => bad5.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{good1.conf.in => good1.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{good2.conf.in => good2.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{good3.conf.in => good3.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{good4.conf.in => good4.conf.j2} (100%) rename bin/tests/system/filter-aaaa/conf/{good5.conf.in => good5.conf.j2} (100%) rename bin/tests/system/filter-aaaa/ns1/{named1.conf.in => named.conf.j2} (65%) delete mode 100644 bin/tests/system/filter-aaaa/ns1/named2.conf.in rename bin/tests/system/filter-aaaa/ns2/{named1.conf.in => named.conf.j2} (64%) delete mode 100644 bin/tests/system/filter-aaaa/ns2/named2.conf.in rename bin/tests/system/filter-aaaa/ns3/{named2.conf.in => named.conf.j2} (63%) delete mode 100644 bin/tests/system/filter-aaaa/ns3/named1.conf.in rename bin/tests/system/filter-aaaa/ns4/{named1.conf.in => named.conf.j2} (65%) delete mode 100644 bin/tests/system/filter-aaaa/ns4/named2.conf.in rename bin/tests/system/filter-aaaa/ns5/{named.conf.in => named.conf.j2} (84%) delete mode 100644 bin/tests/system/filter-aaaa/tests.sh create mode 100644 bin/tests/system/filter-aaaa/tests_filter_aaaa.py delete mode 100644 bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py diff --git a/bin/tests/system/filter-aaaa/conf/bad1.conf.in b/bin/tests/system/filter-aaaa/conf/bad1.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad1.conf.in rename to bin/tests/system/filter-aaaa/conf/bad1.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad2.conf.in b/bin/tests/system/filter-aaaa/conf/bad2.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad2.conf.in rename to bin/tests/system/filter-aaaa/conf/bad2.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad3.conf.in b/bin/tests/system/filter-aaaa/conf/bad3.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad3.conf.in rename to bin/tests/system/filter-aaaa/conf/bad3.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad4.conf.in b/bin/tests/system/filter-aaaa/conf/bad4.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad4.conf.in rename to bin/tests/system/filter-aaaa/conf/bad4.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad5.conf.in b/bin/tests/system/filter-aaaa/conf/bad5.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad5.conf.in rename to bin/tests/system/filter-aaaa/conf/bad5.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good1.conf.in b/bin/tests/system/filter-aaaa/conf/good1.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good1.conf.in rename to bin/tests/system/filter-aaaa/conf/good1.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good2.conf.in b/bin/tests/system/filter-aaaa/conf/good2.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good2.conf.in rename to bin/tests/system/filter-aaaa/conf/good2.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good3.conf.in b/bin/tests/system/filter-aaaa/conf/good3.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good3.conf.in rename to bin/tests/system/filter-aaaa/conf/good3.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good4.conf.in b/bin/tests/system/filter-aaaa/conf/good4.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good4.conf.in rename to bin/tests/system/filter-aaaa/conf/good4.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good5.conf.in b/bin/tests/system/filter-aaaa/conf/good5.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good5.conf.in rename to bin/tests/system/filter-aaaa/conf/good5.conf.j2 diff --git a/bin/tests/system/filter-aaaa/ns1/named1.conf.in b/bin/tests/system/filter-aaaa/ns1/named.conf.j2 similarity index 65% rename from bin/tests/system/filter-aaaa/ns1/named1.conf.in rename to bin/tests/system/filter-aaaa/ns1/named.conf.j2 index 8dea5f5d22..e5e76b1ecf 100644 --- a/bin/tests/system/filter-aaaa/ns1/named1.conf.in +++ b/bin/tests/system/filter-aaaa/ns1/named.conf.j2 @@ -11,6 +11,9 @@ * information regarding copyright ownership. */ +{% set filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + options { query-source address 10.53.0.1; notify-source 10.53.0.1; @@ -25,13 +28,19 @@ options { minimal-responses no; }; +{% if family == "v6" %} + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v6 yes; + filter-@filtertype@ { fd92:7065:b8e:ffff::1; }; + }; +{% else %} + acl filterees { 10.53.0.1; }; -acl filterees { 10.53.0.1; }; - -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v4 yes; - filter-aaaa { filterees; }; -}; + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v4 yes; + filter-@filtertype@ { filterees; }; + }; +{% endif %} key rndc_key { secret "1234abcd8765"; diff --git a/bin/tests/system/filter-aaaa/ns1/named2.conf.in b/bin/tests/system/filter-aaaa/ns1/named2.conf.in deleted file mode 100644 index b03fda546a..0000000000 --- a/bin/tests/system/filter-aaaa/ns1/named2.conf.in +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ - -options { - query-source address 10.53.0.1; - notify-source 10.53.0.1; - transfer-source 10.53.0.1; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.1; }; - listen-on-v6 { fd92:7065:b8e:ffff::1; }; - recursion no; - dnssec-validation no; - notify yes; - minimal-responses no; -}; - - -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v6 yes; - filter-aaaa { fd92:7065:b8e:ffff::1; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type primary; file "root.db"; }; -zone "signed" { type primary; file "signed.db.signed"; }; -zone "unsigned" { type primary; file "unsigned.db"; }; diff --git a/bin/tests/system/filter-aaaa/ns2/named1.conf.in b/bin/tests/system/filter-aaaa/ns2/named.conf.j2 similarity index 64% rename from bin/tests/system/filter-aaaa/ns2/named1.conf.in rename to bin/tests/system/filter-aaaa/ns2/named.conf.j2 index c714c5429c..9fee67291c 100644 --- a/bin/tests/system/filter-aaaa/ns2/named1.conf.in +++ b/bin/tests/system/filter-aaaa/ns2/named.conf.j2 @@ -11,6 +11,9 @@ * information regarding copyright ownership. */ +{% set filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + options { query-source address 10.53.0.2; notify-source 10.53.0.2; @@ -25,10 +28,17 @@ options { minimal-responses no; }; -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v4 yes; - filter-aaaa { 10.53.0.2; }; -}; +{% if family == "v6" %} + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v6 yes; + filter-@filtertype@ { fd92:7065:b8e:ffff::2; }; + }; +{% else %} + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v4 yes; + filter-@filtertype@ { 10.53.0.2; }; + }; +{% endif %} key rndc_key { secret "1234abcd8765"; diff --git a/bin/tests/system/filter-aaaa/ns2/named2.conf.in b/bin/tests/system/filter-aaaa/ns2/named2.conf.in deleted file mode 100644 index fc77fc4699..0000000000 --- a/bin/tests/system/filter-aaaa/ns2/named2.conf.in +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -options { - query-source address 10.53.0.2; - notify-source 10.53.0.2; - transfer-source 10.53.0.2; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.2; }; - listen-on-v6 { fd92:7065:b8e:ffff::2; }; - recursion yes; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v6 yes; - filter-aaaa { fd92:7065:b8e:ffff::2; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type hint; file "hints"; }; - -include "trusted.conf"; diff --git a/bin/tests/system/filter-aaaa/ns3/named2.conf.in b/bin/tests/system/filter-aaaa/ns3/named.conf.j2 similarity index 63% rename from bin/tests/system/filter-aaaa/ns3/named2.conf.in rename to bin/tests/system/filter-aaaa/ns3/named.conf.j2 index 5553e05b4d..d89f96df2c 100644 --- a/bin/tests/system/filter-aaaa/ns3/named2.conf.in +++ b/bin/tests/system/filter-aaaa/ns3/named.conf.j2 @@ -11,6 +11,9 @@ * information regarding copyright ownership. */ +{% set filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + options { query-source address 10.53.0.3; notify-source 10.53.0.3; @@ -25,10 +28,17 @@ options { minimal-responses no; }; -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v6 break-dnssec; - filter-aaaa { fd92:7065:b8e:ffff::3; }; -}; +{% if family == "v6" %} + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v6 break-dnssec; + filter-@filtertype@ { fd92:7065:b8e:ffff::3; }; + }; +{% else %} + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v4 break-dnssec; + filter-@filtertype@ { 10.53.0.3; }; + }; +{% endif %} key rndc_key { secret "1234abcd8765"; diff --git a/bin/tests/system/filter-aaaa/ns3/named1.conf.in b/bin/tests/system/filter-aaaa/ns3/named1.conf.in deleted file mode 100644 index b11eea3dd9..0000000000 --- a/bin/tests/system/filter-aaaa/ns3/named1.conf.in +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -options { - query-source address 10.53.0.3; - notify-source 10.53.0.3; - transfer-source 10.53.0.3; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.3; }; - listen-on-v6 { fd92:7065:b8e:ffff::3; }; - recursion yes; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v4 break-dnssec; - filter-aaaa { 10.53.0.3; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type hint; file "hints"; }; - -include "trusted.conf"; diff --git a/bin/tests/system/filter-aaaa/ns4/named1.conf.in b/bin/tests/system/filter-aaaa/ns4/named.conf.j2 similarity index 65% rename from bin/tests/system/filter-aaaa/ns4/named1.conf.in rename to bin/tests/system/filter-aaaa/ns4/named.conf.j2 index 6d3a9cceee..4246092923 100644 --- a/bin/tests/system/filter-aaaa/ns4/named1.conf.in +++ b/bin/tests/system/filter-aaaa/ns4/named.conf.j2 @@ -11,6 +11,9 @@ * information regarding copyright ownership. */ +{% set filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + options { query-source address 10.53.0.4; notify-source 10.53.0.4; @@ -25,10 +28,17 @@ options { minimal-responses no; }; -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v4 break-dnssec; - filter-aaaa { 10.53.0.4; }; -}; +{% if family == "v6" %} + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v6 break-dnssec; + filter-@filtertype@ { fd92:7065:b8e:ffff::4; }; + }; +{% else %} + plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v4 break-dnssec; + filter-@filtertype@ { 10.53.0.4; }; + }; +{% endif %} key rndc_key { secret "1234abcd8765"; diff --git a/bin/tests/system/filter-aaaa/ns4/named2.conf.in b/bin/tests/system/filter-aaaa/ns4/named2.conf.in deleted file mode 100644 index 91e38533b2..0000000000 --- a/bin/tests/system/filter-aaaa/ns4/named2.conf.in +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -options { - query-source address 10.53.0.4; - notify-source 10.53.0.4; - transfer-source 10.53.0.4; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.4; }; - listen-on-v6 { fd92:7065:b8e:ffff::4; }; - recursion no; - dnssec-validation no; - notify yes; - minimal-responses no; -}; - -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v6 break-dnssec; - filter-aaaa { fd92:7065:b8e:ffff::4; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type primary; file "root.db"; }; -zone "signed" { type primary; file "signed.db.signed"; }; -zone "unsigned" { type primary; file "unsigned.db"; }; diff --git a/bin/tests/system/filter-aaaa/ns5/named.conf.in b/bin/tests/system/filter-aaaa/ns5/named.conf.j2 similarity index 84% rename from bin/tests/system/filter-aaaa/ns5/named.conf.in rename to bin/tests/system/filter-aaaa/ns5/named.conf.j2 index 58acd797ea..ae72eb33c4 100644 --- a/bin/tests/system/filter-aaaa/ns5/named.conf.in +++ b/bin/tests/system/filter-aaaa/ns5/named.conf.j2 @@ -11,6 +11,8 @@ * information regarding copyright ownership. */ +{% set filtertype = filtertype | default("aaaa") %} + options { query-source address 10.53.0.5; notify-source 10.53.0.5; @@ -30,9 +32,9 @@ options { minimal-responses no; }; -plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { - filter-aaaa-on-v4 break-dnssec; - filter-aaaa { any; }; +plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { + filter-@filtertype@-on-v4 break-dnssec; + filter-@filtertype@ { any; }; }; key rndc_key { diff --git a/bin/tests/system/filter-aaaa/setup.sh b/bin/tests/system/filter-aaaa/setup.sh index 3e151f04d4..e60dc57fd3 100644 --- a/bin/tests/system/filter-aaaa/setup.sh +++ b/bin/tests/system/filter-aaaa/setup.sh @@ -13,23 +13,5 @@ . ../conf.sh -copy_setports ns1/named1.conf.in ns1/named.conf -copy_setports ns2/named1.conf.in ns2/named.conf -copy_setports ns3/named1.conf.in ns3/named.conf -copy_setports ns4/named1.conf.in ns4/named.conf -copy_setports ns5/named.conf.in ns5/named.conf - -copy_setports conf/good1.conf.in conf/good1.conf -copy_setports conf/good2.conf.in conf/good2.conf -copy_setports conf/good3.conf.in conf/good3.conf -copy_setports conf/good4.conf.in conf/good4.conf -copy_setports conf/good5.conf.in conf/good5.conf - -copy_setports conf/bad1.conf.in conf/bad1.conf -copy_setports conf/bad2.conf.in conf/bad2.conf -copy_setports conf/bad3.conf.in conf/bad3.conf -copy_setports conf/bad4.conf.in conf/bad4.conf -copy_setports conf/bad5.conf.in conf/bad5.conf - (cd ns1 && $SHELL -e sign.sh) (cd ns4 && $SHELL -e sign.sh) diff --git a/bin/tests/system/filter-aaaa/tests.sh b/bin/tests/system/filter-aaaa/tests.sh deleted file mode 100644 index e6cca5222f..0000000000 --- a/bin/tests/system/filter-aaaa/tests.sh +++ /dev/null @@ -1,1405 +0,0 @@ -#!/bin/sh - -# 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. - -set -e - -. ../conf.sh - -status=0 -n=0 - -rm -f dig.out.* - -DIGOPTS="+tcp +noadd +nosea +nostat +nocmd -p ${PORT}" -RNDCCMD="$RNDC -c ../_common/rndc.conf -p ${CONTROLPORT} -s" - -for conf in conf/good*.conf; do - n=$((n + 1)) - echo_i "checking that $conf is accepted ($n)" - ret=0 - $CHECKCONF "$conf" || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -done - -for conf in conf/bad*.conf; do - n=$((n + 1)) - echo_i "checking that $conf is rejected ($n)" - ret=0 - $CHECKCONF "$conf" >/dev/null && ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -done - -# -# Authoritative tests against: -# filter-aaaa-on-v4 yes; -# filter-aaaa { 10.53.0.1; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::5 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "AUTHORITY: 2," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0," dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 2," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.2 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6 ($n)" -if testsock6 fd92:7065:b8e:ffff::1; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 - grep 2001:db8::6 dig.out.ns1.test$n >/dev/null || ret=1 - grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep AAAA dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -grep "ANSWER: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep "ADDITIONAL: 2" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -grep "AUTHORITY: 2," dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv6 ($n)" -if testsock6 fd92:7065:b8e:ffff::1; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 - grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -# -# Authoritative tests against: -# filter-aaaa-on-v4 break-dnssec; -# filter-aaaa { 10.53.0.4; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns4.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns4.test$n >/dev/null || ret=1 -grep ::5 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0," dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.2 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6 with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::4; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 - grep 2001:db8::6 dig.out.ns4.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep AAAA dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv6, with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::4; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -# -# Recursive tests against: -# filter-aaaa-on-v4 yes; -# filter-aaaa { 10.53.0.2; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep ::5 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.1 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6, recursive ($n)" -if testsock6 fd92:7065:b8e:ffff::2; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 - grep 2001:db8::6 dig.out.ns2.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep AAAA dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed, recursive ($n)" -ret=0 -# we need to prime the cache with addresses for the MX, since additional -# section data won't be included unless it's validated, and that doesn't -# necessarily happen otherwise. -$DIG $DIGOPTS +dnssec mx.signed @10.53.0.2 >/dev/null -$DIG $DIGOPTS +dnssec mx.signed aaaa @10.53.0.2 >/dev/null -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, recursive, over IPv6 ($n)" -if testsock6 fd92:7065:b8e:ffff::2; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -# -# Recursive tests against: -# filter-aaaa-on-v4 break-dnssec; -# filter-aaaa { 10.53.0.3; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep ::5 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.1 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6, recursive with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::3; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 - grep 2001:db8::6 dig.out.ns3.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep AAAA dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv6, recursive with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::3; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -if ! testsock6 fd92:7065:b8e:ffff::1; then - echo_i "IPv6 address not configured; skipping IPv6 query tests" - echo_i "exit status: $status" - exit $status -fi - -# Reconfiguring for IPv6 tests -echo_i "reconfiguring servers" -copy_setports ns1/named2.conf.in ns1/named.conf -rndc_reconfig ns1 10.53.0.1 -copy_setports ns2/named2.conf.in ns2/named.conf -rndc_reconfig ns2 10.53.0.2 -copy_setports ns3/named2.conf.in ns3/named.conf -rndc_reconfig ns3 10.53.0.3 -copy_setports ns4/named2.conf.in ns4/named.conf -rndc_reconfig ns4 10.53.0.4 - -# BEGIN IPv6 TESTS - -# -# Authoritative tests against: -# filter-aaaa-on-v6 yes; -# filter-aaaa { fd92:7065:b8e:ffff::1; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep ::2 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep ::5 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4 ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep 2001:db8::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep AAAA dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4 ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# -# Authoritative tests against: -# filter-aaaa-on-v6 break-dnssec; -# filter-aaaa { fd92:7065:b8e:ffff::4; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep ::2 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep ::5 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4 with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep 2001:db8::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep AAAA dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# -# Recursive tests against: -# filter-aaaa-on-v6 yes; -# filter-aaaa { fd92:7065:b8e:ffff::2; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep ::5 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep 2001:db8::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep AAAA dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4 ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# -# Recursive tests against: -# filter-aaaa-on-v6 yes; -# filter-aaaa { fd92:7065:b8e:ffff::3; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep ::5 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep 2001:db8::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep AAAA dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# We don't check for the AAAA record here as configuration in ns5 does -# not make sense. The AAAA record is wanted by filter-aaaa but discarded -# by the dns64 configuration. We just want to ensure the server stays -# running. -n=$((n + 1)) -echo_i "checking filter-aaaa with dns64 ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned @10.53.0.5 >dig.out.ns5.test$n || ret=1 -grep "status: NOERROR" dig.out.ns5.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -echo_i "exit status: $status" -[ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/filter-aaaa/tests_filter_aaaa.py b/bin/tests/system/filter-aaaa/tests_filter_aaaa.py new file mode 100644 index 0000000000..920a8876f3 --- /dev/null +++ b/bin/tests/system/filter-aaaa/tests_filter_aaaa.py @@ -0,0 +1,1401 @@ +#!/bin/sh + +# 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. + +import glob +import os +import subprocess + +from dns import message, rdatatype + +import pytest + +import isctest +import isctest.mark + + +pytestmark = pytest.mark.extra_artifacts( + [ + "conf/*.conf", + "ns*/trusted.conf", + "ns*/*.signed", + "ns*/K*", + "ns*/dsset-*", + "ns*/signer.err", + ] +) + + +# helper functions +def reset_server(server, family, ftype, servers, templates): + templates.render(f"{server}/named.conf", + {"family": family, "filtertype": ftype}) + servers[server].reconfigure(log=False) + + +filter_family = "v4" +filter_type = "aaaa" +def reset_servers(family, ftype, servers, templates): + reset_server("ns1", family, ftype, servers, templates) + reset_server("ns2", family, ftype, servers, templates) + reset_server("ns3", family, ftype, servers, templates) + reset_server("ns4", family, ftype, servers, templates) + filter_family = family + + +# run the checkconf tests +def test_checkconf(): + for filename in glob.glob("conf/good*.conf"): + isctest.run.cmd([os.environ["CHECKCONF"], filename]) + for filename in glob.glob("conf/bad*.conf"): + with pytest.raises(subprocess.CalledProcessError): + isctest.run.cmd([os.environ["CHECKCONF"], filename]) + + +# These tests are against an authoritative server configured with: +## filter-aaaa-on-v4 yes; +## filter-aaaa { 10.53.0.1; }; +def test_auth_filter_aaaa_on_v4(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0 + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0 + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned when both AAAA and A exist, signed, DO=1 + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa = res.answer[0] + assert "2001:db8::3" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1 + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0 + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, DO=1 + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0 + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1 + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, unsigned + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, unsigned + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is included in additional section, qtype=MX, signed + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +@isctest.mark.with_ipv6 +def test_auth_filter_aaaa_on_v4_via_v6(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6 + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6 + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +# These tests are against an authoritative server configured with: +## filter-aaaa-on-v4 break-dnssec; +## filter-aaaa { 10.53.0.4; }; +def test_auth_break_dnssec_filter_aaaa_on_v4(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed, + # with break-dnssec + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned, + # with break-dnssec + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0, with break-dnssec + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0, with break-dnssec + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned when both AAAA and A exist, signed, DO=1, + # with break-dnssec + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, with break-dnssec + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=1, with break-dnssec + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0, with break-dnssec + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1, with break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL, with break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, + # unsigned, with break-dnssec + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # unsigned, with break-dnssec + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # signed, with break-dnssec + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +@isctest.mark.with_ipv6 +def test_auth_break_dnssec_filter_aaaa_on_v4_via_v6(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6, with break-dnssec + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +# These tests are against a recursive server configured with: +## filter-aaaa-on-v4 yes; +## filter-aaaa { 10.53.0.2; }; +def test_recursive_filter_aaaa_on_v4(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed, + # recursive + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.adflag(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned, + # recursive + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0, recursive + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0, recursive + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned when both AAAA and A exist, signed, DO=1, + # recursive + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.adflag(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa = res.answer[0] + assert "2001:db8::3" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, recursive + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noadflag(res) + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, recursive + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.noadflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, DO=1, recursive + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.adflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0, recursive + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1, recursive + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL, recursive + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, + # unsigned, recursive + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # unsigned, recursive + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # (we need to prime the cache first with the MX addresses, since + # additional section data isn't included unless it's already validated.) + msg = isctest.query.create("mx.signed", "a") + isctest.query.tcp(msg, "10.53.0.2") + msg = isctest.query.create("mx.signed", "aaaa") + isctest.query.tcp(msg, "10.53.0.2") + + # check that AAAA is included in additional section, qtype=MX, signed, + # recursive + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +@isctest.mark.with_ipv6 +def test_recursive_filter_aaaa_on_v4_via_v6(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6, recursive + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6, recursive + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +# These tests are against a recursive server configured with: +## filter-aaaa-on-v4 break-dnssec; +## filter-aaaa { 10.53.0.3; }; +def test_recursive_break_dnssec_filter_aaaa_on_v4(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed, + # recursive, with break-dnssec + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.adflag(res) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned, + # recursive, with break-dnssec + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, recursive, with break-dnssec + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, recursive, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noadflag(res) + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.1") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, recursive, with break-dnssec + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1, recursive, with break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL, recursive, with + # break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, + # unsigned, recursive, with break-dnssec + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # unsigned, recursive, with break-dnssec + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, signed, + # recursive, with break-dnssec + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +@isctest.mark.with_ipv6 +def test_recursive_break_dnssec_filter_aaaa_on_v4_via_v6(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6, recursive + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6, recursive + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +# These tests are against an authoritative server configured with: +## filter-aaaa-on-v6 yes; +## filter-aaaa { fd92:7065:b8e:ffff::1; }; +@isctest.mark.with_ipv6 +def test_auth_filter_aaaa_on_v6(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0 + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0 + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned when both AAAA and A exist, signed, DO=1 + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa = res.answer[0] + assert "2001:db8::3" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1 + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0 + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, DO=1 + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0 + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1 + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, unsigned + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, unsigned + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is included in additional section, qtype=MX, signed + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +def test_auth_filter_aaaa_on_v6_via_v4(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6 + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6 + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.1") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +# These tests are against an authoritative server configured with: +## filter-aaaa-on-v6 break-dnssec; +## filter-aaaa { fd92:7065:b8e:ffff::4; }; +@isctest.mark.with_ipv6 +def test_auth_break_dnssec_filter_aaaa_on_v6(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed, + # with break-dnssec + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned, + # with break-dnssec + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0, with break-dnssec + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0, with break-dnssec + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned when both AAAA and A exist, signed, DO=1, + # with break-dnssec + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, with break-dnssec + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=1, with break-dnssec + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0, with break-dnssec + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1, with break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL, with break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, + # unsigned, with break-dnssec + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # unsigned, with break-dnssec + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # signed, with break-dnssec + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", + source="fd92:7065:b8e:ffff::4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +def test_auth_break_dnssec_filter_aaaa_on_v6_via_v4(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6, with break-dnssec + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +# These tests are against a recursive server configured with: +## filter-aaaa-on-v6 yes; +## filter-aaaa { fd92:7065:b8e:ffff::2; }; +@isctest.mark.with_ipv6 +def test_recursive_filter_aaaa_on_v6(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed, + # recursive + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.adflag(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned, + # recursive + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0, recursive + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0, recursive + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned when both AAAA and A exist, signed, DO=1, + # recursive + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.adflag(res) + isctest.check.rr_count_eq(res.authority, 2) + aaaa = res.answer[0] + assert "2001:db8::3" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, recursive + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noadflag(res) + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, recursive + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.noadflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, DO=1, recursive + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.adflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0, recursive + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1, recursive + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL, recursive + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, + # unsigned, recursive + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # unsigned, recursive + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # (we need to prime the cache first with the MX addresses, since + # additional section data isn't included unless it's already validated.) + msg = isctest.query.create("mx.signed", "a") + isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2") + msg = isctest.query.create("mx.signed", "aaaa") + isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2") + + # check that AAAA is included in additional section, qtype=MX, signed, + # recursive + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", + source="fd92:7065:b8e:ffff::2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +def test_recursive_filter_aaaa_on_v6_via_v4(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6, recursive + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6, recursive + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +# These tests are against a recursive server configured with: +## filter-aaaa-on-v6 break-dnssec; +## filter-aaaa { fd92:7065:b8e:ffff::3; }; +@isctest.mark.with_ipv6 +def test_recursive_break_dnssec_filter_aaaa_on_v6(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when only AAAA record exists, signed, + # recursive, with break-dnssec + msg = isctest.query.create("aaaa-only.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.adflag(res) + aaaa, _ = res.answer + assert "2001:db8::2" in str(aaaa[0]) + + # check that AAAA is returned when only AAAA record exists, unsigned, + # recursive, with break-dnssec + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + aaaa = res.answer[0] + assert "2001:db8::5" in str(aaaa[0]) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # signed, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.signed", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, recursive, with break-dnssec + msg = isctest.query.create("dual.signed", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.empty_answer(res) + + # check that NODATA/NOERROR is returned when both AAAA and A exist, + # unsigned, DO=1, recursive, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noadflag(res) + isctest.check.noerror(res) + isctest.check.empty_answer(res) + + # check that AAAA is returned if both AAAA and A exist and the query + # source doesn't match the ACL, with break-dnssec + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + isctest.check.noadflag(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.signed", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # signed, qtype=ANY, DO=0, recursive, with break-dnssec + msg = isctest.query.create("dual.signed", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.noadflag(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.3" in r for r in records) + assert not any("2001:db8::3" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=0, recursive, with break-dnssec + msg = message.make_query("dual.unsigned", "any") # sends DO=0 + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that A (and not AAAA) is returned if both AAAA and A exist, + # unsigned, qtype=ANY, DO=1, recursive, with break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert not any("2001:db8::6" in r for r in records) + + # check that both A and AAAA are returned if both AAAA and A exist, + # signed, qtype=ANY, query source does not match ACL, recursive, with + # break-dnssec + msg = isctest.query.create("dual.unsigned", "any") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::1") + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + assert any("1.0.0.6" in r for r in records) + assert any("2001:db8::6" in r for r in records) + + # check that AAAA is omitted from additional section, qtype=NS, + # unsigned, recursive, with break-dnssec + msg = isctest.query.create("unsigned", "ns") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 1) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, + # unsigned, recursive, with break-dnssec + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # check that AAAA is omitted from additional section, qtype=MX, signed, + # recursive, with break-dnssec + msg = isctest.query.create("signed", "mx") + res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", + source="fd92:7065:b8e:ffff::3") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 2) + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + +def test_recursive_break_dnssec_filter_aaaa_on_v6_via_v4(servers, templates): + if filter_family != "v6" or filter_type != "aaaa": + reset_servers("v6", "aaaa", servers, templates) + + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6, recursive + msg = isctest.query.create("dual.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + aaaa = res.answer[0] + assert "2001:db8::6" in str(aaaa[0]) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6, recursive + msg = isctest.query.create("unsigned", "mx") + res = isctest.query.tcp(msg, "10.53.0.4") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.authority, 1) + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] diff --git a/bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py b/bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py deleted file mode 100644 index 51c04dc32c..0000000000 --- a/bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py +++ /dev/null @@ -1,32 +0,0 @@ -# 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. - -import pytest - -pytestmark = pytest.mark.extra_artifacts( - [ - "conf/*.conf", - "dig.out.*", - "ns*/trusted.conf", - "ns1/*.signed", - "ns1/K*", - "ns1/dsset-*", - "ns1/signer.err", - "ns4/*.signed", - "ns4/K*", - "ns4/dsset-*", - "ns4/signer.err", - ] -) - - -def test_filter_aaaa(run_tests_sh): - run_tests_sh() diff --git a/bin/tests/system/isctest/mark.py b/bin/tests/system/isctest/mark.py index 97a03d217a..e1b97f8f84 100644 --- a/bin/tests/system/isctest/mark.py +++ b/bin/tests/system/isctest/mark.py @@ -13,12 +13,12 @@ import os import platform +import socket import shutil import subprocess import pytest - long_test = pytest.mark.skipif( not os.environ.get("CI_ENABLE_LONG_TESTS"), reason="CI_ENABLE_LONG_TESTS not set" ) @@ -91,3 +91,15 @@ softhsm2_environment = pytest.mark.skipif( ), reason="SOFTHSM2_CONF and SOFTHSM2_MODULE environmental variables must be set and pkcs11-tool and softhsm2-util tools present", ) + + +def have_ipv6(): + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + try: + sock.bind(("fd92:7065:b8e:ffff::1", 0)) + except OSError: + return False + return True + + +with_ipv6 = pytest.mark.skipif(not have_ipv6(), reason="IPv6 not available") From 58fe984c9505a2052dfd572cdde836686f710bd1 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 10 Jul 2025 17:17:41 -0700 Subject: [PATCH 2/6] reduce code duplication in filter-aaaa test cut down the number of identical lines in the filter-aaaa test: - replace identical test cases with small check functions (check_aaaa_only, check_any, check_nodata, etc). - group those together into large check functions (check_filter, check_filter_other_family) that have options for recursive and break_dnssec, then run those for each combination of options on servers connfigured with filter-aaaa-on-v4 and filter-aaaa-on-v6. --- .../system/filter-aaaa/tests_filter_aaaa.py | 1440 ++--------------- 1 file changed, 159 insertions(+), 1281 deletions(-) diff --git a/bin/tests/system/filter-aaaa/tests_filter_aaaa.py b/bin/tests/system/filter-aaaa/tests_filter_aaaa.py index 920a8876f3..b11addc263 100644 --- a/bin/tests/system/filter-aaaa/tests_filter_aaaa.py +++ b/bin/tests/system/filter-aaaa/tests_filter_aaaa.py @@ -37,13 +37,14 @@ pytestmark = pytest.mark.extra_artifacts( # helper functions def reset_server(server, family, ftype, servers, templates): - templates.render(f"{server}/named.conf", - {"family": family, "filtertype": ftype}) + templates.render(f"{server}/named.conf", {"family": family, "filtertype": ftype}) servers[server].reconfigure(log=False) filter_family = "v4" filter_type = "aaaa" + + def reset_servers(family, ftype, servers, templates): reset_server("ns1", family, ftype, servers, templates) reset_server("ns2", family, ftype, servers, templates) @@ -52,6 +53,63 @@ def reset_servers(family, ftype, servers, templates): filter_family = family +def check_aaaa_only(dest, source, qname, expected, adflag): + msg = isctest.query.create(qname, "aaaa") + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + if adflag: + isctest.check.adflag(res) + else: + isctest.check.noadflag(res) + assert not [a for a in res.answer if a.rdtype == rdatatype.A] + aaaa = res.answer[0] + assert aaaa.rdtype == rdatatype.AAAA + assert expected in str(aaaa[0]) + + +def check_any(dest, source, qname, expected4, expected6, do): + if do: + msg = isctest.query.create(qname, "any") # sends DO=1 + else: + msg = message.make_query(qname, "any") # sends DO=0 + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + records = sum([str(a).splitlines() for a in res.answer], []) + if expected4: + assert any(expected4 in r for r in records), str(res) + else: + assert not any(a.rdtype == rdatatype.A for a in res.answer), str(res) + if expected6: + assert any(expected6 in r for r in records), str(res) + else: + assert not any(a.rdtype == rdatatype.AAAA for a in res.answer), str(res) + + +def check_nodata(dest, source, qname, qtype, do, adflag): + if do: + msg = isctest.query.create(qname, qtype) # sends DO=1 + else: + msg = message.make_query(qname, qtype) # sends DO=0 + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + isctest.check.empty_answer(res) + if adflag: + isctest.check.adflag(res) + else: + isctest.check.noadflag(res) + + +def check_additional(dest, source, qname, qtype, expect_aaaa, adcount): + msg = isctest.query.create(qname, qtype) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, adcount) + if expect_aaaa: + assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + else: + assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + + # run the checkconf tests def test_checkconf(): for filename in glob.glob("conf/good*.conf"): @@ -61,1341 +119,161 @@ def test_checkconf(): isctest.run.cmd([os.environ["CHECKCONF"], filename]) -# These tests are against an authoritative server configured with: -## filter-aaaa-on-v4 yes; -## filter-aaaa { 10.53.0.1; }; -def test_auth_filter_aaaa_on_v4(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) +def check_filter(addr, altaddr, break_dnssec, recursive): + if recursive: + # (when testing recursive, we need to prime the cache first with + # the MX addresses, since additional section data isn't included + # unless it's been validated.) + for name in ["mx", "ns"]: + for zone in ["signed", "unsigned"]: + for qtype in ["a", "aaaa"]: + isctest.query.tcp(isctest.query.create(f"{name}.{zone}", qtype), addr) # check that AAAA is returned when only AAAA record exists, signed - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) + check_aaaa_only(addr, addr, "aaaa-only.signed", "2001:db8::2", recursive) # check that AAAA is returned when only AAAA record exists, unsigned - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) + check_aaaa_only(addr, addr, "aaaa-only.unsigned", "2001:db8::5", False) # check that NODATA/NOERROR is returned when both AAAA and A exist, # signed, DO=0 - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.empty_answer(res) + check_nodata(addr, addr, "dual.signed", "aaaa", False, False) # check that NODATA/NOERROR is returned when both AAAA and A exist, # unsigned, DO=0 - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.empty_answer(res) + check_nodata(addr, addr, "dual.unsigned", "aaaa", False, False) - # check that AAAA is returned when both AAAA and A exist, signed, DO=1 - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa = res.answer[0] - assert "2001:db8::3" in str(aaaa[0]) + # check that AAAA is returned when both AAAA and A exist, signed, + # DO=1, unless break-dnssec is enabled + if break_dnssec: + check_nodata(addr, addr, "dual.signed", "aaaa", False, False) + else: + check_aaaa_only(addr, addr, "dual.signed", "2001:db8::3", recursive) # check that NODATA/NOERROR is returned when both AAAA and A exist, # unsigned, DO=1 - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.empty_answer(res) + check_nodata(addr, addr, "dual.unsigned", "aaaa", recursive, False) # check that AAAA is returned if both AAAA and A exist and the query # source doesn't match the ACL - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) + check_aaaa_only(addr, altaddr, "dual.unsigned", "2001:db8::6", False) # check that A (and not AAAA) is returned if both AAAA and A exist, # signed, qtype=ANY, DO=0 - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) + check_any(addr, addr, "dual.signed", "1.0.0.3", None, False) # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, DO=1 - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert any("2001:db8::3" in r for r in records) + # signed, qtype=ANY, DO=1, unless break-dnssec is enabled + if break_dnssec: + check_any(addr, addr, "dual.signed", "1.0.0.3", None, True) + else: + check_any(addr, addr, "dual.signed", "1.0.0.3", "2001:db8::3", True) # check that A (and not AAAA) is returned if both AAAA and A exist, # unsigned, qtype=ANY, DO=0 - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) + check_any(addr, addr, "dual.unsigned", "1.0.0.6", None, False) # check that A (and not AAAA) is returned if both AAAA and A exist, # unsigned, qtype=ANY, DO=1 - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) + check_any(addr, addr, "dual.unsigned", "1.0.0.6", None, True) # check that both A and AAAA are returned if both AAAA and A exist, # signed, qtype=ANY, query source does not match ACL - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) + check_any(addr, altaddr, "dual.unsigned", "1.0.0.6", "2001:db8::6", True) # check that AAAA is omitted from additional section, qtype=NS, unsigned - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + check_additional(addr, addr, "unsigned", "ns", False, 1) # check that AAAA is omitted from additional section, qtype=MX, unsigned - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is included in additional section, qtype=MX, signed - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "10.53.0.1", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -@isctest.mark.with_ipv6 -def test_auth_filter_aaaa_on_v4_via_v6(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6 - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6 - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -# These tests are against an authoritative server configured with: -## filter-aaaa-on-v4 break-dnssec; -## filter-aaaa { 10.53.0.4; }; -def test_auth_break_dnssec_filter_aaaa_on_v4(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - # check that AAAA is returned when only AAAA record exists, signed, - # with break-dnssec - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) - - # check that AAAA is returned when only AAAA record exists, unsigned, - # with break-dnssec - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0, with break-dnssec - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0, with break-dnssec - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned when both AAAA and A exist, signed, DO=1, - # with break-dnssec - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, with break-dnssec - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=1, with break-dnssec - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0, with break-dnssec - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1, with break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL, with break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) - - # check that AAAA is omitted from additional section, qtype=NS, - # unsigned, with break-dnssec - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # unsigned, with break-dnssec - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # signed, with break-dnssec - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "10.53.0.4", source="10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -@isctest.mark.with_ipv6 -def test_auth_break_dnssec_filter_aaaa_on_v4_via_v6(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6, with break-dnssec - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -# These tests are against a recursive server configured with: -## filter-aaaa-on-v4 yes; -## filter-aaaa { 10.53.0.2; }; -def test_recursive_filter_aaaa_on_v4(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - # check that AAAA is returned when only AAAA record exists, signed, - # recursive - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.adflag(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) - - # check that AAAA is returned when only AAAA record exists, unsigned, - # recursive - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0, recursive - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0, recursive - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned when both AAAA and A exist, signed, DO=1, - # recursive - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.adflag(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa = res.answer[0] - assert "2001:db8::3" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, recursive - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noadflag(res) - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, recursive - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.noadflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, DO=1, recursive - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.adflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0, recursive - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1, recursive - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL, recursive - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) - - # check that AAAA is omitted from additional section, qtype=NS, - # unsigned, recursive - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # unsigned, recursive - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # (we need to prime the cache first with the MX addresses, since - # additional section data isn't included unless it's already validated.) - msg = isctest.query.create("mx.signed", "a") - isctest.query.tcp(msg, "10.53.0.2") - msg = isctest.query.create("mx.signed", "aaaa") - isctest.query.tcp(msg, "10.53.0.2") + check_additional(addr, addr, "unsigned", "mx", False, 2) # check that AAAA is included in additional section, qtype=MX, signed, - # recursive - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "10.53.0.2", source="10.53.0.2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + # unless break-dnssec is enabled + if break_dnssec: + check_additional(addr, addr, "signed", "mx", False, 4) + else: + check_additional(addr, addr, "signed", "mx", True, 8) + + +def check_filter_other_family(addr): + # check that AAAA is returned when both AAAA and A record exists, + # unsigned, over IPv6 + check_aaaa_only(addr, addr, "dual.unsigned", "2001:db8::6", False) + + # check that AAAA is included in additional section, qtype=MX, + # unsigned, over IPv6 + check_additional(addr, addr, "unsigned", "mx", True, 4) + + +def test_filter_aaaa_on_v4(servers, templates): + if filter_family != "v4" or filter_type != "aaaa": + reset_servers("v4", "aaaa", servers, templates) + + # ns1: auth, configured with: + ## filter-aaaa-on-v4 yes; + ## filter-aaaa { 10.53.0.1; }; + check_filter("10.53.0.1", "10.53.0.2", False, False) + + # ns4: auth, configured with: + ## filter-aaaa-on-v4 break-dnssec; + ## filter-aaaa { 10.53.0.4; }; + check_filter("10.53.0.4", "10.53.0.2", True, False) + + # ns2: recursive, configured with: + ## filter-aaaa-on-v4 yes; + ## filter-aaaa { 10.53.0.2; }; + check_filter("10.53.0.2", "10.53.0.1", False, True) + + # ns3: recursive, configured with: + ## filter-aaaa-on-v4 break-dnssec; + ## filter-aaaa { 10.53.0.3; }; + check_filter("10.53.0.3", "10.53.0.1", True, True) @isctest.mark.with_ipv6 -def test_recursive_filter_aaaa_on_v4_via_v6(servers, templates): +def test_filter_aaaa_on_v4_via_v6(servers, templates): if filter_family != "v4" or filter_type != "aaaa": reset_servers("v4", "aaaa", servers, templates) - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6, recursive - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6, recursive - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -# These tests are against a recursive server configured with: -## filter-aaaa-on-v4 break-dnssec; -## filter-aaaa { 10.53.0.3; }; -def test_recursive_break_dnssec_filter_aaaa_on_v4(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - # check that AAAA is returned when only AAAA record exists, signed, - # recursive, with break-dnssec - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.adflag(res) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) - - # check that AAAA is returned when only AAAA record exists, unsigned, - # recursive, with break-dnssec - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, recursive, with break-dnssec - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, recursive, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noadflag(res) - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.1") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, recursive, with break-dnssec - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1, recursive, with break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL, recursive, with - # break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) - - # check that AAAA is omitted from additional section, qtype=NS, - # unsigned, recursive, with break-dnssec - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # unsigned, recursive, with break-dnssec - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, signed, - # recursive, with break-dnssec - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "10.53.0.3", source="10.53.0.3") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -@isctest.mark.with_ipv6 -def test_recursive_break_dnssec_filter_aaaa_on_v4_via_v6(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6, recursive - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6, recursive - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + check_filter_other_family("fd92:7065:b8e:ffff::1") + check_filter_other_family("fd92:7065:b8e:ffff::2") + check_filter_other_family("fd92:7065:b8e:ffff::3") + check_filter_other_family("fd92:7065:b8e:ffff::4") # These tests are against an authoritative server configured with: ## filter-aaaa-on-v6 yes; -## filter-aaaa { fd92:7065:b8e:ffff::1; }; @isctest.mark.with_ipv6 -def test_auth_filter_aaaa_on_v6(servers, templates): +def test_filter_aaaa_on_v6(servers, templates): if filter_family != "v6" or filter_type != "aaaa": reset_servers("v6", "aaaa", servers, templates) - # check that AAAA is returned when only AAAA record exists, signed - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) + # ns1: auth, configured with: + ## filter-aaaa-on-v6 yes; + ## filter-aaaa { fd92:7065:b8e:ffff::1; }; + check_filter("fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", False, False) - # check that AAAA is returned when only AAAA record exists, unsigned - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) + # ns4: auth, configured with: + ## filter-aaaa-on-v6 break-dnssec; + ## filter-aaaa { fd92:7065:b8e:ffff::4; }; + check_filter("fd92:7065:b8e:ffff::4", "fd92:7065:b8e:ffff::2", True, False) - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0 - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.empty_answer(res) + # ns2: recursive, configured with: + ## filter-aaaa-on-v6 yes; + ## filter-aaaa { fd92:7065:b8e:ffff::2; }; + check_filter("fd92:7065:b8e:ffff::2", "fd92:7065:b8e:ffff::1", False, True) - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0 - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned when both AAAA and A exist, signed, DO=1 - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa = res.answer[0] - assert "2001:db8::3" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1 - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0 - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, DO=1 - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0 - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1 - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) - - # check that AAAA is omitted from additional section, qtype=NS, unsigned - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, unsigned - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is included in additional section, qtype=MX, signed - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::1", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + # ns3: recursive, configured with: + ## filter-aaaa-on-v6 break-dnssec; + ## filter-aaaa { fd92:7065:b8e:ffff::3; }; + check_filter("fd92:7065:b8e:ffff::3", "fd92:7065:b8e:ffff::1", True, True) -def test_auth_filter_aaaa_on_v6_via_v4(servers, templates): +def test_filter_aaaa_on_v6_via_v4(servers, templates): if filter_family != "v6" or filter_type != "aaaa": reset_servers("v6", "aaaa", servers, templates) - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6 - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6 - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.1") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -# These tests are against an authoritative server configured with: -## filter-aaaa-on-v6 break-dnssec; -## filter-aaaa { fd92:7065:b8e:ffff::4; }; -@isctest.mark.with_ipv6 -def test_auth_break_dnssec_filter_aaaa_on_v6(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - # check that AAAA is returned when only AAAA record exists, signed, - # with break-dnssec - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) - - # check that AAAA is returned when only AAAA record exists, unsigned, - # with break-dnssec - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0, with break-dnssec - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0, with break-dnssec - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned when both AAAA and A exist, signed, DO=1, - # with break-dnssec - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, with break-dnssec - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=1, with break-dnssec - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0, with break-dnssec - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1, with break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL, with break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) - - # check that AAAA is omitted from additional section, qtype=NS, - # unsigned, with break-dnssec - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # unsigned, with break-dnssec - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # signed, with break-dnssec - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::4", - source="fd92:7065:b8e:ffff::4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -def test_auth_break_dnssec_filter_aaaa_on_v6_via_v4(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6, with break-dnssec - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -# These tests are against a recursive server configured with: -## filter-aaaa-on-v6 yes; -## filter-aaaa { fd92:7065:b8e:ffff::2; }; -@isctest.mark.with_ipv6 -def test_recursive_filter_aaaa_on_v6(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - # check that AAAA is returned when only AAAA record exists, signed, - # recursive - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.adflag(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) - - # check that AAAA is returned when only AAAA record exists, unsigned, - # recursive - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0, recursive - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0, recursive - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned when both AAAA and A exist, signed, DO=1, - # recursive - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.adflag(res) - isctest.check.rr_count_eq(res.authority, 2) - aaaa = res.answer[0] - assert "2001:db8::3" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, recursive - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noadflag(res) - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, recursive - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.noadflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, DO=1, recursive - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.adflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0, recursive - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1, recursive - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL, recursive - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) - - # check that AAAA is omitted from additional section, qtype=NS, - # unsigned, recursive - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # unsigned, recursive - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # (we need to prime the cache first with the MX addresses, since - # additional section data isn't included unless it's already validated.) - msg = isctest.query.create("mx.signed", "a") - isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2") - msg = isctest.query.create("mx.signed", "aaaa") - isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2") - - # check that AAAA is included in additional section, qtype=MX, signed, - # recursive - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::2", - source="fd92:7065:b8e:ffff::2") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -def test_recursive_filter_aaaa_on_v6_via_v4(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6, recursive - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6, recursive - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -# These tests are against a recursive server configured with: -## filter-aaaa-on-v6 break-dnssec; -## filter-aaaa { fd92:7065:b8e:ffff::3; }; -@isctest.mark.with_ipv6 -def test_recursive_break_dnssec_filter_aaaa_on_v6(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - # check that AAAA is returned when only AAAA record exists, signed, - # recursive, with break-dnssec - msg = isctest.query.create("aaaa-only.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.adflag(res) - aaaa, _ = res.answer - assert "2001:db8::2" in str(aaaa[0]) - - # check that AAAA is returned when only AAAA record exists, unsigned, - # recursive, with break-dnssec - msg = isctest.query.create("aaaa-only.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - aaaa = res.answer[0] - assert "2001:db8::5" in str(aaaa[0]) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.signed", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.unsigned", "aaaa") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, recursive, with break-dnssec - msg = isctest.query.create("dual.signed", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.empty_answer(res) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1, recursive, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noadflag(res) - isctest.check.noerror(res) - isctest.check.empty_answer(res) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL, with break-dnssec - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - isctest.check.noadflag(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.signed", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0, recursive, with break-dnssec - msg = isctest.query.create("dual.signed", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.noadflag(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.3" in r for r in records) - assert not any("2001:db8::3" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0, recursive, with break-dnssec - msg = message.make_query("dual.unsigned", "any") # sends DO=0 - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1, recursive, with break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert not any("2001:db8::6" in r for r in records) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL, recursive, with - # break-dnssec - msg = isctest.query.create("dual.unsigned", "any") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::1") - isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) - assert any("1.0.0.6" in r for r in records) - assert any("2001:db8::6" in r for r in records) - - # check that AAAA is omitted from additional section, qtype=NS, - # unsigned, recursive, with break-dnssec - msg = isctest.query.create("unsigned", "ns") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 1) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, - # unsigned, recursive, with break-dnssec - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - # check that AAAA is omitted from additional section, qtype=MX, signed, - # recursive, with break-dnssec - msg = isctest.query.create("signed", "mx") - res = isctest.query.tcp(msg, "fd92:7065:b8e:ffff::3", - source="fd92:7065:b8e:ffff::3") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 2) - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] - - -def test_recursive_break_dnssec_filter_aaaa_on_v6_via_v4(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6, recursive - msg = isctest.query.create("dual.unsigned", "aaaa") - res = isctest.query.tcp(msg, "10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - aaaa = res.answer[0] - assert "2001:db8::6" in str(aaaa[0]) - - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6, recursive - msg = isctest.query.create("unsigned", "mx") - res = isctest.query.tcp(msg, "10.53.0.4") - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.authority, 1) - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + check_filter_other_family("10.53.0.1") + check_filter_other_family("10.53.0.2") + check_filter_other_family("10.53.0.3") + check_filter_other_family("10.53.0.4") From 1c5363cf99c7df18d13cb01f1c7a51f31088d769 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 10 Jul 2025 22:00:20 -0700 Subject: [PATCH 3/6] add filter-a tests add test cases to exercise the filter-a plugin. --- bin/tests/system/filter-aaaa/ns1/signed.db.in | 2 +- bin/tests/system/filter-aaaa/ns1/unsigned.db | 2 +- bin/tests/system/filter-aaaa/ns4/signed.db.in | 2 +- bin/tests/system/filter-aaaa/ns4/unsigned.db | 2 +- .../system/filter-aaaa/tests_filter_aaaa.py | 237 +++++++++++++----- 5 files changed, 175 insertions(+), 70 deletions(-) diff --git a/bin/tests/system/filter-aaaa/ns1/signed.db.in b/bin/tests/system/filter-aaaa/ns1/signed.db.in index 36a037316d..66d1795d9e 100644 --- a/bin/tests/system/filter-aaaa/ns1/signed.db.in +++ b/bin/tests/system/filter-aaaa/ns1/signed.db.in @@ -17,7 +17,7 @@ $TTL 120 ns A 10.53.0.1 AAAA fd92:7065:b8e:ffff::1 -a-only NS 1.0.0.1 +a-only A 1.0.0.2 aaaa-only AAAA 2001:db8::2 dual A 1.0.0.3 dual AAAA 2001:db8::3 diff --git a/bin/tests/system/filter-aaaa/ns1/unsigned.db b/bin/tests/system/filter-aaaa/ns1/unsigned.db index abc3947c82..2fc656e0ec 100644 --- a/bin/tests/system/filter-aaaa/ns1/unsigned.db +++ b/bin/tests/system/filter-aaaa/ns1/unsigned.db @@ -17,7 +17,7 @@ $TTL 120 ns A 10.53.0.1 AAAA fd92:7065:b8e:ffff::1 -a-only NS 1.0.0.4 +a-only A 1.0.0.5 aaaa-only AAAA 2001:db8::5 dual A 1.0.0.6 dual AAAA 2001:db8::6 diff --git a/bin/tests/system/filter-aaaa/ns4/signed.db.in b/bin/tests/system/filter-aaaa/ns4/signed.db.in index fa521068e2..935088d5ef 100644 --- a/bin/tests/system/filter-aaaa/ns4/signed.db.in +++ b/bin/tests/system/filter-aaaa/ns4/signed.db.in @@ -17,7 +17,7 @@ $TTL 120 ns A 10.53.0.4 AAAA fd92:7065:b8e:ffff::4 -a-only NS 1.0.0.1 +a-only A 1.0.0.2 aaaa-only AAAA 2001:db8::2 dual A 1.0.0.3 dual AAAA 2001:db8::3 diff --git a/bin/tests/system/filter-aaaa/ns4/unsigned.db b/bin/tests/system/filter-aaaa/ns4/unsigned.db index 4baa4628d0..d2aced2f2a 100644 --- a/bin/tests/system/filter-aaaa/ns4/unsigned.db +++ b/bin/tests/system/filter-aaaa/ns4/unsigned.db @@ -17,7 +17,7 @@ $TTL 120 ns A 10.53.0.4 AAAA fd92:7065:b8e:ffff::4 -a-only NS 1.0.0.4 +a-only A 1.0.0.5 aaaa-only AAAA 2001:db8::5 dual A 1.0.0.6 dual AAAA 2001:db8::6 diff --git a/bin/tests/system/filter-aaaa/tests_filter_aaaa.py b/bin/tests/system/filter-aaaa/tests_filter_aaaa.py index b11addc263..58149973ae 100644 --- a/bin/tests/system/filter-aaaa/tests_filter_aaaa.py +++ b/bin/tests/system/filter-aaaa/tests_filter_aaaa.py @@ -15,7 +15,8 @@ import glob import os import subprocess -from dns import message, rdatatype +import dns +from dns import message, rdataclass, rdatatype import pytest @@ -41,6 +42,9 @@ def reset_server(server, family, ftype, servers, templates): servers[server].reconfigure(log=False) +# these are the default configuration values for the jinja2 +# templates. if some other value is needed for a test, then +# the named.conf files must be regenerated. filter_family = "v4" filter_type = "aaaa" @@ -50,46 +54,56 @@ def reset_servers(family, ftype, servers, templates): reset_server("ns2", family, ftype, servers, templates) reset_server("ns3", family, ftype, servers, templates) reset_server("ns4", family, ftype, servers, templates) - filter_family = family -def check_aaaa_only(dest, source, qname, expected, adflag): - msg = isctest.query.create(qname, "aaaa") +def check_filtertype_only(dest, source, qname, ftype, expected, adflag): + qname = dns.name.from_text(qname) + msg = isctest.query.create(qname, ftype) res = isctest.query.tcp(msg, dest, source=source) isctest.check.noerror(res) if adflag: isctest.check.adflag(res) else: isctest.check.noadflag(res) - assert not [a for a in res.answer if a.rdtype == rdatatype.A] - aaaa = res.answer[0] - assert aaaa.rdtype == rdatatype.AAAA - assert expected in str(aaaa[0]) + a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) + aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) + if ftype == "aaaa": + assert not a_record + if expected: + assert ( + aaaa_record[0].address == expected + ), f"expected AAAA {expected} in ANSWER: {res}" + else: + assert not aaaa_record + if expected: + assert ( + a_record[0].address == expected + ), f"expected A {expected} in ANSWER: {res}" def check_any(dest, source, qname, expected4, expected6, do): - if do: - msg = isctest.query.create(qname, "any") # sends DO=1 - else: - msg = message.make_query(qname, "any") # sends DO=0 + qname = dns.name.from_text(qname) + msg = isctest.query.create(qname, "any", dnssec=do) res = isctest.query.tcp(msg, dest, source=source) isctest.check.noerror(res) - records = sum([str(a).splitlines() for a in res.answer], []) + a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) if expected4: - assert any(expected4 in r for r in records), str(res) + assert ( + a_record and a_record[0].address == expected4 + ), f"expected A {expected4} in ANSWER: {res}" else: - assert not any(a.rdtype == rdatatype.A for a in res.answer), str(res) + assert not a_record + aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) if expected6: - assert any(expected6 in r for r in records), str(res) + assert ( + aaaa_record and aaaa_record[0].address == expected6 + ), f"expected AAAA {expected6} in ANSWER: {res}" else: - assert not any(a.rdtype == rdatatype.AAAA for a in res.answer), str(res) + assert not aaaa_record def check_nodata(dest, source, qname, qtype, do, adflag): - if do: - msg = isctest.query.create(qname, qtype) # sends DO=1 - else: - msg = message.make_query(qname, qtype) # sends DO=0 + msg = isctest.query.create(qname, qtype, dnssec=do) res = isctest.query.tcp(msg, dest, source=source) isctest.check.noerror(res) isctest.check.empty_answer(res) @@ -99,15 +113,16 @@ def check_nodata(dest, source, qname, qtype, do, adflag): isctest.check.noadflag(res) -def check_additional(dest, source, qname, qtype, expect_aaaa, adcount): +def check_additional(dest, source, qname, qtype, ftype, expected, adcount): msg = isctest.query.create(qname, qtype) res = isctest.query.tcp(msg, dest, source=source) isctest.check.noerror(res) isctest.check.rr_count_eq(res.additional, adcount) - if expect_aaaa: - assert [a for a in res.additional if a.rdtype == rdatatype.AAAA] + t = rdatatype.A if ftype == "a" else rdatatype.AAAA + if expected: + assert [a for a in res.additional if a.rdtype == t] else: - assert not [a for a in res.additional if a.rdtype == rdatatype.AAAA] + assert not [a for a in res.additional if a.rdtype == t] # run the checkconf tests @@ -119,7 +134,7 @@ def test_checkconf(): isctest.run.cmd([os.environ["CHECKCONF"], filename]) -def check_filter(addr, altaddr, break_dnssec, recursive): +def check_filter(addr, altaddr, ftype, break_dnssec, recursive): if recursive: # (when testing recursive, we need to prime the cache first with # the MX addresses, since additional section data isn't included @@ -127,82 +142,98 @@ def check_filter(addr, altaddr, break_dnssec, recursive): for name in ["mx", "ns"]: for zone in ["signed", "unsigned"]: for qtype in ["a", "aaaa"]: - isctest.query.tcp(isctest.query.create(f"{name}.{zone}", qtype), addr) + isctest.query.tcp( + isctest.query.create(f"{name}.{zone}", qtype), addr + ) # check that AAAA is returned when only AAAA record exists, signed - check_aaaa_only(addr, addr, "aaaa-only.signed", "2001:db8::2", recursive) + expected = "1.0.0.2" if ftype == "a" else "2001:db8::2" + check_filtertype_only( + addr, addr, f"{ftype}-only.signed", ftype, expected, recursive + ) # check that AAAA is returned when only AAAA record exists, unsigned - check_aaaa_only(addr, addr, "aaaa-only.unsigned", "2001:db8::5", False) + expected = "1.0.0.5" if ftype == "a" else "2001:db8::5" + check_filtertype_only(addr, addr, f"{ftype}-only.unsigned", ftype, expected, False) # check that NODATA/NOERROR is returned when both AAAA and A exist, # signed, DO=0 - check_nodata(addr, addr, "dual.signed", "aaaa", False, False) + check_nodata(addr, addr, "dual.signed", ftype, False, False) # check that NODATA/NOERROR is returned when both AAAA and A exist, # unsigned, DO=0 - check_nodata(addr, addr, "dual.unsigned", "aaaa", False, False) + check_nodata(addr, addr, "dual.unsigned", ftype, False, False) # check that AAAA is returned when both AAAA and A exist, signed, # DO=1, unless break-dnssec is enabled if break_dnssec: - check_nodata(addr, addr, "dual.signed", "aaaa", False, False) + check_nodata(addr, addr, "dual.signed", ftype, False, False) else: - check_aaaa_only(addr, addr, "dual.signed", "2001:db8::3", recursive) + expected = "1.0.0.3" if ftype == "a" else "2001:db8::3" + check_filtertype_only(addr, addr, "dual.signed", ftype, expected, recursive) # check that NODATA/NOERROR is returned when both AAAA and A exist, # unsigned, DO=1 - check_nodata(addr, addr, "dual.unsigned", "aaaa", recursive, False) + check_nodata(addr, addr, "dual.unsigned", ftype, recursive, False) # check that AAAA is returned if both AAAA and A exist and the query # source doesn't match the ACL - check_aaaa_only(addr, altaddr, "dual.unsigned", "2001:db8::6", False) + expected = "1.0.0.6" if ftype == "a" else "2001:db8::6" + check_filtertype_only(addr, altaddr, "dual.unsigned", ftype, expected, False) # check that A (and not AAAA) is returned if both AAAA and A exist, # signed, qtype=ANY, DO=0 - check_any(addr, addr, "dual.signed", "1.0.0.3", None, False) + expected4 = "1.0.0.3" if ftype == "aaaa" else None + expected6 = "2001:db8::3" if ftype == "a" else None + check_any(addr, addr, "dual.signed", expected4, expected6, False) # check that both A and AAAA are returned if both AAAA and A exist, # signed, qtype=ANY, DO=1, unless break-dnssec is enabled if break_dnssec: - check_any(addr, addr, "dual.signed", "1.0.0.3", None, True) + if ftype == "a": + expected4 = None + else: + expected6 = None + check_any(addr, addr, "dual.signed", expected4, expected6, True) else: check_any(addr, addr, "dual.signed", "1.0.0.3", "2001:db8::3", True) + expected4 = "1.0.0.6" if ftype == "aaaa" else None + expected6 = "2001:db8::6" if ftype == "a" else None # check that A (and not AAAA) is returned if both AAAA and A exist, # unsigned, qtype=ANY, DO=0 - check_any(addr, addr, "dual.unsigned", "1.0.0.6", None, False) + check_any(addr, addr, "dual.unsigned", expected4, expected6, False) # check that A (and not AAAA) is returned if both AAAA and A exist, # unsigned, qtype=ANY, DO=1 - check_any(addr, addr, "dual.unsigned", "1.0.0.6", None, True) + check_any(addr, addr, "dual.unsigned", expected4, expected6, True) # check that both A and AAAA are returned if both AAAA and A exist, # signed, qtype=ANY, query source does not match ACL check_any(addr, altaddr, "dual.unsigned", "1.0.0.6", "2001:db8::6", True) # check that AAAA is omitted from additional section, qtype=NS, unsigned - check_additional(addr, addr, "unsigned", "ns", False, 1) + check_additional(addr, addr, "unsigned", "ns", ftype, False, 1) # check that AAAA is omitted from additional section, qtype=MX, unsigned - check_additional(addr, addr, "unsigned", "mx", False, 2) + check_additional(addr, addr, "unsigned", "mx", ftype, False, 2) # check that AAAA is included in additional section, qtype=MX, signed, # unless break-dnssec is enabled if break_dnssec: - check_additional(addr, addr, "signed", "mx", False, 4) + check_additional(addr, addr, "signed", "mx", ftype, False, 4) else: - check_additional(addr, addr, "signed", "mx", True, 8) + check_additional(addr, addr, "signed", "mx", ftype, True, 8) -def check_filter_other_family(addr): - # check that AAAA is returned when both AAAA and A record exists, - # unsigned, over IPv6 - check_aaaa_only(addr, addr, "dual.unsigned", "2001:db8::6", False) +def check_filter_other_family(addr, ftype): + # check that the filtered type is returned when both AAAA and A + # record exists, unsigned, over IPv6 + check_filtertype_only(addr, addr, "dual.unsigned", ftype, None, False) - # check that AAAA is included in additional section, qtype=MX, - # unsigned, over IPv6 - check_additional(addr, addr, "unsigned", "mx", True, 4) + # check that the filtered type is included in additional section, + # qtype=MX, unsigned, over IPv6 + check_additional(addr, addr, "unsigned", "mx", ftype, True, 4) def test_filter_aaaa_on_v4(servers, templates): @@ -212,22 +243,22 @@ def test_filter_aaaa_on_v4(servers, templates): # ns1: auth, configured with: ## filter-aaaa-on-v4 yes; ## filter-aaaa { 10.53.0.1; }; - check_filter("10.53.0.1", "10.53.0.2", False, False) + check_filter("10.53.0.1", "10.53.0.2", "aaaa", False, False) # ns4: auth, configured with: ## filter-aaaa-on-v4 break-dnssec; ## filter-aaaa { 10.53.0.4; }; - check_filter("10.53.0.4", "10.53.0.2", True, False) + check_filter("10.53.0.4", "10.53.0.2", "aaaa", True, False) # ns2: recursive, configured with: ## filter-aaaa-on-v4 yes; ## filter-aaaa { 10.53.0.2; }; - check_filter("10.53.0.2", "10.53.0.1", False, True) + check_filter("10.53.0.2", "10.53.0.1", "aaaa", False, True) # ns3: recursive, configured with: ## filter-aaaa-on-v4 break-dnssec; ## filter-aaaa { 10.53.0.3; }; - check_filter("10.53.0.3", "10.53.0.1", True, True) + check_filter("10.53.0.3", "10.53.0.1", "aaaa", True, True) @isctest.mark.with_ipv6 @@ -235,10 +266,10 @@ def test_filter_aaaa_on_v4_via_v6(servers, templates): if filter_family != "v4" or filter_type != "aaaa": reset_servers("v4", "aaaa", servers, templates) - check_filter_other_family("fd92:7065:b8e:ffff::1") - check_filter_other_family("fd92:7065:b8e:ffff::2") - check_filter_other_family("fd92:7065:b8e:ffff::3") - check_filter_other_family("fd92:7065:b8e:ffff::4") + check_filter_other_family("fd92:7065:b8e:ffff::1", "aaaa") + check_filter_other_family("fd92:7065:b8e:ffff::2", "aaaa") + check_filter_other_family("fd92:7065:b8e:ffff::3", "aaaa") + check_filter_other_family("fd92:7065:b8e:ffff::4", "aaaa") # These tests are against an authoritative server configured with: @@ -251,29 +282,103 @@ def test_filter_aaaa_on_v6(servers, templates): # ns1: auth, configured with: ## filter-aaaa-on-v6 yes; ## filter-aaaa { fd92:7065:b8e:ffff::1; }; - check_filter("fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", False, False) + check_filter("fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", "aaaa", False, False) # ns4: auth, configured with: ## filter-aaaa-on-v6 break-dnssec; ## filter-aaaa { fd92:7065:b8e:ffff::4; }; - check_filter("fd92:7065:b8e:ffff::4", "fd92:7065:b8e:ffff::2", True, False) + check_filter("fd92:7065:b8e:ffff::4", "fd92:7065:b8e:ffff::2", "aaaa", True, False) # ns2: recursive, configured with: ## filter-aaaa-on-v6 yes; ## filter-aaaa { fd92:7065:b8e:ffff::2; }; - check_filter("fd92:7065:b8e:ffff::2", "fd92:7065:b8e:ffff::1", False, True) + check_filter("fd92:7065:b8e:ffff::2", "fd92:7065:b8e:ffff::1", "aaaa", False, True) # ns3: recursive, configured with: ## filter-aaaa-on-v6 break-dnssec; ## filter-aaaa { fd92:7065:b8e:ffff::3; }; - check_filter("fd92:7065:b8e:ffff::3", "fd92:7065:b8e:ffff::1", True, True) + check_filter("fd92:7065:b8e:ffff::3", "fd92:7065:b8e:ffff::1", "aaaa", True, True) def test_filter_aaaa_on_v6_via_v4(servers, templates): if filter_family != "v6" or filter_type != "aaaa": reset_servers("v6", "aaaa", servers, templates) - check_filter_other_family("10.53.0.1") - check_filter_other_family("10.53.0.2") - check_filter_other_family("10.53.0.3") - check_filter_other_family("10.53.0.4") + check_filter_other_family("10.53.0.1", "aaaa") + check_filter_other_family("10.53.0.2", "aaaa") + check_filter_other_family("10.53.0.3", "aaaa") + check_filter_other_family("10.53.0.4", "aaaa") + + +def test_filter_a_on_v4(servers, templates): + if filter_family != "v4" or filter_type != "a": + reset_servers("v4", "a", servers, templates) + + # ns1: auth, configured with: + ## filter-a-on-v4 yes; + ## filter-a { 10.53.0.1; }; + check_filter("10.53.0.1", "10.53.0.2", "a", False, False) + + # ns4: auth, configured with: + ## filter-a-on-v4 break-dnssec; + ## filter-a { 10.53.0.4; }; + check_filter("10.53.0.4", "10.53.0.2", "a", True, False) + + # ns2: recursive, configured with: + ## filter-a-on-v4 yes; + ## filter-a { 10.53.0.2; }; + check_filter("10.53.0.2", "10.53.0.1", "a", False, True) + + # ns3: recursive, configured with: + ## filter-a-on-v4 break-dnssec; + ## filter-a { 10.53.0.3; }; + check_filter("10.53.0.3", "10.53.0.1", "a", True, True) + + +@isctest.mark.with_ipv6 +def test_filter_a_on_v4_via_v6(servers, templates): + if filter_family != "v4" or filter_type != "a": + reset_servers("v4", "a", servers, templates) + + check_filter_other_family("fd92:7065:b8e:ffff::1", "a") + check_filter_other_family("fd92:7065:b8e:ffff::2", "a") + check_filter_other_family("fd92:7065:b8e:ffff::3", "a") + check_filter_other_family("fd92:7065:b8e:ffff::4", "a") + + +# These tests are against an authoritative server configured with: +## filter-a-on-v6 yes; +@isctest.mark.with_ipv6 +def test_filter_a_on_v6(servers, templates): + if filter_family != "v6" or filter_type != "a": + reset_servers("v6", "a", servers, templates) + + # ns1: auth, configured with: + ## filter-a-on-v6 yes; + ## filter-a { fd92:7065:b8e:ffff::1; }; + check_filter("fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", "a", False, False) + + # ns4: auth, configured with: + ## filter-a-on-v6 break-dnssec; + ## filter-a { fd92:7065:b8e:ffff::4; }; + check_filter("fd92:7065:b8e:ffff::4", "fd92:7065:b8e:ffff::2", "a", True, False) + + # ns2: recursive, configured with: + ## filter-a-on-v6 yes; + ## filter-a { fd92:7065:b8e:ffff::2; }; + check_filter("fd92:7065:b8e:ffff::2", "fd92:7065:b8e:ffff::1", "a", False, True) + + # ns3: recursive, configured with: + ## filter-a-on-v6 break-dnssec; + ## filter-a { fd92:7065:b8e:ffff::3; }; + check_filter("fd92:7065:b8e:ffff::3", "fd92:7065:b8e:ffff::1", "a", True, True) + + +def test_filter_a_on_v6_via_v4(servers, templates): + if filter_family != "v6" or filter_type != "a": + reset_servers("v6", "a", servers, templates) + + check_filter_other_family("10.53.0.1", "a") + check_filter_other_family("10.53.0.2", "a") + check_filter_other_family("10.53.0.3", "a") + check_filter_other_family("10.53.0.4", "a") From 28a3706ec5206ff9e9cd9d09bb3ba168dc16c45b Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 10 Jul 2025 22:12:10 -0700 Subject: [PATCH 4/6] rename filter-aaaa to filters since the test now covers both plugins, the filter-aaaa name is misleading. --- bin/tests/system/{filter-aaaa => filters}/.gitignore | 0 bin/tests/system/{filter-aaaa => filters}/conf/bad1.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/bad2.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/bad3.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/bad4.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/bad5.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/good1.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/good2.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/good3.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/good4.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/conf/good5.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/ns1/named.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/ns1/root.db | 0 bin/tests/system/{filter-aaaa => filters}/ns1/sign.sh | 0 bin/tests/system/{filter-aaaa => filters}/ns1/signed.db.in | 0 bin/tests/system/{filter-aaaa => filters}/ns1/unsigned.db | 0 bin/tests/system/{filter-aaaa => filters}/ns2/hints | 0 bin/tests/system/{filter-aaaa => filters}/ns2/named.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/ns3/hints | 0 bin/tests/system/{filter-aaaa => filters}/ns3/named.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/ns4/named.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/ns4/root.db | 0 bin/tests/system/{filter-aaaa => filters}/ns4/sign.sh | 0 bin/tests/system/{filter-aaaa => filters}/ns4/signed.db.in | 0 bin/tests/system/{filter-aaaa => filters}/ns4/unsigned.db | 0 bin/tests/system/{filter-aaaa => filters}/ns5/hints | 0 bin/tests/system/{filter-aaaa => filters}/ns5/named.conf.j2 | 0 bin/tests/system/{filter-aaaa => filters}/setup.sh | 0 .../tests_filter_aaaa.py => filters/tests_filters.py} | 0 29 files changed, 0 insertions(+), 0 deletions(-) rename bin/tests/system/{filter-aaaa => filters}/.gitignore (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/bad1.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/bad2.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/bad3.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/bad4.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/bad5.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/good1.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/good2.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/good3.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/good4.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/conf/good5.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/ns1/named.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/ns1/root.db (100%) rename bin/tests/system/{filter-aaaa => filters}/ns1/sign.sh (100%) rename bin/tests/system/{filter-aaaa => filters}/ns1/signed.db.in (100%) rename bin/tests/system/{filter-aaaa => filters}/ns1/unsigned.db (100%) rename bin/tests/system/{filter-aaaa => filters}/ns2/hints (100%) rename bin/tests/system/{filter-aaaa => filters}/ns2/named.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/ns3/hints (100%) rename bin/tests/system/{filter-aaaa => filters}/ns3/named.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/ns4/named.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/ns4/root.db (100%) rename bin/tests/system/{filter-aaaa => filters}/ns4/sign.sh (100%) rename bin/tests/system/{filter-aaaa => filters}/ns4/signed.db.in (100%) rename bin/tests/system/{filter-aaaa => filters}/ns4/unsigned.db (100%) rename bin/tests/system/{filter-aaaa => filters}/ns5/hints (100%) rename bin/tests/system/{filter-aaaa => filters}/ns5/named.conf.j2 (100%) rename bin/tests/system/{filter-aaaa => filters}/setup.sh (100%) rename bin/tests/system/{filter-aaaa/tests_filter_aaaa.py => filters/tests_filters.py} (100%) diff --git a/bin/tests/system/filter-aaaa/.gitignore b/bin/tests/system/filters/.gitignore similarity index 100% rename from bin/tests/system/filter-aaaa/.gitignore rename to bin/tests/system/filters/.gitignore diff --git a/bin/tests/system/filter-aaaa/conf/bad1.conf.j2 b/bin/tests/system/filters/conf/bad1.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad1.conf.j2 rename to bin/tests/system/filters/conf/bad1.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad2.conf.j2 b/bin/tests/system/filters/conf/bad2.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad2.conf.j2 rename to bin/tests/system/filters/conf/bad2.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad3.conf.j2 b/bin/tests/system/filters/conf/bad3.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad3.conf.j2 rename to bin/tests/system/filters/conf/bad3.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad4.conf.j2 b/bin/tests/system/filters/conf/bad4.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad4.conf.j2 rename to bin/tests/system/filters/conf/bad4.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/bad5.conf.j2 b/bin/tests/system/filters/conf/bad5.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/bad5.conf.j2 rename to bin/tests/system/filters/conf/bad5.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good1.conf.j2 b/bin/tests/system/filters/conf/good1.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good1.conf.j2 rename to bin/tests/system/filters/conf/good1.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good2.conf.j2 b/bin/tests/system/filters/conf/good2.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good2.conf.j2 rename to bin/tests/system/filters/conf/good2.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good3.conf.j2 b/bin/tests/system/filters/conf/good3.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good3.conf.j2 rename to bin/tests/system/filters/conf/good3.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good4.conf.j2 b/bin/tests/system/filters/conf/good4.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good4.conf.j2 rename to bin/tests/system/filters/conf/good4.conf.j2 diff --git a/bin/tests/system/filter-aaaa/conf/good5.conf.j2 b/bin/tests/system/filters/conf/good5.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/conf/good5.conf.j2 rename to bin/tests/system/filters/conf/good5.conf.j2 diff --git a/bin/tests/system/filter-aaaa/ns1/named.conf.j2 b/bin/tests/system/filters/ns1/named.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/ns1/named.conf.j2 rename to bin/tests/system/filters/ns1/named.conf.j2 diff --git a/bin/tests/system/filter-aaaa/ns1/root.db b/bin/tests/system/filters/ns1/root.db similarity index 100% rename from bin/tests/system/filter-aaaa/ns1/root.db rename to bin/tests/system/filters/ns1/root.db diff --git a/bin/tests/system/filter-aaaa/ns1/sign.sh b/bin/tests/system/filters/ns1/sign.sh similarity index 100% rename from bin/tests/system/filter-aaaa/ns1/sign.sh rename to bin/tests/system/filters/ns1/sign.sh diff --git a/bin/tests/system/filter-aaaa/ns1/signed.db.in b/bin/tests/system/filters/ns1/signed.db.in similarity index 100% rename from bin/tests/system/filter-aaaa/ns1/signed.db.in rename to bin/tests/system/filters/ns1/signed.db.in diff --git a/bin/tests/system/filter-aaaa/ns1/unsigned.db b/bin/tests/system/filters/ns1/unsigned.db similarity index 100% rename from bin/tests/system/filter-aaaa/ns1/unsigned.db rename to bin/tests/system/filters/ns1/unsigned.db diff --git a/bin/tests/system/filter-aaaa/ns2/hints b/bin/tests/system/filters/ns2/hints similarity index 100% rename from bin/tests/system/filter-aaaa/ns2/hints rename to bin/tests/system/filters/ns2/hints diff --git a/bin/tests/system/filter-aaaa/ns2/named.conf.j2 b/bin/tests/system/filters/ns2/named.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/ns2/named.conf.j2 rename to bin/tests/system/filters/ns2/named.conf.j2 diff --git a/bin/tests/system/filter-aaaa/ns3/hints b/bin/tests/system/filters/ns3/hints similarity index 100% rename from bin/tests/system/filter-aaaa/ns3/hints rename to bin/tests/system/filters/ns3/hints diff --git a/bin/tests/system/filter-aaaa/ns3/named.conf.j2 b/bin/tests/system/filters/ns3/named.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/ns3/named.conf.j2 rename to bin/tests/system/filters/ns3/named.conf.j2 diff --git a/bin/tests/system/filter-aaaa/ns4/named.conf.j2 b/bin/tests/system/filters/ns4/named.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/ns4/named.conf.j2 rename to bin/tests/system/filters/ns4/named.conf.j2 diff --git a/bin/tests/system/filter-aaaa/ns4/root.db b/bin/tests/system/filters/ns4/root.db similarity index 100% rename from bin/tests/system/filter-aaaa/ns4/root.db rename to bin/tests/system/filters/ns4/root.db diff --git a/bin/tests/system/filter-aaaa/ns4/sign.sh b/bin/tests/system/filters/ns4/sign.sh similarity index 100% rename from bin/tests/system/filter-aaaa/ns4/sign.sh rename to bin/tests/system/filters/ns4/sign.sh diff --git a/bin/tests/system/filter-aaaa/ns4/signed.db.in b/bin/tests/system/filters/ns4/signed.db.in similarity index 100% rename from bin/tests/system/filter-aaaa/ns4/signed.db.in rename to bin/tests/system/filters/ns4/signed.db.in diff --git a/bin/tests/system/filter-aaaa/ns4/unsigned.db b/bin/tests/system/filters/ns4/unsigned.db similarity index 100% rename from bin/tests/system/filter-aaaa/ns4/unsigned.db rename to bin/tests/system/filters/ns4/unsigned.db diff --git a/bin/tests/system/filter-aaaa/ns5/hints b/bin/tests/system/filters/ns5/hints similarity index 100% rename from bin/tests/system/filter-aaaa/ns5/hints rename to bin/tests/system/filters/ns5/hints diff --git a/bin/tests/system/filter-aaaa/ns5/named.conf.j2 b/bin/tests/system/filters/ns5/named.conf.j2 similarity index 100% rename from bin/tests/system/filter-aaaa/ns5/named.conf.j2 rename to bin/tests/system/filters/ns5/named.conf.j2 diff --git a/bin/tests/system/filter-aaaa/setup.sh b/bin/tests/system/filters/setup.sh similarity index 100% rename from bin/tests/system/filter-aaaa/setup.sh rename to bin/tests/system/filters/setup.sh diff --git a/bin/tests/system/filter-aaaa/tests_filter_aaaa.py b/bin/tests/system/filters/tests_filters.py similarity index 100% rename from bin/tests/system/filter-aaaa/tests_filter_aaaa.py rename to bin/tests/system/filters/tests_filters.py From cbebeacec15a2716cce74f4a3f8544abd62b398f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicki=20K=C5=99=C3=AD=C5=BEek?= Date: Thu, 31 Jul 2025 19:00:27 +0200 Subject: [PATCH 5/6] Split up and parametrize filters tests Move tests which use different configuration to dedicated modules to avoid possible interference with other tests. Parametrize the test cases to have a dedicated test for each server configuration. Turn the check_filter() comments into log messages to help with debugging. --- .gitlab-ci.yml | 2 +- bin/tests/system/filters/common.py | 231 +++++++++++ bin/tests/system/filters/ns2/named.conf.j2 | 1 + bin/tests/system/filters/ns3/named.conf.j2 | 1 + bin/tests/system/filters/ns5/named.conf.j2 | 8 +- bin/tests/system/filters/tests_filter_a_v4.py | 60 +++ bin/tests/system/filters/tests_filter_a_v6.py | 80 ++++ .../system/filters/tests_filter_aaaa_v4.py | 61 +++ .../system/filters/tests_filter_aaaa_v6.py | 81 ++++ .../system/filters/tests_filter_checkconf.py | 32 ++ .../system/filters/tests_filter_dns64.py | 28 ++ bin/tests/system/filters/tests_filters.py | 384 ------------------ 12 files changed, 579 insertions(+), 390 deletions(-) create mode 100644 bin/tests/system/filters/common.py create mode 100644 bin/tests/system/filters/tests_filter_a_v4.py create mode 100644 bin/tests/system/filters/tests_filter_a_v6.py create mode 100644 bin/tests/system/filters/tests_filter_aaaa_v4.py create mode 100644 bin/tests/system/filters/tests_filter_aaaa_v6.py create mode 100644 bin/tests/system/filters/tests_filter_checkconf.py create mode 100644 bin/tests/system/filters/tests_filter_dns64.py delete mode 100644 bin/tests/system/filters/tests_filters.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d334ae1ae5..1c694395b9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -573,7 +573,7 @@ vulture: <<: *precheck_job needs: [] script: - - vulture --exclude "*ans.py,conftest.py,isctest" --ignore-names "pytestmark,reconfigure_policy" bin/tests/system/ + - vulture --exclude "*ans.py,conftest.py,isctest" --ignore-names "pytestmark,reconfigure_policy,setup_filters" bin/tests/system/ ci-variables: <<: *precheck_job diff --git a/bin/tests/system/filters/common.py b/bin/tests/system/filters/common.py new file mode 100644 index 0000000000..a009d31c0a --- /dev/null +++ b/bin/tests/system/filters/common.py @@ -0,0 +1,231 @@ +# 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. + +import dns +from dns import rdataclass, rdatatype + +import isctest + + +ARTIFACTS = [ + "conf/*.conf", + "ns*/trusted.conf", + "ns*/*.signed", + "ns*/K*", + "ns*/dsset-*", + "ns*/signer.err", +] + + +def reconfigure_servers(ftype, family, servers, templates): + for server_id in ["ns1", "ns2", "ns3", "ns4"]: + templates.render( + f"{server_id}/named.conf", {"family": family, "filtertype": ftype} + ) + servers[server_id].reconfigure(log=False) + + +def check_filtertype_only(dest, source, qname, ftype, expected, adflag): + qname = dns.name.from_text(qname) + + msg = isctest.query.create(qname, ftype) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + + if adflag: + isctest.check.adflag(res) + else: + isctest.check.noadflag(res) + a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) + aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) + if ftype == "aaaa": + assert not a_record + if expected: + assert ( + aaaa_record and aaaa_record[0].address == expected + ), f"expected AAAA {expected} in ANSWER: {res}" + else: + assert not aaaa_record + if expected: + assert ( + a_record and a_record[0].address == expected + ), f"expected A {expected} in ANSWER: {res}" + + +def check_any(dest, source, qname, expected4, expected6, do): + qname = dns.name.from_text(qname) + msg = isctest.query.create(qname, "any", dnssec=do) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) + if expected4: + assert ( + a_record and a_record[0].address == expected4 + ), f"expected A {expected4} in ANSWER: {res}" + else: + assert not a_record + aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) + if expected6: + assert ( + aaaa_record and aaaa_record[0].address == expected6 + ), f"expected AAAA {expected6} in ANSWER: {res}" + else: + assert not aaaa_record + + +def check_nodata(dest, source, qname, qtype, do, adflag): + msg = isctest.query.create(qname, qtype, dnssec=do) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + isctest.check.empty_answer(res) + if adflag: + isctest.check.adflag(res) + else: + isctest.check.noadflag(res) + + +def check_additional(dest, source, qname, qtype, ftype, expected, adcount): + msg = isctest.query.create(qname, qtype) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, adcount) + t = rdatatype.A if ftype == "a" else rdatatype.AAAA + if expected: + assert [a for a in res.additional if a.rdtype == t] + else: + assert not [a for a in res.additional if a.rdtype == t] + + +def prime_cache(addr): + isctest.log.debug("prime cache for recursive testing:") + # (when testing recursive, we need to prime the cache first with + # the MX addresses, since additional section data isn't included + # unless it's been validated.) + for name in ["mx", "ns"]: + for zone in ["signed", "unsigned"]: + for qtype in ["a", "aaaa"]: + isctest.log.debug(f"{addr}: {name}.{zone}/{qtype}") + isctest.query.tcp(isctest.query.create(f"{name}.{zone}", qtype), addr) + + +def check_filter(addr, altaddr, ftype, break_dnssec, recursive): + qtype = ftype.upper() + isctest.log.debug( + f"check that {qtype} is returned when only {qtype} record exists, signed" + ) + expected = "1.0.0.2" if ftype == "a" else "2001:db8::2" + check_filtertype_only( + addr, addr, f"{ftype}-only.signed", ftype, expected, recursive + ) + + isctest.log.debug( + f"check that {qtype} is returned when only {qtype} record exists, unsigned" + ) + expected = "1.0.0.5" if ftype == "a" else "2001:db8::5" + check_filtertype_only(addr, addr, f"{ftype}-only.unsigned", ftype, expected, False) + + isctest.log.debug( + "check that NODATA/NOERROR is returned when both AAAA and A exist, signed, DO=0" + ) + check_nodata(addr, addr, "dual.signed", ftype, False, False) + + isctest.log.debug( + "check that NODATA/NOERROR is returned when both AAAA and A exist, unsigned, DO=0" + ) + check_nodata(addr, addr, "dual.unsigned", ftype, False, False) + + isctest.log.debug( + f"check that {qtype} is returned when both AAAA and A exist, signed, DO=1, unless break-dnssec is enabled" + ) + if break_dnssec: + check_nodata(addr, addr, "dual.signed", ftype, False, False) + else: + expected = "1.0.0.3" if ftype == "a" else "2001:db8::3" + check_filtertype_only(addr, addr, "dual.signed", ftype, expected, recursive) + + isctest.log.debug( + "check that NODATA/NOERROR is returned when both AAAA and A exist, unsigned, DO=1" + ) + check_nodata(addr, addr, "dual.unsigned", ftype, recursive, False) + + isctest.log.debug( + f"check that {qtype} is returned if both AAAA and A exist and the query source doesn't match the ACL" + ) + + expected = "1.0.0.6" if ftype == "a" else "2001:db8::6" + check_filtertype_only(addr, altaddr, "dual.unsigned", ftype, expected, False) + + isctest.log.debug( + f"check that A/AAAA (and not {qtype}) is returned if both AAAA and A exist, signed, qtype=ANY, DO=0" + ) + expected4 = "1.0.0.3" if ftype == "aaaa" else None + expected6 = "2001:db8::3" if ftype == "a" else None + check_any(addr, addr, "dual.signed", expected4, expected6, False) + + isctest.log.debug( + "check that both A and AAAA are returned if both AAAA and A exist, signed, qtype=ANY, DO=1, unless break-dnssec is enabled" + ) + if break_dnssec: + if ftype == "a": + expected4 = None + else: + expected6 = None + check_any(addr, addr, "dual.signed", expected4, expected6, True) + else: + check_any(addr, addr, "dual.signed", "1.0.0.3", "2001:db8::3", True) + + expected4 = "1.0.0.6" if ftype == "aaaa" else None + expected6 = "2001:db8::6" if ftype == "a" else None + + isctest.log.debug( + f"check that A/AAAA (and not {qtype}) is returned if both AAAA and A exist, unsigned, qtype=ANY, DO=0" + ) + check_any(addr, addr, "dual.unsigned", expected4, expected6, False) + + isctest.log.debug( + f"check that A/AAAA (and not {qtype}) is returned if both AAAA and A exist, unsigned, qtype=ANY, DO=1" + ) + check_any(addr, addr, "dual.unsigned", expected4, expected6, True) + + isctest.log.debug( + "check that both A and AAAA are returned if both AAAA and A exist, signed, qtype=ANY, query source does not match ACL" + ) + check_any(addr, altaddr, "dual.unsigned", "1.0.0.6", "2001:db8::6", True) + + isctest.log.debug( + f"check that {qtype} is omitted from additional section, qtype=NS, unsigned" + ) + check_additional(addr, addr, "unsigned", "ns", ftype, False, 1) + + isctest.log.debug( + f"check that {qtype} is omitted from additional section, qtype=MX, unsigned" + ) + check_additional(addr, addr, "unsigned", "mx", ftype, False, 2) + + isctest.log.debug( + f"check that {qtype} is included in additional section, qtype=MX, signed, unless break-dnssec is enabled" + ) + if break_dnssec: + check_additional(addr, addr, "signed", "mx", ftype, False, 4) + else: + check_additional(addr, addr, "signed", "mx", ftype, True, 8) + + +def check_filter_other_family(addr, ftype): + isctest.log.debug( + "check that the filtered type is returned when both AAAA and A record exists, unsigned, over other family" + ) + check_filtertype_only(addr, addr, "dual.unsigned", ftype, None, False) + + isctest.log.debug( + "check that the filtered type is included in additional section, qtype=MX, unsigned, over other family" + ) + check_additional(addr, addr, "unsigned", "mx", ftype, True, 4) diff --git a/bin/tests/system/filters/ns2/named.conf.j2 b/bin/tests/system/filters/ns2/named.conf.j2 index 9fee67291c..e02dd97cc7 100644 --- a/bin/tests/system/filters/ns2/named.conf.j2 +++ b/bin/tests/system/filters/ns2/named.conf.j2 @@ -16,6 +16,7 @@ options { query-source address 10.53.0.2; + query-source-v6 address fd92:7065:b8e:ffff::2; notify-source 10.53.0.2; transfer-source 10.53.0.2; port @PORT@; diff --git a/bin/tests/system/filters/ns3/named.conf.j2 b/bin/tests/system/filters/ns3/named.conf.j2 index d89f96df2c..286fe0cdc4 100644 --- a/bin/tests/system/filters/ns3/named.conf.j2 +++ b/bin/tests/system/filters/ns3/named.conf.j2 @@ -16,6 +16,7 @@ options { query-source address 10.53.0.3; + query-source-v6 address fd92:7065:b8e:ffff::3; notify-source 10.53.0.3; transfer-source 10.53.0.3; port @PORT@; diff --git a/bin/tests/system/filters/ns5/named.conf.j2 b/bin/tests/system/filters/ns5/named.conf.j2 index ae72eb33c4..58acd797ea 100644 --- a/bin/tests/system/filters/ns5/named.conf.j2 +++ b/bin/tests/system/filters/ns5/named.conf.j2 @@ -11,8 +11,6 @@ * information regarding copyright ownership. */ -{% set filtertype = filtertype | default("aaaa") %} - options { query-source address 10.53.0.5; notify-source 10.53.0.5; @@ -32,9 +30,9 @@ options { minimal-responses no; }; -plugin query "@TOP_BUILDDIR@/filter-@filtertype@.@DYLIB@" { - filter-@filtertype@-on-v4 break-dnssec; - filter-@filtertype@ { any; }; +plugin query "@TOP_BUILDDIR@/filter-aaaa.@DYLIB@" { + filter-aaaa-on-v4 break-dnssec; + filter-aaaa { any; }; }; key rndc_key { diff --git a/bin/tests/system/filters/tests_filter_a_v4.py b/bin/tests/system/filters/tests_filter_a_v4.py new file mode 100644 index 0000000000..e5aea1bcfb --- /dev/null +++ b/bin/tests/system/filters/tests_filter_a_v4.py @@ -0,0 +1,60 @@ +# 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. + +import pytest + +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter A on V4") + reconfigure_servers("a", "v4", servers, templates) + prime_cache("10.53.0.2") + prime_cache("10.53.0.3") + + +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param("10.53.0.1", "10.53.0.2", False, False, id="auth"), + pytest.param("10.53.0.4", "10.53.0.2", True, False, id="auth-break-dnssec"), + pytest.param("10.53.0.2", "10.53.0.1", False, True, id="recurs"), + pytest.param("10.53.0.3", "10.53.0.1", True, True, id="recurs-break-dnssec"), + ], +) +def test_filter_a_on_v4(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "a", break_dnssec, recursive) + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr", + [ + pytest.param("fd92:7065:b8e:ffff::1", id="auth"), + pytest.param("fd92:7065:b8e:ffff::4", id="auth-break-dnssec"), + pytest.param("fd92:7065:b8e:ffff::2", id="recurs"), + pytest.param("fd92:7065:b8e:ffff::3", id="recurs-break-dnssec"), + ], +) +def test_filter_a_on_v4_via_v6(addr): + check_filter_other_family(addr, "a") diff --git a/bin/tests/system/filters/tests_filter_a_v6.py b/bin/tests/system/filters/tests_filter_a_v6.py new file mode 100644 index 0000000000..17e14e8b34 --- /dev/null +++ b/bin/tests/system/filters/tests_filter_a_v6.py @@ -0,0 +1,80 @@ +# 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. + +import pytest + +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter A on V6") + reconfigure_servers("a", "v6", servers, templates) + prime_cache("fd92:7065:b8e:ffff::2") + prime_cache("fd92:7065:b8e:ffff::3") + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param( + "fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", False, False, id="auth" + ), + pytest.param( + "fd92:7065:b8e:ffff::4", + "fd92:7065:b8e:ffff::2", + True, + False, + id="auth-break-dnssec", + ), + pytest.param( + "fd92:7065:b8e:ffff::2", + "fd92:7065:b8e:ffff::1", + False, + True, + id="recurs", + ), + pytest.param( + "fd92:7065:b8e:ffff::3", + "fd92:7065:b8e:ffff::1", + True, + True, + id="recurs-break-dnssec", + ), + ], +) +def test_filter_a_on_v6(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "a", break_dnssec, recursive) + + +@pytest.mark.parametrize( + "addr", + [ + pytest.param("10.53.0.1", id="auth"), + pytest.param("10.53.0.4", id="auth-break-dnssec"), + pytest.param("10.53.0.2", id="recurs"), + pytest.param("10.53.0.3", id="recurs-break-dnssec"), + ], +) +def test_filter_a_on_v6_via_v4(addr): + check_filter_other_family(addr, "a") diff --git a/bin/tests/system/filters/tests_filter_aaaa_v4.py b/bin/tests/system/filters/tests_filter_aaaa_v4.py new file mode 100644 index 0000000000..90aac2a0cd --- /dev/null +++ b/bin/tests/system/filters/tests_filter_aaaa_v4.py @@ -0,0 +1,61 @@ +# 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. + +import pytest + +import isctest +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter AAAA on V4") + reconfigure_servers("aaaa", "v4", servers, templates) + prime_cache("10.53.0.2") + prime_cache("10.53.0.3") + + +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param("10.53.0.1", "10.53.0.2", False, False, id="auth"), + pytest.param("10.53.0.4", "10.53.0.2", True, False, id="auth-break-dnssec"), + pytest.param("10.53.0.2", "10.53.0.1", False, True, id="recurs"), + pytest.param("10.53.0.3", "10.53.0.1", True, True, id="recurs-break-dnssec"), + ], +) +def test_filter_aaaa_on_v4(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "aaaa", break_dnssec, recursive) + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr", + [ + pytest.param("fd92:7065:b8e:ffff::1", id="auth"), + pytest.param("fd92:7065:b8e:ffff::4", id="auth-break-dnssec"), + pytest.param("fd92:7065:b8e:ffff::2", id="recurs"), + pytest.param("fd92:7065:b8e:ffff::3", id="recurs-break-dnssec"), + ], +) +def test_filter_aaaa_on_v4_via_v6(addr): + check_filter_other_family(addr, "aaaa") diff --git a/bin/tests/system/filters/tests_filter_aaaa_v6.py b/bin/tests/system/filters/tests_filter_aaaa_v6.py new file mode 100644 index 0000000000..a439316677 --- /dev/null +++ b/bin/tests/system/filters/tests_filter_aaaa_v6.py @@ -0,0 +1,81 @@ +# 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. + +import pytest + +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter AAAA on V6") + reconfigure_servers("aaaa", "v6", servers, templates) + prime_cache("fd92:7065:b8e:ffff::2") + prime_cache("fd92:7065:b8e:ffff::3") + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param( + "fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", False, False, id="auth" + ), + pytest.param( + "fd92:7065:b8e:ffff::4", + "fd92:7065:b8e:ffff::2", + True, + False, + id="auth-break-dnssec", + ), + pytest.param( + "fd92:7065:b8e:ffff::2", + "fd92:7065:b8e:ffff::1", + False, + True, + id="recurs", + ), + pytest.param( + "fd92:7065:b8e:ffff::3", + "fd92:7065:b8e:ffff::1", + True, + True, + id="recurs-break-dnssec", + ), + ], +) +def test_filter_aaaa_on_v6(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "aaaa", break_dnssec, recursive) + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr", + [ + pytest.param("10.53.0.1", id="auth"), + pytest.param("10.53.0.4", id="auth-break-dnssec"), + pytest.param("10.53.0.2", id="recurs"), + pytest.param("10.53.0.3", id="recurs-break-dnssec"), + ], +) +def test_filter_aaaa_on_v6_via_v4(addr): + check_filter_other_family(addr, "aaaa") diff --git a/bin/tests/system/filters/tests_filter_checkconf.py b/bin/tests/system/filters/tests_filter_checkconf.py new file mode 100644 index 0000000000..17dbdb989a --- /dev/null +++ b/bin/tests/system/filters/tests_filter_checkconf.py @@ -0,0 +1,32 @@ +# 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. + +import glob +import os +import subprocess + +import pytest + +import isctest + +from filters.common import ARTIFACTS + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +# FUTURE: move this to checkconf test - it doesn't need nsX servers +def test_filters_checkconf(): + for filename in glob.glob("conf/good*.conf"): + isctest.run.cmd([os.environ["CHECKCONF"], filename]) + for filename in glob.glob("conf/bad*.conf"): + with pytest.raises(subprocess.CalledProcessError): + isctest.run.cmd([os.environ["CHECKCONF"], filename]) diff --git a/bin/tests/system/filters/tests_filter_dns64.py b/bin/tests/system/filters/tests_filter_dns64.py new file mode 100644 index 0000000000..218b834682 --- /dev/null +++ b/bin/tests/system/filters/tests_filter_dns64.py @@ -0,0 +1,28 @@ +# 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. + +import pytest + +import isctest + +from filters.common import ARTIFACTS + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +def test_filter_dns64(): + # This configuration doesn't make sense. The AAAA is wanted by + # filter-aaaa, but discarded by the dns64 configuration. We just + # need to ensure that the server keeps running. + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.5") + isctest.check.noerror(res) diff --git a/bin/tests/system/filters/tests_filters.py b/bin/tests/system/filters/tests_filters.py deleted file mode 100644 index 58149973ae..0000000000 --- a/bin/tests/system/filters/tests_filters.py +++ /dev/null @@ -1,384 +0,0 @@ -#!/bin/sh - -# 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. - -import glob -import os -import subprocess - -import dns -from dns import message, rdataclass, rdatatype - -import pytest - -import isctest -import isctest.mark - - -pytestmark = pytest.mark.extra_artifacts( - [ - "conf/*.conf", - "ns*/trusted.conf", - "ns*/*.signed", - "ns*/K*", - "ns*/dsset-*", - "ns*/signer.err", - ] -) - - -# helper functions -def reset_server(server, family, ftype, servers, templates): - templates.render(f"{server}/named.conf", {"family": family, "filtertype": ftype}) - servers[server].reconfigure(log=False) - - -# these are the default configuration values for the jinja2 -# templates. if some other value is needed for a test, then -# the named.conf files must be regenerated. -filter_family = "v4" -filter_type = "aaaa" - - -def reset_servers(family, ftype, servers, templates): - reset_server("ns1", family, ftype, servers, templates) - reset_server("ns2", family, ftype, servers, templates) - reset_server("ns3", family, ftype, servers, templates) - reset_server("ns4", family, ftype, servers, templates) - - -def check_filtertype_only(dest, source, qname, ftype, expected, adflag): - qname = dns.name.from_text(qname) - msg = isctest.query.create(qname, ftype) - res = isctest.query.tcp(msg, dest, source=source) - isctest.check.noerror(res) - if adflag: - isctest.check.adflag(res) - else: - isctest.check.noadflag(res) - a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) - aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) - if ftype == "aaaa": - assert not a_record - if expected: - assert ( - aaaa_record[0].address == expected - ), f"expected AAAA {expected} in ANSWER: {res}" - else: - assert not aaaa_record - if expected: - assert ( - a_record[0].address == expected - ), f"expected A {expected} in ANSWER: {res}" - - -def check_any(dest, source, qname, expected4, expected6, do): - qname = dns.name.from_text(qname) - msg = isctest.query.create(qname, "any", dnssec=do) - res = isctest.query.tcp(msg, dest, source=source) - isctest.check.noerror(res) - a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) - if expected4: - assert ( - a_record and a_record[0].address == expected4 - ), f"expected A {expected4} in ANSWER: {res}" - else: - assert not a_record - aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) - if expected6: - assert ( - aaaa_record and aaaa_record[0].address == expected6 - ), f"expected AAAA {expected6} in ANSWER: {res}" - else: - assert not aaaa_record - - -def check_nodata(dest, source, qname, qtype, do, adflag): - msg = isctest.query.create(qname, qtype, dnssec=do) - res = isctest.query.tcp(msg, dest, source=source) - isctest.check.noerror(res) - isctest.check.empty_answer(res) - if adflag: - isctest.check.adflag(res) - else: - isctest.check.noadflag(res) - - -def check_additional(dest, source, qname, qtype, ftype, expected, adcount): - msg = isctest.query.create(qname, qtype) - res = isctest.query.tcp(msg, dest, source=source) - isctest.check.noerror(res) - isctest.check.rr_count_eq(res.additional, adcount) - t = rdatatype.A if ftype == "a" else rdatatype.AAAA - if expected: - assert [a for a in res.additional if a.rdtype == t] - else: - assert not [a for a in res.additional if a.rdtype == t] - - -# run the checkconf tests -def test_checkconf(): - for filename in glob.glob("conf/good*.conf"): - isctest.run.cmd([os.environ["CHECKCONF"], filename]) - for filename in glob.glob("conf/bad*.conf"): - with pytest.raises(subprocess.CalledProcessError): - isctest.run.cmd([os.environ["CHECKCONF"], filename]) - - -def check_filter(addr, altaddr, ftype, break_dnssec, recursive): - if recursive: - # (when testing recursive, we need to prime the cache first with - # the MX addresses, since additional section data isn't included - # unless it's been validated.) - for name in ["mx", "ns"]: - for zone in ["signed", "unsigned"]: - for qtype in ["a", "aaaa"]: - isctest.query.tcp( - isctest.query.create(f"{name}.{zone}", qtype), addr - ) - - # check that AAAA is returned when only AAAA record exists, signed - expected = "1.0.0.2" if ftype == "a" else "2001:db8::2" - check_filtertype_only( - addr, addr, f"{ftype}-only.signed", ftype, expected, recursive - ) - - # check that AAAA is returned when only AAAA record exists, unsigned - expected = "1.0.0.5" if ftype == "a" else "2001:db8::5" - check_filtertype_only(addr, addr, f"{ftype}-only.unsigned", ftype, expected, False) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # signed, DO=0 - check_nodata(addr, addr, "dual.signed", ftype, False, False) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=0 - check_nodata(addr, addr, "dual.unsigned", ftype, False, False) - - # check that AAAA is returned when both AAAA and A exist, signed, - # DO=1, unless break-dnssec is enabled - if break_dnssec: - check_nodata(addr, addr, "dual.signed", ftype, False, False) - else: - expected = "1.0.0.3" if ftype == "a" else "2001:db8::3" - check_filtertype_only(addr, addr, "dual.signed", ftype, expected, recursive) - - # check that NODATA/NOERROR is returned when both AAAA and A exist, - # unsigned, DO=1 - check_nodata(addr, addr, "dual.unsigned", ftype, recursive, False) - - # check that AAAA is returned if both AAAA and A exist and the query - # source doesn't match the ACL - expected = "1.0.0.6" if ftype == "a" else "2001:db8::6" - check_filtertype_only(addr, altaddr, "dual.unsigned", ftype, expected, False) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # signed, qtype=ANY, DO=0 - expected4 = "1.0.0.3" if ftype == "aaaa" else None - expected6 = "2001:db8::3" if ftype == "a" else None - check_any(addr, addr, "dual.signed", expected4, expected6, False) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, DO=1, unless break-dnssec is enabled - if break_dnssec: - if ftype == "a": - expected4 = None - else: - expected6 = None - check_any(addr, addr, "dual.signed", expected4, expected6, True) - else: - check_any(addr, addr, "dual.signed", "1.0.0.3", "2001:db8::3", True) - - expected4 = "1.0.0.6" if ftype == "aaaa" else None - expected6 = "2001:db8::6" if ftype == "a" else None - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=0 - check_any(addr, addr, "dual.unsigned", expected4, expected6, False) - - # check that A (and not AAAA) is returned if both AAAA and A exist, - # unsigned, qtype=ANY, DO=1 - check_any(addr, addr, "dual.unsigned", expected4, expected6, True) - - # check that both A and AAAA are returned if both AAAA and A exist, - # signed, qtype=ANY, query source does not match ACL - check_any(addr, altaddr, "dual.unsigned", "1.0.0.6", "2001:db8::6", True) - - # check that AAAA is omitted from additional section, qtype=NS, unsigned - check_additional(addr, addr, "unsigned", "ns", ftype, False, 1) - - # check that AAAA is omitted from additional section, qtype=MX, unsigned - check_additional(addr, addr, "unsigned", "mx", ftype, False, 2) - - # check that AAAA is included in additional section, qtype=MX, signed, - # unless break-dnssec is enabled - if break_dnssec: - check_additional(addr, addr, "signed", "mx", ftype, False, 4) - else: - check_additional(addr, addr, "signed", "mx", ftype, True, 8) - - -def check_filter_other_family(addr, ftype): - # check that the filtered type is returned when both AAAA and A - # record exists, unsigned, over IPv6 - check_filtertype_only(addr, addr, "dual.unsigned", ftype, None, False) - - # check that the filtered type is included in additional section, - # qtype=MX, unsigned, over IPv6 - check_additional(addr, addr, "unsigned", "mx", ftype, True, 4) - - -def test_filter_aaaa_on_v4(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - # ns1: auth, configured with: - ## filter-aaaa-on-v4 yes; - ## filter-aaaa { 10.53.0.1; }; - check_filter("10.53.0.1", "10.53.0.2", "aaaa", False, False) - - # ns4: auth, configured with: - ## filter-aaaa-on-v4 break-dnssec; - ## filter-aaaa { 10.53.0.4; }; - check_filter("10.53.0.4", "10.53.0.2", "aaaa", True, False) - - # ns2: recursive, configured with: - ## filter-aaaa-on-v4 yes; - ## filter-aaaa { 10.53.0.2; }; - check_filter("10.53.0.2", "10.53.0.1", "aaaa", False, True) - - # ns3: recursive, configured with: - ## filter-aaaa-on-v4 break-dnssec; - ## filter-aaaa { 10.53.0.3; }; - check_filter("10.53.0.3", "10.53.0.1", "aaaa", True, True) - - -@isctest.mark.with_ipv6 -def test_filter_aaaa_on_v4_via_v6(servers, templates): - if filter_family != "v4" or filter_type != "aaaa": - reset_servers("v4", "aaaa", servers, templates) - - check_filter_other_family("fd92:7065:b8e:ffff::1", "aaaa") - check_filter_other_family("fd92:7065:b8e:ffff::2", "aaaa") - check_filter_other_family("fd92:7065:b8e:ffff::3", "aaaa") - check_filter_other_family("fd92:7065:b8e:ffff::4", "aaaa") - - -# These tests are against an authoritative server configured with: -## filter-aaaa-on-v6 yes; -@isctest.mark.with_ipv6 -def test_filter_aaaa_on_v6(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - # ns1: auth, configured with: - ## filter-aaaa-on-v6 yes; - ## filter-aaaa { fd92:7065:b8e:ffff::1; }; - check_filter("fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", "aaaa", False, False) - - # ns4: auth, configured with: - ## filter-aaaa-on-v6 break-dnssec; - ## filter-aaaa { fd92:7065:b8e:ffff::4; }; - check_filter("fd92:7065:b8e:ffff::4", "fd92:7065:b8e:ffff::2", "aaaa", True, False) - - # ns2: recursive, configured with: - ## filter-aaaa-on-v6 yes; - ## filter-aaaa { fd92:7065:b8e:ffff::2; }; - check_filter("fd92:7065:b8e:ffff::2", "fd92:7065:b8e:ffff::1", "aaaa", False, True) - - # ns3: recursive, configured with: - ## filter-aaaa-on-v6 break-dnssec; - ## filter-aaaa { fd92:7065:b8e:ffff::3; }; - check_filter("fd92:7065:b8e:ffff::3", "fd92:7065:b8e:ffff::1", "aaaa", True, True) - - -def test_filter_aaaa_on_v6_via_v4(servers, templates): - if filter_family != "v6" or filter_type != "aaaa": - reset_servers("v6", "aaaa", servers, templates) - - check_filter_other_family("10.53.0.1", "aaaa") - check_filter_other_family("10.53.0.2", "aaaa") - check_filter_other_family("10.53.0.3", "aaaa") - check_filter_other_family("10.53.0.4", "aaaa") - - -def test_filter_a_on_v4(servers, templates): - if filter_family != "v4" or filter_type != "a": - reset_servers("v4", "a", servers, templates) - - # ns1: auth, configured with: - ## filter-a-on-v4 yes; - ## filter-a { 10.53.0.1; }; - check_filter("10.53.0.1", "10.53.0.2", "a", False, False) - - # ns4: auth, configured with: - ## filter-a-on-v4 break-dnssec; - ## filter-a { 10.53.0.4; }; - check_filter("10.53.0.4", "10.53.0.2", "a", True, False) - - # ns2: recursive, configured with: - ## filter-a-on-v4 yes; - ## filter-a { 10.53.0.2; }; - check_filter("10.53.0.2", "10.53.0.1", "a", False, True) - - # ns3: recursive, configured with: - ## filter-a-on-v4 break-dnssec; - ## filter-a { 10.53.0.3; }; - check_filter("10.53.0.3", "10.53.0.1", "a", True, True) - - -@isctest.mark.with_ipv6 -def test_filter_a_on_v4_via_v6(servers, templates): - if filter_family != "v4" or filter_type != "a": - reset_servers("v4", "a", servers, templates) - - check_filter_other_family("fd92:7065:b8e:ffff::1", "a") - check_filter_other_family("fd92:7065:b8e:ffff::2", "a") - check_filter_other_family("fd92:7065:b8e:ffff::3", "a") - check_filter_other_family("fd92:7065:b8e:ffff::4", "a") - - -# These tests are against an authoritative server configured with: -## filter-a-on-v6 yes; -@isctest.mark.with_ipv6 -def test_filter_a_on_v6(servers, templates): - if filter_family != "v6" or filter_type != "a": - reset_servers("v6", "a", servers, templates) - - # ns1: auth, configured with: - ## filter-a-on-v6 yes; - ## filter-a { fd92:7065:b8e:ffff::1; }; - check_filter("fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", "a", False, False) - - # ns4: auth, configured with: - ## filter-a-on-v6 break-dnssec; - ## filter-a { fd92:7065:b8e:ffff::4; }; - check_filter("fd92:7065:b8e:ffff::4", "fd92:7065:b8e:ffff::2", "a", True, False) - - # ns2: recursive, configured with: - ## filter-a-on-v6 yes; - ## filter-a { fd92:7065:b8e:ffff::2; }; - check_filter("fd92:7065:b8e:ffff::2", "fd92:7065:b8e:ffff::1", "a", False, True) - - # ns3: recursive, configured with: - ## filter-a-on-v6 break-dnssec; - ## filter-a { fd92:7065:b8e:ffff::3; }; - check_filter("fd92:7065:b8e:ffff::3", "fd92:7065:b8e:ffff::1", "a", True, True) - - -def test_filter_a_on_v6_via_v4(servers, templates): - if filter_family != "v6" or filter_type != "a": - reset_servers("v6", "a", servers, templates) - - check_filter_other_family("10.53.0.1", "a") - check_filter_other_family("10.53.0.2", "a") - check_filter_other_family("10.53.0.3", "a") - check_filter_other_family("10.53.0.4", "a") From e49c467efb64229f536f2f116f402da176656ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicki=20K=C5=99=C3=AD=C5=BEek?= Date: Mon, 4 Aug 2025 16:30:41 +0200 Subject: [PATCH 6/6] Use full path for shared test code imports in rollover tests Previously, symlinks and relative directory imports were used in test modules. This caused a name clash when a shared code module "common.py" was introduced for a different test. To avoid the issue, use full paths in imports. --- bin/tests/system/rollover-algo-csk/common.py | 1 - .../system/rollover-algo-csk/tests_rollover_algo_csk_initial.py | 2 +- .../rollover-algo-csk/tests_rollover_algo_csk_reconfig.py | 2 +- bin/tests/system/rollover-algo-ksk-zsk/common.py | 1 - .../tests_rollover_algo_ksk_zsk_initial.py | 2 +- .../tests_rollover_algo_ksk_zsk_reconfig.py | 2 +- bin/tests/system/rollover-csk-roll1/common.py | 1 - bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py | 2 +- bin/tests/system/rollover-csk-roll2/common.py | 1 - bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py | 2 +- bin/tests/system/rollover-dynamic2inline/common.py | 1 - .../rollover-dynamic2inline/tests_rollover_dynamic2inline.py | 2 +- bin/tests/system/rollover-enable-dnssec/common.py | 1 - .../rollover-enable-dnssec/tests_rollover_enable_dnssec.py | 2 +- bin/tests/system/rollover-going-insecure/common.py | 1 - .../tests_rollover_going_insecure_initial.py | 2 +- .../tests_rollover_going_insecure_reconfig.py | 2 +- bin/tests/system/rollover-ksk-3crowd/common.py | 1 - .../rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py | 2 +- bin/tests/system/rollover-ksk-doubleksk/common.py | 1 - .../rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py | 2 +- bin/tests/system/rollover-lifetime/common.py | 1 - .../system/rollover-lifetime/tests_rollover_lifetime_initial.py | 2 +- .../rollover-lifetime/tests_rollover_lifetime_reconfig.py | 2 +- bin/tests/system/rollover-multisigner/common.py | 1 - .../system/rollover-multisigner/tests_rollover_multisigner.py | 2 +- bin/tests/system/rollover-straight2none/common.py | 1 - .../tests_rollver_straight2none_initial.py | 2 +- .../tests_rollver_straight2none_reconfig.py | 2 +- bin/tests/system/rollover-zsk-prepub/common.py | 1 - .../rollover-zsk-prepub/tests_rollover_zsk_prepublication.py | 2 +- bin/tests/system/rollover/tests_rollover_manual.py | 2 +- 32 files changed, 19 insertions(+), 32 deletions(-) delete mode 120000 bin/tests/system/rollover-algo-csk/common.py delete mode 120000 bin/tests/system/rollover-algo-ksk-zsk/common.py delete mode 120000 bin/tests/system/rollover-csk-roll1/common.py delete mode 120000 bin/tests/system/rollover-csk-roll2/common.py delete mode 120000 bin/tests/system/rollover-dynamic2inline/common.py delete mode 120000 bin/tests/system/rollover-enable-dnssec/common.py delete mode 120000 bin/tests/system/rollover-going-insecure/common.py delete mode 120000 bin/tests/system/rollover-ksk-3crowd/common.py delete mode 120000 bin/tests/system/rollover-ksk-doubleksk/common.py delete mode 120000 bin/tests/system/rollover-lifetime/common.py delete mode 120000 bin/tests/system/rollover-multisigner/common.py delete mode 120000 bin/tests/system/rollover-straight2none/common.py delete mode 120000 bin/tests/system/rollover-zsk-prepub/common.py diff --git a/bin/tests/system/rollover-algo-csk/common.py b/bin/tests/system/rollover-algo-csk/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-algo-csk/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py index a4f518a3f9..9db1f819fa 100644 --- a/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py +++ b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py @@ -12,7 +12,7 @@ # pylint: disable=redefined-outer-name,unused-import import isctest -from common import ( +from rollover.common import ( pytestmark, CDSS, DURATION, diff --git a/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py index ef1c9842b9..e10d15a5af 100644 --- a/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py +++ b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py @@ -15,7 +15,7 @@ import pytest import isctest from isctest.kasp import KeyTimingMetadata -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-algo-ksk-zsk/common.py b/bin/tests/system/rollover-algo-ksk-zsk/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-algo-ksk-zsk/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py index 914f05d335..d1e54a05a7 100644 --- a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py +++ b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py @@ -12,7 +12,7 @@ # pylint: disable=unused-import import isctest -from common import ( +from rollover.common import ( pytestmark, CDSS, DURATION, diff --git a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py index 2eac0cdd3b..6058780de0 100644 --- a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py +++ b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py @@ -15,7 +15,7 @@ import pytest import isctest from isctest.kasp import KeyTimingMetadata -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-csk-roll1/common.py b/bin/tests/system/rollover-csk-roll1/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-csk-roll1/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py b/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py index 664d1fef9c..abf27aca65 100644 --- a/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py +++ b/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py @@ -15,7 +15,7 @@ from datetime import timedelta import isctest from isctest.kasp import Ipub, Iret -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-csk-roll2/common.py b/bin/tests/system/rollover-csk-roll2/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-csk-roll2/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py b/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py index 6bbe19345c..1e93dfff7b 100644 --- a/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py +++ b/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py @@ -15,7 +15,7 @@ from datetime import timedelta import isctest from isctest.kasp import Ipub, Iret -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-dynamic2inline/common.py b/bin/tests/system/rollover-dynamic2inline/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-dynamic2inline/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py b/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py index 23accc0941..5570ce070f 100644 --- a/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py +++ b/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py @@ -12,7 +12,7 @@ # pylint: disable=redefined-outer-name,unused-import import isctest -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-enable-dnssec/common.py b/bin/tests/system/rollover-enable-dnssec/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-enable-dnssec/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py b/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py index 544e8d5be0..9c4dd31b85 100644 --- a/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py +++ b/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py @@ -13,7 +13,7 @@ import isctest from isctest.kasp import Ipub, IpubC, Iret -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-going-insecure/common.py b/bin/tests/system/rollover-going-insecure/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-going-insecure/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py index 229fcb7f77..dbfb485c5a 100644 --- a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py +++ b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py @@ -14,7 +14,7 @@ import pytest import isctest -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py index d20b0e4c0e..8e74b9bfcf 100644 --- a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py +++ b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py @@ -14,7 +14,7 @@ import pytest import isctest -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-ksk-3crowd/common.py b/bin/tests/system/rollover-ksk-3crowd/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-ksk-3crowd/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py b/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py index 7891c37fa5..88ca2196a4 100644 --- a/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py +++ b/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py @@ -15,7 +15,7 @@ from datetime import timedelta import isctest from isctest.kasp import KeyTimingMetadata -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-ksk-doubleksk/common.py b/bin/tests/system/rollover-ksk-doubleksk/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-ksk-doubleksk/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py b/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py index e8a4e6bb18..6a12328892 100644 --- a/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py +++ b/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py @@ -14,7 +14,7 @@ from datetime import timedelta import isctest -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-lifetime/common.py b/bin/tests/system/rollover-lifetime/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-lifetime/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py index 29acc4fddd..55478d86bc 100644 --- a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py +++ b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py @@ -15,7 +15,7 @@ import pytest import isctest from isctest.util import param -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py index 8d1d92f51d..76ee89eff3 100644 --- a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py +++ b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py @@ -15,7 +15,7 @@ import pytest import isctest from isctest.util import param -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-multisigner/common.py b/bin/tests/system/rollover-multisigner/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-multisigner/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py b/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py index 313cd7189a..2d49ef7cf4 100644 --- a/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py +++ b/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py @@ -21,7 +21,7 @@ import dns.update import isctest from isctest.kasp import Iret -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-straight2none/common.py b/bin/tests/system/rollover-straight2none/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-straight2none/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py b/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py index fd87d49807..1d5a108d2a 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py +++ b/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py @@ -14,7 +14,7 @@ import pytest import isctest -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py b/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py index 68ce4e134d..a25b8334f6 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py +++ b/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py @@ -14,7 +14,7 @@ import pytest import isctest -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover-zsk-prepub/common.py b/bin/tests/system/rollover-zsk-prepub/common.py deleted file mode 120000 index 64b8084c5a..0000000000 --- a/bin/tests/system/rollover-zsk-prepub/common.py +++ /dev/null @@ -1 +0,0 @@ -../rollover/common.py \ No newline at end of file diff --git a/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py b/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py index 726940f24c..d5550bf509 100644 --- a/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py +++ b/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py @@ -15,7 +15,7 @@ from datetime import timedelta import isctest from isctest.kasp import Ipub, Iret -from common import ( +from rollover.common import ( pytestmark, alg, size, diff --git a/bin/tests/system/rollover/tests_rollover_manual.py b/bin/tests/system/rollover/tests_rollover_manual.py index 3602329180..2103fcd7e5 100644 --- a/bin/tests/system/rollover/tests_rollover_manual.py +++ b/bin/tests/system/rollover/tests_rollover_manual.py @@ -15,7 +15,7 @@ import os import isctest from isctest.kasp import KeyTimingMetadata, Ipub, Iret -from common import pytestmark # pylint: disable=unused-import +from rollover.common import pytestmark # pylint: disable=unused-import def test_rollover_manual(ns3):