坑边闲话:DNS 是现代互联网的基石,在我看来 DNS 比 TCP/IP 还要重要。没有 TCP/IP 还可以用其他通信协议,但是没了 DNS,互联网就要熄灭了。

1. DNS 简介与 DNS 劫持、污染·

1.1 DNS 常识·

DNS 的全称是 Domain Name System,也就是域名系统。原则上,我们这套互联网基于 TCP/IP,也就是可靠传输加全球路由寻址。然而,因为人类不方便记忆 IP 地址,所以产生了域名系统。比如要访问谷歌,你第一想到的是 google.com 而不是 google 的 IP 地址。毕竟,人类并不能准确记忆大量的数字地址。将 IP 地址与域名通过 DNS 联系起来,是个非常聪明的办法。

将域名对应的 IP 地址找出来的过程,叫做 DNS 查询。从这里你就看出来了,DNS 查询实际上是个应用层协议。我们往 DNS 服务器的 53 端口发送一个 DNS 解析请求,然后 DNS 服务器把域名对应的 IP 地址返回给我们,这样我们就可以愉快地使用 IP 地址进行路由通信了。有过编程经验的同学应该清楚,在写某些记录的时候你可以用域名代替 IP 地址,这时候系统会自动为我们做一次 DNS 查询。这个查询一般是调用了操作系统 libc 库中的 getaddressinfo 函数。当然,如果你用了 Clash 这种代理软件,可能你的 DNS 请求会被 Clash 拦截,然后 Clash 用自己实现的域名解析模块帮你解析,然后返回 IP 地址给你,这样就不需要操作系统参与了。这个过程叫做 DNS 劫持。

1.2 DNS 记录类型·

在正式介绍之前,我们要讲一下 DNS 记录类型。

  • 比如有普通的主机记录,也叫 A 记录,它就是普通的 IPv4 地址记录。
  • 与此对应的还有 IPv6 主机记录,也叫 AAAA 记录。因为 IPv6 的地址长度是 IPv4 的四倍,所以用四个 A 来标识。
  • 此外还有 C-NAME 记录,也就是将域名指向另一个域名。这种解析记录在反向代理环境下非常有用。
  • 此外还有很多种记录类型,因为不太常用,我们就直接跳过。有兴趣的小伙伴可以自己学习一下。

看到这里,敏锐的同学应该发现了,域名既然已经写到了某些软件的源代码里,那么如果域名解析发生了错误,软件运行就会产生异常。的确,域名解析的速度和正确性,将直接决定你的上网体验。然而,糟糕的事情是域名解析采用了 UDP 明文传输,也就是你的网络提供商能看到你请求了哪些域名解析。如果某些神秘网站不允许被访问,那么你的运营商就会直接返回一个错误的地址给你,然后你就无法访问真实的网站了。这就是 DNS 污染技术。

现在有越来越多的讨论在针对这种传统的域名解析服务,比如有人提倡用 HTTPS 或 TLS 做域名解析系统,也就是 DoH 和 DoT,有人认为这样将会完全避免 DNS 污染问题。然而 TLS 里面有一个 SNI 字段用来标识 SSL 证书,这个字段是没办法隐藏的,隐藏了你就没法向 web 服务器索要正确的证书了。某些有心人可以通过侦听你的 SNI 字段来精准地识别你的网络请求,这在某些场景下简直是屡试不爽。当然,现在也有某些 DNS 服务商能对 SNI 字段进行加密,不过加密本身就是一种特征,防火墙可以直接把 SNI 加密的流量阻断。所以,真是令人很无奈。

墙是一种艺术。讲了这么多,希望读者同学能明白 DNS 的重要性,以及我们的 DNS 并不安全。如果有人故意耍坏心思,你的 DNS 就有可能被污染。

2. 如何使自己的 DNS 更安全?·

那么接下来的内容,我们会略微讲解一下如何让 DNS 变得更快速、更干净、更安全

2.1 更快速·

快速可能是最容易做到的。因为 DNS 的迭代结构,我们可以很轻松地使用私有的 DNS 服务器缓存自己常用的域名解析结果,然后按照一定的替换原则动态更新这组缓存。用了这种缓存技术,你常用的域名解析起来简直飞快。

常用的本地 DNS 服务器是 AdGuardHome.

2.2 更干净·

更干净这个目标是很困难的,因为我们不容易定义什么是干净。

2.2.1 就近解析·

比如京东的 Web 服务器有很多,可能有的在中国北方,有的在中国南方,有的在中国香港。如果身在北京的你每次请求京东的地址,得到的都是京东香港的地址,那你肯定很抓狂,因为

  • 北京到香港可是有着相当的距离,网络延迟比较大,
  • 香港有货的产品,不一定能寄送到北京

所以解析结果离你越近,体验一般会越好,服务也更加贴近真实需求。这个相对更容易做到,运营商为我们提供的域名解析就可以做到这一点,因为当地运营商很清楚京东北京的服务器在哪里、IP 地址是多少。因此,访问国内网站还是向运营商的域名服务器请求解析比较好。

2.2.2·

然而,当你要访问谷歌学术时,因为谷歌被 GFW 拦截了,所以你的运营商不会给你返回谷歌学术的正确地址。那么这时候应该怎么办呢?爱动手的同学一定用过 Clash 等软件。因为被封锁的 IP 地址一般都是国外的,所以我们可以把国内的 IP 地址、域名列一个清单,凡是在这个清单上的域名解析请求,就向本地运营商请求查询。不在这个清单上的域名解析,就通过 DoT 或 DoH 向安全无污染的域名解析服务器请求。你可能会想,既然都能访问干净无污染的域名解析服务器了,为什么不干脆把所有的解析请求都发给它们呢?这是因为这些域名解析可能解析出了离你很远的 IP 地址,甚至是国外的 IP 地址,这样你访问 QQ 音乐、网易云等国内服务就首先版权限制,体验也是很不好的,甚至哔哩哔哩小破站会因为你的地址经常变化而封锁你的大会员。

获得了正确的地址之后,我们可以查看一下这个地址是否在清单里,如果不在,就说明这个是国外的地址,就走 Clash 隧道。因为一般的代理软件会将域名封装到代理数据包里,因此你的目的 IP 地址在代理服务器上可能会被替换,因为代理服务器一般不会根据你代理客户端查出来的 IP 地址进行转发。这是为什么呢?聪明的你可以想一想。答案是这样的,因为代理服务器远在国外,它虽然能不受限制地访问互联网,但是你的 Clash 查出来的 IP 对代理服务器来说可能也不太合适,这就会发生之前我们说的那种 IP 地址离你很远的问题。

简单小结一下就是远端服务器连接的 IP 地址与你 Clash 代理客户端解析出来的地址可能没有关系,Clash 解析是为了分流,而代理服务器再次解析是为了更快速地转发。

2.2.2 Clash 的普通模式与 Fake-IP 模式·

通过这个清单和代理服务,我们就可以获得谷歌学术的正确地址,并通过代理来访问谷歌学术了。这里我们简单介绍一下 Clash 的代理模式。上面我们讲到,Clash 支持传统的 re-direct 代理,原理就是通过判断域名是国内还是国外,然后分别向 name serverfallback 回落地址进行域名解析请求,随后再把解析结果返回给局域网里的设备。这个过程因为要等到 Clash 的域名解析模块完成解析才能给出域名响应,因此我们要访问谷歌学术的客户端就得一直等域名解析结果。所以有人提出了 Fake IP 模式,也就是假 IP 地址。首先,局域网里的一台电脑要访问谷歌学术,这时 Clash 通过域名解析劫持,直接返回一个谷歌学术的假地址给你,然后你就可以准备建立连接了。而在你准备建立连接的同时,Clash 可以进行域名解析,等到你以假 IP 地址为目的地的转发请求发给路由器时,Clash 再用真地址替换掉假地址。因为这个过程里,浏览器在准备向假地址建立连接的同时 Clash 完成了一些域名解析工作,所以 Fake IP 模式会比 re-direct 高效一些。不过这也是有代价的。因为 Fake IP 模式返回给用户的全都是假地址,而域名的真地址与假地址之间的映射存放在路由器上,所以路由器在崩溃重启之后,因为浏览器的缓存里还是假地址,而路由器上真假地址之间的映射不复存在了,所以你在缓存失效之前无法上网。

2.3 更安全·

俗话说,没有任何一个安全专家敢给某计算机系统的安全性打包票,另外也有人说,安全不绝对就是绝对不安全。但是如果你只是想让 DNS 变得安全,那我们还是有很多方法的。首先说一个绝对安全的方案,那就是使用跳板机。你可以先用 WireGuard 建立一个到跳板机的 VPN 链路,然后所有的流量从跳板机走。因为你的流量经过了跳板机做 S-NAT,所以出口都是跳板机的 IP 地址,你的本地路由器地址就被保护了。在跳板机的日志不被窃取的情况下,你的 DNS 以及其他流量都是安全的。

2.4 IPv6 疑云·

最后我们说一下 IPv6 的配置。古往今来,很多人都认为 IPv6 会影响代理的效果。然而非也,虽然 IPv6 不太常用,但是微软对 IPv6 非常重视,在有 IPv6 连接的情况下,系统会优先使用 IPv6. 然而现在很多代理节点并不支持 IPv6,这就导致你的流量只能走 IPv6 默认网关而非代理服务器,所以你就无法使用谷歌学术了。另外,在 Fake IP 模式下,因为 Clash 会直接返回一个假 IPv4 地址给你,而这个过程是有缺陷的。因为一旦你的目的地址是 IPv6 地址的 AAAA 资源记录,那么返回给你的 IPv4 虚假地址就会使你采用 IPv4 协议进行通信,你这边准备好了用 IPv4,而回头 Clash 发现你其实是要用 IPv6,这能通信才怪呢。

这个问题的解决方案太复杂了,既然是双栈的网络,那么必然就有两个网关,一个 IPv4 网关,一个 IPv6 网关。在 IPv6 网络正常时,必然采用 IPv6 网关作为默认网关,因为 Windows 认为 IPv6 权限高。此时可以把 Google 的 IPv6 DNS 作为默认 DNS,这样能绕过 Clash Fake-IP 模式,谷歌 IPv6 的 DNS 查到 IPv4 地址就走 Clash,查到 IPv6 地址就走默认 IPv6 网关。

3. 公共 DNS 服务器·

腾讯云·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# dnspod IPv4

119.29.29.29

#dnspod IPv6

2402:4e00::

# DoH
https://1.12.12.12/dns-query
https://120.53.53.53/dns-query
https://doh.pub/dns-query

# DoT
dot.pub
1.12.12.12
120.53.53.53

参考

1
计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\PowerPoint\Options

ExportBitmapResolution Dword32 = 300

谷歌·

1
2
3
4
5
6
7
8
9
10
11
8.8.8.8
8.8.4.4

2001:4860:4860::8888
2001:4860:4860::8844

# 某些设备要求 IPv6 地址的所有八个字段都必须具有显式值,并且它们不接受缩略的 :: IPv6 地址语法。对于此类设备,请输入:


2001:4860:4860:0:0:0:0:8888
2001:4860:4860:0:0:0:0:8844