系统设计 / DNS · 层级、委任、缓存,以及不存在的「浸透」 / 逆向解析:地址反查名字 待审核 6 / 11
PTR · in-addr.arpa · ip6.arpa

逆向解析:地址反查名字

「从 203.0.113.40 查出它叫什么」这件事,DNS 里不存在专门的机制。它被实现成另一棵名字树:把地址逆序写成域名,挂在一个保留的后缀之下,然后照常查一条 PTR 记录。

1 · 地址写成域名

IPv4 的四个八位组逆序,每组一个 label,加后缀 in-addr.arpa.

203.0.113.40   →   40.113.0.203.in-addr.arpa.

IPv6 的 16 个字节展开成 32 个 nibble(每个 4 位),逆序,每个 nibble 一个 label,加后缀 ip6.arpa.。所以 IPv6 的逆向名恒为 34 个 label,与地址的文本写法多短无关——:: 只是文本压缩。

图 1-1 · 地址到逆向名的换算,以及逆向名上每一处 label 边界对应的委任粒度。可改地址观察 IPv4 与 IPv6 在 label 数与委任粒度上的差别。

2 · 为什么要逆序

因为 DNS 的委任只能自右向左收窄,而 IP 地址的网络号在左。

不逆序的话,「把 203.0.113.0/24 这一段的逆向解析交给某个组织」这件事就无法表达成一次 DNS 委任——203.0.113 这三段在正序下是名字的前缀,而委任只能切后缀。逆序之后它成了后缀,于是 RIR 把地址段分配给 ISP、ISP 再分给客户这条链,可以逐级映射成 in-addr.arpa 之下的逐级委任。

代价是委任粒度被钉在 label 边界上:IPv4 每 8 位一刀,IPv6 每 4 位一刀。

注 · 于是 /25 这类非八位组对齐的网段就没有对应的 label 边界可切。RFC 2317 给了一个绕法:在 /24 的 zone 里为每个地址写一条 CNAME,指到一个人为构造的子名字(如 40.0-25.113.0.203.in-addr.arpa.),再把那个子名字委任出去。这是个公认的 hack——它借 CNAME 模拟了一次本不存在的委任,代价是每个地址都要一条 CNAME。

3 · 正向与逆向的维护者

这是逆向解析最要紧的一点,也是最常被误解的一点:

正向记录由域名的持有者写。mail.vega.dev. IN A 203.0.113.40 落在 vega.dev 这个 zone 里,谁持有这个域名谁说了算。

逆向记录由地址段的持有者写。40.113.0.203.in-addr.arpa. IN PTR mail.vega.dev. 落在 113.0.203.in-addr.arpa. 之下,谁持有这段地址谁说了算——通常是云厂商或 ISP,不是域名的持有者。

两者之间没有任何协议层的一致性约束。可以只有正向没有逆向(绝大多数云主机的默认状态)、只有逆向没有正向、或者两者指向完全不相干的名字。用一台云主机搭邮件服务器时那一步「联系厂商设置 PTR」,正是因为这条记录不在域名持有者的 zone 里。

警示 · PTR 的 RDATA 是一个名字,但解析到此为止——不像 CNAME 那样继续。而且它不构成任何身份证明:任何能写自己那段逆向 zone 的人都可以让 203.0.113.40 声称自己叫 mail.example.com。因此「反查得到的名字」不能单独当作认证依据,要用就得做前向确认:反查得名字,再正查那个名字,看是否回到原地址(这套做法叫 FCrDNS,forward-confirmed reverse DNS)。

4 · 实际用途

逆向解析的用途比人们以为的窄,而且集中在几处:

邮件反垃圾是最硬的一处。多数收信方会检查发信 IP 是否有 PTR,以及是否通过前向确认;缺 PTR 的主机发出的邮件被拒或降权很常见。这也是逆向解析唯一一处「不设置就真的不能工作」的场景。

日志与诊断是最常见的一处。traceroutessh 的连接日志、Web 服务器的访问日志都会做反查,把地址换成可读的名字。

反过来,ssh 之类工具的反查也是登录变慢的一个经典原因:逆向 zone 不存在或其权威服务器不响应时,反查要等超时。sshdUseDNS no 关掉的就是它。

5 · 参考文献

  1. Mockapetris, P. (1987). Domain Names — Implementation and Specification (RFC 1035). IETF. §3.5 定义 IN-ADDR.ARPA 的构造方式。
  2. Thomson, S., Huitema, C., Ksinant, V., & Souissi, M. (2003). DNS Extensions to Support IP Version 6 (RFC 3596). IETF.(ip6.arpa 的 nibble 展开。)
  3. Eidnes, H., de Groot, G., & Vixie, P. (1998). Classless IN-ADDR.ARPA Delegation (RFC 2317). IETF.
  4. Howard, L. (2018). Reverse DNS in IPv6 for Internet Service Providers (RFC 8501). IETF. (IPv6 逆向 zone 的规模问题与几种应对。)