DNS SVCB/HTTPS 记录介绍

2021-05-04 ⏳4.7分钟(1.9千字)

IETF 正在为 DNS 引入一种新型记录,名为 SVCB/HTTPS。这个 SVCB/HTTPS 记录可以解决一些很重要的问题,我一直关注该标准的推进工作。今天就给大家介绍一下。

1987 CNAME 记录

DNS 系统最早在 1987 年就支持 CNAME 记录(RFC 1034)。CNAME全称 canonical name,中文意思是权威名称。举个例子,我们可以将a.example.com记录类型设为CNAME,将其值设为b.example.com。这样,我样在解析a.example.com的其他记录(比如 A/AAAA),实际上得到的是b.example.com的记录值。b.example.com就是a.example.com的权威域名。如果我们同时给a.example.comb.example.com设置了A/AAAA记录,那在查询的时候应该以哪个为准呢?从 CNAME 语义上讲,应该以b.example.com的记录为准。为了避免歧义,标准规定,如果一个域名设置了CNAME记录,就不能再设置其他类型的记录。所有的其他记录都要以CNAME指向的域名为准。

这就带来一个问题,你没法给 apex 域名设置CNAME。所谓 apex 域名就是根域名。比如 a.example.com 的 apex 域名就是 example.com。为什么不能给 example.com 设置 CNAME 呢?因为每个 apex 域名必须设置一条 NS 类型的记录。没有 NS 记录根本没法查询域名的其他记录(包括 CNAME 记录)。

2000 SRV 记录

DNS 系统在 2000 年引入了 SRV 记录(RFC 2782)。SRV 可以看成是 MX 记录的推广形式,理论上可以使用 SRV 记录发现其他服务的协议、端口、权重等信息。SRV 记录的结构如下:

_服务._协议.子域名 TTL IN SRV 优先级 权重 端口 目标域名

SRV 主要用在 SIP、LDAP 等协议。理论上我们也可以能过查询_http._tcp.example.com 的 SRV 记录来获取 http 服务的域名和端口信息,但是很少有 HTTP 客户端/浏览器实现这一功能。

2000-2015 CDN 的大规模使用

从 2000 年到 2015 年,CDN 技术得到大力推广。我们只需要将 www.example.com 设置一个 CNAME 记录指向对应 CDN 的域名就能完成全球加速。

但是,如果我们想使用 example.com 作为主域名(没法设置 CNAME 记录),我们可以:

总之,我们可以给根域名添加 CDN,但不是很方便。

2010-2020 多 CDN 部署

我们能不能给域名指定多家 CDN 呢?之前阿里的机房被挖断光纤影响了所有 CDN 客户。所以不能把鸡蛋都放在一个篮子里。

一种方法是设置两条 CNAME 记录。这多少有点违返标准,但能用。另一种是设置多条 A/AAAA 记录。但这要求不同的 CDN 节点可以相互替换。

2018 ESNI/ECH

随着 HTTPS/TLS 的日益普及,互联网的隐私问题得到极大的缓解。但是现在很多域名都会部署在云端,共享 IP,所以在建立 TLS 会话的时候需要协商使用哪个域名的证书。为此,TLS 支持一个名为 SNI 的扩展。浏览器在发起 TLS 连接的时候会将目标网站的域名以明文的方式发送给服务端。别有用心的人就可以监视用户所访问的网站。

所以SNI成了TLS最后一个隐私隐患。为此,人们提出 ESNI 方案来加密 SNI 信息。其基本原理就是通过 DNS 发布一个公钥(TXT 记录)。浏览器通过 DNS 查询到公钥对 SNI 加密,之后再发起 TLS 连接。最早只是加密 SNI 信息。最早只是加密 SNI 信息,后来发现还是有问题,索性将所有 ClientHello 信息都加密。这样 TLS 最后薄弱的一环也被修复了(标准还在制定中)。

不同的 CDN 肯定使用不同的 ECH 密钥。如果用 CDN A 的公钥加密并连接 CDN B 的 IP,这肯定会失败。现有的 DNS 系统也没有提供将不同记录绑定到一起的能力。

所以,有必要引入一种新型记录,其作用就是将服务的 IP 地址、ECH 公钥以及其他建立连接所需的信息关联起来,而且还要支持绑定根域名。这种新型记录就叫 Service Binding Record(SVCB)。

SVCB 记录概览

SVCB 记录的结构如下:

_端口._协议.子域名 TTL IN SVCB 优先级 目标域名 [服务参数...]

HTTPS 记录概览

https 记录是一类特殊的 svcb 记录,功能上没有任何区别,但不需要指定 _https 协议前缀。可以更好地支持通配符域名。比如*.example.com TTL IN HTTPS ...,妆容现有的 CNAME 语义。

如果一个域名设置了 HTTPS 记录,就说明该域名支持 HTTPS/TLS 访问(类似 HSTS)。

DNS 服务器本身不对 SVCB/HTTPS 作任何区分。

别名模式 AliasMode

以下记录是将 example.com 的 http 服务信息指向 svc.example.net 域名。

example.com. 7200 IN HTTPS 0 svc.example.net.

如果还在 example.com 监听了非标准的端口(比如 8443),则应该再设置如下记录

_8443._https.example.com. 7200 IN HTTPS 0 svc.example.net.

服务模式 ServiceMode

下面是两条服务模式的 HTTPS 记录

svc.example.net. 7200 IN HTTPS 2 svc3.example.net. alpn=h3 port=8003 ech=...
svc.example.net. 7200 IN HTTPS 3 svc2.example.net. alpn=h2 port=8002 ech=...

其含义是可以使用 QUIC 协议连接 svc3.example.net 的 8003 端口或者使用 HTTP/2 连接 svc2.example.net 的 8002 端口,并且可以使用 ech 信息对 TLS 握手信息作加密处理。

DNS 查询流程

  1. 客户端同时发起 A/AAAA 和 HTTPS 记录(增加 50% 的查询量)
  2. 如果 HTTPS 记录是别名模式,则需要查询指向域名的 A/AAAA 和 HTTPS 记录
  3. 客户端需要查询服务模式下目标域名的 A/AAAA 记录
  4. DNS 递归解析服务器可以通过附加字段提供这些记录
  5. ECH 记录的特殊要求:
    1. 客户端需要在收到 HTTPS 查询结果之后再发起 TLS 连接,以防服务端开启 ECH
    2. 如果 HTTPS 查询超时,客户端不能假设服务端不支持 ECH,以防降级攻击

IP 提示

SVCB/HTTPS 记录还可以添加所谓的 IP 提示信息,效果如下:

@ 7200 IN HTTPS 1 svc.cdn.example ipv4hint=192.0.0.1

IP提示信息是可选的。主要用于加速 dns 解析过程。如果 HTTPS 记录含有 ip 提示信息,则可以不用再查询目标域名的IP地址。

当前状态

其他随想

我为什么这么关注 SVCB/HTTPS 标准的进展呢?这和国内的网络管控有关。大家都知道,国内运营商会封锁 80/443 等标准端口。也就是说,你不能使用家庭宽带对外提供网站服务。HTTP/1.1 和 HTTP/2 只能工作在标准的 80 和 443 端口。但 HTTP/3 可以工作在任意端口。也就是说,你可以随便监听一个端口,再把端口信息更新到对应的 HTTPS 记录,支持的客户端就能访问对应的 HTTP/3 内容。到时候,大家又可以使用家庭宽带对外提供网络服务了。关键是苹果对 SVCB/HTTPS 非常支持,我相信 SVCB/HTTPS 一定能很快完成标准化。

当然了,国家肯定会继续管控互联网。到时候一定会对 SVCB/HTTPS 查询进行干扰。这个只能使用 DNS over HTTPS/TLS 加以应对了。好在现在主流的系统都在加快部署 DoH/DoT,再配合 ECH 技术,应该很难阻止大家对外提供网络服务了。