自制旁路网关(二) ——用unbound和smartdns来优化dns服务
今天是三月一日,我应该昨天更新,因为昨天是四年一度的二月二十九日。错过了了个好日子 T_T 。不过没关系,今天还是一年一次的三月一号那(
先来回顾一下 dns 查询会遇到那些问题
- 运营商 dns 基本上是最快的,但可能有污染
- 国内公共 dns ,国内地址准确,但未必最快,国外有污染
- 出口节点运营商 dns ,国外地址准确,速度基本最快
- 国外公共 dns ,国外地址准确,但未必快
- 国外网站可能有国内地址的 cdn ,cdn 最快
我们先把国内外分开查询,然后再汇总
使用 smartdns 来查询国内,只用公共 dns ,(smartdns 可以测速并返回你的位置最快的地址)
国内外 dns 该如何进行分流?有一个很重要的问题是国外网站有国内 cdn
基于 geo-ip 来分流查询,查到固定国家或特色网段的地址时,不使用这个结果(大陆白名单就是这种)
基于域名 GFWlist 是把被墙掉的域名收集起来做成一个数据库
究极方案 ICPlist:
我还没见过有这么干的,不过这才是一劳永逸的办法,用于大陆法律的问题 ICP 你懂的,不过这个数据库可以反过来利用(只要在 icp 清单可以认为在大陆一定有服务器)
不过最大的问题是这个库过于庞大。。。绝大部分你都是永远都不会用的地址
国外的可以分成两种情况
- 出口固定(比如你自建的服务)
- 出口不确定(比如使用机场)
出口固定的情况很好解决,这里不做考虑(你自己在出口节点上建一个 dns 服务,然后加密传回来就行了)
出口不确定,你不知道运营商 dns 只能把查询请求给代理,保佑能给你返回个快的地址
目前我用的方案
使用 unbound
来做主 dns 服务(其实用什么都无所谓 coredns 也可以)
smartdns
来查询国内的 dns (我设成 5351 端口)
clash
来查询国外的 dns (我设成 5352 端口)
dnsmasq-china-list
的规则来分流国内外
smartdns
wget https://github.com/pymumu/smartdns/releases/download/Release28/smartdns.1.2019.12.15-1028.arm-debian-all.deb
dpkg -i smartdns.1.2019.12.15-1028.arm-debian-all.deb
systemctl start smartdns.service
systemctl enable smartdns.service
这个没啥说的,按官方文档的说法,就多些几个上游 dns 地址 从这里挑几个看着顺眼的写上就行
smartdns有测速机制,在配置上游服务器时,建议配置多个上游DNS服务器,包含多个不同区域的服务器,但总数建议在10个左右
unbound
这个直接从源里安装就行 apt install unbound
不过这个源里的 unbound
, DD (Debian Developer) 定制了一点东西
sudo systemctl cat unbound
# /lib/systemd/system/unbound.service
[Unit]
Description=Unbound DNS server
Documentation=man:unbound(8)
After=network.target
Before=nss-lookup.target
Wants=nss-lookup.target
[Service]
Type=notify
Restart=on-failure
EnvironmentFile=-/etc/default/unbound
ExecStartPre=-/usr/lib/unbound/package-helper chroot_setup
ExecStartPre=-/usr/lib/unbound/package-helper root_trust_anchor_update
ExecStart=/usr/sbin/unbound -d $DAEMON_OPTS
ExecReload=/usr/sbin/unbound-control reload
PIDFile=/run/unbound.pid
[Install]
WantedBy=multi-user.target
这里有两个 hook 的脚本。Debian Developer 对这个定制了点东西,先把他禁用掉
凡是DD (Debian Developer) 打包时自己定制的功能一律禁用掉
顺着那个 hook 去这个文件里 /usr/lib/unbound/package-helper
可以找到这样一段
# Override these variables by editing or creating /etc/default/unbound.
RESOLVCONF="true"
ROOT_TRUST_ANCHOR_UPDATE="true"
之后自己建个 /etc/default/unbound
把那个功能关掉
cat > /etc/default/unbound << EOF
# 这个默认会修改 /etc/resolv.conf 文件,设成 false 禁用掉
RESOLVCONF="false"
# 这个我也不知道具体是干什么的,反正是 DD (Debian Developer) 自己搞出来东西,直接禁用就行 ╮( ̄▽ ̄)╭
ROOT_TRUST_ANCHOR_UPDATE="false"
EOF
然后去修改 /etc/unbound/unbound.conf
server:
verbosity: 1
num-threads: 2
interface: 0.0.0.0@53
do-ip4: yes
do-udp: yes
do-tcp: no
do-not-query-localhost: no # 这句很关键,不把这个关掉上游 dns 不能用本地的 dns 服务
access-control: 0.0.0.0/0 allow
local-data: "test.com. A 192.168.1.1"
include: "/etc/unbound/unbound.conf.d/accelerated-domains.china.unbound.conf"
include: "/etc/unbound/unbound.conf.d/apple.china.unbound.conf"
include: "/etc/unbound/unbound.conf.d/google.china.unbound.conf"
forward-zone:
name: "."
forward-addr: 127.0.0.1@5352
之后把 include
的文件放进去
dnsmasq-china-list
git clone https://github.com/felixonmars/dnsmasq-china-list.git --depth 1
cd dnsmasq-china-list
make SERVER=127.0.0.1@5351 unbound
cp *unbound.conf /etc/unbound/unbound.conf.d/
最后
clash
的配置去看我前几篇文章
最好别忘了 systemctl restart unbound
排查文件直接用 dig
, nslookup
这个软件 debian 是在 dnsutils
这个包里