为什么“dig”会成功,但“host”、“nslookup”、“curl”、“ping”却都失败?

为什么“dig”会成功,但“host”、“nslookup”、“curl”、“ping”却都失败?

从今天起,每当我使用任何带有网络接口的 docker 容器时bridge,某些实用程序的 DNS 解析似乎都会失败。

例如,如果我运行:

sudo docker run --rm \
    --cap-add=NET_ADMIN \
    --log-driver json-file \
    --log-opt max-size=10m \
    --net=bridge --dns 9.9.9.9 \
    alpine \
    sh -c 'apk add curl bind-tools; printf "\nDATE:\n"; date; printf "\nRESOLV.conf\n"; cat /etc/resolv.conf; printf "\nDIG:\n"; dig api.nordvpn.com; printf "\nTRACE:\n"; dig +trace api.nordvpn.com; printf "\nHOST:\n"; host -va api.nordvpn.com; printf "\nNSLOOKUP:\n"; nslookup api.nordvpn.com; printf "\nCURL:\n"; curl api.nordvpn.com; printf "\nPING:\n"; ping -c 5 api.nordvpn.com; printf "\nWHOIS:\n"; whois api.nordvpn.com; printf "\nRESOLVE:\n"; systemd-resolve --status'

我回复说:

DATE:
Sun Jul  4 05:58:26 UTC 2021

RESOLV.conf
nameserver 9.9.9.9

DIG:

; <<>> DiG 9.16.16 <<>> api.nordvpn.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60558
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;api.nordvpn.com.       IN  A

;; ANSWER SECTION:
api.nordvpn.com.    30  IN  A   104.17.50.74
api.nordvpn.com.    30  IN  A   104.17.49.74

;; Query time: 43 msec
;; SERVER: 9.9.9.9#53(9.9.9.9)
;; WHEN: Sun Jul 04 05:58:26 UTC 2021
;; MSG SIZE  rcvd: 106


TRACE:

; <<>> DiG 9.16.16 <<>> +trace api.nordvpn.com
;; global options: +cmd
.           39329   IN  NS  m.root-servers.net.
.           39329   IN  NS  b.root-servers.net.
.           39329   IN  NS  a.root-servers.net.
.           39329   IN  NS  e.root-servers.net.
.           39329   IN  NS  d.root-servers.net.
.           39329   IN  NS  c.root-servers.net.
.           39329   IN  NS  j.root-servers.net.
.           39329   IN  NS  k.root-servers.net.
.           39329   IN  NS  h.root-servers.net.
.           39329   IN  NS  i.root-servers.net.
.           39329   IN  NS  f.root-servers.net.
.           39329   IN  NS  g.root-servers.net.
.           39329   IN  NS  l.root-servers.net.
.           39329   IN  RRSIG   NS 8 0 518400 20210716050000 20210703040000 26838 . EB6qz8ilTb/5LvUg+xcuMuPL5KeZCcJNJxwD7kFGX/UiWdLuhk11/MZ3 R11asqSV7dC0pmttG+1h8kJG+IR022UaPBH7C/mV5vfvk5s0Vcp+DA7Y j3Rya2qm7UdTRPX3VEaL1C2ji/hnX2VIL1bU68t7OPNmhx/g0M9uwgXx hjL5jhPmRYTDInUHJThFn894VE0/HtkoIFZrWSDZjzMLf+j/CqWluRDI HH0JoOQVO5fSj7Vjtr9T67x6QG7C9qyMQ0xfTTkURkMQN4A1TEW5YGGB Ti6ypbLUmJQvHMKgFhoAc4Be/4dAm/spIlD4srIHMzECAayRXn2IXDsq xCCjaQ==
;; Received 717 bytes from 9.9.9.9#53(9.9.9.9) in 43 ms

api.nordvpn.com.    299 IN  A   104.17.50.74
api.nordvpn.com.    299 IN  A   104.17.49.74
;; Received 106 bytes from 199.7.83.42#53(l.root-servers.net) in 43 ms


HOST:
Trying "api.nordvpn.com"
Host api.nordvpn.com not found: 2(SERVFAIL)
Received 33 bytes from 9.9.9.9#53 in 43 ms

NSLOOKUP:
Server:     9.9.9.9
Address:    9.9.9.9#53

Non-authoritative answer:
Name:   api.nordvpn.com
Address: 104.17.49.74
Name:   api.nordvpn.com
Address: 104.17.50.74
** server can't find api.nordvpn.com: SERVFAIL


CURL:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:04 --:--:--     0curl: (6) Could not resolve host: api.nordvpn.com

PING:
ping: bad address 'api.nordvpn.com'

WHOIS:
[Querying whois.iana.org:43 'api.nordvpn.com']
[Redirected to whois.verisign-grs.com]
[Querying whois.verisign-grs.com:43 'api.nordvpn.com']
[Querying whois.verisign-grs.com:43 'domain api.nordvpn.com']
[whois.verisign-grs.com]
No match for domain "API.NORDVPN.COM".
>>> Last update of whois database: 2021-07-04T05:58:26Z <<<

NOTICE: The expiration date displayed in this record is the date the
registrar's sponsorship of the domain name registration in the registry is
currently set to expire. This date does not necessarily reflect the expiration
date of the domain name registrant's agreement with the sponsoring
registrar.  Users may consult the sponsoring registrar's Whois database to
view the registrar's reported date of expiration for this registration.

TERMS OF USE: You are not authorized to access or query our Whois
database through the use of electronic processes that are high-volume and
automated except as reasonably necessary to register domain names or
modify existing registrations; the Data in VeriSign Global Registry
Services' ("VeriSign") Whois database is provided by VeriSign for
information purposes only, and to assist persons in obtaining information
about or related to a domain name registration record. VeriSign does not
guarantee its accuracy. By submitting a Whois query, you agree to abide
by the following terms of use: You agree that you may use this Data only
for lawful purposes and that under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the transmission of mass
unsolicited, commercial advertising or solicitations via e-mail, telephone,
or facsimile; or (2) enable high volume, automated, electronic processes
that apply to VeriSign (or its computer systems). The compilation,
repackaging, dissemination or other use of this Data is expressly
prohibited without the prior written consent of VeriSign. You agree not to
use electronic processes that are automated and high-volume to access or
query the Whois database except as reasonably necessary to register
domain names or modify existing registrations. VeriSign reserves the right
to restrict your access to the Whois database in its sole discretion to ensure
operational stability.  VeriSign may restrict or terminate your access to the
Whois database for failure to abide by these terms of use. VeriSign
reserves the right to modify these terms at any time.

The Registry database contains ONLY .COM, .NET, .EDU domains and
Registrars.

RESOLVE:
sh: systemd-resolve: not found

我已经尝试过了:

  1. 清除 Docker 并重新开始
  2. 刷新 DNS 并尝试不同的名称服务器
  3. 重新启动机器、docker 服务等。
  4. 清除防火墙规则

为了清除防火墙,我在运行 Ubuntu Server arm64 的 Raspberry Pi 4 主机上使用的方法如下

sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -F
sudo iptables -t mangle -F
sudo iptables -F
sudo iptables -X
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -P FORWARD ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
sudo ip6tables -t nat -F
sudo ip6tables -t mangle -F
sudo ip6tables -F
sudo ip6tables -X
sudo iptables -nvL

sudo ufw disable
sudo ufw status verbose

sudo systemctl restart docker

所有命令在主机上均可正常运行。

主机上的Docker网络接口符合预期:

> docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
73b916cb9b14   bridge    bridge    local
ea4702692896   host      host      local
03d46009da3e   none      null      local

> docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "73b916cb9b14ce7d31b091279f2763cba5e2856430ad10883ce93a2cefbf8eee",
        "Created": "2021-07-04T05:58:18.735577898Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

答案1

hostnslookup一些单独的 DNS 查询 – 每种记录类型一个。他们希望向您显示 IPv4 和 IPv6 地址,因此他们需要进行 A 查询和 AAAA 查询。

如果您运行host -v api.nordvpn.com(使用“详细”选项以类似 dig 的格式显示响应),您将看到它实际上相当于连续的这 3 个命令:

dig api.nordvpn.com A
dig api.nordvpn.com AAAA
dig api.nordvpn.com MX

运行nslookup -debug api.nordvpn.com将同样显示它查询 A 和 AAAA 记录(但不是 MX)。

如果仔细查看 Docker 输出,您会发现 A 查询实际上成功了,而 AAAA 查询返回了 SERVFAIL。因此,失败在“dig”中永远不会可见,因为您从未要求它进行 AAAA 查询。

部分失败的查询可能有以下几种解释:

  • 您的解析器与权威服务器之间存在一些连接问题,但它恰好具有之前缓存的 A 的结果,并且仍然能够返回这些结果。

  • nordvpn.com 的权威服务器对 A 查询返回响应,但对 AAAA 查询根本没有响应。

  • 您的 DNS 请求被拦截并重定向到不同的解析器,并且该解析器以“不支持 IPv6”或“避免 IPv6 VPN 泄漏”或类似的借口阻止所有 AAAA 查询。

事实上你的dig +trace输出已经表明这是第三种情况:

api.nordvpn.com.    299 IN  A   104.17.50.74
api.nordvpn.com.    299 IN  A   104.17.49.74
;; Received 106 bytes from 199.7.83.42#53(l.root-servers.net) in 43 ms

在跟踪模式下,dig 首先联系根服务器,它应该在那里收到引荐响应(指向“.com”服务器的响应)并跟踪链条。

但就你的情况而言,dig 会立即收到包含所请求 A 记录的直接答复。不是根服务器如何工作 – 它们不是有能力的提供此类答案。您唯一会看到此结果的情况是,端口 53 上的数据包被重定向到本地解析器,而您实际上并没有与您认为正在对话的 DNS 服务器对话。


尝试在 192.0.2.1 或 203.0.113.1 进行 DNS 查询 - 如果您收到来自该地址的响应,您就会知道它不合法,因为该地址在互联网上的任何地方都不存在。)

dig @192.0.2.1 google.com

尝试进行以下查询来找出您实际正在交谈的 DNS 服务器的名称:

dig @9.9.9.9 hostname.bind chaos txt
dig @9.9.9.9 id.server chaos txt

(如果与真实的9.9.9.9,您应该会看到类似“res600.fra.rrdns.pch.net”的 id.server 响应。)

也许值得一试traceroute --udp --port=53 9.9.9.9;它会显示正常结果,直到到达数据包被重定向的点,之后将显示无意义的结果。

相关内容