前言
在 前文(一) 中我提及了我的目标是在10.0.0.0/24
这个旁路由所在的子网中实现国内网站IPv4/IPv6双栈解析并可正常访问,国外网站仅解析IPv4地址并进行科学上网,那么仅凭Clash很难实现(其他的代理软件我也不介绍了),我们可以借助mosdns来实现(其他的smartdns、coredns我就不介绍了)。又为了能够更加方便的为电视机屏蔽广告、自定义子网中设备解析为私网IPv4地址和公网IPv6地址这种形式的双栈、防止代理有故障需要后备DNS等等功能,我继续在mosdns前加一层adguardhome,以方便的实现。
逻辑图
DNS逻辑
说明
由于我在 前文(二) 中并没有安装 dnsmasq
,53
端口上并没有运行任何服务,所以我可以让 adguardhome
直接监听在 53
端口。在 前文(二) 中我已经设置了旁路由自身的DNS服务器为 127.0.0.1
。在 前文(一) 中我们也设置好了 10.0.0.0/24
整个网段的DNS服务器为旁路由的IP 10.0.0.2
。
当客户端需要解析DNS时,监听在 53
端口上的 adguardhome
会转发给其上游 mosdns
,然后 mosdns
根据设置来进行分流,中国大陆部分使用国内的公共DNS服务器进行解析,保留IPv4/IPv6双栈结果,非中国大陆部分继续转发给上游 clash
,由 clash
通过代理向国外公共DNS服务器进行解析,clash
中的DNS模块设置关闭IPv6解析,这样国外部分只会返回IPv4的结果。
而当 mosdns
出现故障时(mosdns本身也会有一个后备,防止clash出现故障,也就是说会有两层后备),adguardhome
则直接向国内公共DNS服务器请求解析,做到不影响局域网的网络。
AdGuardHome的安装和配置
下载安装
我默认你已经按照 前文(二) 安装好了必要的软件了。以下为root用户运行的命令。
1
2
3
4
5
6
7
8
9
10
11
12
|
## 检查最新稳定版的版本号,如果获取不到请检查网络
remote_ver=$(curl -sS https://api.github.com/repos/AdguardTeam/AdGuardHome/releases/latest | jq -r .tag_name | sed 's|v||' | grep -v "null"); echo $remote_ver
## 下载最新稳定版(前一句有输出这一句才能正常执行)
cd /tmp
wget -q --progress=bar:dot --show-progress -O "AdGuardHome_linux_amd64.tar.gz" "https://github.com/AdguardTeam/AdGuardHome/releases/download/v${remote_ver}/AdGuardHome_linux_amd64.tar.gz"
## 解压
tar --no-same-owner -xf "AdGuardHome_linux_amd64.tar.gz" --strip-components 2 --directory=.
## 安装
install -ps AdGuardHome /usr/local/bin/adguardhome
|
创建服务
创建工作目录/var/lib/adguardhome
。
1
|
mkdir -p /var/lib/adguardhome
|
创建 /etc/systemd/system/adguardhome.service
如下,这时配置文件为 /var/lib/adguardhome/AdGuardHome.yaml
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[Unit]
Description = Network-wide ads & trackers blocking DNS server.
Wants = network-online.target mosdns.service
After = network-online.target mosdns.service
[Service]
Type = simple
Restart = always
StartLimitInterval = 5
StartLimitBurst = 10
ExecStart = /usr/local/bin/adguardhome -w /var/lib/adguardhome
RestartSec = 10
[Install]
WantedBy = multi-user.target
|
如果你比较讲究Linux哲学,可以把ExecStart
改成下面这样,这时配置文件为 /etc/adguardhome/config.yaml
。
1
|
ExecStart = /usr/local/bin/adguardhome -w /var/lib/adguardhome -c /etc/adguardhome/config.yaml
|
如果不想以root用户运行 adguardhome
,可以自行创建用户 adguardhome
和用户组 adguardhome
,然后在 /etc/systemd/system/adguardhome.service
的 [Service]
单元下增加下面几行,同时修改 /var/lib/adguardhome
为该普通用户所有(后续的脚本都是以root用户为运行用户进行的,如果要把 adguardhome
服务调整为普通用户运行,请自行修改脚本)。
1
2
3
4
5
6
|
User = adguardhome
Group = adguardhome
# 我们需要监听特权端口53
CapabilityBoundingSet = CAP_NET_BIND_SERVICE
AmbientCapabilities = CAP_NET_BIND_SERVICE
|
adguardhome
自身的命令行是支持自动创建 /etc/systemd/system/adguardhome.service
的,但个人不是很建议直接使用 adguardhome
本身所支持的命令来完成上述工作,以下仅供参考。
1
2
3
|
adguardhome -s install -w /var/lib/adguardhome # 需要自行创建目录var/lib/adguardhome
# 或者
adguardhome -s install -w /var/lib/adguardhome -c /etc/adguardhome/config.yaml # 需要自行创建目录/etc/adguardhome和/var/lib/adguardhome
|
初始化
先开一个终端输入adguardhome
,然后浏览器打开 http://10.0.0.2:3000 并按下图设置。
网页管理监听端口建议改回3000,至于80端口我们留给nginx使用
DNS服务器就监听53端口
配置
DNS设置
上游DNS服务器设置为mosdns的监听端口。
上游DNS服务器
后备DNS服务器填写公共DNS服务器,可以附加上你的ISP当地的DNS服务器,如果主路由设置了DNS的功能,也可以加上,当mosdns出现故障时,adguardhome会转为使用后备DNS服务器来进行解析。这样。即使mosdns或者clash出现故障时,也不影响adguardhome为局域网提供DNS服务。
后备DNS服务器
我们只在局域网中使用,所以不限制查询流量。
DNS服务配置
开启乐观缓存可以更快的响应,但有些时候可能会导致问题,可以视情况开关。
DNS缓存配置
DNS重写
如果你已经使用DDNS将你的域名解析了IPv4和IPv6,则可以在AdGuardHome的DNS重写模块中按下图这样设置,设置后局域网中的设备在解析时,可以解析私网IPv4地址和公网IPv6地址,做到在局域网中照样使用和公网中一样的域名访问。
一个良好的习惯是针对局域网中每一个运行着需要被访问的服务的IP,都通过 adguardhome
劫持其域名,做到不同IP不同子域名。只要设置好DDNS的子域名以及主路由爱快的端口转发,就可以做到在局域网环境中和在公网环境中,使用相同的域名去访问同一个服务。
DNS重写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
## 解析nas的ip,我的nas双网卡,均配置了IP
$ nslookup nas.evine.win
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: nas.evine.win
Address: 10.0.0.11
Name: nas.evine.win
Address: 10.0.0.12
Name: nas.evine.win
Address: 240e:■■■■:■■■■:■■■■:■■■:■■■■:■■■■:1ee
Name: nas.evine.win
Address: 240e:■■■■:■■■■:■■■■:■■■:■■■■:■■■■:6c4c
## 解析创建在10.0.1.0/24网段docker macvlan上的qbittorrent容器的ip
$ nslookup qb.evine.win
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: qb.evine.win
Address: 10.0.1.2
Name: qb.evine.win
Address: 240e:■■■■:■■■■:■■■■:■■■:■■■■:■■■■:102
|
在完全配置好旁路由后,你就可以实现上述这样的域名解析。这样的话,像手机、笔记本电脑这种会频繁进出局域网的设备,可以在局域网和公网中使用一样的域名去访问各项服务,而不用在公网用域名访问,在局域网得换成IP访问这种形式。
启用服务
完全配置好以后,我们可以设置 /etc/systemd/system/adguardhome.service
为开启自动启动,并立即启动起来(这时上游mosdns尚未配置,会直接跳转到备用DNS服务器去,你可以等后续配置完好以后再来启动它)。
1
|
systemctl enable --now adguardhome.service
|
后续如想查看日志,我们直接使用Debian自带的工具来查看:
1
|
journalctl -efu adguardhome.service
|
如果想要重启:
1
|
systemctl restart adguardhome.service
|
mosdns的安装和配置
下载安装
我默认你已经按照 前文(二) 安装好了必要的软件了。以下为root用户运行的命令。
1
2
3
4
5
6
7
8
9
10
11
12
|
## 检查最新稳定版的版本号,如果获取不到请检查网络
remote_ver=$(curl -sS https://api.github.com/repos/IrineSistiana/mosdns/releases/latest | jq -r .tag_name | sed 's|v||' | grep -v "null"); echo $remote_ver
## 下载最新稳定版(前一句有输出这一句才能正常执行)
cd /tmp
wget -q --progress=bar:dot --show-progress -O "mosdns-linux-amd64.zip" "https://github.com/IrineSistiana/mosdns/releases/download/v${remote_ver}/mosdns-linux-amd64.zip"
## 解压
unzip -oqq mosdns-linux-amd64.zip -d .
## 安装
install -ps mosdns /usr/local/bin/mosdns
|
创建服务
创建工作目录/var/lib/mosdns
。
1
|
mkdir -p /var/lib/mosdns
|
创建 /etc/systemd/system/mosdns.service
如下,这时配置文件为 /var/lib/mosdns/config.yaml
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[Unit]
Description = A DNS forwarder.
Wants = network-online.target clash.service
After = network-online.target clash.service
[Service]
StartLimitInterval = 5
StartLimitBurst = 10
WorkingDirectory = /var/lib/mosdns
ExecStart = /usr/local/bin/mosdns start
Restart = always
RestartSec = 10
[Install]
WantedBy = multi-user.target
|
如果你比较讲究Linux哲学,可以把 ExecStart
改成下面这样,这时配置文件为 /etc/mosdns/config.yaml
。
1
|
ExecStart = /usr/local/bin/mosdns start -c /etc/mosdns/config.yaml
|
如果不想以root用户运行 mosdns
,可以自行创建用户 mosdns
和用户组 mosdns
,然后在 /etc/systemd/system/mosdns.service
的 [Service]
单元下增加两行,同时修改 /var/lib/mosdns
为该普通用户所有(后续的脚本都是以root用户为运行用户进行的,如果要把 mosdns
服务调整为普通用户运行,请自行修改脚本)。
1
2
|
User = mosdns
Group = mosdns
|
同样的,mosdns
自身的命令行也支持自动创建 /etc/systemd/system/mosdns.service
的,但个人不是很建议直接使用 mosdns
本身所支持的命令来完成上述工作,以下仅供参考。
1
2
3
|
mosdns service install -d /var/lib/mosdns # 需要自行创建目录var/lib/mosdns
# 或者指定配置文件为/etc/mosdns/config.yaml
mosdns service install -d /var/lib/mosdns -c /etc/mosdns/config.yaml # 需要自行创建目录/etc/mosdns和/var/lib/mosdns
|
配置
luci-app-mosdns 提供的 默认配置 已经是一份非常好的配置了,我们稍微改改就能用了。考虑到我已经使用 adguardhome
来屏蔽广告,以及用来解析本地局域网内的私有IP了,所以在 mosdns
中我们这可舍弃这一部分配置内容。
稍加修改后的配置文件见 mosdns配置,在该文件中,会引用到以下文件。其中 rule
文件夹下的几份文件可以参考 luci-app-mosdns的配置。至于 geodata
下面的文件,你可以先下载这几个并非是最新的文件,先保存到该目录下:geoip_cn.txt、geosite_cn.txt、geosite_geolocation-!cn.txt,我们将在 本系列第(七)篇 用定时任务系统来定时更新。
1
2
3
4
5
6
7
8
9
10
|
/var/lib/mosdns
├── geodata
│ ├── geoip_cn.txt # 中国大陆IP
│ ├── geosite_cn.txt # 中国大陆网址
│ └── geosite_geolocation-!cn.txt # 非中国大陆网址
└── rule
├── ddnslist.txt # 你的DDNS主域名
├── greylist.txt # 优先通过clash代理获取DNS解析的域名
├── local-ptr.txt # ptr记录
└── whitelist.txt # 优先通过中国大陆DNS服务器获取解析的域名
|
在配置中,由于 fallback
这个后备 tag
的存在,也能保障clash在出现故障时,使用国内DNS服务器进行解析。这一点,再加上 adguardhome
本身也设置了后备节点,两层保障不因clash服务故障而影响DNS的解析。
你也可以参考 mosdns wiki 来进行更加定制化的配置。
启用服务
完全配置好以后,我们可以设置 /etc/systemd/system/mosdns.service
为开启自动启动,并立即启动起来(这时上游clash尚未配置,你可以等后续配置完好以后再来启动它)。
1
|
systemctl enable --now mosdns.service
|
后续如想查看日志,我们直接使用Debian自带的工具来查看:
1
|
journalctl -efu mosdns.service
|
如果想要重启:
1
|
systemctl restart mosdns.service
|
clash
由于clash不仅仅只涉及DNS服务,还涉及到代理、nftables、IP规则相关内容,我们将在接下来的单篇 本系列第(四)篇 中详细详解。
系列