[Dnsmasq-discuss] change in behavior where v4 address exists but not v6 in 2.86 [PATCH]

Petr Menšík pemensik at redhat.com
Fri Oct 1 23:06:22 UTC 2021


On 9/19/21 01:03, Simon Kelley wrote:
> On 16/09/2021 07:29, Todd Derr wrote:
>> Hi, first time poster and I'm relatively new to dnsmasq. I'm using
>> dnsmasq from brew on MacOS; I recently upgraded and ran into an issue
>> with a name that has a v4 address but no v6 address, like so:
>>
>>     log-queries
>>     log-facility=/usr/local/var/log/dnsmasq.log
>>     address=/dummy.com/127.0.0.2 <http://dummy.com/127.0.0.2>
>>
>> On 2.85 and below, the A query is answered and the AAAA returns NODATA:
>>
>>     Sep 13 16:29:38 dnsmasq[68]: query[A] dummy.com <http://dummy.com>
>>     from 127.0.0.1
>>     Sep 13 16:29:38 dnsmasq[68]: config dummy.com <http://dummy.com> is
>>     127.0.0.2
>>     Sep 13 16:29:38 dnsmasq[68]: query[AAAA] dummy.com
>>     <http://dummy.com> from 127.0.0.1
>>     Sep 13 16:29:38 dnsmasq[68]: config dummy.com <http://dummy.com> is
>>     NODATA-IPv6
>>
>>
>> Whereas on 2.86 the AAAA query gets forwarded to the system nameservers:
>>
>>     Sep 14 20:50:08 dnsmasq[31529]: query[A] dummy.com
>>     <http://dummy.com> from 127.0.0.1
>>     Sep 14 20:50:08 dnsmasq[31529]: config dummy.com <http://dummy.com>
>>     is 127.0.0.2
>>     Sep 14 20:50:08 dnsmasq[31529]: query[AAAA] dummy.com
>>     <http://dummy.com> from 127.0.0.1
>>     Sep 14 20:50:08 dnsmasq[31529]: forwarded dummy.com
>>     <http://dummy.com> to 8.8.8.8
>>     Sep 14 20:50:08 dnsmasq[31529]: forwarded dummy.com
>>     <http://dummy.com> to 8.8.4.4
>>     Sep 14 20:50:08 dnsmasq[31529]: reply dummy.com <http://dummy.com>
>>     is <CNAME>
>>     Sep 14 20:50:08 dnsmasq[31529]: reply odrfn4em.cname.us.ngrok.io
>>     <http://odrfn4em.cname.us.ngrok.io> is 2600:1f16:d83:1202::6e:5
>>
>> Was this an intentional change in behavior?  I didn't see anything in
>> the CHANGELOG and haven't tried to look through the code changes yet.
> The whole implementation of this got re-written for 2.86, but the
> intention was not to actually change behaviour.  It looks like this
> slipped through.
>
> I'm in a quandary about if this change is a bad thing, or not. In
> general the dnsmasq philosophy is that you configure stuff that you want
> it to overlay on the public DNS, and everything else gets passed through
> unchanged. It is, for instance, the case that if you put an IPV4 address
> in /etc/hosts but not an IPv6 address, then AAAA queries will be passed
> through, and all versions of dnsmasq forever have done that.
Sure, backward compatibility is important. I am not sure it always makes
sense to forward AAAA queries on locally defined A records. Especially
since --address serves similar purpose, but its behavior is opposite. I
think it might be nice if desired mode could be changed by configuration
options. But unless new options are used, existing configuration from
previous version should behave the same way, unless it was a bug.
>
> In 2.86, there's a defined priority list for domains, so the behaviour
> you want is easy to define
>
> address=/dummy.com/127.0.0.2
> local=/dummy.com/
>
> For A queries, the first line has priority, for all others, the second
> line returns NODATA*
>
>
> *Actually, NODATA comes from the combination of both lines; the second
> by itself would generate NXDOMAIN.
>
>
> TL;DR The new behaviour is a regression, and an unintended one. But the
> new behaviour is more consistent and well defined and allows for a
> different configuration which provides the old behaviour if required.
>
> Maybe better documentation is the solution?

I would consider it a regression. Because even quite old 2.79 release
behaves consistently the same way, this seems quite significant behavior
change. Could --address include also local by default, but allow current
way via modified syntax? For example:

address=/dummy.com/127.0.0.2,only # keep current behavior, similar to
host-record
address=/example.com/::1 # works the same way as up to 2.85

Especially because it can leak previously blocked queries to upstream
servers, which can be used for malicious purposes.

I would have sent a patch, but I were unable to to solve filters in
domain-match.c for it to behave the original way. But I just
reimplemented what Simon has offered as a workaround. It adds a new
unnecessary --local serv_local structure, but is simple enough. So
attached is minimalistic version. I think signalling via SERV_ flags
should be used instead, but I failed to find working way to do it.

>
>
> Cheers,
>
> Simon.
>> Is there any way to disable it? As a workaround I added this to the
>> config, which may have the same basic effect as NODATA but it's hacky
>> and worries me a bit:
>>
>>     address=/dummy.com/ <http://dummy.com/>:: 
>>
> See above.
>
>> The actual problem this caused is kind of comical in retrospect but
>> bewildering and frustrating until I figured it out:
>> * Since the initial A query still returns the expected v4 address
>> (127.0.0.2), the HTTP request that triggered the lookup succeeded.
>> * However, since the AAAA query contains a CNAME, the resolver dutifully
>> looks up the v4 address for that CNAME and effectively poisons the cache
>> and makes future requests fail (since the ngrok tunnel is not up)
>> * Adding to the fun, since ping only does the A query, it didn't perturb
>> the state of the cache.
>> * The TTL for the CNAME is 1 hour
>>
>> add that all up, and I had this running in a terminal and would see the
>> address spontaneously change for reasons that took me quite a while to
>> discern:
>>
>>     while true; do echo "$(date) $(ping -c1 -t1 dummy.com
>>     <http://dummy.com> | head -1)"; sleep 1; done
>>
>>
>> it was a wild ride, thanks for following along and I hope you had a
>> laugh at my expense.
> We're not laughing. We like a thorough analysis of the problem, and that
> is one.
It is true common resolvers like BIND9 or Unbound work only in terms of
zones. AFAIK it is impossible for them to allow CNAME on single query
type but respond without CNAME on another type for the same name. I
guess this is a price paid for working without zones concept, just on
per-query level. Ideally we would cache CNAME also with original query
type and use that cache record only for that type, always together.
Never use it for different types. We rely on upstream recursive resolver
to deliver it anyway.
>
>
>> todd.
>>
Regards,

Petr

-- 
Petr Menšík
Software Engineer
Red Hat, http://www.redhat.com/
email: pemensik at redhat.com
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Fall-back-to-previous-release-behaviour.patch
Type: text/x-patch
Size: 4061 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20211002/523eaa7d/attachment.bin>


More information about the Dnsmasq-discuss mailing list