旧时代的dns配置

之前折腾过好久的dns ,试过很多种dns方案,我列举一下方案和解决的问题

  • 本地dnsmasq服务
    • 允许使用自定义dns
    • 本地缓存dns结果
    • 并发查询dns(貌似没什么用),仅仅取最先返回的结果
    • 特定域名绑定特定dns服务器,server=/www.xxx.com/114.114.114.114
  • dnsmasq+dnsmasq-china-list
    • 该方案在上一方案的基础上利用dnsmasq-china-list实现dns分流
  • smartdns+dnsmasq-chinalist
    • 使用smartdns替代dnsmasq,支持dohdoh、非标准端口查询等技术
    • smartdns支持并发查询,同时支持对结果测速并优选(实际体验,不太好用)

方案设计

​ 最近意识到一线运营商(移动、电信、联通等),对国内常见服务基本不会(不敢)投毒。所以我实际上要解决的是国外服务的dns污染现象。那么正好可以把dnsmasq-china-list当作黑名单,里面的域名的dns查询,转发到运营商dns,从而获得较好的cdn体验和运营商优化。大概如下图:

dns query

方案详细

  • 使用 NetworkManager 作为网络管理器,并启用 dnsmasq 插件
  • dnsmasq 用于国内外分流和dns缓存
  • systemd-resolved 负责解析国内域名,使用NetworkManger 转发的默认dchp配置,即运营商路由
  • smartdns 负责解析国外域名,主要采用加密的dns方案,防止运营商dns抢答和dns污染,有需要的话,可以让部分dns查询走socks5代理

优势

  • 可以得到较好的cdn体验(如果你的运营商不作妖)
  • 国外域名走加密的dns查询,不会被抢答和篡改

缺点

  • 无法解决运营商dns污染(cdn的正常运行是有代价的)
  • 就算国外的域名,也无法避免污染(除非指定使用国外的dns服务器,googlecloudflare都在国内有服务器),如果要彻底解决该问题,建议透明代理或者全局代理本方案重点是解决常用国外域名的dns污染的,兼顾运营商的网络加速和出口优化。

准备

使用环境

我的笔记本使用的是最新版本的Archlinux,网络管理器是NetworkManager

如果你不知道NetworkManager是什么,只要你使用的是KDE或者Gnome那么你的默认网络管理器就是``NetworkManager`。

前提条件

下列体系配套使用依赖于NetworkManager的下列行为,官方文档NerworkManager.conf

  • NetworkManager 可以使用 dnsmasq 插件作为本地 dns 缓存
  • NetworkManager 默认将 dns 配置转发到 systemd-resolved

配置

配置systemd-resolve

确保服务启动

1
systemctl enable --now systemd-resolved

自定义Fallback服务器

如果 systemd-resolved 无法从 接收DNS服务器地址, 网络管理器 并且没有 配置DNS服务器, 手动 systemd-resolved 会回退到后备DNS地址,以确保DNS解析始终有效。

1
2
3
# vim /etc/systemd/resolved.conf.d/fallback_dns.conf
[Resolve]
FallbackDNS=119.29.29.29 223.5.5.5 114.114.114.114

配置NetworkManager

编辑配置文件,启用dnsmasq 插件

1
2
3
# vim /etc/NetworkManager/conf.d/dns.conf
[main]
dns = dnsmasq

配置dnsmasq启动参数

如果使用dnsmasq插件来进行dns缓存,NetworkManager会在启动时启动一个子进程来运行dnsmasq,配置时注意disable其他运行在127.0.0.1:53dns服务。

编辑下列文件设定新的配置目录(可以不配置,我这么做是为了复用之前的dnsmasq配置文件),这样配置后,会使用dnsmasq默认配置目录中的文件。

1
2
# nvim /etc/NetworkManager/dnsmasq.d/custom.conf
conf-dir=/etc/dnsmasq.d

配置dnsmasq

安装并配置dnsmasq-china-list

如果启用了archlinuxcn源

1
# pacman -S dnsmasq-china-list-git
使用 hooks 自动替换 dns 服务器

注意,如果要使用该 hooks ,必须在安装 dnsmasq-china-list 前完成下列配置;如果已经完成安装,可重新安装一次以确保dns服务器被替换完成。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# vim /usr/share/libalpm/hooks/replace-dnsmaq-list-server.hook
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = dnsmasq-china-list*
[Action] 
Description = when dnsmasq-china-list update ,replace it's default server
When = PostTransaction
Exec = /usr/bin/sed -i 's/114.114.114.114/127.0.0.53#53/g' /etc/dnsmasq.d/apple.china.conf  /etc/dnsmasq.d/accelerated-domains.china.conf

未启用archlinuxcn源,使用yay或其他aur helper进行安装:

1
# yay -S dnsmasq-china-list-git

上述hooks,对aur同样有效

非archlinux,前往 dnsmasq-china-list 自行安装:

注意make时编辑一下SERVER变量,不要使用默认的114服务,应当指向我们运行在本地的systemd-resolved

配置smartdns

smartdns主要用于外网dns解析,这种情况下我们基本没有国内cdn可用,不需要考虑,因此直接使用 cloudflaregoogledohdot 服务。在翻墙时,可以开启远程 dns 解析来获取 cdn 服务。

1
2
3
4
5
6
7
8
# vim /etc/smartdns/smartdns.conf
server-tls dns.google
server-tls cloudflare-dns.com
server-https https://dns.google/dns-query
server-https https://cloudflare-dns.com/dns-query

bind [127.0.0.1]:5380
bind [::1]:5380

一些优化(玄学)建议 for smartdns

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 开启dns缓存
cache-size 4096

# 启用dns缓存持久化
cache-persist yes

# 设置dns持久化文件名(把它放在内存里,重启就消失,问题不大,主要是为了避免重启smartdns服务后的冷启动)
cache-file /tmp/smartdns.cache

# prefetch domain,预解析域名,会导致dns包的数量极大程度增加,原理就是提前查询dns,看网页的时候有一点加速
# prefetch-domain [yes|no]
prefetch-domain yes

最后

建议使用 wireshark 测试一下配置是否成功