昨天有人在问 DNS 的事情:
iN 的回复就是 DNS 里面的 " 水可深了 "。对于网络这种东西还是之前和大家说过的概念,没什么神话也没什么平替和投机取巧的地方。一切都在规范的框架之内,至于有人这样理解:
就随他去吧,如果真的不能理解框架和协议规范,你也大可以理解为 " 玄学 ",所谓的玄学不就是指某些人无法理解的内容吗?
现在,DNS 的重点问题其实只有两个,第一个是大家广为传播的 DNS 污染问题。这件事其实在之前的一篇文章《在工作场所访问色情网站?用这一招绝对杜绝》中已经给大家解释过怎么做了。有些东西机理是不能公然讨论的,所以就给大家写了一个案例性的文章,让大家从反方向来理解一下。只不过大多数人就看着大姐访问色情网站的桥段,外加抱怨一下 996 的辛苦……要么说人穷是有原因呢的?一份机缘放在一些人面前,这些人往往还得在自己的认知范围内叨逼叨,却很难看清背后的事物,网络技术的讲解错过了就无所谓了,但同理这些人也会错过人生的很多机会。当然了,又不是 iN 家自己的娃,不去操心。
DNS 的重点问题之二则是 CDN 的介入,DNS 的指向本身是有区域性的。
DNS 污染给大家明说一下,就是利用网络数据包进行劫持,只要你的 DNS 还在使用传统的 UDP 报文通过 53 端口设置到了哪个 IP 地址上,在目前如果想劫持你的 DNS 可以说是轻而易举的。
所以所谓的公共 DNS 这类的东西你要直接用在很多情况下是和没有用一样的,背后的东西咱们不多说。
哪怕你 ping 这类的 DNS 觉得速度很快,但也无法保证你发出的 DNS 查询指令会去到你设置的 DNS IP 上。对于网络流量的话通过检出你的 DNS 特征请求后再甩一个 dst-nat 就完全让你破防了。在这种情况下不明所以的人就会觉得这是一个所谓的 " 玄学 "。
对于 DNS 污染,实际上最有效的工具是使用 DoH 或者 DoT,咱们以 DoH 为例来说一下,DoH 是 DNS over HTTPS 的缩写,意思为通过 Https 协议传输的 DNS 报文。
传统的通过 UDP 协议传输的 DNS 报文是这样的:
在其中可以看到 Queries 和 Answers 两个关键段,也就是你所请求的网址和返回的查询结果。
这个东西甚至不用解码就可以直接从数据包中看到。为了防止 DNS 劫持,衍生出了利用 HTTPS 协议加载的 DNS 请求。在 DoH 的设计中无论哪种情况,DNS 查询都包装在 HTTPS 请求中。这意味着 DNS 查询使用 TLS(传输层安全)协议进行加密,这是用于安全网络通信的相同加密方式。也就是说从外界仅仅可以看到你的 IP 地址向另一个 IP 地址投递了一个 HTTPS 数据包,而包内的内容被完全加密,外界是无法得知和劫持的。
这是 DNS 劫持的问题,答案是我们可以依靠 DoH 来对 dns 报文进行保护。
另一个因素是 CDN 的问题,CDN 叫做内容分发网络(Content Delivery Network),这是很多网站和网络运营商建立起来的网络缓存机制。
简单的说就是把一个网络资源的镜像放置在世界各地的不同服务器上,根据请求 DNS 的 IP 地址不同将距离用户最近的主机 IP 地址作为 DNS 返回项目给予用户。这样一来在不同的地址上用户所访问同一个网址有可能会显示为不同的 IP 地址。
例如我们要看一下百度的主机 IP:
这时候你会发现,返回了 19 个不同的 IP 地址记录,这些不同的 IP 地址被不同地区的 DNS 请求所响应:
最终浏览器也好应用也好,就从不同的 IP 地址获得资源。CDN 就这样加速了我们的网络。当然了还有其他的 CDN 形式和实现方式,但基本上都和你的请求 IP 相关。
如果是正常使用的话,我们的网络请求就会依据 CDN 的就近原则来获取网络资源,这种机制在 CDN 的概念中是最快的。然而现在很多人的访问并不是这样的访问方式。在一些用户尤其是软路由路由器上搭建了很多奇奇怪怪的节点(为什么奇怪大家心知肚明吧?)。这时候 DNS 的原始请求位置就 " 变味了 "。例如这种:
你认为是自己的 IP 地址在访问 8.8.4.4 吗?实际上并不是,而是你的远在新加波的主机在访问。CDN 的优化过程就在针对于你的新加波主机进行了优化。这时候你如果访问一个某宝,你会发现数据竟有海外的一个某宝的 IP 地址再经过新加波的主机到达你的计算机上。兜了一大圈后,网速能快就见了鬼了。
当然了,你还可以通过仅仅使用本地运营商的 IP 来访问国外站点,但你面临的是 DNS 被污染和劫持的另一个问题。
其实这件事真的无解,起初 iN 自己做过一个程序,拉出路由器内的 DNS 缓存记录,再用这些记录和 chinaz 的 ping 程序来找最适合天津联通的 IP 地址。然后将这个记录设置为路由器中的静态 DNS 记录。一来对 chinaz 的访问量巨大,每天都会被 block 几次,二来拉大时间间隔 DNS 记录刷新也不及时……
这件事也就直接做罢了。当然了,你比对本地运营商 DNS 记录的时候还会有一些效果,但是咱们不能忽略掉另外一件事就是设备本身的 DNS 缓存——你的路由器实施的更新了一个更好的 IP 地址记录,但是你的设备上的缓存还是远端 DNS 给出的一个并不怎么好的 IP 记录,你的路由器上的记录在设备有缓存的时候就没有存在的意义了。而当设备 DNS 缓存过期的时候,你也不能保证路由器上的静态记录没有过期,这时候就形成了一个矛盾,导致你访问一个网站的过程变得极其不稳定。
现在的一个最佳实践实际上是这样的:
在远端路由器上使用 cloudflare-dns 的 DoH 服务器,通过这种方式可以找到大多数网络资源对远端路由器最优的 IP 地址。这台远端路由器打开接受远程 DNS 请求的设置。
本地的路由器则直接将 DNS 服务器指向远端路由:
这里就有一个取舍的问题了,iN 平时访问国外网站更多一些,因此国内的网站访问就放在其次的位置上了。另外这里不做 DoH 还能防止劫持吗?注意 10.10.10.1 是内部的网络地址,本身是建立在 WireGuard 隧道下的,这个隧道本身也被加密了,就无所谓是不是 DoH 了。
当然了,你还得有一个在国外网络带宽速度很大的主机用来运行你的路由器系统。iN 自己找到的是一台西雅图机房的主机。在家里经过这台西雅图服务器访问西雅图的测试节点是这样的:
虽然有一定的网络延迟,但是整体的速度还是足够的。
至于国内的常用网址则是可以利用 DNS 劫持的方法劫持到本地的运营商 DNS 中。这里就有一个 ROS 路由器的七层过滤的设置了:
将国内的常用网址建立一个七层过滤记录。
在 NAT 转换协议中捕获需要访问的国内 DNS 的数据包:
包检出后,DNS 劫持一下:
这些国内的 DNS 数据包就转移到了运营商的服务器中了。
这样问题就可以解决 80% 了,还有一些重点的需要指向访问的域名,例如前几天文章说过的暗黑 4 的服务器加速,就可以直接使用静态 DNS 记录的方式进行一下转换:
这样一来本身服务器本身被鉴定是美国的访问流量就被这个 DNS 静态记录硬生生的转到更近的韩国主机上,再把韩国这个主机的网断开个门进行直通,暗黑 4 这样的游戏也就不用太过于绕圈了。
当然了,这仅仅是 iN 自己的经验而已,并不适合所有的人。但咱们在做网络设定的时候有一个基本原则就是——清楚的知道自己在做些什么以及会带来什么结果。要不然就真的成了玄学了。
附加一个忠告:从真正使用的意义上来说,不建议大家去看很多数码博主的教程,甚至 iN 这篇文章对大家的帮助也并不大,如果想真的弄明白,找几本网络的基础书来看看比看博主教程要有意义得多。