#5 关于 DNS(历史和未来)

2018-05-02

历史

从阿帕网(ARPANET)时代一直到互联网的早期,网络节点比较少,都是通过本地 hosts 文件来实现主机名到 IP 地址的映射。

根据维基百科的信息,斯坦福研究所(SRI-NIC,Stanford Research Institute Network Information Center)负责维护一个公共 HOSTS.TXT 文件(RFC 606、RFC 608),各个网络节点定期通过 FTP 下载最新版本进行同步。

PS:这个时候如果有主机名重复了谁来管?打电话过去让他们改名?

这套机制一直运行了十几年。随着互联网规模扩大,公共 HOSTS.TXT 文件变得越来越大,变化也越来越频繁。每当有新的主机加入网络、IP 地址发生变化,都需要重新同步整个文件。

这种模式存在几个明显问题:

  • 中央管理机构压力越来越大;
  • 全网频繁同步效率较低;
  • 主机数量增长后难以维护;
  • 名称冲突和管理问题越来越复杂。

后来人们开始设计域名和域名相关的公共设施。RFC 819《The Domain Naming Convention for Internet User Applications》和 RFC 881《The Domain Names Plan and Schedule》提出了域名系统的早期设计思路。

最终在 1983 年形成了下面两个 RFC 文档:

  • RFC 882, DOMAIN NAMES - CONCEPTS and FACILITIES
  • RFC 883, DOMAIN NAMES - IMPLEMENTATION and SPECIFICATION

几年后(1987),正式的 DNS 标准 RFC 1034 和 RFC 1035 推出。我们现在常见的 A / MX / NS / CNAME / PTR / SOA 等记录类型都是在这个标准中定义的。

  • RFC 1034, Domain Names Concepts and Facilities
  • RFC 1035, Domain Names Implementation and Specification

这套标准一直运行到现在。虽然几十年来不断增加新的记录类型、支持国际化域名(IDN)、引入 DNSSEC、安全加密传输等扩展能力,但其核心设计思想基本没有改变:

  • 分层命名;
  • 分布式管理;
  • 缓存加速;
  • 递归解析。

DNS 可以说是互联网历史上寿命最长、最成功的基础设施之一。并且,在可以预见的未来,DNS 仍然会是互联网最重要的基础设施之一。

DNS over TCP

最初 DNS 主要运行于 UDP 53 端口。RFC 1035 同时规定了 TCP 支持,最早 TCP 主要用于:

  • 区域传送(AXFR);
  • 超大响应数据返回。

今天绝大多数 DNS 服务仍同时支持 UDP 和 TCP。

DNS 的管理权问题

互联网本是美国国防部高级研究计划局(DARPA)的产物,早期域名分配几乎由南加州大学教授乔恩·波斯特尔一人代管。1998年,克林顿政府为避免让联合国下属的国际电信联盟(ITU)——一个由各国政府和官营电信主导的机构——接管互联网,刻意设计了一条"私有化"路线:成立非营利组织 ICANN,负责全球域名系统(DNS)和顶级域名分配,与美国商务部签合同但通过"私人身份"运作,以此保持互联网开放、不受单一政府直接操控。然而 ICANN 总部在加州、受美国法律管辖,全球13台根服务器多数也在美国手里,等于事实上的互联网域名最高仲裁者仍是美国。这让包括中国、俄罗斯在内的大量国家长期不满,伊拉克战争期间".iq"域名被暂停解析一事更被视为美国"悬剑在手"的象征。

2013年斯诺登曝光美国大规模监听后,国际社会对"美国垄断互联网命门"的反弹到达顶点,联合国层面甚至出现推动另建政府主导治理体系的呼声。为消解这一合法性危机、顺应互联网去中心化叙事,奥巴马政府于2014年宣布启动移交程序——将美国商务部对 ICANN 的"合同监管权"解除。2016年3月,ICANN 正式提交脱离美国政府联系的过渡计划。

真正的问题不在"美国是否善良",而在于:这根命门本来就不该由任何一个国家独握。移交的本质是把制度合法性从"美国庇护下的开放"转向"多方利益攸关体(multi‑stakeholder)自我维持的透明与问责"。但争议也正在于此——保守派担心脱离美国后,ICANN 会被威权国家通过政府咨询渠道逐步蚕食;支持者则认为根服务器的分布式结构和自下而上的共识机制本身就是防火墙。美国让出的不是善意,而是一张越来越护不住的垄断椅子。

新的发展

年份 技术/标准 RFC 主要创新
1983 DNS 概念与实现 RFC 882, RFC 883 首次提出 DNS,替代 HOSTS.TXT
1987 DNS 正式标准 RFC 1034, RFC 1035 建立现代 DNS 架构,至今仍是核心基础
1997 动态更新(DDNS) RFC 2136 DNS UPDATE 接口,允许客户端动态修改 DNS 记录
1998 NOTIFY RFC 1996 主 DNS 主动通知从 DNS 更新,不用定时轮询
1999 IXFR(增量同步) RFC 1995 只同步变更部分,降低 Zone Transfer 成本
1999 EDNS0 RFC 2671 -> 6891 打破 UDP 512 字节限制(拓展到 KB 级别)
2000 SRV 记录 RFC 2782 DNS 服务发现机制
2003 国际化域名(IDNA) RFC 3490 系列 支持中文、日文等 Unicode 域名
2005 DNSSEC RFC 4033/4034/4035 DNS 数据签名与验证
2008 Source Port Randomization RFC 5452 提高抗缓存投毒能力
2010 NSEC3 RFC 5155 防止 DNSSEC Zone Walking(枚举所有域名)
2011 CAA 记录 RFC 6844 -> 8659 允许域名所有者声明:仅承认某些 CA 给该域名颁发的证书
2013 DNS Cookies RFC 7873 防御 DNS 放大攻击
2016 DNS over TLS (DoT) RFC 7858 DNS 加密传输
2018 QNAME Minimization RFC 7816 降低 DNS 查询隐私泄露
2018 DNS over HTTPS (DoH) RFC 8484 DNS 走 HTTPS 通道
2020 SVCB / HTTPS RR RFC 9460 服务发现和 HTTPS 配置优化
2021 Oblivious DoH (ODoH) RFC 9230 隐藏客户端 IP
2022 DNS over QUIC (DoQ) RFC 9250 基于 QUIC 的 DNS
2023 DDR RFC 9462 自动发现 DoH/DoT 服务
  • DDNS

RFC 2136: Dynamic Updates in the Domain Name System (DNS UPDATE)

复用 DNS 报文格式,但把 Opcode 设为 5(UPDATE),直接在 UDP/TCP 53 端口上向权威 DNS 服务器发送增删改指令(四段式结构):

作用
Zone​ 声明你要改哪个 zone(如 home.arpa.或 example.com.)
Prerequisite​ 前置条件——"只有当 host A == 1.2.3.4时才更新"(原子 compare-and-swap,防竞态)
Update​ 实际操作——ADD / DELETE 某条 RR
Additional​ 认证载体——通常是 TSIG(RFC 2845)或 GSS-TSIG(RFC 3645, Kerberos)

注意:DDNS 本身可以说是一个需求,就是动态调整 DNS,虽然 RFC 2136 经常被称之为 DDNS,但实质是 DDNS 的一种技术方案。
有一些脚本或者路由器插件轮询 IP 然后通过云服务商 API 来动态修改 DNS 记录,在很多场景下也被称之为 DDNS,不要混淆。
云服务商 DNS 都不对外提供 UPDATE 操作,它们通过 HTTP API(IAM/Key 鉴权)来提供 DNS 记录更新。

RFC 2136 DDNS 的典型阵地是你自有/私有部署的受控权威服务器(BIND、PowerDNS、Windows AD DNS、Infoblox 等),其中最常见生产场景是:
客户端发起 DHCP 请求时会带上 hostname(Option 12),DHCP 服务器分配地址后,通过 TSIG/GSS-TSIG 向可写 zone 发 UPDATE,自动注册内部名 A 记录及对应 PTR(反向区也要可被管理)。

  • DNSSEC
    安全

  • DNSCrypt
    2011 年提出。
    DNSCrypt 在 DNS 请求和解析服务器之间建立加密通信,并验证服务器身份。
    它并非 IETF 标准,但曾经被 OpenDNS 等服务广泛采用。

  • DNS over TLS(DoT
    2016 年成为标准。RFC 7858 Specification for DNS over Transport Layer Security (TLS)
    DNS 全程加密,默认使用 TCP 853 端口。

  • DNS over HTTPS(DoH
    2018 年成为标准。RFC 8484 DNS Queries over HTTPS (DoH)
    特点:

  • 基于 HTTPS;
  • 默认使用 HTTPS 443 端口;
  • 更容易穿透网络限制;
  • 可以复用现有 Web 基础设施。

  • DNS over QUIC(DoQ
    RFC 9250。
    基于 QUIC,兼具 UDP 的低延迟和 TLS 的安全性。

  • DNS over Tor
    通过 Tor 网络转发 DNS 查询,其主要目标是隐藏客户端来源地址,提高匿名性。
    它不是 DNS 标准协议,而是一种部署方案。

  • Oblivious DNS-over-HTTPS(ODoH
    ODoH 在 DoH 基础上增加代理节点,确保代理服务器看不到查询内容,DNS 服务器看不到客户端 IP,从而进一步提升隐私保护能力。

参考资料与拓展阅读

#4 域名查询 dig

2017-06-02

dig(Domain Information Groper)是 DNS 查询与诊断工具,功能比 nslookup 更强大,是 Linux 运维、网络工程和 DNS 管理中最常用的调试工具。它能够查询各种 DNS 记录、追踪完整解析过程、指定 DNS 服务器、查看权威应答和调试 DNSSEC 信息,是分析域名解析问题的标准工具。

命令 作用
dig qq.com 查询域名 A 记录
dig AAAA qq.com 查询 IPv6 地址记录
dig MX qq.com 查询邮件服务器记录
dig NS qq.com 查询名称服务器记录
dig TXT qq.com 查询 TXT 记录(SPF、DKIM 等)
dig CNAME qq.com 查询 CNAME 记录
dig -x 8.8.8.8 IP 反向解析(PTR 查询)
dig qq.com @8.8.8.8 使用指定 DNS 服务器查询
dig +short qq.com 仅输出结果,便于脚本处理
dig +trace qq.com 从根服务器开始追踪完整解析链路
dig ANY qq.com 查询所有可返回的记录(很多 DNS 已限制)
dig +noall +answer qq.com 仅显示 Answer 区域
dig +dnssec qq.com 查询 DNSSEC 相关信息
dig SOA qq.com 查询 SOA(区域授权)记录

dig -h 输出太多参数了,我就不贴出来了。

#3 中文域名

2016-06-06
$ curl -v "http://成都大运会.网址"
* Input domain encoded as `UTF-8'
* About to connect() to xn--6oqv8vrnhtp3c7hb.xn--ses554g port 80 (#0)
*   Trying 202.173.11.233... connected
* Connected to 成都大运会.网址 (202.173.11.233) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: xn--6oqv8vrnhtp3c7hb.xn--ses554g
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: openresty/1.21.4.3
< Date: Sat, 16 Dec 2023 06:09:33 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 61
< Connection: keep-alive
< Location: http://www.2021chengdu.com
<
<a href="http://www.2021chengdu.com">Moved Permanently</a>.

* Connection #0 to host 成都大运会.网址 left intact
* Closing connection #0

中文域名,中文顶级域名都已经支持很多年了,虽然看到不多。

上面示例中的域名 成都大运会.网址 实际上在域名系统中是以 xn--6oqv8vrnhtp3c7hb.xn--ses554g 形式存在的。
这种编码方式叫做 Punycode,非 ASCII 字符会被按照 Unicode 编号转换成 ASCII 字符。

国际化域名

域名系统中允许的字符集基于 ASCII,不允许以母语或字母表示多种语言的名称和单词。
ICANN 批准了国际化域名(IDNA)系统,该系统通过一种称为 Punycode 的编码将应用程序用户界面中使用的 Unicode 字符串映射到有效的 DNS 字符集。

Example of Greek IDN with domain name in non-Latin alphabet: ουτοπία.δπθ.gr (Punycode is xn--kxae4bafwg.xn--pxaix.gr)

Punycode

'I❤️U'.encode('punycode')
b'IU-ony8085h'

'baidu.com'.encode('idna').decode()
# baidu.com
'中国.com'.encode('idna').decode()
# 'xn--fiqs8s.com'
'编程.中国'.encode('idna').decode()
# 'xn--9nz56h.xn--fiqs8s'

先提取 ASCII 字符,再编码非 ASCII 字符。

#2 DNS 反解(反向解析)

2014-11-01

在日常网络排查中,我们经常会把域名解析成 IP 地址,例如将 www.example.com 解析为 93.184.216.34。这个过程叫做正向解析(Forward DNS Lookup)
而 DNS 反解(Reverse DNS Lookup)则正好相反:根据 IP 地址查询对应的域名。

-> % dig +noall +answer -x 8.8.8.8
8.8.8.8.in-addr.arpa.   17864   IN  PTR dns.google.

这里表示 IP 地址 8.8.8.8 对应的主机名为 dns.google

原理

核心:DNS PTR(Pointer)记录。

DNS 设计了一套特殊域名空间:in-addr.arpa,比如要查询 120.48.97.18 的反解记录,就去查询域名 18.97.48.120.in-addr.arpa.(IPv4 地址倒序)的 PTR 记录。

可以通过以下命令观察全过程:

dig +trace -x 8.8.8.8

IPv6 地址反解

只是域名空间改成了 ip6.arpa 而已,然后地址变长了一些,不再是 4 段,而是 32 段。

IPv4 地址 32 bits,每段 8 bits(0-255),分成 4 段。
IPv6 地址 128 bits,每段 4 bits(0-f),分成 32 段。

-> % dig +noall +answer -x 2001:4860:4860::8888
8.8.8.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8.4.0.6.8.4.1.0.0.2.ip6.arpa. 9710 IN PTR dns.google.

注意

  1. 多数 IP 没有反向解析。
  2. 正向解析和反向解析是由不同管理员独立配置,不一定对应。
  3. PTR 记录通常由 IP 地址拥有者配置,普通人无法直接操作。
    如果是云服务商提供的 IP,要看他们是否提供了 “反向解析” 或 “PTR Record” 配置功能,如果没有就只能提交工单,找售后了。

应用场景

核心的应用场景:邮件系统会检查发信 IP 是否存在合法 PTR 记录。

邮件系统经常要求正反向一致验证,英文叫做 Forward Confirmed Reverse DNS (FCrDNS)。
我随便找了一封阿里云的邮件,根据 Received 中给的发信 IP 做一个检验:

-> % dig +noall +answer -x 47.90.197.163
163.197.90.47.in-addr.arpa. 7200 IN PTR out197-163.us.a.dm.aliyun.com.
-> % dig +noall +answer out197-163.us.a.dm.aliyun.com.
out197-163.us.a.dm.aliyun.com. 60 IN    A   47.90.197.163

这里面 47.90.197.163 和 out197-163.us.a.dm.aliyun.com. 就是能够互相对应的。

很多邮件服务商会将 FCrDNS 作为信誉评估的重要指标,如果没有对应上,邮件可能被判定为可疑来源。

除此之外,反解还可辅助判断 IP 归属:

  1. 运维排查异常连接时手动反查;
  2. 部分服务写日志时会自动记录 PTR 主机名;
  3. 少数系统也用于访问控制。

参考资料与拓展阅读

#1 nslookup

2014-10-23

nslookup 是用于查询 DNS(域名系统)信息的命令行工具,可查看域名对应的 IP 地址、邮件服务器、名称服务器等记录。它支持指定 DNS 服务器、查询不同记录类型,并可用于排查域名解析问题。Linux、macOS 和 Windows 都提供该工具,是网络运维与故障诊断中最常用的 DNS 调试命令之一。

PS C:\Users\nosch> nslookup /?
用法:
   nslookup [-opt ...]             # 使用默认服务器的交互模式
   nslookup [-opt ...] - server    # 使用 "server" 的交互模式
   nslookup [-opt ...] host        # 仅查找使用默认服务器的 "host"
   nslookup [-opt ...] host server # 仅查找使用 "server" 的 "host"1
PS C:\Users\nosch> nslookup
默认服务器:  UnKnown
Address:  192.168.1.1

> help
命令:   (标识符以大写表示,[] 表示可选)
NAME            - 打印有关使用默认服务器的主机/域 NAME 的信息
NAME1 NAME2     - 同上,但将 NAME2 用作服务器
help or ?       - 打印有关常用命令的信息
set OPTION      - 设置选项
    all                 - 打印选项、当前服务器和主机
    [no]debug           - 打印调试信息
    [no]d2              - 打印详细的调试信息
    [no]defname         - 将域名附加到每个查询
    [no]recurse         - 询问查询的递归应答
    [no]search          - 使用域搜索列表
    [no]vc              - 始终使用虚拟电路
    domain=NAME         - 将默认域名设置为 NAME
    srchlist=N1[/N2/.../N6] - 将域设置为 N1,并将搜索列表设置为 N1、N2 等
    root=NAME           - 将根服务器设置为 NAME
    retry=X             - 将重试次数设置为 X
    timeout=X           - 将初始超时间隔设置为 X 秒
    type=X              - 设置查询类型(如 A、AAAA、A+AAAA、ANY、CNAME、MX、
                          NS、PTR、SOA 和 SRV)
    querytype=X         - 与类型相同
    class=X             - 设置查询类(如 IN (Internet)和 ANY)
    [no]msxfr           - 使用 MS 快速区域传送
    ixfrver=X           - 用于 IXFR 传送请求的当前版本
server NAME     - 将默认服务器设置为 NAME,使用当前默认服务器
lserver NAME    - 将默认服务器设置为 NAME,使用初始服务器
root            - 将当前默认服务器设置为根服务器
ls [opt] DOMAIN [> FILE] - 列出 DOMAIN 中的地址(可选: 输出到文件 FILE)
    -a          -  列出规范名称和别名
    -d          -  列出所有记录
    -t TYPE     -  列出给定 RFC 记录类型(例如 A、CNAME、MX、NS 和 PTR 等)
                   的记录
view FILE           - 对 'ls' 输出文件排序,并使用 pg 查看
exit            - 退出程序

常用命令清单

命令 作用
nslookup qq.com 查询域名的 A 记录(IPv4 地址)
nslookup -type=AAAA qq.com 查询 AAAA 记录(IPv6 地址)
nslookup -type=MX qq.com 查询邮件服务器记录
nslookup -type=NS qq.com 查询权威名称服务器记录
nslookup -type=TXT qq.com 查询 TXT 记录(如 SPF、DKIM)
nslookup 8.8.8.8 反向查询 IP 对应的域名
nslookup qq.com 1.1.1.1 使用指定 DNS 服务器进行查询
nslookup 进入交互模式,可连续执行多次查询
set type=MX 在交互模式中设置查询类型为 MX
server 8.8.8.8 在交互模式中切换 DNS 服务器
exit 退出交互模式