有时候方案一些网站的时候,会由于 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