使用Nginx+AdGuard家庭搭建的DOH服务
分享一下自己在使用AdGuardHome 搭建的DOH 服务
今天看到大量的人讨论dns污染,以及海外一些doh服务被阻塞的帖子,故而分享一下我在使用AdGuardHome搭建的DOH服务的配置。
下面分享使用nginx和AdGuardHome搭建的DOH服务。
实现的效果:多个服务共享443端口,不必担心端口占用。提供doh服务进行dns解析,同时可以提供dot、doq服务进行dns解析,以及AdGuardHome的广告过滤功能。
个人用了两个月,很稳定。
一些个人观点
DOH,DOT,DOQ均属于加密dns,可以在一定的编程中防止
基于HTTPS的DNS和基于TLS的DNS | 安全域名系统
个人推荐使用DOH
理由:DOT、DOQ默认使用853端口,具备一定的特征,如果使用其他端口则需要客户端支持指定端口。DOH默认使用443端口,和普通的https流量混在一起,比较难识别。
以上为个人观点,如有不同观点,欢迎各位大佬在评论区进行讨论
nginx、AdGuardHome安装和卸载(基于命令行debian12,其他系统参考官方文档)
1.nginx安装
#安装相关依赖工具
apt install -y curl gnupg2 ca-certificates lsb-release
#添加 Nginx 官方签名密钥
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
#设置官方仓库源(后续可以使用apt命令升级nginx)
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian $(lsb_release -cs) nginx" | tee /etc/apt/sources.list.d/nginx.list
#更新依赖并安装nginx
apt update
apt install -y nginx
2.nginx卸载
apt remove -y nginx
apt purge -y nginx
apt autoremove -y
#删除相关文件(如果需要)
rm -rf /etc/nginx
rm -rf /var/log/nginx
...
3.AdGuardHome安装
#1.使用官方安装脚本(安装目录在/opt/AdGuardHome)
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v
#2.手动安装(以在/{自定义目录}/AdGuardHome为安装目录为例)
cd /{自定义目录}
#到官方仓库选择自己喜欢的版本
wget https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.107.57/AdGuardHome_linux_amd64.tar.gz
#解压压缩包
tar xvf AdGuardHome_linux_amd64.tar.gz
cd /{自定义目录}/AdGuardHome
./AdGuardHome -s install
4.AdGuardHome卸载
手动安装
./{自定义目录}/AdGuardHome/AdGuardHome -s uninstall
#删除相关文件(如果需要)
rm -rf /{自定义目录}/AdGuardHome
nginx、AdGuardHome 欠缺使用 systemctl 管理服务的启动、停止、重启等操作,基础不够,自行GG
nginx配置
1.nginx Stream模块的sni分流配置文件路径:/etc/nginx/modules-enabled/stream.conf
请确保/etc/nginx/nginx.conf中的配置引用了/etc/nginx/modules-enabled/目录下的配置,
include /etc/nginx/modules-enabled/*.conf;
确认安装的nginx加载了steam模块,默认Debian仓库的nginx不包含steam模块,建议使用教程中的安装方法安装模块较为完整的nginx。
nginx -V
在输出的信息中,表示找到–with-stream参数。如果存在该参数,则启用了stream模块。
流模块的sni分流是通过证书的域名进行分流,所以需要提前准备好证书,如果开启http2多路复用则不建议使用泛域名证书!!!
stream {
map $ssl_preread_server_name $sni_backend {
{域名} doh;
www.tesla.com proxy_reality2direct;
apps.apple.com proxy_reality2route;
default web;
}
upstream web {
server unix:/dev/shm/web.sock;
}
upstream doh {
server unix:/dev/shm/doh.sock;
}
upstream proxy_reality2direct {
server unix:/dev/shm/proxy_reality2direct.sock;
}
upstream reality2direct {
server 127.0.0.1:3729;
}
upstream proxy_reality2route {
server unix:/dev/shm/proxy_reality2route.sock;
}
upstream reality2route {
server 127.0.0.1:3726;
}
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $sni_backend;
# 启用代理协议
proxy_protocol on;
# 启用 SSL 预读模块
ssl_preread on;
# 拒绝不匹配的 SNI
# ssl_reject_handshake on;
tcp_nodelay on;
}
server {
listen unix:/dev/shm/proxy_reality2direct.sock proxy_protocol;
set_real_ip_from unix:;
# 代理到 Reality 后端
proxy_pass reality2direct;
}
server {
listen unix:/dev/shm/proxy_reality2route.sock proxy_protocol;
set_real_ip_from unix:;
# 代理到 Reality 后端
proxy_pass reality2route;
}
}
2.doh反代配置文件路径:/etc/nginx/sites-enabled/ad_guard_home.conf
server {
listen unix:/dev/shm/doh.sock ssl proxy_protocol;
http2 on;
server_name {域名};
# 如果需要启用 SSL 证书,可以启用以下配置
ssl_certificate /etc/nginx/ssl/域名证书.cer;
ssl_certificate_key /etc/nginx/ssl/证书密钥.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# 静态文件目录,伪装成一个普通的网站
root /usr/share/nginx/html;
set_real_ip_from unix:;
real_ip_header proxy_protocol;
charset 'utf-8';
location /dashboard {
# AdGuardHome 的配置页面
proxy_pass http://127.0.0.1:3000;
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_set_header X-Forwarded-Proto $scheme;
# 修正 AdGuardHome 的重定向路径
proxy_redirect / /dashboard/;
# 避免 AdGuardHome 的重复路径前缀
rewrite ^/dashboard(/.*)?$ $1 break;
}
location {path}/{自定义path} {
proxy_buffering off;
proxy_redirect off;
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_set_header X-Forwarded-Proto $scheme;
# 端口
# 这里的 Path 必须为 dns-query
proxy_pass https://127.0.0.1:1787/dns-query;
}
location {path}/common {
proxy_buffering off;
proxy_redirect off;
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_set_header X-Forwarded-Proto $scheme;
# 端口
# 这里的 Path 必须为 dns-query
proxy_pass https://127.0.0.1:1787/dns-query;
}
location / {
index index.html;
}
location ~ /\.ht {
deny all;
}
}
#测试配置是否正常
nginx -t
#重新加载nginx配置
nginx -s reload
AdGuardHome配置加密DNS的端口
通过 ip:3000 或者 https://{域名}/dashboard 访问AdGuardHome后台界面。
如果访问 https://{域名} ,将会出现伪装的静态网站,默认为/usr/share/nginx/html目录,可以修改nginx配置文件,将root路径修改为自己的静态页面目录,更多玩法自行研究。
另外,通过指定路径路径进行反代,增加了隐秘性,降低被爆发的可能。添加UUID作为客户端id,并通过配置仅允许客户端访问,可以降低被扫描的可能,同时可以区分客户端访问的网站有哪些,涉及隐私。
UUID生成:
#debian系统直接执行命令
cat /proc/sys/kernel/random/uuid
#Windows系统执行打开PowerShell执行命令
New-Guid
如何使用?
在chrome浏览器中,设置->隐私与安全->安全->使用安全DNS,配置https://{域名}/{path}/{自定义路径}/UUID
其他上网客户端支持自定义DOH服务器的话,可以根据自己的客户端配置格式进行修改,参考各上网工具客户端官方文档
这里我使用的是sing-box,所以贴出一个singbox的配置参考
"dns": {
"servers": [
{
"tag": "DirectDNS",
"address": "https://223.6.6.6/dns-query",
"strategy": "ipv4_only",
"client_subnet": "1.0.8.0",
"detour": "🎯 全球直连"
},
{
"tag": "DIYDNS",
"address": "https://{域名}/{path}/{自定义path}/UUID",
"address_resolver": "DirectDNS",
"address_strategy": "ipv4_only",
"strategy": "ipv4_only",
"client_subnet": "1.36.0.0",
"detour": "🎯 全球直连"
}
]
}
注意,域名不要使用doh.xxx.xxx,太明显了!
注意,域名不要使用doh.xxx.xxx,太明显了!
注意,域名不要使用doh.xxx.xxx,太明显了!
也不要仅使用 /doh-query 或 /dns-querypath 作为,太明显了!
本文配置仅作参考请自行修改。
由于https的加密,一般的嗅探功能只能查看到你访问的域名和ip,在这种情况下,由于加入了路径路径,在一定编程中阻止主动探测,这也是为什么不建议使用/doh-query或/dns-querypath作为原因。
建议配置AdGuardHome仅允许本机访问(通过防火墙关闭AdGuardHome配置DOH的端口),只保留nginx反代的443端口作为外部入口。
编辑{安装目录}/AdGuardHome.yaml,找到下面两个配置,修改ip部分为127.0.0.1即可。否则强烈建议关闭无加密dns,被扫描到53端口很容易被判定为dns服务器。
dns:
bind_hosts:
- 127.0.0.1
port: 53
http:
address: 127.0.0.1
port: 3000
AdGuardHome上游配置以及开启ECS
个人建议,国内使用阿里的dns作为上游,国外使用google的dns作为上游,这相当于对ECS的支持效果较好。
附上我的上游配置,打开乐观的服务器,全部在google。另外还有一个不错的dns上游https://dns11.quad9.net/dns-query,对ECS支持也不错,如果配置了多个上游,建议配置为最上游。
ECS重中之重,建议打开。因为我本地dns分流,国内使用阿里的DOH,海外和漏网之鱼才使用自建的DOH,而且我使用TW的落地机,所以ECS设置了根据TW的ip,请自己实际情况修改。如果你的代理客户端的dns支持ECS,那么以客户端发起dns请求时提交的ECS为基准,否则以AdGuardHome配置的ECS生效。
3!2!1!上效果图
比喻修改的是个人域名、ip和UUID,请自行。查询运行时间参考,建议在延迟较低的中转机搭建DOH服务器,使用kdig每次查询都需要进行TLS握手,短暂,实际上建立TCP长连接之后(需要客户端支持,要同时nginx配置允许长连接),查询运行时间并不高。
使用 kdig 测试 DoH 服务器的 ECS 支持
使用 +subnet=<subnet> 选项来指定 ECS 信息,结合 +https 指定自定义 DoH 路径。
命令格式:
kdig @{域名} +https=/{path}/{自定义path}/UUID +subnet=1.33.0.0/24 www.example.com
参数说明:
+https=/{path}/{自定义path}/UUID:指定自定义路径。
+subnet=1.33.0.0/24:指定 ECS 子网 1.33.0.0/24,这是你希望传递的客户端子网信息。
www.example.com:查询的域名
AdGuardHome服务自带dns层的广告过滤,安装时默认启用,可自行修改拦截配置。