这本身并不是一个问题,但当你遇到 DNS 问题时,一般都会跟 DNS 解析器有关。我没有一种判断 DNS 解析器的万能方法。
下面是我知道的方法:
在 Linux 系统上,最常见的是通过 /etc/resolv.conf来选择 DNS 解析器。但是也有例外,比如浏览器可能会忽略/etc/resolv.conf,而是使用 基于 HTTPS 的 DNSDNS-over-HTTPS 服务。如果你使用的是 UDP DNS,你可以通过 sudo tcpdump port 53来查看 DNS 请求被发送到了哪里。但如果你使用的是基于 HTTPS 的 DNS 或 基于 TLS 的 DNSDNS over TLS,这个方法就不行了。
我依稀记得这在 MacOS 系统上会更加令人迷惑,我也不清楚原因。
问题:DNS 服务器返回 NXDOMAIN 而不是 NOERROR
这是我曾经遇到过的一个 Nginx 不能解析域名的问题。
我设置 Nginx 使用一个特定的 DNS 服务器来解析 DNS 查询当访问这个域名时,Nginx 做了两次查询,第一次是对 A的,第二次是对AAAA的对于 A的查询,DNS 服务器返回NXDOMAINNginx 认为这个域名不存在,然后放弃查询对于 AAAA的查询 DNS 服务器返回了成功但 Nginx 忽略了对 AAAA返回的查询结果,因为它前面已经放弃查询了
问题出在 DNS 服务器本应该返回 NOERROR的——那个域名确实存在,只是没有关于A的记录罢了。我报告了这个问题,然后他们修复了这个问题。
很多应用程序使用 libc的getaddrinfo来做 DNS 查询。musl是用在 Alpine Docker 容器上的glibc替代品。而它不支持 TCP DNS。如果你的 DNS 查询的响应数据超过 DNS UDP 数据包的大小(512 字节)就会出现问题。
我对此仍然不太清楚,我下面我的理解也可能是错的:
musl的getaddrinfo发起一个 DNS 请求DNS 服务器发现请求的响应数据太大了,没法放入一个 DNS 数据包中DNS 服务器返回一个空截断响应empty truncated response,并期望客户端通过 TCP DNS 重新用发起查询但 musl不支持 TCP DNS,所以根本不会重试
关于这个问题的文章:在 Alpine Linux 上的 DNS 解析问题。
问题:getaddrinfo 不支持轮询 DNS
轮询round robin DNS 是一种 负载均衡load balancing 技术,每次 DNS 查询都会获得一个不同的 IP 地址。显然如果你使用 gethostbyname做 DNS 查询不会有任何问题,但是用getaddrinfo就不行了。因为getaddrinfo会对获得的 IP 地址进行排序。