[Dnsmasq-discuss] Client retries broken in 2.84
Simon Kelley
simon at thekelleys.org.uk
Thu Feb 18 00:03:16 UTC 2021
On 16/02/2021 00:42, Nicholas Mu wrote:
> Hi,
>
> I noticed a low level increase in DNS errors after upgrading to 2.84.
> After doing some packet diving, it seems that retries behave differently
> in the new version. For my testing, I'm using dnspython but I believe
> this issue would affect any client that uses different source ports and
> query ids for retries. As a result, dnspython will attempt retries for
> up to 30 seconds and will eventually timeout as only a single packet is
> ever sent and retries are rendered ineffective.
>
> On 2.82, multiple packets are sent as dnspython retries. Note the
> retries are using different source ports and query ids:
>
> |[ec2-user at ip-172-31-44-29 src]$ grep cell-1 /tmp/dnsmasq-2.82
> 19:59:03.826638 IP 172.31.44.29.44547 > 172.31.0.2.53: 51880+ NS?
> somedomain. (64)
> 19:59:05.928335 IP 172.31.44.29.33363 > 172.31.0.2.53: 41382+ NS?
> somedomain. (64)
> 19:59:08.130620 IP 172.31.44.29.21177 > 172.31.0.2.53: 36073+ NS?
> somedomain. (64)
> 19:59:10.532792 IP 172.31.44.29.57223 > 172.31.0.2.53: 50309+ NS?
> somedomain. (64)|
> |
> |
> |On 2.84, only a single packet is sent:|
> |
> |
> |[ec2-user at ip-172-31-44-29 src]$ grep cell-1 /tmp/dnsmasq-2.84
> 19:53:12.189849 IP 172.31.44.29.5335 > 172.31.0.2.53: 826+ NS?
> somedomain. (64)|
> |
> |
> I also tested using dig, nslookup, and host which all use the same
> source port and query id on retries. The behavior works as intended on
> both versions. I would suspect the following commit is responsible for
> this behavior change:
>
> Handle multiple identical near simultaneous DNS queries better.
> Previously, such queries would all be forwarded
> independently. This is, in theory, inefficent but in practise
> not a problem, _except_ that is means that an answer for any
> of the forwarded queries will be accepted and cached.
> An attacker can send a query multiple times, and for each repeat,
> another {port, ID} becomes capable of accepting the answer he is
> sending in the blind, to random IDs and ports. The chance of a
> succesful attack is therefore multiplied by the number of repeats
> of the query. The new behaviour detects repeated queries and
> merely stores the clients sending repeats so that when the
> first query completes, the answer can be sent to all the
> clients who asked. Refer: CVE-2020-25686.
>
> Is this intended? Seems to me any clients with retry behavior similar to
> dnspython are now broken. Clients will hang until their configured
> timeouts are reached on any single DNS failure.
>
> Thanks,
>
> Nick
>
Your analysis is spot-on.
I think it's possible to satisfy both the security and robustness
requirements here.
Pre 2.84, a retry for the same query with different query-id and/or
source port would be treated as an independent query and forwarded
again, with a new source-port and query-id. This gives the attacker the
ability to increase the attack surface for cache pollution by sending
many repeat queries.
In 2.84 a repeat with the same SP/QID gets treated as it always has: as
a retry, and the query gets forwarded again, and this time to all
available servers. The same query but with different SP/QID now gets
piggy-backed onto the existing query, as you noted.
The solution here is for a repeat query with different SP/QID to trigger
the same retry behaviour as a repeat query with the same SP/QID, but
also to still piggy back the existing query, so that no new SP/QID
tuples are generated going upstream.
I just pushed
http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=141a26f979b4bc959d8e866a295e24f8cf456920
which should implement this. Please test!
Cheers,
Simon.
More information about the Dnsmasq-discuss
mailing list