3842 字
19 分钟
AdGuardHome 完整配置指南:打造纯净DNS

AdGuardHome 完整配置指南:打造纯净DNS#

上个月路由器挂了,重装系统后顺手把 AdGuardHome 也升级了一下。折腾了两天,发现现在的配置跟两年前差别挺大。趁着记忆还新鲜,把完整的配置写下来,顺便也聊聊这几年用下来的感受。

说实话,AdGuardHome 这种工具,配置一次能用很久。但正因为这样,配置文件一旦丢失,重新配起来就很痛苦。这篇文章既是给自己备份,也希望对刚接触的朋友有点帮助。

为什么要用 AdGuardHome#

先回答一个常见问题:直接用运营商的 DNS 不行吗?或者 Cloudflare、阿里这种公共 DNS?

可以用。但 AdGuardHome 能做的事情远不止转发 DNS 请求:

去广告。这是最直观的好处。浏览网页时,页面加载速度变快了,视频前没有 30 秒广告,App 里那些烦人的弹窗也少了。拦截是在 DNS 层做的,不需要在每台设备上装插件。

防劫持。某些运营商会劫持 DNS,把正常请求重定向到广告页,或者干脆报错页面。AdGuardHome 用加密协议跟上游通信,运营商只能看到你在连某个服务器,但不知道你在查什么域名。

隐私保护。查 DNS 这个动作本身就在泄露隐私——运营商知道你在访问哪些网站。AdGuardHome 可以通过 DoH、DoT 加密查询,向发送的每一级都只能看到加密的流量。

统一管理。所有设备都走这一个入口,拦截规则、访问控制、查询日志全在一个地方。孩子用的平板可以单独配家长控制,自己的工作机可以走不同的上游。

当然,它也不是完美的。跟浏览器插件比,DNS 层拦截粒度粗一些,没法针对页面元素处理。遇到有些域名,cdn.example.com 可能既用来加载广告也用来加载正常内容,一刀切可能会误伤。但总体利大于弊。

完整配置文件#

这是我的生产环境配置,已经稳定跑了小半年。敏感信息(用户名、API密钥等)已脱敏处理,你可以直接复制使用,只需要改一下密码。

http:
pprof:
port: 6060
enabled: false
address: 0.0.0.0:3000
session_ttl: 720h
users:
- name: admin
password: $2a$10$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
auth_attempts: 5
block_auth_min: 15
http_proxy: ""
language: ""
theme: auto
dns:
bind_hosts:
- 0.0.0.0
port: 5625
anonymize_client_ip: false
ratelimit: 0
ratelimit_subnet_len_ipv4: 24
ratelimit_subnet_len_ipv6: 56
ratelimit_whitelist: []
refuse_any: false
upstream_dns:
- h3://dns.alidns.com/dns-query
- https://doh.360.cn/dns-query
- https://doh.pub/dns-query
- https://sm2.doh.pub/dns-query
- quic://dns.alidns.com
- tls://dns.alidns.com
- tls://dot.360.cn
- tls://dot.pub
upstream_dns_file: ""
bootstrap_dns:
- 180.184.1.1
- 180.184.2.2
fallback_dns: []
upstream_mode: parallel
fastest_timeout: 1s
allowed_clients: []
disallowed_clients: []
blocked_hosts:
- version.bind
- id.server
- hostname.bind
trusted_proxies:
- 127.0.0.0/8
- ::1/128
cache_enabled: true
cache_size: 8388608
cache_ttl_min: 60
cache_ttl_max: 86400
cache_optimistic: true
cache_optimistic_answer_ttl: 30s
cache_optimistic_max_age: 12h
bogus_nxdomain: []
aaaa_disabled: false
enable_dnssec: true
edns_client_subnet:
custom_ip: ""
enabled: true
use_custom: false
max_goroutines: 300
handle_ddr: true
ipset: []
ipset_file: ""
bootstrap_prefer_ipv6: true
upstream_timeout: 5s
private_networks: []
use_private_ptr_resolvers: true
local_ptr_upstreams: []
use_dns64: false
dns64_prefixes: []
serve_http3: true
use_http3_upstreams: true
serve_plain_dns: true
hostsfile_enabled: false
pending_requests:
enabled: true
tls:
enabled: false
server_name: ""
force_https: false
port_https: 443
port_dns_over_tls: 853
port_dns_over_quic: 853
port_dnscrypt: 0
dnscrypt_config_file: ""
allow_unencrypted_doh: false
certificate_chain: ""
private_key: ""
certificate_path: ""
private_key_path: ""
strict_sni_check: false
querylog:
dir_path: ""
ignored: []
interval: 1h
size_memory: 1000
enabled: true
ignored_enabled: false
file_enabled: false
statistics:
dir_path: ""
ignored: []
interval: 24h
enabled: true
ignored_enabled: false
filters:
- enabled: true
url: https://adrules.top/dns.txt
name: AdRules
id: 1765543189
- enabled: true
url: https://anti-ad.net/easylist.txt
name: anti-AD
id: 1765543190
- enabled: true
url: https://cdn.uura.cn/AWAvenue/AWAvenue-Ads-Rule.txt
name: AWAvenue Ads Rule
id: 1772008847
whitelist_filters: []
user_rules:
- '||example.com^'
- '||internal.lan^'
dhcp:
enabled: false
interface_name: ""
local_domain_name: lan
dhcpv4:
gateway_ip: ""
subnet_mask: ""
range_start: ""
range_end: ""
lease_duration: 86400
icmp_timeout_msec: 1000
options: []
dhcpv6:
range_start: ""
lease_duration: 86400
ra_slaac_only: false
ra_allow_slaac: false
filtering:
blocking_ipv4: ""
blocking_ipv6: ""
blocked_services:
schedule:
time_zone: UTC
ids: []
protection_disabled_until: null
safe_search:
enabled: false
bing: true
duckduckgo: true
ecosia: true
google: true
pixabay: true
yandex: true
youtube: true
blocking_mode: default
parental_block_host: family-block.dns.adguard.com
safebrowsing_block_host: standard-block.dns.adguard.com
rewrites: []
safe_fs_patterns:
- /data/AdGuardHome/userfilters/*
safebrowsing_cache_size: 1048576
safesearch_cache_size: 1048576
parental_cache_size: 1048576
cache_time: 30
filters_update_interval: 24
blocked_response_ttl: 10
filtering_enabled: true
rewrites_enabled: true
parental_enabled: false
safebrowsing_enabled: false
protection_enabled: true
clients:
runtime_sources:
whois: true
arp: true
rdns: true
dhcp: true
hosts: true
persistent: []
log:
enabled: true
file: ""
max_backups: 0
max_size: 100
max_age: 3
compress: false
local_time: false
verbose: false
os:
group: ""
user: ""
rlimit_nofile: 0
schema_version: 33

文件保存后,放在 /data/AdGuardHome/ 目录下,启动时会自动读取。

核心配置详解#

接下来逐段解释这些配置的含义和选型思路。有些配置项看着简单,实际用下来有不少坑。

1. Web 界面与安全设置#

http:
address: 0.0.0.0:3000
session_ttl: 720h
users:
- name: admin
password: $2a$10$...
auth_attempts: 5
block_auth_min: 15

address 绑定了管理界面的监听地址和端口。0.0.0.0 表示所有网卡都能访问,如果你只需要本地管理,改成 127.0.0.1 更安全。

session_ttl: 720h 把登录会话有效期设成了 30 天,免去了频繁登录的麻烦。这个值设太长有风险,但家用环境问题不大。

密码必须用 bcrypt 哈希,明文写进去不会生效。生成 bcrypt 密码的命令:

Terminal window
docker exec adguardhome ./AdGuardHome --glinet-hash-password

auth_attempts: 5block_auth_min: 15 是防暴力破解:5 次失败后锁定 15 分钟。这个阈值对家用足够了,正常不会触发。

2. DNS 上游服务器配置#

这是最重要的部分,直接决定了查询速度、准确性和隐私安全。

dns:
upstream_dns:
- h3://dns.alidns.com/dns-query
- https://doh.360.cn/dns-query
- https://doh.pub/dns-query
- https://sm2.doh.pub/dns-query
- quic://dns.alidns.com
- tls://dns.alidns.com
- tls://dot.360.cn
- tls://dot.pub

配置了 8 个上游,涵盖了四种加密协议:

h3:// 是基于 HTTP/3 的 DoH,用了 QUIC 传输层,延迟更低。阿里 DNS 和腾讯 DNS 都支持,但需要双方都支持才能生效。

https:// 是标准 DoH,兼容性最好。阿里、360、腾讯的国内节点,响应速度都在 10ms 以内。

tls:// 是 DoT,DNS-over-TLS。配置简单,就是端口 853 的 TLS 连接。有些防火墙会限制这个端口,不如 443 通用。

quic:// 是 DNS-over-QUIC,直接在 QUIC 上传输 DNS,没有 HTTP 封装。延迟很低,但部分设备支持不好。

为什么配这么多?AdGuardHome 默认采用并行查询模式,会向所有上游同时发送请求,谁先返回用谁的结果。多配几个相当于多路竞争,能提高成功率。

upstream_mode: parallel 就是这个并行模式。还有一个选项是 fastest_ip,会等所有上游都返回后,选择响应最快的那个 IP。这个模式延迟会高一点,但能确保拿到最快的 CDN 节点。

3. Bootstrap DNS#

bootstrap_dns:
- 180.184.1.1
- 180.184.2.2

这是一个容易踩坑的地方。

上游 DNS 的地址往往是域名形式,比如 dns.alidns.com。但 AdGuardHome 在启动时需要先知道这些上游的 IP 地址,才能去连接它们。如果这时候去问 “dns.alidns.com 的 IP 是多少”,又需要 DNS,这就成了鸡生蛋蛋生鸡的问题。

Bootstrap DNS 就是用来打破这个循环的。它必须是 IP 地址,不能是域名。180.184.1.1 和 180.184.2.2 是字节 DNS 的地址,国内访问速度快。

4. 缓存配置#

cache_enabled: true
cache_size: 8388608
cache_ttl_min: 60
cache_ttl_max: 86400
cache_optimistic: true
cache_optimistic_answer_ttl: 30s
cache_optimistic_max_age: 12h

缓存是提升性能的关键。配置里有几个参数需要理解:

cache_size: 8388608 是 8MB 内存缓存,家用绰绰有余。按每个记录几百字节算,能存几万条记录。

cache_ttl_min: 60cache_ttl_max: 86400 限制了缓存记录的存活时间。即使上游返回的 TTL 只有几秒,也会至少缓存 60 秒;即使上游说可以缓存一周,最多也只存一天。这是为了防止上游设置不合理的 TTL。

cache_optimistic: true 是乐观缓存,强烈推荐开启。它的工作原理是:当缓存记录过期后,先返回缓存中的旧结果(并把 TTL 设为 30 秒),同时后台去刷新。这样用户不会感知到延迟,体验更流畅。

有个细节需要注意:乐观缓存返回的过期记录,TTL 是 cache_optimistic_answer_ttl 设置的 30 秒,而不是原记录的 TTL。如果这段时间内上游刷新失败了,用户可能会拿到一个已经失效的 IP。但权衡之下,这点风险换来的是用户体验的大幅提升。

5. EDNS Client Subnet#

edns_client_subnet:
enabled: true
use_custom: false

ECS(EDNS Client Subnet)是一项 DNS 扩展,作用是把客户端的子网信息传给上游 DNS。没有这个,CDN 只能根据 DNS 服务器的 IP 来选择节点,可能选到离用户很远的节点。

比如你在上海,用的 DNS 服务器在北京。没有 ECS,CDN 以为你在北京,可能给你分配一个北京的节点,延迟就高了。有 ECS 后,CDN 知道你在上海,会优先分配上海节点。

开启这个选项能让解析结果更准确,但也有隐私代价:上游 DNS 能看到你的大致位置(城市级别)。如果你觉得隐私更重要,可以关掉。

6. DNSSEC#

enable_dnssec: true

DNSSEC 用来防止 DNS 欺骗(DNS spoofing)。它通过数字签名确保返回的记录没有被篡改。

但这个功能在国内有些尴尬。很多国内域名没有启用 DNSSEC,开了之后反而可能解析失败。不过主流的国际域名(.com、.org 等)都支持,开着也没坏处。

如果某天发现某些网站打不开,可以试试临时关掉这个选项排查问题。

7. 过滤器列表#

filters:
- enabled: true
url: https://adrules.top/dns.txt
name: AdRules
id: 1765543189
- enabled: true
url: https://anti-ad.net/easylist.txt
name: anti-AD
id: 1765543190
- enabled: true
url: https://cdn.uura.cn/AWAvenue/AWAvenue-Ads-Rule.txt
name: AWAvenue Ads Rule
id: 1772008847

过滤器是去广告的核心。这三份是国内维护的高质量列表:

  • AdRules: 规则数量适中,更新频繁,误杀少
  • anti-AD: 专注中文环境,对一些国产 App 的广告域名覆盖很全
  • AWAvenue Ads Rule: 主要针对移动端广告,对 App 启动广告、弹窗广告效果好

为什么不直接用 AdGuard 自带的列表?自带的列表针对国际环境优化,对中文广告覆盖不够。这三份列表互补,日常浏览基本看不到广告。

filters_update_interval: 24 表示每天自动更新一次。广告域名变化很快,自动更新很重要。

8. 用户自定义规则#

user_rules:
- '||example.com^'
- '||internal.lan^'

自定义规则优先级最高,可以用来覆盖过滤器列表的决定。

||example.com^ 这种格式表示拦截整个域名及所有子域名。开头的 || 是通配符,表示匹配任何子域名;结尾的 ^ 是边界符,表示域名结束。

如果你发现某个域名被误杀,可以用 @@||example.com^ 放行(两个 @@ 表示例外规则)。

9. TLS 加密配置#

tls:
enabled: false
port_https: 443
port_dns_over_tls: 853
port_dns_over_quic: 853

我目前没启用 TLS,因为只在局域网使用。如果你要把 AdGuardHome 暴露到公网(比如放在 VPS 上给多台设备用),必须启用 TLS 并配置证书。

配置证书后,远程设备可以通过 DoH/DoT 安全地访问你的 DNS 服务器,运营商无法窥探查询内容。

10. DHCP 设置#

dhcp:
enabled: false

DHCP 功能默认关闭。如果你的路由器 DHCP 功能不够好(比如不能指定 DNS),可以在这里开启,让 AdGuardHome 接管 DHCP。

但我建议保持关闭。专业的事交给专业设备,路由器做 DHCP 更稳定。AdGuardHome 专注做好 DNS 就行。

Docker 部署指南#

我目前用 Docker Compose 部署,配置如下:

version: '3'
services:
adguardhome:
image: adguard/adguardhome:latest
container_name: adguardhome
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "3000:3000/tcp"
- "5625:5625/tcp"
- "5625:5625/udp"
volumes:
- ./data:/opt/adguardhome/work
- ./config:/opt/adguardhome/conf
environment:
- TZ=Asia/Shanghai

端口说明:

  • 53:53 是标准 DNS 端口,方便内网设备直接指定
  • 3000:3000 是 Web 管理界面
  • 5625:5625 是 AdGuardHome 实际监听的 DNS 端口(因为非 root 用户不能绑定 53 端口)

如果你不想把主机的 53 端口给 Docker,可以改成 5625:53,然后在主机的 iptables 里做端口转发:

Terminal window
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 5625
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-port 5625

这样对外还是标准的 53 端口,对内转发到 5625。

持久化数据:

  • ./data 存放工作数据,包括查询日志、统计信息、过滤器缓存等
  • ./config 存放配置文件(AdGuardHome.yaml)

启动命令:

Terminal window
docker-compose up -d

第一次启动后,打开 http://服务器IP:3000 完成初始化向导,然后就可以把配置文件复制进去覆盖了。

系统服务配置(非 Docker)#

如果你不用 Docker,直接跑二进制文件,建议配置成系统服务。

Systemd 服务文件/etc/systemd/system/adguardhome.service):

[Unit]
Description=AdGuard Home
After=network.target
[Service]
Type=simple
User=adguard
Group=adguard
WorkingDirectory=/opt/adguardhome
ExecStart=/opt/adguardhome/AdGuardHome -c /opt/adguardhome/AdGuardHome.yaml
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target

创建专用用户:

Terminal window
sudo useradd -r -s /bin/false adguard
sudo mkdir -p /opt/adguardhome
sudo chown adguard:adguard /opt/adguardhome

授权非 root 绑定 53 端口:

Terminal window
sudo setcap 'cap_net_bind_service=+ep' /opt/adguardhome/AdGuardHome

启动服务:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable adguardhome
sudo systemctl start adguardhome

性能优化建议#

用了这么久,总结几个提升性能的经验:

1. 观察缓存命中率

登录 Web 界面,在「统计」页面可以看到缓存命中率。家用环境一般能在 70% 以上,如果低于这个数,可能需要:

  • 增大 cache_size
  • 检查是不是上游响应太慢,导致缓存未命中就超时了

2. 上游不要贪多

我配了 8 个上游,但实际上 3-4 个高质量的就够了。配太多会增加并发查询的网络开销,而且有些上游可能根本不会被用到。

3. 调整超时时间

upstream_timeout: 5s

默认 10 秒太长,用户等不及。改成 5 秒,如果某个上游 5 秒内没响应就放弃,换其他上游的结果。

4. 定期清理过滤器

过滤器列表越多,内存占用越大,匹配速度越慢。建议只保留最常用的 3-5 个列表。如果发现某个列表长期不更新或者误杀严重,果断移除。

5. 限制并发连接

max_goroutines: 300

这个参数限制最大并发处理的查询数。家用环境 300 足够,如果设备很多可以适当调高。

6. 启用 HTTP/3

serve_http3: true
use_http3_upstreams: true

如果你的设备和上游都支持 HTTP/3,开启后 Web 界面加载会更快。DoH 查询也会优先尝试 HTTP/3。

常见问题排查#

问题 1:部分网站打不开

可能是被过滤器误杀。查看查询日志,找到被拦截的域名,加入白名单:

user_rules:
- '@@||example.com^'

问题 2:解析速度慢

检查上游 DNS 的响应时间。在服务器上手动测试:

Terminal window
dig @180.184.1.1 baidu.com

如果某个上游响应慢,从配置里移除。

问题 3:缓存不生效

检查 cache_enabled 是否为 true,以及 cache_size 是否足够大。如果配置正确但缓存始终为空,可能是权限问题,检查数据目录的写入权限。

问题 4:Docker 启动后无法访问 Web 界面

检查端口映射是否正确,防火墙是否放行 3000 端口。如果是远程服务器,确认安全组规则允许入站流量。

总结#

AdGuardHome 的配置不算复杂,但要调优需要理解每个参数的含义。这篇文章的配置已经经过实战检验,你可以直接复制使用,然后根据实际需求微调。

核心思路:

  • 上游用多协议并行查询,提高可靠性和速度
  • 开启乐观缓存,大幅改善用户体验
  • 过滤器用国内维护的列表,对中文环境更友好
  • Docker 部署最省心,配合端口转发对外暴露标准 DNS 端口

如果你也在用 AdGuardHome,欢迎分享你的配置经验。DNS 优化是一件持续迭代的事,总有新的技巧和更好的实践。


参考链接:

AdGuardHome 完整配置指南:打造纯净DNS
https://im.awsl.app/posts/networking/080-adguardhome-config/
作者
uu
发布于
2026-03-02
许可协议
CC0 1.0