之前一直用的是学校提供的 DNS Server,在学校查询速度快,但是有这么几个与DNS有关的问题实在是不能忍,忍无可忍无须再忍。

  1. 在学校下载App Store上的Apps实在是太慢!了!偶尔挂VPN加速还行。
  2. 前不久某国开始清理未备案的域名使用教育网IP。
  3. 某高科技部门的大招之一:专业投毒污染三十年。

好了,针对以上问题我们使用两招就好了——ChinaDNS + ss-redir, 这篇提供 DNS 层级的解决方案,科学上网方案另写一篇。

ChinaDNS - 正确解析国外域名

ChinaDNS 主要作为正确地解析国外域名用,基本原理是同时向国内国外 DNS 发起请求,过滤掉国内 DNS 返回的污染结果。 ChinaDNS 暂时在 AUR 中,故通过如下命令安装:

packer -S chinadns

鉴于国外 DNS Server 可选较少,较具代表性的有 OpenDNS 和 Google 两家,所以我们可以将国外 IP 固定,故新建文件 chinadns-local@.service.

cp /usr/lib/systemd/system/chinadns@.service /etc/systemd/system/chinadns-local@.service

将其中的行 ExecStart 换为:

ExecStart=/usr/bin/chinadns -s %i,8.8.8.8,208.67.222.222:443 -m -p 5353 -y 0.3 -d -c /etc/chnroute.txt

默认监听 5353 端口,使用114/阿里/DNSPod DNS(114.114.114.114223.5.5.5119.29.29.29) 作为国内 DNS Server, 8.8.8.8 对国内 CDN 更为友好,所以放在 OpenDNS 前面。

# sudo systemctl start chinadns-local@114.114.114.114
# sudo systemctl enable chinadns-local@114.114.114.114

与之前熟知的 dig 不同,Arch 的 wiki 中建议使用 ldns(已在 Arch 的 base 中安装)的 drill 作为 DNS 查询诊断工具。

drill -p 5353 dropbox.com @127.0.0.1

若显示结果为

;; ANSWER SECTION:
dropbox.com.    49      IN      A       108.160.172.206
dropbox.com.    49      IN      A       108.160.172.238

则说明 chinadns 正常运行。能达到同样功能的还有 DNSCrypt, 但是相比 ChinaDNS 解析时间较长,且未能充分利用国内 CDN, 所以建议主要使用 ChinaDNS.

加速国内网站 DNS 查询

ChinaDNS 的重度使用者可能会发现

local_ns_initparse: Message too long

类似 log, 此时 DNS 解析会出现问题,网络彻底瘫痪,所以我们可以采用 @felixonmars 维护的 china-list 分流和加速. 使用其中的 install.sh 即可,我添加了每天凌晨自动更新 list 并重启 dnsmasq 的 service 及 timer. 见 dnsmasq-china-list.servicednsmasq-china-list.timer

Unbounddnsmasq - 缓存域名解析结果

每次查询同样的域名也同时向多个上游 DNS Server 发起请求的话则会引发较大的域名解析时延,为了减少重复查找浪费解析时间,我们还需要一个能提供缓存功能的前端 DNS,常用的有 dnsmasq 和 unbound, 由于 dnsmasq 已经在 AP 中作为 DHCP Server 使用,未尽量减少对 AP service 的影响,这里选用了另一款同样简单好用的 Unbound. 已使用 dnsmasq 替代,dnsmasq 默认读取 hosts 文件,更为省心一些。 Arch 下通过 sudo pacman -S unbound 安装,安装完之后可以把 /etc/unbound/uncound.conf.example 拷贝到 /etc/unbounc/uncound.conf, Arch 的 wiki 上有 Unbound 的详细配置介绍,仔细看看就好了。我的配置文件见 unbound.conf

dnsmasq 的配置较为简单 ==> dnsmasq.conf, 指定 ChinaDNS 为上游就好了,对于家用服务器,你使用的很可能是 DHCP 分配 IP, 显然我们并不需要 ISP 提供的 DNS,所以不让其更新 resolv.conf 就好了。

echo "nohook resolv.conf" >> /etc/dhcpcd.conf

最终 /etc/resolv.conf 的内容应该如下:

# Generated by resolvconf
nameserver 127.0.0.1

至此你应该能获得一个比较纯净的 DNS 解析结果了,然而要想达到更为方便地科学上网,我们还需要 ss-redirss-rules 这两个工具。

相关参考

  1. dnsmasq - ArchWiki
  2. Unbound - ArchWiki
  3. Unbound documentation
  4. Unbound DNS Server Tutorial @ Calomel.org