用 Dnspooh 自建安全 DNS 服务器
Dnspooh 是一款使用 Python 开发的开源 DNS 代理/中继,支持 DoH 和 DoT 协议。用户可以将 Dnspooh 部署在本地,借助它可以让不支持 DoH 和 DoT 协议的客户端应用或操作系统使用安全的 DNS 服务,从而避免被运营商或网管之类的中间人劫持或嗅探。
除此之外, Dnspooh 还支持可插拔中间件用于扩展软件功能。 Dnspooh 内置了几个比较有用的中间件:缓存中间件用于加速访问;黑名单中间件用于屏蔽域名和 IP 地址; Hosts 中间件用于自定义解析结果;日志中间件用于记录解析记录、监控应用行为;规则中间件提供更加灵活复杂的操作。
安装和运行
Windows 用户可以下载已编译好的软件包,从下面的网页找到最新版的软件(目前版本为 1.3.0 ):
将压缩包释放到本地任意目录下,执行 dnspooh\dnspooh.exe
便可以启动程序。也可以以管理员身份运行 dnspooh\service-install.bat
,将 Dnspooh 安装为 Windows 服务。同理,运行 dnspooh\service-uninstall.bat
可以卸载服务。
右键点击 service-install.bat
或 dnspooh\service-uninstall.bat
文件,在右键菜单中选择「以管理员身份运行」。
也可以用 scoop 命令进行安装:
powershellscoop install https://github.com/tabris17/dnspooh/releases/latest/download/dnspooh.json
安装成功后,以管理员身份运行下面的命令将 Dnspooh 安装为 Windows 服务:
powershelldnspooh install
用下面的命令卸载服务:
powershelldnspooh uninstall
其他平台用户需要安装 Python 3.10 或以上版本,通过 pip 命令进行安装:
shellpip install dnspooh
以 pip 方式安装的 Dnspooh 不提供默认配置文件和 Web 管理界面的前端资源,用户可以从 Windows 安装包内提取 dnspooh\config
和 dnspooh\public
两个文件夹,并保存到当前工作目录。然后运行命令 dnspooh
,程序启动时会自动加载 config/config.yml
配置文件。
需要注意的是,由于 Dnspooh 服务使用到 53 端口,所以可能需要以管理员权限运行。
基础配置
Dnspooh 的配置文件是 YAML 格式的。默认的配置文件 config/config.yml
的内容如下:
yaml# 设置用于访问上游 DNS 服务器的代理(默认未开启)
# 支持 socks5 和 http 代理
# socks5 代理支持所有类型的 DNS 服务器
# http 代理仅支持 DoH 和 DoT 协议的 DNS 服务器
# proxy: socks5://127.0.0.1:1080
# 仅启用 DoT 和 DoH 协议的上游 DNS 服务器
secure: true
# 将 stdout 输出到日志文件
output: !path ../log/output.txt
# 加载 hosts 文件
hosts:
- !path hosts
- https://raw.hellogithub.com/hosts # 提供中国境内可用的 github IP
# 启用 Web 管理界面
# 浏览器打开 http://127.0.0.1:23315
http:
root: !path ../public
port: 23315
# 加载黑名单文件
# block.txt 包含广告和恶意网站的域名,以及运营商劫持 DNS 解析的 IP
block:
- !path block.txt
# 记录 DNS 请求
# access.log 为 sqlite3 数据库
log:
path: !path ../log/access.log
# 加载规则配置
# cn-domain.yml 规则:如果是中国的网站域名,则使用中国境内的 DNS 服务器解析
rules:
- !include cn-domain.yml
# 启用的中间件列表
# 可以将不用的中间件注释掉,但最好不要修改列表顺序
middlewares:
- rules
- hosts
- block
- cache
- log
用户修改配置文件后,需要重启服务才能使更改生效。更多细节请访问用户手册和配置说明。
如果用户设置了 secure: false
,且没有设置代理或使用 http 代理的情况下,用户的 DNS 请求可能仍然是明文且可被劫持的;如果使用本地 socks5 代理,则安全性取决于代理服务上游协议本身。
HOSTS
Hosts 中间件用于用户自定义域名解析。允许加载一个或多个 hosts 文件,hosts 文件可以是本地文件,也可以是 URL 地址。用户可以在默认配置的 config/hosts
文件中写入自定义解析记录。
hosts 文件每行是一条记录,格式和系统 hosts 一致。支持 IPv4 和 IPv6 地址,分别对应 A 记录和 AAAA 记录。相同的域名允许同时存在多条记录,该域名的解析结果会包含多个 IP 地址记录。
黑名单
黑名单中间件用于屏蔽域名和 IP 地址,允许加载一个或多个黑名单,文件可以是本地文件,也可以是 URL 地址。
黑名单中每行为一条记录。黑名单中的域名不支持通配符,不过会屏蔽该域名及其子域名。比如,黑名单中存在 abc.com
记录,则 www.abc.com
, www.xyz.abc.com
等子域名也将被一起屏蔽。若要屏蔽 IP 地址,则需要在 IP 地址前加上 ip:
前缀 。例如 ip:127.0.0.1
将屏蔽解析记录中包含 127.0.0.1
的 DNS 解析。所有被屏蔽的 DNS 请求将得到 NXDOMAIN
(域名不存在)的响应。
默认配置内置的 config/block.txt
黑名单包含了广告和恶意网站域名,以及运营商用于域名劫持的服务器 IP 地址。如果用户需要建立自己的黑名单,建议新建另一个黑名单配置文件。比如修改配置文件内容为:
yamlblock:
- !path block.txt
- !path user-block.txt
然后在 config
目录下新建 user-block.txt
黑名单文件。
自定义规则
规则中间件为用户提供了更高的定制自由度,允许用户按条件屏蔽或修改请求及响应、选择上游 DNS 服务器、设置代理、执行命令等一系列操作。默认配置中的 config\cn-domain.yml
的规则为:如果是中国的网站域名,则使用中国境内的 DNS 服务器解析。
由于自定义规则可以运行任意命令,有一定的安全性风险,所以不要使用来历不明的配置文件。这个功能可能在后期会进行调整。
规则中间件会影响 DNS 解析响应速度,如果用户不需要,最好禁用此中间件。下面是一些常用的规则案例:
案例一:屏蔽广告域名
如果域名中包含 lianmeng
, adwords
, adservice
关键字则屏蔽,且不再处理其他规则:
yamlrules:
- if: (lianmeng, adwords, adservice) in domian
then: block
end: true
案例二:指定 DNS 服务器
如果是 .cn
或 .top
结尾的域名,将使用中国境内的 DNS 服务器来解析。对于使用 CDN 的网站:
yamlrules:
- if: domain ends with (.cn, .top)
before: set upstream group to cn
案例三:指定代理服务器
总是使用 google 的 DNS 服务,并使用指定的代理服务器访问:
yamlrules:
- if: always
before: set upstream group to google, set proxy to socks5://127.0.0.1:1080
案例四:根据解析结果执行命令
如果域名解析结果中的 IP 所在地位于中国境内,则为本机此 IP 地址添加的路由规则(适用于启用全局 VPN 的场景):
yamlrules:
- if: always
after: run "sudo route add {ip} mask 255.255.255.255 192.168.1.1" where geoip is cn
命令语句中可以用 {ip}
占位符来表示当前记录的 IP 地址;用 {domain}
占位符来表示当前域名。
管理面板
默认配置启用了 Web 管理面板,在浏览器中访问 http://127.0.0.1:23315 就可以看到管理界面:

管理界面的主页显示了服务运行状态。用户修改配置文件后,可以通过首页上的「重启」按钮来使配置生效。
在「上游节点」页面中可以查看全部可用的 DNS 节点。默认配置下启用 13 个安全上游节点。程序会自动推选响应最快的节点作为默认节点,也可以在管理面板中手动设置默认节点。

在不使用代理的情况下,中国境内网络无法访问 Google DNS 节点。通常情况下,阿里的 DoT 服务器是中国境内响应最快的节点。Adguard 节点提供广告过滤功能,会屏蔽广告和恶意网站的域名。用户可以按照自己的需求选择。
在「解析日志」页面中可以查看和搜索 DNS 解析日志。其中「跟踪」字段记录了该次 DNS 请求经历的中间件和最终用于解析请求的 DNS 服务器名称。
