[Dnsmasq-discuss] REFUSED PTR queries without recursion desired

2019-07-09 Thread Chiang Fong Lee
Hello,

I’m having some trouble getting dnsmasq to respond to PTR queries without 
recursion desired, even when authoritative mode is enabled.

Given the following config:
domain-needed
bogus-priv
no-resolv
no-hosts
port=10053
server=/example.com/
log-queries
host-record=host1.example.com,10.2.3.4

Observed results:
Query host1.example.com A (with recursion) - NOERROR, returns answer
Query host1.example.com A (without recursion) - REFUSED
Query 4.3.2.10.in-addr.arpa PTR (with recursion) - NOERROR, returns answer
Query 4.3.2.10.in-addr.arpa PTR (without recursion) - REFUSED

Given the above config, plus the following two lines to enable authoritative 
mode:
auth-server=ns1.example.com
auth-zone=example.com,10.0.0.0/8

Observed results:
Query host1.example.com A (with recursion) - NOERROR, returns answer
Query host1.example.com A (without recursion) - NOERROR, returns answer
Query 4.3.2.10.in-addr.arpa PTR (with recursion) - NOERROR, returns answer
Query 4.3.2.10.in-addr.arpa PTR (without recursion) - REFUSED

Expected results:
Enabling auth mode for the zone, and specifying the subnet, would result in the 
last PTR query being accepted instead of refused.

The log lines seen when the REFUSED occurs are:
dnsmasq_1  | Jul  9 09:42:06 dnsmasq[1]: query[PTR] 4.3.2.10.in-addr.arpa from 
172.19.0.1
dnsmasq_1  | Jul  9 09:42:06 dnsmasq[1]: config error is REFUSED

Version info:
Dnsmasq version 2.80  Copyright (c) 2000-2018 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua 
TFTP no-conntrack ipset auth no-DNSSEC loop-detect inotify dumpfile

I was looking through the source and I’m guessing that PTR queries don’t ever 
trigger the auth zone path, since the query ends in “in-addr.arpa” instead of 
the auth-zone domain like “example.com”. Once it reaches the regular 
answer_request path, it immediately returns since the RD flag is not set, 
without checking host-records, and proceeds to forward the query instead.

Is this intended behaviour? The 2.79 CHANGELOG states that this always-SERVFAIL 
(or forward, in 2.80) behaviour for queries without recursion desired should 
always happen “UNLESS acting as an authoritative DNS server”, without a caveat 
that it only works for non-reverse DNS queries.

Thanks,
Chiang Fong


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


[Dnsmasq-discuss] [PATCH] Issues with TCP queries on recreated interfaces.

2019-07-09 Thread Petr Mensik
Hello Simon and others,

we have discovered issues with TCP DNS query on dnsmasq, when running in
bind-dynamic or bind-interfaces mode. dnsmasq scans automatically new
interfaces or do that on new query in second case. However, because used
speedup comparing only IP adresses in iface_allowed function, it never
gets updated index of an interface.

In case where named interface is destroyed and created again, that drops
TCP queries on that interface. They are checked for incoming interface
number. If such number is not found in interfaces list, query is denied.

Luckily, there was a bug in checking, hiding this problem from usual
configuration. If IPv6 address is enabled on the new device, new iface
entry would be created, because scope_id of sockaddr_in6 does not match
previous. That makes even IPv4 queries succeed.

Bug on bugzilla [1] is partly private.

I propose three changes. First is just helper to log what happens with
listeners on bind-dynamic configuration.

Second is the most important. Create new interface every time index
changes. Also test address family of incoming TCP query when checking
allowed clients.

Third is cleanup of unused interfaces. On some virtual machines hosts,
interfaces may often be created and destroyed. It might have negative
effect on walking trough interfaces list. I think listeners should be
garbage collected also on bind-interfaces configuration. But for now,
release memory for unused interfaces at least for bind-dynamic.

1. https://bugzilla.redhat.com/show_bug.cgi?id=1721668
-- 
Petr Menšík
Software Engineer
Red Hat, http://www.redhat.com/
email: pemen...@redhat.com  PGP: 65C6C973
From c9cc7aa2fb5463626bf6795531390ca3f2d2752b Mon Sep 17 00:00:00 2001
From: Petr Mensik 
Date: Tue, 9 Jul 2019 14:05:59 +0200
Subject: [PATCH 3/3] Cleanup interfaces no longer available

Clean addresses and interfaces not found after enumerate. Free unused
records to speed up checking active interfaces and reduce used memory.
---
 src/network.c | 31 +--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/src/network.c b/src/network.c
index f487617..5a37f61 100644
--- a/src/network.c
+++ b/src/network.c
@@ -533,7 +533,29 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
 
   return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
 }
-   
+
+/*
+ * Clean old interfaces no longer found.
+ */
+static void clean_interfaces()
+{
+  struct irec *iface;
+  struct irec **up = &daemon->interfaces;
+
+  for (iface = *up; iface; iface = *up)
+{
+  if (!iface->found && !iface->done) {
+*up = iface->next;
+	my_syslog(LOG_DEBUG, _("dropping interface %s(#%d) family %d"),
+	 iface->name, iface->index, iface->addr.sa.sa_family);
+	free(iface->name);
+	free(iface);
+  } else {
+	up = &iface->next;
+	  }
+}
+}
+
 int enumerate_interfaces(int reset)
 {
   static struct addrlist *spare = NULL;
@@ -631,6 +653,7 @@ int enumerate_interfaces(int reset)
 	 in OPT_CLEVERBIND mode, that at listener will just disappear after
 	 a call to enumerate_interfaces, this is checked OK on all calls. */
   struct listener *l, *tmp, **up;
+  int freed = 0;
   
   for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
 	{
@@ -660,10 +683,14 @@ int enumerate_interfaces(int reset)
 		close(l->tftpfd);
 	  
 	  free(l);
+	  freed = 1;
 	}
 	}
+
+  if (freed)
+	clean_interfaces();
 }
-  
+
   errno = errsave;
   spare = param.spare;
 
-- 
2.20.1

From e3a22a2ad93c518507cd1b41fabbf0c1160daef1 Mon Sep 17 00:00:00 2001
From: Petr Mensik 
Date: Wed, 3 Jul 2019 17:02:16 +0200
Subject: [PATCH 2/3] Compare address and interface index for allowed interface

If interface is recreated with the same address but different index, it
would not change any other parameter.

Test also address family on incoming TCP queries.
---
 src/dnsmasq.c | 3 ++-
 src/network.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 704475f..939e69e 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -1792,7 +1792,8 @@ static void check_dns_listeners(time_t now)
 		addr.addr4 = tcp_addr.in.sin_addr;
 		  
 		  for (iface = daemon->interfaces; iface; iface = iface->next)
-		if (iface->index == if_index)
+		if (iface->index == if_index &&
+		iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
 		  break;
 		  
 		  if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
diff --git a/src/network.c b/src/network.c
index 1fe25f7..f487617 100644
--- a/src/network.c
+++ b/src/network.c
@@ -388,10 +388,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
   /* check whether the interface IP has been added already 
  we call this routine multiple times. */
   for (iface = da

Re: [Dnsmasq-discuss] [PATCH] Issues with TCP queries on recreated interfaces.

2019-07-09 Thread Vladislav Grishenko
Hi Petr,

Regarding 0002-Compare-address-and-interface-index-for-allowed-inte.patch, does 
it support case with different valid interfaces with the same address?
For example:
eth0 192.168.1.1/24
tun0 192.168.1.1./16 (created/destroyed dynamically)

Regarding appearance, seems newly added code doesn’t fully follow dnsmasq code 
style in several places:
* indentation (should be ident ==2 spaces, 8 spaces == \t)
* brackets on the same code lines
* function args on the next line are not aligned with the first argument
* prettyprint_addr() result is forcibly ignored with (void) unlike other places

Best Regards, Vladislav Grishenko

-Original Message-
From: Dnsmasq-discuss  On 
Behalf Of Petr Mensik
Sent: Tuesday, July 9, 2019 5:31 PM
To: dnsmasq-discuss@lists.thekelleys.org.uk
Subject: [Dnsmasq-discuss] [PATCH] Issues with TCP queries on recreated 
interfaces.

Hello Simon and others,

we have discovered issues with TCP DNS query on dnsmasq, when running in 
bind-dynamic or bind-interfaces mode. dnsmasq scans automatically new 
interfaces or do that on new query in second case. However, because used 
speedup comparing only IP adresses in iface_allowed function, it never gets 
updated index of an interface.

In case where named interface is destroyed and created again, that drops TCP 
queries on that interface. They are checked for incoming interface number. If 
such number is not found in interfaces list, query is denied.

Luckily, there was a bug in checking, hiding this problem from usual 
configuration. If IPv6 address is enabled on the new device, new iface entry 
would be created, because scope_id of sockaddr_in6 does not match previous. 
That makes even IPv4 queries succeed.

Bug on bugzilla [1] is partly private.

I propose three changes. First is just helper to log what happens with 
listeners on bind-dynamic configuration.

Second is the most important. Create new interface every time index changes. 
Also test address family of incoming TCP query when checking allowed clients.

Third is cleanup of unused interfaces. On some virtual machines hosts, 
interfaces may often be created and destroyed. It might have negative effect on 
walking trough interfaces list. I think listeners should be garbage collected 
also on bind-interfaces configuration. But for now, release memory for unused 
interfaces at least for bind-dynamic.

1. https://bugzilla.redhat.com/show_bug.cgi?id=1721668
--
Petr Menšík
Software Engineer
Red Hat, http://www.redhat.com/
email: pemen...@redhat.com  PGP: 65C6C973


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