最近了解到了dns over https所以就心血来潮的想尝试一下,刚好发现AdGuard Home这个项目,背靠AdGuard大公司,而且也是开源的比较放心。这篇文章就记录一下搭建AdGuard Home、只允许特定客户端使用、设置AdGuard Home国内外分流、每天凌晨自动更新分流规则、自动修改规则并更新后自动推送信息到iPhone、用Nginx反代AdGuard Home以去除doh的dns-query并仅允许特定IP访问AdGuard Home主页的步骤。
要求
1、一台vps,延迟越低越好
2、一个域名
1、搭建AdGuard Home
首先可以看AdGuard Home的github主页,里面有一键安装脚本。
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v
按照这个脚本就可以自动AdGuard Home,访问http://ip:3000就可以进入设置了。
首先很重要的就是进入“设置”➡“加密设置”,将启用加密打开,其中会让你填写你的证书文件和密钥,你可以按照这篇文章来申请证书,申请好了以后填上去就行了。
然后填写一下你的https端口,不建议填写443,因为待会要反代到443端口,填一个你喜欢的端口就行了,然后你再进入https://你的域名:你设置的端口,记得把HTTP自动重定向给勾选上。
接下来就是设置你的客户端了,进入“设置”➡“客户端设置”,添加你的客户端,名称和标签随便填,这个主要用来AdGuard Home区分客户端名称,“标识符”填一个你能记住的,貌似不能有大写字母(我用大写字母就用不了),剩下的就看你心情填写。
添加好你的客户端以后就去“设置”➡“DNS设置”➡“访问设置”➡“允许的客户端”中填写你客户端的标识符,这样填完以后就只有你指定的客户端可以使用了。
然后你就可以去“过滤器”➡“DNS黑名单”中开启你的黑名单规则了,个人推荐开启anti-AD。
恭喜,到此你的简易AdGuard Home就算搭建完成了。
2、设置国内外分流
如果你的dns在境外,那么它默认的dns请求到的IP可能并不适合你,但是如果你把它的上游DNS设置成国内的DNS有的域名会被污染,所以我们要让它请求国内域名时用国内的上游,请求国外的域名时使用国外的上游。
你可以去这个项目中找到你想下载的规则文件下载到你的VPS中,我下载的是gfwlist2adguardhome/whitelist_full_combine.txt,你可以将文件中第一行的https://dns.opendns.com:443/dns-query改成其他你想要的DNS,当然默认不改就行了。
cd /home/AdGuardHome
wget https://raw.githubusercontent.com/hezhijie0327/GFWList2AGH/main/gfwlist2adguardhome/whitelist_full_combine.txt
下载完成以后修改你的AdGuard Home配置文件(在你安装目录)中的upstream_dns_file,将这个填你下载文件的路径,比如我下载在/home/AdGuardHome,就填/home/AdGuardHome/whitelist_full_combine.txt。修改完成以后重启你的AdGuard Home。
vim AdGuardHome.yaml
systemctl restart AdGuardHome
这样一来你的AdGuard Home就是国外的域名时使用opendns的doh,国内的使用腾讯的doh了,当然这两个你都可以修改。
3、每天凌晨自动更新分流规则
经过我刚才的教程,相信你也用上分流了,但是分流规则是经常会更新的,我们总不可能每天都手动去更新一遍,如果你不在乎的话其实几个月更新一次也行。
但是我这样的强迫症是想要每天都自动更新的,那也很简单,写一个脚本然后让他每天凌晨运行一遍就好了。
#!/bin/bash
# 切换到AdGuardHome目录
cd /home/AdGuardHome
# 停止AdGuardHome服务
systemctl stop AdGuardHome
# 删除whitelist_full_combine.txt
rm whitelist_full_combine.txt
# 下载最新的whitelist_full_combine.txt文件
wget https://raw.githubusercontent.com/hezhijie0327/GFWList2AGH/main/gfwlist2adguardhome/whitelist_full_combine.txt
# 启动AdGuardHome服务
systemctl start AdGuardHome
你只要新建一个updatedns.sh的文件,然后里面写上上面的脚本就好了,自己修改一下AdGuardHome目录和下载链接就好了。
接下来修改crontab文件,设置好你的自动任务
crontab -e
#示例,该任务触发时间为每天凌晨3:15
15 3 * * * ./root/updatedns.sh #这里记得换成你自己的脚本文件
4、自动修改规则并更新后自动推送信息到iPhone(可选)
如果我们想自定义分流规则中的国内DNS和国外DNS怎么办?如果你是手动更新的话直接修改文件就好了,但是如果你是像我一样自动更新怎么办?那接下来我就教你怎么办。
首先你先申请一个github的token,可以访问这里申请,Expiration选择无限时间,这个随你,Select scopes把repo全勾上,workflow好像不勾也行,然后就申请到了,记得保存到记事本中,要不然刷新一下就不显示了。
然后你需要新建一个repository,设置为公开,然后上传或创建一个文件,我创建的文件名是Update file-download-and-edit.yml,内容如下:
name: GitHub Actions
on:
schedule:
- cron: "0 19 * * *"
workflow_dispatch: # 添加这一行,表示允许手动触发
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Git
run: |
git config --global user.email "你的github电子邮件"
git config --global user.name "你的github用户名"
- name: Download file
run: |
wget -O whitelist_full_combine.txt.tmp https://raw.githubusercontent.com/hezhijie0327/GFWList2AGH/main/gfwlist2adguardhome/whitelist_full_combine.txt #这里是你要下载的文件,修改了记得改下面的名字
mv whitelist_full_combine.txt.tmp whitelist_full_combine.txt
- name: Edit file
run: |
sed -i 's~https://dns.opendns.com:443/dns-query~https://dns.google/dns-query~' whitelist_full_combine.txt # 文件名应改为下载的文件名,自行修改上面的两个dns,这里我是把opendns的doh换成了谷歌的,下面的也一样
sed -i 's~https://doh.pub:443/dns-query~https://dns.alidns.com/dns-query~' whitelist_full_combine.txt
- name: Upload file
run: |
git add whitelist_full_combine.txt # 文件名应改为下载的文件名
git commit -m "Updated file"
git push origin main
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
保存了以后去repository的“Settings”➡“Secrets and variables”➡“Actions”添加一个“secret”,名字为“TOKEN”,内容为你刚才生成的密钥。
到此自动修改分流规则便完成了,也可以不用github。
接下来就是推送通知了,这个方法有很多,各位可以自行选择。
由于我用的是iPhone,它本来就有非常优秀的推送服务,所以我就直接用apple的推送了。
首先先下载一个名为 bark – 给你的手机发推送 的app,需要自行搜索一下它的TestFlight,这位大佬开发的这个项目主页在这。然后按照app的教程获取到这台手机的token,接下来按照app教程测试一下就好了,你可以自定义你的推送。
设置完成以后可以修改VPS上自动更新的脚本,在结尾加一个curl就行了。
当然推送的方法非常非常多,我这里不过是抛砖引玉,各位可以自己设置自己独一无二的推送。
5、使用Nginx反代并且去除doh的dns-query
首先安装nginx
apt install nginx
然后写配置文件,可以按照我下面写的改
nano /etc/nginx/sites-available/dns.conf
#配置文件示例:
server {
listen 443 ssl;
server_name 你的反代域名;
ssl_certificate 你的证书文件;
ssl_certificate_key 你的密钥文件;
location /iphoen { #你AdGuard Home设置的客户端表示,例如我的是iphone
proxy_cookie_path /iphone/ /;
proxy_set_header CF-Connecting-IP $remote_addr;
proxy_set_header True-Client-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass https://你的域名:你的https端口/dns-query/iphone;
proxy_redirect /iphone/ /;
proxy_set_header Host 你的域名;
}
location /iphoen { #这里是重复,你有其他客户端可以依次类推添加
proxy_cookie_path /iphone/ /;
proxy_set_header CF-Connecting-IP $remote_addr;
proxy_set_header True-Client-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass https://你的域名:你的https端口/dns-query/iphone;
proxy_redirect /iphone/ /;
proxy_set_header Host 你的域名;
}
}
将配置文件写完以后创建软连接,检查nginx配置文件有没有写错,没错就重启。
ln -s /etc/nginx/sites-available/dns.conf /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx
到此为止,你就可以输入https://你的域名/你的客户端标识符 来使用doh了,当然原来那个https://你的域名:你的端口/dns-query/你的客户端标识符 也还能使用。
不过我这样的配置你使用https://你的域名/你的客户端标识符可能会出现一个小问题,就是AdGuard Home的查询日志中的客户端IP都是你反代服务器的IP,如果出现这个问题解决方法也很简单,只需要修改AdGuard Home配置文件就好了,在配置文件中的trusted_proxies添加反代的VPS的IP就好了。
6、仅允许特定IP访问AdGuard Home主页
AdGuard Home主页在你第一次进入的时候就要求设置密码,但是有可能你会觉得这还是不够安全,那么解决方法也有,就是通过防火墙设置仅反代IP可以访问你AdGuard Home的https端口,然后在nginx反代中设置仅指定IP可以访问AdGuard Home主页,其他IP可以访问你设置的客户端表示路径,其他路径不允许任何除你指定的IP外访问。看到这里你可能会觉得很麻烦,但其实几条命令就搞定了。
首先修改我们刚刚的nginx反代文件,以下是示例
nano /etc/nginx/sites-available/dns.conf
#配置文件示例:
server {
listen 443 ssl;
server_name 你的反代域名;
ssl_certificate 你的证书文件;
ssl_certificate_key 你的密钥文件;
location / {
allow 1.2.3.4; # 替换为你允许访问的 IP 地址
deny all;
proxy_set_header Host $host;
proxy_pass https://你的域名:你的端口/; # AdGuard Home 管理页面的地址
}
location /iphoen { #你AdGuard Home设置的客户端表示,例如我的是iphone
proxy_cookie_path /iphone/ /;
proxy_set_header CF-Connecting-IP $remote_addr;
proxy_set_header True-Client-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass https://你的域名:你的https端口/dns-query/iphone;
proxy_redirect /iphone/ /;
proxy_set_header Host 你的域名;
}
location /iphoen { #这里是重复,你有其他客户端可以依此类推添加
proxy_cookie_path /iphone/ /;
proxy_set_header CF-Connecting-IP $remote_addr;
proxy_set_header True-Client-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass https://你的域名:你的https端口/dns-query/iphone;
proxy_redirect /iphone/ /;
proxy_set_header Host 你的域名;
}
}
对的,就只是加了一个“location /”而已
location / {
allow 1.2.3.4; # 替换为你允许访问的 IP 地址
deny all;
allow 1.2.3.4;
deny all; # 替换为你你允许访问的第二个 IP 地址,后面要加依此类推
proxy_set_header Host $host;
proxy_pass https://你的域名:你的端口/; # AdGuard Home 管理页面的地址
}
这样设置完成以后你反代的AdGuard Home 管理页面就只有你指定的IP可以访问了,但是你的客户端标识的路径还是任何人都可以访问,不过你原来的AdGuard Home 管理页面还是任何人都能访问怎么办?那也很简单,两条iptables防火墙命令就解决了。
iptables -I INPUT -p tcp --dport AdGuard Home的https端口 -j DROP #这个命令是禁止任何IP访问你的AdGuard Home 管理页面
iptables -I INPUT -s 你反代的VPS的IP -p tcp --dport AdGuard Home的https端口 -j ACCEPT #这个命令是允许你指定的反代的IP访问你的AdGuard Home 管理页面
如果就是在本机反代的话用下面的命令也行
iptables -I INPUT -i lo -p tcp --dport AdGuard Home的https端口 -j ACCEPT
这样一来,只有我们指定的IP可以访问AdGuard Home 管理页面了,其他IP只能访问我们设定好的客户端标识的路径了,也就是只能用https://你的域名/你的客户端标识符了,原先那个也用不了了,更加的安全。