moby / moby/libnetwork

DNS: client does not receive an NXDOMAIN when 1 of 3 servers times out

Open
#2,613 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
2.2k
Forks
875
PR merge metrics
No merged PRs in 30d

Description

Hi there,

We discovered an issue today in how queries passed to an external DNS server are retried when an NXDOMAIN is received.

# /etc/resolv.conf (host)
search example.com
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3
nameserver 10.0.0.4
# /etc/resolv.conf (container)
search example.com
nameserver 127.0.0.11
options single-request timeout:1 ndots:0

Under normal circumstances, DNS works as expected. The NXDOMAIN is received by the client, resulting in the search domain being appended and the query retried.

$ time host usw125
Host usw125 not found: 3(NXDOMAIN)
real    0m0.052s
user    0m0.000s
sys     0m0.010s

However, when 10.0.0.3 goes offline, the container never receives the NXDOMAIN and thus never tries to resolve the query with the search domain.

$ time host foo
;; connection timed out; no servers could be reached
real    0m10.011s
user    0m0.004s
sys     0m0.007s

We can see that the docker daemon tried 3 servers (expected, since the NXDOMAIN is not authoritative).
It receives 2 NXDOMAIN responses followed by a timeout.
At this point we've hit our limit (since maxExtDNS = 3) and we fall through without sending a response

# /var/logl/dockerd.log
Name To resolve: foo.
[resolver] query foo. (A) from 172.18.0.5:55172, forwarding to udp:10.0.0.1
[resolver] external DNS udp:10.0.0.1 responded with NXDOMAIN for "foo."
[resolver] query foo. (A) from 172.18.0.5:39805, forwarding to udp:10.0.0.2
[resolver] external DNS udp:10.0.0.2 responded with NXDOMAIN for "foo."
[resolver] query foo. (A) from 172.18.0.5:54945, forwarding to udp:10.0.0.3
[resolver] read from DNS server failed, read udp 172.18.0.5:54945->10.0.0.3:53: i/o timeout

It seems to me that somehow this failure mode should(?)/could return one of the NXDOMAIN responses we previously received allowing the client to continue operating rather than hanging for extended periods of time as if all DNS servers were unreachable.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read libnetwork/resolver.go around lines 510 and 540, then follow the external DNS retry path described in the report. Reproduce the case with three configured servers where two return NXDOMAIN and the third times out; done means the client receives an NXDOMAIN response instead of hanging without a response.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.