DNS

本文属于 DNS 相关的进阶文章,需要读者对 DNS 的基础有所了解。基础文章可以看看这篇

DNSSEC

DNSSEC(Domain Name System Security Extensions)是 DNS 协议的一个安全性拓展。其地位就相当于 HTTPS 于 HTTP。DNS 系统设计的时候,网络规模还很小,没有考虑到现在复杂的安全性问题。所以 DNS 的数据很容易被篡改。

中间人攻击

中间人攻击在中国是一种十分常见的 DNS 攻击技术。被某防火墙广泛应用。

Man-in-the-middle attacks

中间人攻击很容易理解,就是在用户的解析器和域名的解析服务器之间,有一个中间人,他会抢在解析服务器返回结果之前,抢先把一个错误的假结果伪装成原 DNS 请求的返回结果,然后由于 DNS 协议的缺陷,解析器会认为收到的第一个结果就是真的,抛弃后续收到的返回。

DNS 投毒

DNS 投毒是促使 DNSSEC 标准尽快推进的一个动力。

DNS poisoning

由于 DNS 通常都是基于无连接的 UDP 协议的,并且由于上面说的,DNS 解析器会认为接收到的第一个结果就是真实的,而抛弃后续的结果。所以,DNS 投毒就是利用一大批的肉鸡,向解析器发送伪装的假结果,让解析器误把假结果当作是正确的返回。从而使得诱导用户访问到错误的地方。

Resource Records

Resource Records 也就是所谓的资源记录,用于表示 DNS 请求的哪种类型的资源。其中最常用的是以下几种:

记录类型 含义
A 主机的 IPv4 地址记录
AAAA 主机的 IPv6 地址记录
CNAME 一个域名的别名
MX 域名的邮件域记录
NS 域名的权威解析服务器的地址

DNSSEC 加密

DNSSEC 为了保证请求结果的正确性,是通过对请求的资源记录使用非对称加密算法进行加密,然后把公钥放到 DNS 的请求结果中,私钥由权威解析服务器自己保留。然后解析器在拿到结果的时候,使用拿到的公钥,解密出 DNS 请求,来确认结果的正确性。为了实现这样的目的,DNSSEC 增加了几种资源记录:

记录类型 含义
DNSKEY 非对称加密算法中的公钥
DS 权威服务器使用的私钥的 hash
RRSIG 使用私钥对资源记录加密过的数据
KSK 用于解开 DNSKEY 资源记录使用的公钥
ZSK 用于解开其他资源记录使用的公钥

信任链

那么 DNSSEC 具体是如何利用上面的几种资源记录工作的呢。

DNSSEC

这是一个工作的信任链。假如我需要请求 example.com 的 A 记录,也就是想拿到它的 IPv4 地址。那么在 DNSSEC 体系中,我肯定需要拿到这个 A 记录的 RRSIG,也就是加密过的数据用于比较。为了解开这个加密过的数据,我肯定是得拿公钥。而在 DNSSEC 中,除了DNSKEY 公钥本身,其他资源记录都是使用 ZSK 进行加密的。所以这里我们需要拿到 ZSK 记录。同样的道理啊,ZSK 也是一种资源记录,和前面的 A 记录一样,为了保证我拿到的 ZSK 也是可信的,没有被篡改过的,我也得拿 DNSKEY ZSK 记录的 RRSIG,也就是加密数据。为了解开这个加密数据,我又得拿非对称加密算法中的公钥,这里我们为了解开 KEY,所以我们需要拿的就是 KSK 了。只要拿到这么些个数据,我们就可以解开所有被非对称加密算法加密过的数据,然后确保所有的数据的正确性了。

但是,这个 KSK 记录如何保证它的真实性呢?这里我们就不能继续在 example.com 的权威服务器里解决了,这里无法构成信任链,成了一个死循环。所以我们要请求 example.com 的上一层权威服务器,也就是 .com 的权威服务器,请求 example.com 的 KSK 的 hash 值,也就是上面提到的 DS 资源记录。通过比较这个 hash 值,我们就可以确定这个 KSK 的正确性。

当然,为了能够请求到正确的,未被篡改的 DS 记录,我们又得重复上述的过程,请求 DS 记录的 RRSIG 加密数据。 这样不断的重复上述过程,最终我们会如上图一样,一路走到根服务器,请求根服务器的 KSK。这样,信任链就走到根服务器的 KSK 记录了。而,全球十几个根服务器的 KSK 记录,是公开的,所有人都知道的,无法被篡改的,可信的。就这样,我们的信任链就建立起来了。

Anycast

Anycast 中文叫任播。其特性就是分布在全球的不同的服务器,使用同一个 IP 地址,然后通过动态路由协议,使得用户的请求会被路由到距离他们最近的一个服务器上去。通常用于实现 Public DNS 和 CDN。

Public DNS 就是我们经常见到的例如 114.114.114.114,或者 8.8.8.8 之类的 DNS 解析服务器。特点就是在全球各地,ping 这些服务器的延迟都非常低,都在几毫秒到三十几毫秒之间。

Anycast 就这么简单,全球各地部署多个机房,每个对外服务的机器都是用同一个 IP 地址,然后通过动态路由协议使得用户的请求可以被送到距离他们最近的服务器上去。

BGP

到这里我们来讲讲上面 Anycast 中,是如何实现动态路由,使得用户的请求可以被路由到最近的服务器上去的。

自治系统

自治系统(AS)是指在一个实体管辖下的所有网络。通常比如中国电信是一个自治系统,中国联通是一个自治系统,阿里云的所有服务器是一个自治系统。

边界网关协议

BGP 就是边界网关协议,用于在自治系统间进行路由的协议。在自治系统内部,通常使用 RIP 和 OSPF 进行动态路由。RIP 由于历史原因,已经基本被 OSPF 替代。

现实的互联网,其实是两层网络组成的。我们平常接触到的网络是属于一个自治系统,是一个网状的结构。然后我们上一层,也就是在自治系统外,又有一个网络,也就是所谓的骨干网。

BGP 面对的就是一个个的自治系统之间的路由问题。BGP 是一种基于 TCP 协议的动态路由协议,他通过启动时和周围的其他 BGP 邻居建立 TCP 连接的方式交换路由数据。

BGP 的路由策略有 13 条之多,所以十分复杂。其中最容易理解,最简单的就是 AS_PATH 的概念。AS_PATH 就是自治系统之间的路径。通常而言,路径越短的,肯定越优先选择。

所以我们来谈谈,Anycast 是如何利用 BGP 实现动态路由到最近的服务器这件事情的。

OpenDNS

一个 Anycast 系统,通常都会申请一个 ASN,也就是一个自治系统编号,也就是自己就是一个自治系统。然后在全球的各个服务器上,运行 BGP 程序。比如上图的 Miami 的服务器,他会和自己附近的自治系统建立 BGP 邻居关系,宣告自己负责的 IP 网段。更新附近 AS 的路由信息。由于 Miami 的服务器,在地理位置上距离最下面的 AS64496 最近,所以他们之间建立了一个直连的 BGP 邻居关系。这样 Miami 的机器和 AS64496 就只有一跳的距离。所以 AS64496 会把请求路由到最近的 Miami 的服务器上去。

参考资料

DNSSEC: An Introduction

Understanding DNSSEC

BIND DNSSEC Guide

List of DNS record types

Resource Record Types

A Brief Primer on Anycast

Anycast DNS - Part 1, Overview

Best Practices in
IPv4 Anycast Routing

How OpenDNS achieves high availability with Anycast routing

http://www.ccietea.com/