公众号旧文

DNS 不仅缓存存在,也缓存不存在

作者:胖子阅读 —

一、问题背景:从 youtube 域名切换开始

最开始,我的 YouTube 下载站使用的域名是:

youtube.19900429.xyz

后来发现,这个域名被拦截。

当时发了贴图:加更一篇通知

于是,我就换了一个新的域名:

videodownload.19900429.xyz

并配置了:

youtube.19900429.xyz
        HTTP 301
        ↓
videodownload.19900429.xyz

当时测试一切正常。

于是我认为 301 跳转已经生效,问题已经解决。

但是,这个判断并不完整。

二、新问题出现:域名突然无法访问

今天再次尝试访问:

youtube.19900429.xyz

浏览器却提示:

无法访问此网站
youtube.19900429.xyz 意外终止了连接。
请试试以下办法:
检查网络连接
检查代理服务器和防火墙
运行 Windows 网络诊断
ERR_CONNECTION_CLOSED

于是开始逐层排查。

三、检查 Cloudflare 权威 DNS

首先,直接查询权威 DNS。

dig @gail.ns.cloudflare.com youtube.19900429.xyz A

返回:

status: NOERROR

并且:

flags: aa

其中:

aa = Authoritative Answer

表示这是权威 DNS 直接返回的答案。

结果:

104.21.xx.xx
172.67.xx.xx

说明 Cloudflare 权威 DNS 已经存在正确记录。

所以 Tunnel 配置没有问题;DNS 创建成功。

四、奇怪现象:不同 DNS 返回不同答案

继续测试公共 DNS。

Cloudflare DNS

dig @1.1.1.1 youtube.19900429.xyz A

正常:

NOERROR
104.21.xx.xx
172.67.xx.xx

Google DNS

dig @8.8.8.8 youtube.19900429.xyz A

结果:

NXDOMAIN

也就是说,Google DNS 认为这个域名不存在。

但更加奇怪的是,另一台日本 VPS:

dig @8.8.8.8 youtube.19900429.xyz A

却返回:

NOERROR
104.21.xx.xx
172.67.xx.xx

同一个 8.8.8.8,为什么不同机器结果不同?

五、NSID 揭示 Google DNS Anycast

DNS 有一个很有用的功能:

NSID

可以显示实际响应你的 DNS 节点。

在美国 LAX:

dig @8.8.8.8 youtube.19900429.xyz A +nsid

返回:

NSID: gpdns-lax

而日本:

返回:

NSID: gpdns-nrt

说明 Google Public DNS 并不是一台服务器。

              8.8.8.8
                  |
        --------------------
        |                  |
   gpdns-lax          gpdns-nrt
   洛杉矶节点          东京节点

虽然用户看到的都是 8.8.8.8,但实际上不同地区访问的是不同节点。

六、SOA Serial 证明缓存没有更新

继续观察 SOA。

LAX 返回:

SOA Serial:
2408251833

而权威 DNS:

2408898100

两个版本不同。

这说明 gpdns-lax 仍然保存旧版本 DNS 信息。

因为之前查询过:

youtube.19900429.xyz

当时不存在。

于是 Google DNS 缓存:

NXDOMAIN

也就是:

这个域名不存在

七、DNS 不仅缓存存在,也缓存不存在

很多人知道 DNS 会缓存:

  • A 记录
  • AAAA 记录
  • CNAME

但是容易忽略 DNS 也会缓存:

NXDOMAIN

这叫 Negative Cache(负缓存)

第一次:

查询 youtube.19900429.xyz
↓
不存在
↓
缓存 NXDOMAIN

之后:

创建 DNS:

youtube.19900429.xyz
↓
现在存在

但是旧缓存还没有过期。

于是不同 DNS 节点出现不同结果。

八、这次排查最大的收获

整个排查过程:

浏览器无法访问
↓
怀疑域名
↓
检查 Cloudflare Tunnel
↓
检查权威 DNS
↓
发现递归 DNS 差异
↓
NSID 定位 Anycast 节点
↓
SOA Serial 判断缓存
↓
发现 Negative Cache
↓
DNS恢复

九、不要相信一次成功测试

这次还有一个非常重要的经验。

之前:

youtube.19900429.xyz

已经能够:

301 Redirect

跳转到:

videodownload.19900429.xyz

当时看起来网站已经恢复。

但实际上那只能说明当时测试所在的 DNS 解析路径已经更新。

并不代表全球所有 DNS 节点都已经恢复。

DNS 是分布式系统。

不同:

  • 地区;
  • 运营商;
  • Resolver;

可能拥有不同缓存状态。

所以一次成功访问,不代表所有用户都正常。