From 807ef8545d2e06c77826f3b2ac3f1cb7a7413dad Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 11 Mar 2025 14:03:56 +0000 Subject: [PATCH 1/2] Implement -T cookiealwaysvalid When -T cookiealwaysvalid is passed to named, DNS cookie checks for the incoming queries always pass, given they are structurally correct. --- bin/named/main.c | 8 +++++++- bin/tests/system/start.pl | 3 ++- lib/ns/client.c | 14 +++++++++++++- lib/ns/include/ns/server.h | 37 +++++++++++++++++++------------------ 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/bin/named/main.c b/bin/named/main.c index 9e2208befb..5cc6fb625d 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -129,6 +129,7 @@ static int maxudp = 0; /* * -T options: */ +static bool cookiealwaysvalid = false; static bool dropedns = false; static bool ednsformerr = false; static bool ednsnotimp = false; @@ -652,7 +653,9 @@ parse_T_opt(char *option) { * force the server to behave (or misbehave) in * specified ways for testing purposes. */ - if (!strcmp(option, "dropedns")) { + if (!strcmp(option, "cookiealwaysvalid")) { + cookiealwaysvalid = true; + } else if (!strcmp(option, "dropedns")) { dropedns = true; } else if (!strcmp(option, "ednsformerr")) { ednsformerr = true; @@ -1220,6 +1223,9 @@ setup(void) { /* * Modify server context according to command line options */ + if (cookiealwaysvalid) { + ns_server_setoption(sctx, NS_SERVER_COOKIEALWAYSVALID, true); + } if (disable4) { ns_server_setoption(sctx, NS_SERVER_DISABLE4, true); } diff --git a/bin/tests/system/start.pl b/bin/tests/system/start.pl index 9110b5231a..20e8bdc82b 100755 --- a/bin/tests/system/start.pl +++ b/bin/tests/system/start.pl @@ -264,7 +264,8 @@ sub construct_ns_command { foreach my $t_option( "dropedns", "ednsformerr", "ednsnotimp", "ednsrefused", - "noaa", "noedns", "nosoa", "maxudp512", "maxudp1460", + "cookiealwaysvalid", "noaa", "noedns", "nosoa", + "maxudp512", "maxudp1460", ) { if (-e "$testdir/$server/named.$t_option") { $command .= "-T $t_option " diff --git a/lib/ns/client.c b/lib/ns/client.c index 222a4f4f50..8420dcacc0 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -1290,6 +1290,7 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { isc_stdtime_t now; uint32_t when; isc_buffer_t db; + bool alwaysvalid; /* * If we have already seen a cookie option skip this cookie option. @@ -1335,11 +1336,22 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { when = isc_buffer_getuint32(buf); isc_buffer_forward(buf, 8); + /* + * For '-T cookiealwaysvalid' still process everything to not skew any + * performance tests involving cookies, but make sure that the cookie + * check passes in the end, given the cookie was structurally correct. + */ + alwaysvalid = ns_server_getoption(client->manager->sctx, + NS_SERVER_COOKIEALWAYSVALID); + /* * Allow for a 5 minute clock skew between servers sharing a secret. * Only accept COOKIE if we have talked to the client in the last hour. */ now = isc_stdtime_now(); + if (alwaysvalid) { + now = when; + } if (isc_serial_gt(when, (now + 300)) /* In the future. */ || isc_serial_lt(when, (now - 3600)) /* In the past. */) { @@ -1352,7 +1364,7 @@ process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { isc_buffer_init(&db, dbuf, sizeof(dbuf)); compute_cookie(client, when, client->manager->sctx->secret, &db); - if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) { + if (isc_safe_memequal(old, dbuf, COOKIE_SIZE) || alwaysvalid) { ns_stats_increment(client->manager->sctx->nsstats, ns_statscounter_cookiematch); client->attributes |= NS_CLIENTATTR_HAVECOOKIE; diff --git a/lib/ns/include/ns/server.h b/lib/ns/include/ns/server.h index fa21986ca4..822ec81399 100644 --- a/lib/ns/include/ns/server.h +++ b/lib/ns/include/ns/server.h @@ -32,24 +32,25 @@ #include -#define NS_SERVER_LOGQUERIES 0x00000001U /*%< log queries */ -#define NS_SERVER_NOAA 0x00000002U /*%< -T noaa */ -#define NS_SERVER_NOSOA 0x00000004U /*%< -T nosoa */ -#define NS_SERVER_NONEAREST 0x00000008U /*%< -T nonearest */ -#define NS_SERVER_NOEDNS 0x00000020U /*%< -T noedns */ -#define NS_SERVER_DROPEDNS 0x00000040U /*%< -T dropedns */ -#define NS_SERVER_NOTCP 0x00000080U /*%< -T notcp */ -#define NS_SERVER_DISABLE4 0x00000100U /*%< -6 */ -#define NS_SERVER_DISABLE6 0x00000200U /*%< -4 */ -#define NS_SERVER_FIXEDLOCAL 0x00000400U /*%< -T fixedlocal */ -#define NS_SERVER_SIGVALINSECS 0x00000800U /*%< -T sigvalinsecs */ -#define NS_SERVER_EDNSFORMERR 0x00001000U /*%< -T ednsformerr (STD13) */ -#define NS_SERVER_EDNSNOTIMP 0x00002000U /*%< -T ednsnotimp */ -#define NS_SERVER_EDNSREFUSED 0x00004000U /*%< -T ednsrefused */ -#define NS_SERVER_TRANSFERINSECS 0x00008000U /*%< -T transferinsecs */ -#define NS_SERVER_TRANSFERSLOWLY 0x00010000U /*%< -T transferslowly */ -#define NS_SERVER_TRANSFERSTUCK 0x00020000U /*%< -T transferstuck */ -#define NS_SERVER_LOGRESPONSES 0x00040000U /*%< log responses */ +#define NS_SERVER_LOGQUERIES 0x00000001U /*%< log queries */ +#define NS_SERVER_NOAA 0x00000002U /*%< -T noaa */ +#define NS_SERVER_NOSOA 0x00000004U /*%< -T nosoa */ +#define NS_SERVER_NONEAREST 0x00000008U /*%< -T nonearest */ +#define NS_SERVER_NOEDNS 0x00000020U /*%< -T noedns */ +#define NS_SERVER_DROPEDNS 0x00000040U /*%< -T dropedns */ +#define NS_SERVER_NOTCP 0x00000080U /*%< -T notcp */ +#define NS_SERVER_DISABLE4 0x00000100U /*%< -6 */ +#define NS_SERVER_DISABLE6 0x00000200U /*%< -4 */ +#define NS_SERVER_FIXEDLOCAL 0x00000400U /*%< -T fixedlocal */ +#define NS_SERVER_SIGVALINSECS 0x00000800U /*%< -T sigvalinsecs */ +#define NS_SERVER_EDNSFORMERR 0x00001000U /*%< -T ednsformerr (STD13) */ +#define NS_SERVER_EDNSNOTIMP 0x00002000U /*%< -T ednsnotimp */ +#define NS_SERVER_EDNSREFUSED 0x00004000U /*%< -T ednsrefused */ +#define NS_SERVER_TRANSFERINSECS 0x00008000U /*%< -T transferinsecs */ +#define NS_SERVER_TRANSFERSLOWLY 0x00010000U /*%< -T transferslowly */ +#define NS_SERVER_TRANSFERSTUCK 0x00020000U /*%< -T transferstuck */ +#define NS_SERVER_LOGRESPONSES 0x00040000U /*%< log responses */ +#define NS_SERVER_COOKIEALWAYSVALID 0x00080000U /*%< -T cookiealwaysvalid */ /*% * Type for callback function to get hostname. From 4e75a20b6a63c3840559accc9df2af2d50a747f6 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 11 Mar 2025 14:29:22 +0000 Subject: [PATCH 2/2] Test -T cookiealwaysvalid Add a check in the "cookie" system test to make sure that the new '-T cookiealwaysvalid' option works. --- bin/tests/system/cookie/tests.sh | 17 +++++++++++++++++ bin/tests/system/cookie/tests_sh_cookie.py | 1 + 2 files changed, 18 insertions(+) diff --git a/bin/tests/system/cookie/tests.sh b/bin/tests/system/cookie/tests.sh index 73473885f0..5c08beb05c 100755 --- a/bin/tests/system/cookie/tests.sh +++ b/bin/tests/system/cookie/tests.sh @@ -361,6 +361,23 @@ grep "status: NOERROR," dig.out.test$n >/dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) +n=$((n + 1)) +echo_i "Restart NS4 with -T cookiealwaysvalid ($n)" +stop_server ns4 +touch ns4/named.cookiealwaysvalid +start_server --noclean --restart --port ${PORT} ns4 || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n + 1)) +echo_i "test NS6 cookie on NS4 with -T cookiealwaysvalid (expect success) ($n)" +ret=0 +$DIG $DIGOPTS +cookie=$ns6cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.4 >dig.out.test$n || ret=1 +grep "; COOKIE:.*(good)" dig.out.test$n >/dev/null || ret=1 +grep "status: NOERROR," dig.out.test$n >/dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + n=$((n + 1)) echo_i "check that test server is correctly configured ($n)" ret=0 diff --git a/bin/tests/system/cookie/tests_sh_cookie.py b/bin/tests/system/cookie/tests_sh_cookie.py index 768f8601ed..1c9e8280f5 100644 --- a/bin/tests/system/cookie/tests_sh_cookie.py +++ b/bin/tests/system/cookie/tests_sh_cookie.py @@ -19,6 +19,7 @@ pytestmark = pytest.mark.extra_artifacts( "ans*/ans.run", "ans*/query.log", "ns1/named_dump.db*", + "ns4/named.cookiealwaysvalid", ] )