dnsproxy

dnsproxy 安装与使用笔记

这篇笔记记录如何在 Linux 服务器上安装并使用 AdGuardTeam/dnsproxy,通过本机 127.0.0.1:53 提供 DNS 解析服务,并使用 DoH、DoH3、DoQ 等加密 DNS 作为上游。

适用场景

  • 希望服务器本机通过加密 DNS 解析域名
  • 希望统一管理上游 DNS、缓存、hosts 文件和 fallback DNS
  • 希望 dnsproxy 作为 systemd 服务开机自启

一、安装 dnsproxy

先从 dnsproxy 的 GitHub Releases 页面下载适合当前系统架构的二进制文件。

下载地址:

https://github.com/AdguardTeam/dnsproxy/releases

解压后将 dnsproxy 移动到 /usr/local/bin/,并赋予执行权限:

Terminal window
sudo mv dnsproxy /usr/local/bin/dnsproxy
sudo chmod +x /usr/local/bin/dnsproxy

也可以使用 install 一步完成复制和权限设置:

Terminal window
sudo install -m 0755 dnsproxy /usr/local/bin/dnsproxy

检查是否安装成功:

Terminal window
dnsproxy --version

二、检查 53 端口占用

DNS 默认使用 53 端口。dnsproxy 要监听本机 53 端口前,需要确认该端口没有被其他服务占用。

Terminal window
sudo ss -lntup | grep ':53 '

如果看到 systemd-resolved 占用了 53 端口,可以停止并禁用它:

Terminal window
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

注意:某些发行版,例如 Ubuntu,默认依赖 systemd-resolved 管理 DNS。禁用前建议确认自己可以通过 SSH 正常登录,避免误操作后断网。

为了防止临时断网,可以先把 /etc/resolv.conf 临时指向公共 DNS:

Terminal window
echo 'nameserver 8.8.8.8' | sudo tee /etc/resolv.conf

如果 /etc/resolv.conf 是软链接,可以先查看它指向哪里:

Terminal window
ls -l /etc/resolv.conf

必要时删除软链接并重新创建普通文件:

Terminal window
sudo rm /etc/resolv.conf
echo 'nameserver 8.8.8.8' | sudo tee /etc/resolv.conf

三、创建 dnsproxy 配置文件

虽然 dnsproxy 可以直接通过命令行参数启动,但更推荐使用 YAML 配置文件,后续维护更清晰。

创建配置目录:

Terminal window
sudo mkdir -p /etc/dnsproxy

创建配置文件:

Terminal window
sudo vim /etc/dnsproxy/config.yaml

写入以下内容:

# 监听地址和端口
# 127.0.0.1 表示只监听本机,不对局域网开放
listen-addrs:
- "127.0.0.1"
listen-ports:
- 53
# 上游 DNS 服务器
# 这里混合使用 DoQ、DoH3 等加密 DNS
upstream:
- "quic://dns-unfiltered.adguard.com" # AdGuard DoQ
- "h3://1.1.1.1/dns-query" # Cloudflare DoH3
- "h3://8.8.8.8/dns-query" # Google DoH3
# 备用 DNS
# 当上游 DNS 全部不可用时使用
fallback:
- "1.1.1.1"
- "8.8.8.8"
# Bootstrap DNS
# 用于解析上游 DNS 服务器的域名,例如 dns-unfiltered.adguard.com
bootstrap:
- "1.1.1.1"
- "8.8.8.8"
# 缓存设置
# cache-size 单位为字节,67108864 约等于 64 MB
cache-size: 67108864
cache-optimistic: true
# 性能选项
# fastest-addr 会测速并返回较快的 IP
# all-servers 会向所有上游并发查询,速度更快,但请求量也更高
fastest-addr: true
all-servers: true
# 日志设置
verbose: false
output: "/etc/dnsproxy/dnsproxy.log"
# 启用 hosts 文件读取
hosts-file-enabled: true
hosts-files:
- "/etc/hosts"

如果只是给服务器本机使用,监听 127.0.0.1 最稳妥。如果想给局域网其他设备使用,可以改成 0.0.0.0,同时需要配置防火墙,只允许可信网段访问 53 端口。

四、配置 systemd 服务

创建 systemd 服务文件:

Terminal window
sudo vim /etc/systemd/system/dnsproxy.service

写入以下内容:

[Unit]
Description=AdGuard DNS Proxy
After=network.target
Wants=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/dnsproxy --config-path=/etc/dnsproxy/config.yaml
Restart=on-failure
RestartSec=5s
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target

重载 systemd 配置:

Terminal window
sudo systemctl daemon-reload

启动 dnsproxy:

Terminal window
sudo systemctl start dnsproxy

设置开机自启:

Terminal window
sudo systemctl enable dnsproxy

查看服务状态:

Terminal window
sudo systemctl status dnsproxy

查看日志:

Terminal window
sudo journalctl -u dnsproxy -f

也可以查看配置里指定的日志文件:

Terminal window
sudo tail -f /etc/dnsproxy/dnsproxy.log

五、接管系统 DNS

确认 dnsproxy 服务正常运行后,将系统 DNS 指向本机。

编辑 /etc/resolv.conf:

Terminal window
sudo vim /etc/resolv.conf

写入:

nameserver 127.0.0.1
nameserver 8.8.8.8

说明:

  • nameserver 127.0.0.1:首选 DNS,系统会优先请求本机 dnsproxy
  • nameserver 8.8.8.8:备用 DNS,dnsproxy 异常时仍有机会联网修复

如果确认配置稳定,可以锁定 /etc/resolv.conf,防止它被系统或网络管理工具覆盖:

Terminal window
sudo chattr +i /etc/resolv.conf

之后如果需要修改 /etc/resolv.conf,先解锁:

Terminal window
sudo chattr -i /etc/resolv.conf

chattr +i 会让文件不可修改。系统升级、网络管理工具或容器环境中可能会因此出现写入失败,建议只在确认需要时使用。

六、测试 DNS 解析

测试本机 dnsproxy 是否可用:

Terminal window
dig @127.0.0.1 www.google.com

如果结果中看到类似内容,说明解析成功:

status: NOERROR
ANSWER SECTION

也可以测试系统默认 DNS 是否已经走 dnsproxy:

Terminal window
dig www.google.com

检查 dnsproxy 是否正在监听 53 端口:

Terminal window
sudo ss -lntup | grep ':53 '

七、常见问题

1. dnsproxy 启动失败,提示 53 端口被占用

检查端口占用:

Terminal window
sudo ss -lntup | grep ':53 '

如果是 systemd-resolved 占用,可以停止并禁用:

Terminal window
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

然后重启 dnsproxy:

Terminal window
sudo systemctl restart dnsproxy

2. 修改 /etc/resolv.conf 后又被覆盖

先检查它是否是软链接:

Terminal window
ls -l /etc/resolv.conf

如果确认要固定使用自己的 DNS 配置,可以改成普通文件后再使用 chattr +i 锁定。

3. 解析很慢或部分域名失败

可以先关闭并发查询和最快 IP 测速,排查是否是上游兼容性问题:

fastest-addr: false
all-servers: false

修改后重启服务:

Terminal window
sudo systemctl restart dnsproxy

4. 上游使用域名时无法启动或解析失败

确认 bootstrap 配置可用。比如:

bootstrap:
- "1.1.1.1"
- "8.8.8.8"

因为类似 quic://dns-unfiltered.adguard.com 这种上游地址本身需要先被解析,dnsproxy 会使用 bootstrap DNS 完成这一步。

八、完整操作速查

Terminal window
# 安装
sudo install -m 0755 dnsproxy /usr/local/bin/dnsproxy
# 检查 53 端口
sudo ss -lntup | grep ':53 '
# 如有需要,停用 systemd-resolved
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
# 临时设置 DNS,避免断网
echo 'nameserver 8.8.8.8' | sudo tee /etc/resolv.conf
# 创建配置目录
sudo mkdir -p /etc/dnsproxy
# 编辑配置
sudo vim /etc/dnsproxy/config.yaml
# 编辑 systemd 服务
sudo vim /etc/systemd/system/dnsproxy.service
# 启动服务
sudo systemctl daemon-reload
sudo systemctl start dnsproxy
sudo systemctl enable dnsproxy
sudo systemctl status dnsproxy
# 修改系统 DNS
sudo vim /etc/resolv.conf
# 测试
dig @127.0.0.1 www.google.com
dig www.google.com

总结

完成以上配置后,系统会优先通过本机 127.0.0.1:53 请求 dnsproxy,再由 dnsproxy 转发到加密上游 DNS。这样既方便统一管理 DNS 配置,也可以使用缓存、hosts 文件和 fallback DNS 提升稳定性。