DNS一般是通过UDP以明文的方式查询,这将给中间人留下了很多攻击的可能。为了进一步加强网络安全,可以使用CoreDNS,通过DNS over TLS(DoT)来实现相对更安全的DNS server。
CoreDNS
CoreDNS是一个由Go语言写成的,高度灵活的DNS服务器。常被用来给k8s集群做服务发现。
这里选择CoreDNS的原因是:
- Docker支持较好。有官方的Docker镜像,而不用自己维护Dockerfile或者依赖社区中由个人维护的镜像。且官方镜像使用不算太复杂。
- As Code。代码化的好处我想不需要多解释了。
- 社区活跃。这一点也许是得益于k8s,导致这个工具的各方面资料稍微多一些。
- 较为灵活。CoreDNS拥有不少插件,可以假设CoreDNS能更灵活的应对更多复杂的场景。
- 上手简单。配置的可读性较高,较为表意。而且本地调试也非常容易。
DoT
首先DNS over TLS是通过或者可以通过TLS来加密DNS通信的。这样的加密阻止了中间人窃听或篡改DNS查询,从而提高了网络的安全性。
假如,直接使用不经过加密的普通UDP的DNS查询,那么就可能出现以下情景:
- 你的运营商清楚的知道你每天访问了哪些网站,即使这些网站你并不都能访问。
- 你的网络访问可能被代理。虽然也许你的浏览器并没有爆出警告,但是我们应该牢记CNNIC证书的教训。
- 你的网络访问可能被负优化。比如虽然结果仍然是同一个网站的服务器,但结果却是此网站位于荷兰的CDN节点。
具体实施
首先,我们需要选择一个可信的上游DNS server,不论是8.8.8.8还是114.114.114.114都好。关键是你愿意信任,或者至少相信对方不至于拿着你的这一点点信息作恶。其次是最好能支持DoT或者DoH。(当然,如果你说你信任你的运行商,以及信任传输过程的中间人。那我个人的建议是点击关闭此网页)
接下来就可以开始写Corefile和Dockerfile了。
首先是Corefile,其实就非常简单:
.:53 {
forward . tls://8.8.8.8 {
tls_servername dns.google
}
log
errors
}
然后是Dockerfile,也非常简单,甚至不需要dockerfile,直接-v
用volume挂进去也是可以的:
FROM coredns/coredns
ADD Corefile ./
唯一注意的是,CoreDNS配置里的.53是UDP端口,所有docker运行的时候应该是-p 53:53/udp
。
最后一公里
假如你的CoreDNS部署在一台VPS上,那么请警惕“最后一公里”的问题。这里要么就直接把CoreDNS部署到内网,要么就需要将VPS上的CoreDNS的DNS改成只听DoT的请求:
tls://.:1443 {
tls /certs/fullchain.pem /certs/privkey.pem
forward . tls://8.8.8.8 {
tls_servername dns.google
}
log
errors
}
并且记得将你的证书映射进container中。
然后依然需要在内网起一个CoreDNS的服务,来和你自己VPS上的服务对接。
最后这一篇博客更多的是给一个CoreDNS的基础。接下来将写一篇基于于国内网络和透明代理场景下运用CoreDNS实现DNS服务搭建。