修改 DNS 这事……
从 17.04 开始,Ubuntu桌面系统 的 DNS 解析不再靠那个 NetworkManager 操作的 dnsmasq 了,而是交给了 systemd。自此呢,许多 Ubuntu 的本地 DNS 服务器方案都不准确了(不过 GNOME/KDE 界面的设置应该没问题)。咱就先铺垫一下。
如何修改系统默认 DNS?修改 resolved.conf
根据 man resolved.conf 的说法,把 DNS 设定写到 /etc/systemd/resolved.conf。同时为了防止本地 dnscrypt-proxy 的问题,也指定了一个后备 DNS。
DNS=127.0.0.54 FallbackDNS=9.9.9.9 (其余略)makefile
如果也要折腾 DNSSEC 的话,把下面的 DNSSEC 也改一下。可能是因为 DNSSEC 并不是很普及,我个人在强行开启 DNSSEC 的时候体验很差(大多数域名不能解析)。建议先不要设置为 DNSSEC=true,而改为DNSSEC=allow-downgrade。
考虑到是本地 DNS 服务器,而且 dnscrypt-proxy 已经有缓存功能了,可以在 resolved.conf 中指定 Cache=false。(虽然有可能这就是默认选项)
部分程序(例如 dig)可能不会按照 systemd-resolved 的配置工作,所以 resolv.conf 也需要按照下文设置的 DNS 服务器 IP 改一下。systemd 基本不管 resolv.conf,所以还是“自己动手,丰衣足食”吧。
dnscrypt-proxy,启动!
dnscrypt-proxy 的安装请参阅文档。
配置呢,按这里的 Setting up dnscrypt-proxy (general guidelines) 填写就可以。
我修改了的地方:
listen_addresses改为在resolved.conf中写的那个地址(例如listen_addresses = ['127.0.0.54:53'])server_names从列表里找几个舒服的写吧,反正会自动选择最快的。ignore_system_dns = true,因为你自己就是系统 DNS。这里吐槽 Google 的 DNSCrypt 服务器的配置(sdns://…)用的是域名(dns.google.com)而不是 IP。- 后面基本上不用改了。
sudo service dnscrypt-proxy start,跑起来吧。如果出错记得检查一下端口占用和配置文件格式。
一个你可能会遇到的问题:
权限不够,53 端口监听不了?
改 /lib/systemd/system/multi-user.target.wants/dnscrypt-proxy.service。加两行:
User=root
Group=root
ini然后:
sudo systemctl daemon-reload #重新加载下配置
sudo services dnscrypt-proxy restart
nginx差不多了。dig white.ac.cn @127.0.0.54 测试一下,应该有了。
小补充:dnsmasq-china-list
把所有的域名都通过 dnscrypt-proxy 进行解析会使 CDN 无法发挥出它的能力。虽然我们有 edns-client-subnet,但这玩意的支持依然不是很广泛,而且 dnscrypt-proxy 似乎没有这个功能,所以我们需要手动处理。这里我们用到了 felixonmars 大佬的 dnsmasq-china-list 项目。
git clone https://github.com/felixonmars/dnsmasq-china-list.git --depth=1 cd dnsmasq-china-list make dnscrypt-proxy sudo cp dnscrypt-proxy-forwarding-rules.txt /etc/dnscrypt-proxy/dnscrypt-proxy-forwarding-rules.txtshell
然后在 dnscrypt-proxy.toml 中把 forwarding_rules 改为:
forwarding_rules = 'dnscrypt-proxy-forwarding-rules.txt'
ini然后:
sudo systemctl daemon-reload #重新加载下配置
sudo services dnscrypt-proxy restart
nginxDNSSEC
有些 DNSCrypt 服务器是支持 DNSSEC 的。当连接到这些服务器的时候(当然你也可以通过在 DNSCrypt 的配置文件中写 require_dnssec = true 来只使用那些支持 DNSSEC 的服务器)dig paypal.com +dnssec @127.0.0.54,你将可以看到一些 DNSSEC 相关的东西,例如:
paypal.com. 593 IN RRSIG A 5 2 300 20180901094929 20180802084929 11811 paypal.com. hJxmJDkNgD6w1Qep+wq7izH87CbL1rvb6Ftcd9xHCcImtpvRFin6hQIM QmcMT8empxN6eBvnn/++Ujt1QQ2tAQGmHpGmurcALjAHBZkN3otwXLvq 135WJB/5pISk6Qt3aW2k4YCGg/nIQ76uw5FA0rUbMrO/raT0R2nUeDMk PZs=
apache而对于那些 DNSSEC 验证失败的 DNS 记录而言,例如 dig sigfail.verteiltesysteme.net +dnssec @127.0.0.54,回复将是空的(不过在关闭 DNSSEC 之后又会有回复)。
dig 可以通过 +dnssec 来启用 DNSSEC 验证。至于系统层面上的 DNSSEC 验证,systemd-resolve 本来有一个比较优雅的方案(resolved.conf 中设置 DNSSEC=true,然后各种东西应该已经配置好了),不过我在 DNSSEC=true 之后,系统完全解析不出结果。dig 没问题,估计是因为 DNSSEC 验证全都不通过。即使手动把根信任锚加入了 dnssec-trust-anchors.d 之后也没有效果。原因未知,也有可能是我的网络问题(折腾 DNSCrypt + DNSSEC 时使用的网络不太好用)。过段时间找一个稳定点的网络再测试。
9/26 补充:
缓存
[WARNING] /etc/dnscrypt-proxy/public-resolvers.md: open example.tmp: read-only file system
[WARNING] /etc/dnscrypt-proxy/public-resolvers.md.minisig: open example.tmp: read-only file system
perl改一下缓存地址吧…本来想着写到 /var/cache 里某个位置,查看的时候发现其实文件夹已经建立好了,遂把两个缓存文件夹位置分别改一下:
cache_file = '/var/cache/dnscrypt-proxy/cache-public-resolvers.md' 以及
cache_file = '/var/cache/dnscrypt-proxy/cache-opennic-servers.md'
结果
systemd-resolve --status 可以看到各个连接所使用的 DNS 解析方案。man resolved.conf 提到,per-link 设定会优先于系统级设定,所以如果看到你的连接上使用的 DNS 并不是本地的 DNS 的话,在界面上配置一下:

No comments:
Post a Comment