Re: [Dnsmasq-discuss] New option --no-ANY

2024-02-12 Thread Simon Kelley



On 08/02/2024 12:01, Petr Menšík wrote:
I do not think this is good approach. One thing is any queries need to 
be handled by upstream resolver somehow. Whatever it is, dnsmasq will 
reply whatever upstream resolvers chosen to do that. The only exception 
is local data, for example authoritative services.


I would prefer sending just A or  queries, whatever from them comes 
first. Or maybe excluding other types and using just A and  records, 
if they are in cache. Reference 4.3 
. Alternatively do 
what unbound does, return NOTIMPL error.




Tend to agree. I just pushed something which I think works. It leaves 
replies from local data unaltered and filters all except A, , MX and 
CNAME from upstream replies to ANY queries, as 4.3 suggests.


Use

--filter-rr=ANY

to enable.


Simon.


Shown localhost example:

; <<>> DiG 9.18.21 <<>> @localhost -p 2053 -t any localhost
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60904
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;localhost.            IN    ANY

;; ANSWER SECTION:
localhost.        0    IN    A    127.0.0.1
localhost.        0    IN        ::1

With --no-ANY, it returns empty response. I have changed continue; to 
return 0; That gives incorrect results and should not be used. But your 
patch did not apply to my master, on top of commit 
762a3f243099d26b1e87aad2b1b4b696cd8c33ac.


; <<>> DiG 9.18.21 <<>> @localhost -p 2053 -t any localhost
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48980
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;localhost.            IN    ANY

;; AUTHORITY SECTION:
localhost.        10800    IN    SOA    localhost. nobody.invalid. 1 
3600 1200 604800 10800


I think we can modify ANY type query to provide just single type or 
synthetized answer, but empty response seems wrong. I think || qtype == 
T_ANY should be removed from most of types, to make answer smaller. 
Unlike mDNS ANY is not specified in DNS to provide all answers known. If 
anyone relies on it, that would be wrong too.


I disagree with current proposal.

On 06. 02. 24 18:00, Dominik Derigs via Dnsmasq-discuss wrote:

RFC 8482


--
Petr Menšík
Software Engineer, RHEL
Red Hat,http://www.redhat.com/
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB



___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] New option --no-ANY

2024-02-08 Thread Petr Menšík
I do not think this is good approach. One thing is any queries need to 
be handled by upstream resolver somehow. Whatever it is, dnsmasq will 
reply whatever upstream resolvers chosen to do that. The only exception 
is local data, for example authoritative services.


I would prefer sending just A or  queries, whatever from them comes 
first. Or maybe excluding other types and using just A and  records, 
if they are in cache. Reference 4.3 
. Alternatively do 
what unbound does, return NOTIMPL error.


Shown localhost example:

; <<>> DiG 9.18.21 <<>> @localhost -p 2053 -t any localhost
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60904
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;localhost.            IN    ANY

;; ANSWER SECTION:
localhost.        0    IN    A    127.0.0.1
localhost.        0    IN        ::1

With --no-ANY, it returns empty response. I have changed continue; to 
return 0; That gives incorrect results and should not be used. But your 
patch did not apply to my master, on top of commit 
762a3f243099d26b1e87aad2b1b4b696cd8c33ac.


; <<>> DiG 9.18.21 <<>> @localhost -p 2053 -t any localhost
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48980
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;localhost.            IN    ANY

;; AUTHORITY SECTION:
localhost.        10800    IN    SOA    localhost. nobody.invalid. 1 
3600 1200 604800 10800


I think we can modify ANY type query to provide just single type or 
synthetized answer, but empty response seems wrong. I think || qtype == 
T_ANY should be removed from most of types, to make answer smaller. 
Unlike mDNS ANY is not specified in DNS to provide all answers known. If 
anyone relies on it, that would be wrong too.


I disagree with current proposal.

On 06. 02. 24 18:00, Dominik Derigs via Dnsmasq-discuss wrote:

RFC 8482


--
Petr Menšík
Software Engineer, RHEL
Red Hat,http://www.redhat.com/
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB



OpenPGP_0x4931CA5B6C9FC5CB.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature
___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


[Dnsmasq-discuss] New option --no-ANY

2024-02-06 Thread Dominik Derigs via Dnsmasq-discuss

Hey Simon,

this patch adds a method for deprecating ANY queries (following RFC 
8482: Providing Minimal-Sized Responses to DNS Queries That Have 
QTYPE=ANY). This conforms to how many of the large scale upstream DNS 
providers (Google, Cloudflare to name only a few) are dealing with the 
use_less_ness of ANY in general on one hand but the unfortunate 
use_full_ness in DNS amplification attacks on the other hand. Another 
solution could be only disallowing ANY queries over UDP and forcing 
clients to re-try over TCP but - given how useless ANY is - it doesn't 
seem worth implementing this more complex path.


The proposed option --no-ANY simply ensures dnsmasq will not add any RRs 
for such questions.


We are looking forward to enable it by default in Pi-hole v6.0+ given 
this patch is accepted.


Best,
Dominik
From ac3134c48ef3ee6ec9be2f3b0993f710ac36f8f8 Mon Sep 17 00:00:00 2001
From: DL6ER 
Date: Tue, 6 Feb 2024 17:51:22 +0100
Subject: [PATCH] Add option --no-ANY providing minimal-sized responses to ANY
 queries (RFC 8482)

Signed-off-by: DL6ER 
---
 CHANGELOG | 4 
 man/dnsmasq.8 | 9 +
 src/dnsmasq.h | 3 ++-
 src/option.c  | 3 +++
 src/rfc1035.c | 8 
 5 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG b/CHANGELOG
index 2ce53a8..75575b5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,10 @@ version 2.90
 	end up in the query also. This bug only seems to cause problems
 	when the usptream server is a DOH/DOT proxy. Thanks to Justin He
 	for the bug report.
+
+	Add --no-ANY option to stop processing ANY queries.
+	The ANY type has been deprecated by RFC 8482, and is a common vector
+	for DNS amplification attacks.
 	
 	
 version 2.89
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index bb8da54..1a7a280 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -388,6 +388,15 @@ Remove  records from answers. No IPv6 addresses will be returned.
 .B --filter-rr=[,...]
 Remove records of the specified type(s) from answers.
 .TP
+.B --no-ANY
+Provide minimal-sized responses to ANY DNS queries instead of processing them.
+Queries with QTYPE=ANY are frequently observed as part of reflection attacks,
+since a relatively small query can be used to elicit a large response. This is a desirable
+characteristic if the goal is to maximize the amplification potential of a DNS server as
+part of a volumetric attack. With this option being enabled, minimal responses are returned making
+dnsmasq a much less useful amplifier.
+The follows RFC 8482 which effectively deprecates the DNS ANY query type.
+.TP
 .B --cache-rr=[,...]
 By default, dnsmasq caches A, , CNAME and SRV DNS record types.
 This option adds other record types to the cache. The RR-type can be given
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 129e2c9..9ec4d39 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -282,7 +282,8 @@ struct event_desc {
 #define OPT_NO_IDENT   70
 #define OPT_CACHE_RR   71
 #define OPT_LOCALHOST_SERVICE  72
-#define OPT_LAST   73
+#define OPT_NO_ANY 73
+#define OPT_LAST   74
 
 #define OPTION_BITS (sizeof(unsigned int)*8)
 #define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
diff --git a/src/option.c b/src/option.c
index 0cb691e..a5297eb 100644
--- a/src/option.c
+++ b/src/option.c
@@ -191,6 +191,7 @@ struct myoption {
 #define LOPT_NO_DHCP6  382
 #define LOPT_NO_DHCP4  383
 #define LOPT_MAX_PROCS 384
+#define LOPT_NO_ANY385
 
 #ifdef HAVE_GETOPT_LONG
 static const struct option opts[] =  
@@ -231,6 +232,7 @@ static const struct myoption opts[] =
 { "filter-A", 0, 0, LOPT_FILTER_A },
 { "filter-", 0, 0, LOPT_FILTER_ },
 { "filter-rr", 1, 0, LOPT_FILTER_RR },
+{ "no-ANY", 0, 0, LOPT_NO_ANY },
 { "pid-file", 2, 0, 'x' },
 { "strict-order", 0, 0, 'o' },
 { "server", 1, 0, 'S' },
@@ -416,6 +418,7 @@ static struct {
   { LOPT_FILTER_A, ARG_DUP, NULL, gettext_noop("Don't include IPv4 addresses in DNS answers."), NULL },
   { LOPT_FILTER_, ARG_DUP, NULL, gettext_noop("Don't include IPv6 addresses in DNS answers."), NULL },
   { LOPT_FILTER_RR, ARG_DUP, "", gettext_noop("Don't include resource records of the given type in DNS answers."), NULL },
+  { LOPT_NO_ANY, OPT_NO_ANY, NULL, gettext_noop("Don't reply to ANY requests"), NULL },
   { 'F', ARG_DUP, ",...", gettext_noop("Enable DHCP in the range given with lease duration."), NULL },
   { 'g', ARG_ONE, "", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP },
   { 'G', ARG_DUP, "", gettext_noop("Set address or hostname for a specified machine."), NULL },
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 04b1472..423a4b4 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1550,6 +1550,14 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
 
   ans = 0; /* have we answered this question */
 
+  /* Do not answer ANY queries if requested */
+  if (qtype == T_ANY &&