惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
O
OpenAI News
D
Docker
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
M
MIT News - Artificial intelligence
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
C
CXSECURITY Database RSS Feed - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
Security Latest
Security Latest
T
Tailwind CSS Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Vulnerabilities – Threatpost
W
WeLiveSecurity
N
News and Events Feed by Topic
aimingoo的专栏
aimingoo的专栏
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Help Net Security
Help Net Security
爱范儿
爱范儿
宝玉的分享
宝玉的分享
腾讯CDC
H
Heimdal Security Blog
Webroot Blog
Webroot Blog
AI
AI
WordPress大学
WordPress大学
Recorded Future
Recorded Future
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
C
Check Point Blog
TaoSecurity Blog
TaoSecurity Blog
Cisco Talos Blog
Cisco Talos Blog
The Cloudflare Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - Franky
云风的 BLOG
云风的 BLOG

atpX

自建 S3 兼容对象存储服务 Garage 听风的歌 偶尔是深夜就好了 新玩具 AirPods Pro 3 公交车上的时间 从 WHOIS 到 RDAP 通过 WireGuard 访问 NFS 共享文件 自建音乐串流服务探索 我停止了探索 Fediverse 互联网背景噪音 我的数字生活降级 小城与确定性的墙 一只特立独行的猪 Fediverse 与社交 承认的勇气 mediaX - 轻量书影音记录管理工具 我的博客写作流程 网站新增 Misc 页面 擅长对线的鲍勃 在 Chroot 环境下使用 Rsync 同步 再见 JavaScript 当我玩博客时我在玩什么 为什么我的博客没有友链页面 小熊猫与大熊猫 (HDR 照片测试) 是时候为网站开启 HTTP/3 支持了吗 谈谈读书与消遣 2023 年终总结 西安两日游 从 AirPods「升级」到 EarPods Docker 搭建去中心化的微博客平台 Mastodon 聊聊 iPhone 15 Pro 使用感受 能否将 TOTP 二次验证存放在密码管理器里 认识史蒂夫·乔布斯 与“锤哥”克里斯·海姆斯沃斯一起养生 逃离爆炸的信息 你想活出怎样的人生 重温《龙珠》动画 为什么关闭评论 从域名注册商到 DNS 服务,找到自己的组合 如何提高用户网页阅读体验 从 Typecho 迁移到 Hugo 个人博客的最终归宿是静态网站吗 我选择了放弃 jQuery 关于我的小破站折腾速度优化这件事 记一次家庭网络折腾 贴一些 SmokePing 记录 我的域名邮箱选择 不存在的语录 Typecho 评论验证插件 CaptchaPlus 谈谈写字这件事 新的网站 Logo 探索 曲线解决 Typecho 图片占位抖动问题 自建 vaultwarden / bitwarden_rs 密码管理器 使用 Plausible 自建网站流量统计分析工具 如何优雅地徒手剥开火腿肠 简单的集中隔离生活记录 新玩具 M2 MacBook Air 使用 acme.sh 申请 Google 公共证书 Docker 搭建去中心化的微博客平台 Misskey 搭建 Lsky Pro 兰空图床 折腾树莓派系统的一天 我的吉卜力之旅 使用 Uptime Kuma 自建服务器/网站在线率监控 Spartan Host Review - Best Hosting & Service Support Debian 下 Nginx 配合 Fail2Ban 减少恶意扫描和攻击 升级 Typecho 到最新开发版本 v1.2.0 Linux rm 命令详解 Debian 系统安装 Docker 教程 BandwagonHost - Reliable Blog and Business VPS Hosting 使用 Isso 为 Hugo/Hexo 等静态网站添加评论功能 推荐 5 款免费开源的网站流量分析统计工具 搭建 Shynet 网站流量统计分析工具 聊聊 DDoS 攻击那些事 Hugo 使用 Fancybox 实现图片灯箱/放大功能 从 Debian 10 升级到 Debian 11 教程 使用 Umami 自建网站流量统计分析工具 Linux 一次执行多个命令的 3 种方式 Typecho 修改永久链接后旧链接 301 跳转到新链接 从不同需求推荐几家稳定可靠的 VPS 服务商 Build EchoIP service with Docker 浅谈一下这些年折腾过的 VPS 单线复用解决一根网线同时 IPTV 和宽带问题 不完全吃灰的树莓派 开发一个自己的 Telegram Bot 使用 Nginx 实现 TCP 四层反向代理 画画真难 我读村上春树 使用 acme.sh 自动签发和更新证书 卡拉马佐夫式悲剧 安装 File Browser 轻量网盘工具 新玩具树莓派到手 Linux 定时自动备份数据到 OneDrive/Google Drive 记一次服务器崩溃 使用 rsync 同步文件 短信的消失 幻灭的艺术家 新玩具戴尔 S2721DGF 开箱 蝴蝶 用 Docker 整合 SeafilePro 搭建私人云盘 搭建自己的 kms 服务器
使用 AdGuard Home 搭建自用 DoH 服务
ATP · 2024-01-25 · via atpX

众所周知,AdGuard Home 是一款很不错的自建 DNS 服务器软件,除了广告拦截之外的功能都挺好用。自己搭建也很简单,参照官方文档几行命令就能搞定。这几年我也一直在使用家里树莓派上搭建的 AdGuard Home 作为局域网 DNS 服务器,体验很不错。这里要分享的是如何通过 Docker Compose 部署 AdGuard Home 并搭建一个私有自用的 DoH 服务,以及如何使用 AdGuard Home 实现 DNS 分流解析。

搭建 AdGuard Home

国内搭建公共 DNS 服务需要申请无法申请的牌照,用国外服务器搭建也会被抢答或者阻断,53(UDP)和 853(DoT)都是重点关注对象,所以目前只推荐使用 443(DoH 或 DoQ)的方式连接。

Docker 的安装使用可以参考前面的文章:Debian 系统安装 Docker 教程

在合适的路径下(假设为 /home/adguardhome)新建一个 docker-compose.yaml 文件,我们只需要 DoH 服务,因此可以只映射容器内的 443 端口出来,3000 端口是 Web 管理页面,可以根据自己需求修改。此外,这里可以选择添加一个 Volume 用来映射域名证书文件,避免后面手动粘贴的麻烦。

免费的 SSL 证书申请可以参考前面的文章:使用 acme.sh 自动签发和更新证书

同时,当你全部配置好正常运行后会发现控制面板首页的统计数据中来源 IP 全是 Docker 的 172 内网 IP 段,这里需要在配置文件中设置 trusted_proxies 参数,指定受信任的来源 IP 地址列表,AdGuard Home 才会获取代理标头(如 X-Real-IP,X-Forwarded-For 等)中的客户端真实 IP 地址。这里也可以先设置 Docker 容器的 IP 地址段,方便后面在配置文件中添加。

综上,你的 docker-compose.yaml 文件可以写成下面这样:

version: "3"

services:
  adguardhome:
    image: adguard/adguardhome:latest
    container_name: adguardhome
    restart: unless-stopped
    ports:
      - 127.0.0.1:8443:443/tcp
      - 127.0.0.1:3000:3000/tcp
    volumes:
      - /home/adguardhome/work:/opt/adguardhome/work
      - /home/adguardhome/conf:/opt/adguardhome/conf
      - /path/to/ssl:/opt/adguardhome/cert
    networks:
      agh_net:
        ipv4_address: 172.18.1.2

networks:
  agh_net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.18.1.0/24

使用 docker compose up 命令拉取镜像生成相关文件后再 ctrl + c 停止,修改 conf/AdGuardHome.yaml 配置文件,找到 trusted_proxies 参数,后面添加一行 172.18.1.0/24:

trusted_proxies:
  - 127.0.0.0/8
  - ::1/128
  - 172.18.1.0/24

然后 docker compose up -d 启动容器服务。

配置 Nginx 和 DoH 服务

在公网搭建 AdGuard Home 最怕的是主动探测和各种扫描,地址暴露后可能会变成公共 DNS 或者被各种攻击,导致你的域名或服务器被玩坏。你可以自行探索 Nginx 鉴权的方法 ,同时 AdGuard Home 本身也支持设置白名单客户端,两种方式相结合可以提高安全性,降低暴露风险。

配置 Nginx

你应该将 AdGuard Home 服务写在 443 server 块中,这里略去其它相关配置,只贴出关键 location 块:

location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://127.0.0.1:3000/;
}
    
location /dns-query {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass https://127.0.0.1:8443/dns-query;
}

这里请将 location /dns-query 路径修改为其它随机字符串,防止主动探测,同时也可以将控制面板路径修改为复杂地址。

你还可以顺便在这里限制来源 IP,只允许你常用的 IP 访问,一般可以设置为你所在地区的公网 IP 段,这种限制方式的缺点是不够灵活。最后你的 Nginx 配置可以类似这样:

location /aghome/ {
    allow 192.168.1.1;
    allow 172.16.0.0/16;
    deny all;
    proxy_cookie_path / /aghome/;
    proxy_redirect / /aghome/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:3000/;
}
    
location /random-string {
    allow 192.168.1.1;
    allow 172.16.0.0/16;
    deny all;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass https://127.0.0.1:8443/dns-query;
}

重载 Nginx 后打开你的域名地址进行安装,只需将第一步中的管理页面地址(Admin Web Interface)端口修改为和上面对应的 3000,其余可以保持默认一直下一步直到完成安装。

配置 DoH 服务

登陆控制面板后台,进入 设置-加密设置 页面,☑️ 启用加密,服务器名称中输入域名,HTTPS 端口填写 443,DNS-over-TLS 端口和 DNS-over-QUIC 端口如果不需要用到留空即可。下面的证书路径填写前面 docker-compose.yaml 中对应的文件路径。

adguard-home-doh

限制 ClientID

AdGuard Home 0.105.0 及之后版本支持为部分加密查询方式设置 ClientID,你可以限制白名单内 ClientID 才能进行查询。对于 DoH 查询,只需要在地址最后加上一段字符串即可,这里以随机 UUID(7017d85e-99d3-46df-bcbc-77a0a33c9cee)举例。

为了方便查看日志,你可以先设置一个持久客户端名称,在 设置-客户端 中添加客户端:

adguard-home-clientid

设置-DNS 设置-访问设置-允许的客户端 中输入该 UUID:

adguard-home-whitelist

完成以上设置后,你可以尝试通过 https://xxx.example.org/random-string/7017d85e-99d3-46df-bcbc-77a0a33c9cee 链接进行 DNS 查询了,并且基本可以确保只有你自己才能使用。

题外话:自建 DNS 服务器在代理过程中的作用

这里说点题外话,如果你是为了搭建无污染的 DNS 在代理工具中使用,效果可能并不明显。在基于 IP 规则分流的代理过程中,DNS 的作用仅仅是在客户端发起请求的第一步中解析域名获得 IP 地址,然后用该 IP 地址来匹配规则,即使得到的是错误的 IP,只要最终命中代理规则,代理工具依然会将域名发送到远程服务器上再次解析并建立连接,此时与你客户端解析获得的 IP 没有关系,所以不会对访问造成影响。

而且这一作用也被今天主流使用的 fake-ip 所弱化,fake-ip 跳过了上面所述的第一步,命中规则的域名不会在本地进行 DNS 解析,代理工具会直接返回一个内网 IP 地址并建立映射关系,同时在远程服务器上解析并连接后通过该内网 IP 地址进行代理。fake-ip 的优势很明显,加快了响应速度,同时也不会造成 DNS 泄漏。但域名规则是写不完的,总有些规则之外的漏网之鱼(小众域名)需要一个可靠的 DNS 解析兜底。 此外 fake-ip 有一些老生常谈的小问题,我个人是不大喜欢的,仍在使用 redir-host 模式。

由此,自建无污染 DNS 服务器在代理过程中的意义只是为了应对部分特殊情况以及获得更好的隐私性,顺便解决被各种「焦虑化」的 DNS 泄漏问题,对大多数人来说属于可有可无的东西。

设置 DNS 分流解析

AdGuard Home 0.107.3 及之后版本支持为指定域名设置 DNS 上游的,也可以直接使用文件列表。前面提到我还有一台树莓派在局域网内运行 AdGuard Home 服务,这时便解锁了一个新的玩法,树莓派上的 AdGuard Home 设置 DNS 分流解析。

可以实现国内域名通过 AliDNS 或 DNSPod 进行解析,其余域名通过自建的海外 DoH 服务进行解析,配合 AdGuard Home 的乐观缓存,也不会对速度造成多大影响。不过由于国内域名列表肯定是不完整的,不在列表中的域名会通过海外 DoH 解析,得到的 IP 结果是国内的还好,可以直接连接,否则会通过远程服务器连接,此时要是该域名有国内 CDN 节点就绕远了。因此比较依赖规则文件的及时更新和准确性,最后选择了使用 dnsmasq-china-list 项目。

这里写了一个 shell 脚本将 dnsmasq-china-list 发布的文件转换为 AdGuard Home 能识别的格式,如有需要可以参考修改。

#!/bin/bash
# Writen by ATP on Jan 25, 2024
# Website: https://atpx.com

# AdGuard Home 项目路径
AGH_PATH="/home/adguardhome"
# 国内 DNS 服务器,多个用空格隔开
CN_DNS="https://223.6.6.6/dns-query https://120.53.53.53/dns-query"
# 海外 DNS 服务器
GLOBAL_DNS="https://xxx.example.org/random-string/7017d85e-99d3-46df-bcbc-77a0a33c9cee"
# dnsmasq-china-list 规则文件,无法下载的话可以找 CDN 或自建反代
accelerated_domains="https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf"
apple_domains="https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf"

# 下载文件并合并
wget -O "$AGH_PATH/cn-domains.conf" $accelerated_domains
wget -O "$AGH_PATH/cn-apple.conf" $apple_domains
cat "$AGH_PATH/cn-apple.conf" >> "$AGH_PATH/cn-domains.conf"

# 转换为 AdGuard Home 格式
awk -v CN_DNS="$CN_DNS" -F/ '/server=/{print "[/"$2"/]"CN_DNS}' "$AGH_PATH/cn-domains.conf" > "$AGH_PATH/cn-dns.txt"

# 添加默认海外 DNS
sed -i "1i\\$GLOBAL_DNS" "$AGH_PATH/cn-dns.txt"

# 移动文件到 AdGuard Home 目录
mv "$AGH_PATH/cn-dns.txt" "$AGH_PATH/work/data/"

# 清理临时文件
rm "$AGH_PATH/cn-domains.conf"
rm "$AGH_PATH/cn-apple.conf"

echo "规则转换完成"

# 重启 AdGuard Home
# cd $AGH_PATH
# docker compose restart

停止 AdGuard Home 后编辑目录下配置文件 conf/AdGuardHome.yaml,找到 upstream_dns_file: "" 参数,修改为:

upstream_dns_file: /opt/adguardhome/work/data/cn-dns.txt

然后启动 AdGuard Home 即可实现 DNS 分流解析。最后你可以设置一个 crontab 任务,定时执行脚本自动更新域名规则并重启 AdGuard Home,这里不再赘述。