有时候方案一些网站的时候,会由于 DNS 解析出问题,即使网络情况很好,也会出现无法访问的情况, 而最近很流行的 DNS over HTTPS 更是十分的稳定安全,所以,通过自建 DNS,可以精确的得到解析结果。
文章中的所有文件可以直接在我的仓库中找到:
方案
dnsmasq
dnsmasq 是一个十分老牌的软件了,可以提供 DNS 缓存和 DHCP 服务功能,还带了一个 PXE 服务器,但是这些都不是我们需要关注的点,我们只看 DNS 。
作为域名解析服务器 DNS , dnsmasq 可以通过缓存 DNS 请求来提高对访问过的网址的连接速度,所以有一些结果虽然第一次比较耗时,但是后续就可以直接用本地结果了。
最重要的是 dnsmasq 轻量而且容易配置,几乎默认的配置就足够我们使用了。
DNS over HTTPS
DNS over HTTPS 也就是常见的 DoH
没什么问题是加一层解决不了的,如果有,那个加两层。
DNS 经常出问题,那就把 UDP 换成 TCP ,还解决不了?那就再上一层 TLS 。
由于 HTTP 协议需要多次数据交互,还有 TLS 的加解密,所以在时间上,耗时比传统的 DNS 高了不少。
上文也提到了 dnsmasq 有缓存作用,所以也一定程度缓解了这个问题。
Cloudflare 1.1.1.1
Cloudflare 本来是一个主打 CDN 和 权威 DNS 的企业,在 2018 年的时候强势推出了 1.1.1.1 的 local DNS , 还带着 DNS over HTTPS 支持。
目前比较有名的 DoH 服务就只有 Cloudflare 和 Google ,而这是 Cloudflare 的主战场,自然也就是一个优选。
- Cloudflare DoH Client
`Cloudflare` 还提供了一个 `Golang` 开发的 `DoH` [客户端](https://developers.cloudflare.com/1.1.1.1/dns-over-https/cloudflared-proxy/),可以直接在本地把 `DoH` 转为传统 `DNS` 。
得益于 `Golang` 开发,所以所有需要下载的内容就是一个二进制文件: `cloudflared` 。当然如果对应 `Linux 发行版` ,想安装 `deb` 或者 `rpm` ,官网也是有的。
运行方式也只需要如下命令即可:
```shell
cloudflared proxy-dns --address 0.0.0.0 --port 5353
```
dnsmasq china list
上文提到了, DoH 相对比较耗时,而 DNS 的问题更多地出现在国外的域名上,所以国内的域名,我们其实直接用传统方案就可以了,
dnsmasq china list 就是一个国内的域名列表,而最方便的地方在于可以直接生成 dnsmasq 的配置文件。
安装
考虑到这是一个服务,需要长期运行,所以我们使用 systemd 来运行。
配置文件如下,考虑到文章不一定能及时更新,可以看我的 dot file repo:
Cloudflare
[Unit]
Description=cloudflare DoH
Documentation=cloudflare DNS over HTTPS
[Service]
Type=simple
ExecStart=/home/username/.bin/cloudflared proxy-dns --address 0.0.0.0 --port 5353
ExecStop=kill $MAINPID
Restart=always
[Install]
WantedBy=default.target
dnsmasq
dnsmasq 直接使用自已安装的时候带的 systemd 配置文件就足够了,主要是改一下 dnsmasq 的配置文件, /etc/dnsmasq.conf :
no-hosts
no-resolv
server=127.0.0.1#5353
conf-dir=/etc/dnsmasq.d/
log-queries
log-facility=/var/log/dnsmasq/dnsmasq.log
然后安装 dnsmasq-china-list ,简单地来说,运行一个脚本就可以:
wget https://raw.githubusercontent.com/zwpaper/dotfile/master/archlinux/config/dnsmasq/install.sh
sudo bash install.sh
效果
到此,安装就完成了,目前的效果
国内域名:
# dig @127.0.0.1 163.com
; <<>> DiG 9.14.3 <<>> @127.0.0.1 163.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3825
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;163.com. IN A
;; ANSWER SECTION:
163.com. 98 IN A 123.58.180.7
163.com. 98 IN A 123.58.180.8
;; Query time: 44 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Jun 30 17:19:54 HKT 2019
;; MSG SIZE rcvd: 68
查看日志:
Jun 30 17:19:54 dnsmasq[20723]: query[A] 163.com from 127.0.0.1
Jun 30 17:19:54 dnsmasq[20723]: forwarded 163.com to 180.76.76.76
Jun 30 17:19:54 dnsmasq[20723]: forwarded 163.com to 114.114.115.115
Jun 30 17:19:54 dnsmasq[20723]: forwarded 163.com to 114.114.114.114
Jun 30 17:19:54 dnsmasq[20723]: reply 163.com is 123.58.180.7
Jun 30 17:19:54 dnsmasq[20723]: reply 163.com is 123.58.180.8
可以看到 dnsmasq 转发了三个请求到国内的 local dns 了。
国外的请求
# dig @127.0.0.1 google.com
; <<>> DiG 9.14.3 <<>> @127.0.0.1 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36565
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
; PAD (69 bytes)
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 272 IN A 216.58.217.206
;; Query time: 251 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Jun 30 17:30:37 HKT 2019
;; MSG SIZE rcvd: 138
看日志,转发到 127.0.0.1 了,因为我们的 cloudflared 是运行在本地的。
Jun 30 17:30:36 dnsmasq[20723]: query[A] google.com from 127.0.0.1
Jun 30 17:30:36 dnsmasq[20723]: forwarded google.com to 127.0.0.1
Jun 30 17:30:37 dnsmasq[20723]: reply google.com is 216.58.217.206
Cache
再发起一次请求,看日志,直接从 cache 返回了:
Jun 30 17:31:31 dnsmasq[20723]: query[A] google.com from 127.0.0.1
Jun 30 17:31:31 dnsmasq[20723]: cached google.com is 216.58.217.206