ApexDNS(ΛPΞX)是我在 2 年多前维护的公共 DNS 项目,一直没怎么推广。前段时间被人拿来做 DNS Reflect Attack 我才重新关注起来。

Apex 起源

ApexDNS 最早在 Github 上是以 oif/proton 这个项目存在,在 2017 年 1 月写下了第一行代码。

最早提供服务的时候是 ProtonDNS 运行在 119.29.9.92 上

在那时候,某些不可能站点还能通过 Hosts 的姿势上去,所以那时候就是以 Hosts + 递归的姿势去做,到后来(差不多 9 月左右)发现 Hosts 不那么好使了,开始根据证书针对性做一些干扰了。所以就开始了第一次重构,因为 Proton 一直被人吐槽说 CDN 解析老串(主要原因是因为我穷),那时候大部分公共 DNS 是直接做了 Anycast 然后从地级直接请求上游(我拿来那么多钱搞国内 Colocation Anycast 那套)。然后从 Google Public DNS 那边得知有个特性叫 EDNS-Client-Subnet 能够解决,不过那时候这玩意还没怎么普及。本着没啥人用的 DNS 炸了也没事的想法(其实还是有一波用户群的),在重构时实现了 ECS(EDNS-Client-Subnet)。也发现几个问题

期间用 miekg/dns 作为基础库的时候发现了一些 datarace 的问题,然后提了 issue 和 PR 跟作者搞了好久,最后因为处理起来实在及其复杂,作者选择删代码(第一次知道这么骚的操作,当初是我 too young too simple)。这算是第一次往比较大的基础 Repo 里提 PR 的经理(同期另一个 PR 就是 freecache)。

修了几天仙后成了 oif/apex 的第一个版本(期间纠结了好久,Apex 的特性是 Hook 还是 Plugin),然后期间不小心弄丢了 119.29.9.92 这个 IP(花了好些刷到了 119.29.92.92 现在用的这个 IP,顺带拿了 120.55.44.44)一把梭 Docker 一套暴力带走。居然跑得异常稳定,这两年来代码问题导致的服务不可用基本就 5 次以内,然而其他原因就惨不忍睹了,比如

日常被吐槽,不过总体也还算稳定。再后来迫于自己都无法忍受隧道爆炸的问题,所以加了 multi-upstream 说白就是多上游,把一些国内的上游加进去用(算法参考了 bind 的实现,多上游竞争),然后因为这个事情,我的欠费更严重了(流量加倍)不过服务倒是快了稳了。

非酋的 DNS

有一高中兼大学的同学人送外号「非酋」从头到尾一直在用 ApexDNS,有时候还不设备用 DNS。当时他住在某处泊寓,无意间发现了总路由的密码然后问我要不要改成 ApexDNS 😂。还好当初没改,不然估计整栋楼的人都要爆炸了。

一开始是有监控告警的,然后再后来迫于维护成本太大我就下掉了,再后来每次 DNS 炸了非酋都第一时间通知比我还快(黑科技真好)

DNS Reflect Attack

关于反射攻击的问题,我查阅了一些资料也咨询了些老司机但似乎都没有比较合适的解决方案。所以后来我就只好先以域名黑名单(大部分反射都是 .gov 域名)、限速以及做异常请求判断(说白就是频繁请求若干 Cache Hint 的域名)解决。

关于接下来

最近在考虑重构 Apex 的事情,本来是已经想好要重构了。然后今天再看一次 CoreDNS 的代码的时候(Proton 时代就看过)发现似乎我实现的最终 Apex 也跟 CoreDNS 差不多,多的无非是一些比较奇怪偏向安全考虑的特性(CoreDNS 更多关注在服务发现和内网解析),然后我把这个困惑发个了「晒太阳的猫」得到如下回复

实用性来说,没有,因为 CoreDNS 已经做得很好了;纯粹自娱自乐的话,倒可以尝试一下

仔细想想也确实还有道理,对于前者,CoreDNS 虽然我不喜欢(其实是不喜欢 Caddy)但他的拓展能力足以我实现 Apex 同等的功能,对于后者,我已经娱乐过、享受过、学过。所以我打算让 ApexDNS 与 CoreDNS 混跑共同提供服务,并且不做重构(有 Bug 的话还是得 fix),重点提升稳定性。然后也决定说打算开始推广(人少 Cache miss 高啊)。

最后,放下昨晚写的 ApexDNS 官网(你见过这么简陋的吗?)。注意目前 120.55.44.44 还没有正式对外提供服务。