使用AdGuard作为DOH/DOT来对抗DNS污染以及通过ECH突破SNI封锁
本文主要是介绍和分享使用AdGuard作为DOH/DOT的搭建过程以及技术分享
主要使用的设备为一台香港优化机和一台国内腾讯云, 香港作为安装放置AdGuard的设备, 腾讯云主要用来定时扫描ip可连接性不是必须的
本文用doh.com用于代替真实自部署的dns域名
AdGuard版本为 v0.107.79
在 https://jichang.mhdy.net 中有用付费套餐的可以在tg bot中得到属于自己的dot/doh
1. 系统整体拓扑
2. AdGuard搭建和反代
1. AdGuard Home安装
我这里是用的1panel一键安装的AdGuard Home docker版本, 外部只需要开放853, 80, 3000端口即可
首先通过3000端口完成初始化操作, 然后设置端口为80
2. AdGuard配置
这里只列出主要修改点
/opt/1panel/apps/adguardhome/adguardhome/data/conf/AdGuardHome.yaml
http:
doh:
insecure_enabled: true # 这里不是true的话http无法传入
dns:
upstream_dns_file: /opt/adguardhome/conf/upstream_dns.txt # 这里的txt是通过脚本生成的
bootstrap_dns:
- 223.5.5.5
- 119.29.29.29
- 1.1.1.1
- 8.8.8.8
trusted_proxies:
- 127.0.0.0/8
- ::1/128
- 172.18.0.0/12 # 这里是你的容器ip段
allowed_clients: # 这里是白名单, 可识别的有ip, 英文字母/数字, 具体可以看官方文档https://github.com/AdguardTeam/AdGuardHome/wiki/Clients#clientid
- 127.0.0.1
- ::1
- eygweh
edns_client_subnet:
custom_ip:
enabled: true # 这里是EDNS一定要开启
use_custom: false # 如果你不是本地部署的情况这里不要开
tls:
enabled: true # 如果有需要的话可以使用
server_name: doh.com
force_https: false
port_https: 443
port_dns_over_tls: 853
port_dns_over_quic: 853
port_dnscrypt: 0
dnscrypt_config_file: ""
certificate_chain: ""
private_key: ""
certificate_path: /opt/adguardhome/conf/fullchain.pem # 证书路径
private_key_path: /opt/adguardhome/conf/privkey.pem # 私钥路径
strict_sni_check: false部分设置也可以通过AdGuard的后台web进行设置
DNS设置:

加密设置:

3. OpenResty反代AdGuard
这里不是必须OpenResty的, Nginx之类的都可以只是配置文件可能有一定的差异
server {
listen 80 ;
listen [::]:80 ;
listen 443 ssl ;
listen 443 quic ;
listen [::]:443 ssl ;
listen [::]:443 quic ;
server_name doh.com *.doh.com;
index index.php index.html index.htm default.php default.htm default.html;
access_log /www/sites/doh.com/log/access.log main;
error_log /www/sites/doh.com/log/error.log;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {
return 404;
}
location ^~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
return 403;
}
location /123456 { # 这里用于加密doh路径, 你可以用你喜欢的英文字母或数字
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 开启 insecure_enabled: true 后,直接用 http 转发到 AGH 的 Web 端口(请把 3000 换成你实际的 Web 端口)
proxy_pass http://127.0.0.1:3000/dns-query;
}
add_header Alt-Svc 'h3=":443"; ma=2592000';
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
proxy_ssl_server_name off;
proxy_ssl_name $proxy_host;
proxy_pass http://127.0.0.1:3000; # 这里也是AGH的web端口
}
http2 on;
if ($scheme = http) {
return 301 https://$host$request_uri;
}
ssl_certificate /www/sites/doh.com/ssl/fullchain.pem;
ssl_certificate_key /www/sites/doh.com/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
error_page 497 https://$host$request_uri;
proxy_set_header X-Forwarded-Proto https;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
}4. 利用EDNS来智能分流
这个脚本用于生成上文用的上游DNS服务器, 不要使用Cloudflare的doh, 官方为了保护隐身强制丢弃了所有ECS客户端子网信息, 通过Cloudflare的doh解析国内CDN之类的会被判定为境外
#!/bin/bash
CONF_DIR="/opt/1panel/apps/adguardhome/adguardhome/data/conf"
UPSTREAM_FILE="${CONF_DIR}/upstream_dns.txt"
TEMP_FILE="${CONF_DIR}/upstream_dns.tmp"
# 1. 默认国外上游(支持 EDNS ECS 的 Google 与 Quad9)
cat << 'EOF' > $TEMP_FILE
https://dns.google/dns-query
https://dns11.quad9.net/dns-query
EOF
# 2. 国内域名列表(匹配任意原上游 IP,统统抹除并替换为腾讯与阿里 DoH)
curl -sL https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf | \
sed 's|server=/\([^/]*\)/.*|[/\1/]https://doh.pub/dns-query https://dns.alidns.com/dns-query|g' >> $TEMP_FILE
# 3. 苹果与微软国内 CDN 规则
curl -sL https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf | \
sed 's|server=/\([^/]*\)/.*|[/\1/]https://doh.pub/dns-query https://dns.alidns.com/dns-query|g' >> $TEMP_FILE
# 4. 校验并重启生效
LINE_COUNT=$(wc -l < $TEMP_FILE)
if [ "$LINE_COUNT" -gt 10000 ]; then
mv $TEMP_FILE $UPSTREAM_FILE
echo "分流规则更新成功,共 ${LINE_COUNT} 条规则,正在重启 AdGuardHome..."
docker restart $(docker ps -qf "name=adguardhome")
else
rm -f $TEMP_FILE
echo "下载失败或规则数量异常,保留原配置。"
exit 1
fi3. 国内探针
由于海外 VPS 无法准确测量国内不同运营商至境外 CDN 的实际丢包和延迟,因此将测速与清洗工作部署在国内腾讯云 VPS上。
简要说明, 如果你的本地或vps配置了代理一定要让脚本跳过代理, 否则得到的ip可能是无法连通的
不要使用ICMP/TCP Ping, 这样得到的结果不一定可用, 一定要用真实HTTP/HTTPS连接有效
github是有部分ip被官方封锁的一定要注意
1. 深度优化原则与避坑
废弃虚假的 ICMP/TCP Ping,全面改用端到端 HTTPS 应用层探测:
Ping 测的 ICMP 单包仅 64 字节,即使跨洋丢包率达 30%,偶尔溜过一个包也会显示“通(300ms)”;
真实网页需要完成 TCP 握手 + TLS 1.3 协商拉取 4KB+ 证书链 + 接收 HTTP 首包。在 300ms 高延迟线路上稍有丢包就会触发指数退避重传,直接引发浏览器超时;
探针实现
test_https_latency,必须验证 TLS 证书合法有效且取得合法 HTTP 响应码才判定节点存活。
探针强制跳过本地/系统代理:
探针机器若配置了梯子或系统代理(如
127.0.0.1:7890),会导致测出来的是代理速度而非国内直连网络;脚本开头强制清除所有代理环境变量,并注入
ProxyHandler({}),确保探测结果 100% 对应国内原生网络。
集成 Dogfight360 (UsbEAm / S302) 核心 CDN IP 池:
提取近 1000 个细分 CDN 节点,利用 Fastly_C 专属网段(
167.82.x.52)解决 Steam 预告片与静态卡死,利用 Fastly_D(167.82.x.133)加速 GitHub 文件下载,利用 352 个 Akamai 节点为 Steam 社区与头像加速。
GitHub 403 阻断剔除:
微软亚太 Anycast IP 中的
20.205.243.167虽 Ping 延迟低,但被 GitHub 官方 WAF 封锁(返回Access to this site has been restricted (403))。脚本通过深度 HTTP 探测一票否决坏节点,稳定锁定20.205.243.166。
语法规范:
统一采用
|domain^$dnstype=A,dnsrewrite=NOERROR;A;ip语法,避免传统 hosts 将 IPv6(AAAA)解析直接屏蔽导致部分双栈客户端超时。
2. 实际探针代码
下方的代码会暴露出一个端口用于远端拉取规则
通过在ADG web -> 过滤器 -> 黑名单 新增一个 http://ip:端口/rules.txt 这里虽然写的是黑名单, 但实际规则是按照你的文件来的
import urllib.request
import socket
import ssl
import time
import os
import ipaddress
import re
import http.client
import json
import tempfile
from concurrent.futures import ThreadPoolExecutor
# 强制清除系统代理环境变量,确保以国内原生网络环境直连探测与抓取
for _k in (
'http_proxy', 'https_proxy', 'ftp_proxy', 'all_proxy',
'HTTP_PROXY', 'HTTPS_PROXY', 'FTP_PROXY', 'ALL_PROXY'
):
os.environ.pop(_k, None)
os.environ['no_proxy'] = '*'
os.environ['NO_PROXY'] = '*'
# 强制 urllib 全局禁用任何系统/环境变量代理
urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler({})))
def test_https_latency(ip, domain, path="/", timeout=2.0):
"""
使用真实的 HTTPS 端到端连接(TCP握手 + TLS 1.3/SNI 证书校验 + HTTP 首包)
彻底取代虚假的 ICMP/TCP Ping,真实反映国内端到端访问质量与可用性。
"""
t0 = time.monotonic()
try:
ctx = ssl.create_default_context()
with socket.create_connection((ip, 443), timeout=timeout) as s:
with ctx.wrap_socket(s, server_hostname=domain) as tls_s:
tls_s.sendall(f"HEAD {path} HTTP/1.1\r\nHost: {domain}\r\nUser-Agent: Mozilla/5.0\r\nConnection: close\r\n\r\n".encode())
with http.client.HTTPResponse(tls_s) as resp:
resp.begin()
total_ms = (time.monotonic() - t0) * 1000
return total_ms, resp.status
except Exception as e:
return float("inf"), str(e)
def pick_best_https_parallel(candidates, domain, path="/", timeout=2.0, max_workers=10):
def _test(ip):
lat, st = test_https_latency(ip, domain, path=path, timeout=timeout)
return ip, lat, st
with ThreadPoolExecutor(max_workers=max_workers) as ex:
res = list(ex.map(_test, candidates))
valid = [(ip, lat) for ip, lat, st in res if lat < float("inf") and isinstance(st, int)]
if not valid:
return None, float("inf")
valid.sort(key=lambda x: x[1])
return valid[0]
def test_github_web_ok(ip):
"""针对 github.com 必须确保返回 200,且页面不包含 WAF 限制提示"""
try:
ctx = ssl.create_default_context()
with socket.create_connection((ip, 443), timeout=3.0) as s:
with ctx.wrap_socket(s, server_hostname="github.com") as tls_s:
tls_s.sendall(b"GET / HTTP/1.1\r\nHost: github.com\r\nUser-Agent: Mozilla/5.0\r\nConnection: close\r\n\r\n")
with http.client.HTTPResponse(tls_s) as resp:
resp.begin()
if resp.status != 200:
return False
body_snippet = resp.read(1024).decode("utf-8", errors="ignore")
if "Access to this site has been restricted" in body_snippet:
return False
return True
except Exception:
return False
def load_s302_pools():
pool_path = "/opt/1panel/tools/dns_rules/s302_cdn_pools.json"
if os.path.exists(pool_path):
try:
with open(pool_path, "r", encoding="utf-8") as f:
return json.load(f)
except Exception as e:
print(f"[S302] Load pools error: {e}")
return {}
def get_gaming_and_services_rules(s302_pools):
mirrors = [
"https://raw.githubusercontent.com/Clov614/SteamHostSync/main/Hosts",
"https://cdn.jsdelivr.net/gh/Clov614/SteamHostSync@main/Hosts"
]
lines = []
for m in mirrors:
try:
req = urllib.request.Request(m, headers={"User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(req, timeout=8) as resp:
if resp.status == 200:
text = resp.read().decode("utf-8")
candidate_lines = []
for line in text.splitlines():
line = line.strip()
if line and not line.startswith("#") and "github" not in line.lower():
candidate_lines.append(line)
if not parse_hosts(candidate_lines):
raise ValueError("Source returned no valid hosts entries")
lines = candidate_lines
print(f"[Gaming/Services] Fetched {len(lines)} base rules from {m}")
break
except Exception as e:
print(f"[Gaming/Services] Mirror {m} failed: {e}")
if not parse_hosts(lines):
raise RuntimeError("Gaming rules download failed; keeping the published file")
# 1. 针对 Steam App UI 关键依赖进行真实 HTTPS 端到端优选
steam_ui_endpoints = {
"store.steampowered.com": ["184.30.158.110", "23.61.212.219", "23.54.42.115"],
"api.steampowered.com": ["2.23.172.187", "23.215.11.239"],
"store.akamai.steamstatic.com": ["23.46.23.70", "104.95.111.50"],
"shared.akamai.steamstatic.com": ["23.46.23.70", "104.95.111.106"],
"cdn.akamai.steamstatic.com": ["23.214.95.212", "23.46.23.10"]
}
print("[Steam] Optimizing Steam App UI & static endpoints via real HTTPS...")
for domain, ips in steam_ui_endpoints.items():
best_ip, lat = pick_best_https_parallel(ips, domain, timeout=2.5)
if best_ip:
print(f" {domain} -> {best_ip} ({lat:.1f}ms)")
lines = [l for l in lines if not any(domain in l for _ in [1])]
lines.insert(0, f"{best_ip} {domain}")
# 2. 结合 S302 (Dogfight360) 专属池优化 Steam Fastly_C 视频与 Akamai 图片
if s302_pools:
fc_list = s302_pools.get("Fastly_C_IP_List", [])[:25]
if fc_list:
best_fc, lat_fc = pick_best_https_parallel(fc_list, "video.fastly.steamstatic.com", timeout=2.0)
if best_fc:
print(f" [S302 Fastly_C] video.fastly.steamstatic.com -> {best_fc} ({lat_fc:.1f}ms)")
lines.insert(0, f"{best_fc} video.fastly.steamstatic.com")
ak_list = s302_pools.get("Akamai_IP_List", [])[:30]
if ak_list:
best_ak, lat_ak = pick_best_https_parallel(ak_list, "steamcommunity-a.akamaihd.net", timeout=2.0)
if best_ak:
print(f" [S302 Akamai] steamcommunity-a.akamaihd.net -> {best_ak} ({lat_ak:.1f}ms)")
lines.insert(0, f"{best_ak} steamcommunity-a.akamaihd.net")
# 官方短链与验证过的可用节点
lines.append("23.222.131.51 s.team")
lines.append("23.15.140.216 steam.tv")
lines.append("23.35.148.195 valvesoftware.com")
return lines
def get_github_rules(s302_pools):
mirrors = [
"https://raw.hellogithub.com/hosts",
"https://fastly.jsdelivr.net/gh/521xueweihan/GitHub520@main/hosts"
]
lines = []
for m in mirrors:
try:
req = urllib.request.Request(m, headers={"User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(req, timeout=5) as resp:
if resp.status == 200:
text = resp.read().decode("utf-8")
for line in text.splitlines():
line = line.strip()
if line and not line.startswith("#"):
lines.append(line)
print(f"[GitHub] Fetched {len(lines)} rules from {m}")
break
except Exception as e:
print(f"[GitHub] Mirror {m} failed: {e}")
if not parse_hosts(lines):
raise RuntimeError("GitHub rules download failed; keeping the published file")
# 针对 github.com 候选池,基于真实 HTTPS 业务响应选出最佳节点
github_candidates = ["20.205.243.166", "20.205.243.168"]
best_gh_ip = None
min_lat = float("inf")
for ip in github_candidates:
if test_github_web_ok(ip):
lat, _ = test_https_latency(ip, "github.com", timeout=2.5)
if lat < min_lat:
min_lat = lat
best_gh_ip = ip
if not best_gh_ip:
best_gh_ip = "20.205.243.166"
print(f"[GitHub] Selected verified HTTPS IP for github.com: {best_gh_ip} ({min_lat:.1f}ms)")
lines = [l for l in lines if not (l.split() and l.split()[-1].lower() == "github.com")]
lines.insert(0, f"{best_gh_ip} github.com")
# 结合 S302 (Dogfight360) Fastly_D 优化 GitHub Desktop / Releases 静态资源
if s302_pools:
fd_list = s302_pools.get("Fastly_D_IP_List", [])[:25]
if fd_list:
best_fd, lat_fd = pick_best_https_parallel(fd_list, "desktop.githubusercontent.com", timeout=2.0)
if best_fd:
print(f" [S302 Fastly_D] desktop.githubusercontent.com -> {best_fd} ({lat_fd:.1f}ms)")
lines.insert(0, f"{best_fd} desktop.githubusercontent.com")
return lines
def get_docker_rules():
docker_candidates = {
"registry-1.docker.io": ["44.212.194.123", "44.195.142.59", "52.86.255.203", "107.20.145.202", "35.171.80.220"],
"auth.docker.io": ["172.64.144.78", "104.18.43.178", "54.227.20.253"],
"production.cloudflare.docker.com": ["104.16.97.215", "104.16.98.215", "104.16.99.215", "104.16.100.215"]
}
lines = []
print("[Docker] Testing Docker Hub endpoints via real HTTPS...")
for domain, ips in docker_candidates.items():
best_ip, lat = pick_best_https_parallel(ips, domain, timeout=2.5)
if best_ip:
print(f" {domain} -> {best_ip} ({lat:.1f}ms)")
lines.append(f"{best_ip} {domain}")
return lines
def parse_hosts(raw_lines):
entries = {}
for line in raw_lines:
parts = line.split("#", 1)[0].split()
if len(parts) < 2:
continue
try:
ip = ipaddress.ip_address(parts[0])
except ValueError:
continue
if ip.version != 4 or not ip.is_global or ip.is_reserved or ip.is_multicast:
continue
for domain in parts[1:]:
domain = domain.lower().rstrip(".")
labels = domain.split(".")
if len(domain) <= 253 and len(labels) >= 2 and all(
re.fullmatch(r"[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?", label)
for label in labels
):
entries.setdefault(domain, str(ip))
return entries
def verify_entry(entry):
domain, ip = entry
if domain in ("github.com", "api.github.com"):
if domain == "github.com":
if test_github_web_ok(ip):
return entry
return None
lat, st = test_https_latency(ip, domain, timeout=2.5)
if isinstance(st, int):
return entry
return None
lat, st = test_https_latency(ip, domain, timeout=2.5)
if isinstance(st, int):
return entry
print(f"[Skip] {domain} {ip}: HTTPS test failed ({st})")
return None
def format_rule(domain, ip):
return f"|{domain}^$dnstype=A,dnsrewrite=NOERROR;A;{ip}"
def main():
start_time = time.time()
s302_pools = load_s302_pools()
if s302_pools:
print(f"[S302] Successfully loaded Dogfight360 CDN pools ({len(s302_pools)} sets)")
raw_lines = []
raw_lines.extend(get_github_rules(s302_pools))
raw_lines.extend(get_docker_rules())
raw_lines.extend(get_gaming_and_services_rules(s302_pools))
entries = parse_hosts(raw_lines)
print(f"Validating {len(entries)} host entries via full HTTPS handshake...")
with ThreadPoolExecutor(max_workers=8) as pool:
verified = [entry for entry in pool.map(verify_entry, entries.items()) if entry]
if not verified:
raise RuntimeError("No validated rules; keeping the published file")
output_rules = [
"! ==================================================",
"! Auto-generated DNS Rules by Tencent Cloud (Domestic)",
f"! Updated: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}",
"! Verification: Full HTTPS Application-Level Handshake & Response",
"! Powered by: Dogfight360 (S302) CDN Pools + Multi-mirror Aggregation",
"! ==================================================",
""
]
output_rules.extend(format_rule(domain, ip) for domain, ip in verified)
final_content = "\n".join(output_rules) + "\n"
target_path = "/opt/1panel/www/sites/49.33.136.214/index/rules.txt"
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", dir=os.path.dirname(target_path), delete=False) as f:
f.write(final_content)
temporary_path = f.name
try:
os.chmod(temporary_path, 0o644)
os.replace(temporary_path, target_path)
finally:
if os.path.exists(temporary_path):
os.unlink(temporary_path)
print(f"Successfully generated {target_path} (Validated: {len(verified)}/{len(entries)}, elapsed: {time.time()-start_time:.2f}s)")
if __name__ == "__main__":
main()4. AdGuard白名单使用
ADG的白名单叫做客户端id/Client ID, 没有配置客户端id的请求会被拒绝
通过申请一个泛域名证书*.doh.com此时你的dot/dns地址会变为客户端id.doh.com , doh地址为https://doh.com/123456/客户端id
手机通过安全/私人DNS填写的为dot, 浏览器填写的为doh
5. 通过ECH加密可以突破SNI阻断
虽然dot也支持ECH但是安卓底层不支持, 目前ECH只能通过浏览器配置doh来使用
和之前的Cloudflare ECH代理原理类似
1. 突破原理
SNI 阻断机制:GFW 依靠在骨干网边界的 DPI 监听 TLS ClientHello。若读到黑名单明文 SNI,立即向双向注入 TCP RST 切断连接。
ECH (Encrypted Client Hello) 机制:
客户端向支持的 DoH 服务器查询 Type 65 (HTTPS) 记录,获取服务器公钥。握手时将真正的域名加密封装在内层,外层明文 SNI 显示为中立的cloudflare-ech.com,避开 GFW 明文匹配。
2. 客户端开启步骤
Chromium 内核 (Chrome / Edge / Brave):
打开
chrome://flags,将Encrypted ClientHello设为 Enabled;进入 设置 →→ 隐私和安全 →→ 安全 →→ 开启“使用安全 DNS”;
选择“自定义”,填入私有 DoH 地址:
https://doh.com/123456/...;彻底重启浏览器。
验证 ECH 激活:
访问https://crypto.cloudflare.com/cdn-cgi/trace,若输出sni=encrypted即代表 ECH 已全链路生效。
6. 一些常用验证和测试命令
# 1. 验证香港 OpenResty DoH 端点连通性
curl -i -H "accept: application/dns-message" \
"https://doh.com/123456/client_id?dns=AAABAAABAAAAAAAABmdpdGh1YgNjb20AAAEAAQ" --output -
# 2. 验证 DoT (853端口) 带 Client ID 解析与证书合法性
openssl s_client -connect ip:853 -servername 123456.doh.com -brief
# 3. 检查国内探针规则文件是否正常下发
curl -sI http://ip:7865/rules.txt | head -n 10
# 4. 测试特定 IP 直连握手与 HTTP 状态
curl -sI --resolve github.com:443:20.205.243.166 https://github.com/ | head -n 5
# 5. 测试 Type 65 HTTPS 记录与 ECH 是否完整下发
dig @1.1.1.1 HTTPS exhentai.org7. 一些补充内容
一些黑白名单规则, 你可以通过配置文件或者web进行添加修改
filters:
- enabled: true
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt
name: AdGuard DNS filter
id: 1
- enabled: false
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt
name: AdAway Default Blocklist
id: 2
- enabled: true
url: http://ip:7865/rules.txt
name: AdGuard Tencent
id: 3
- enabled: true
url: https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-adguard.txt
name: anti-AD 中文广告防护
id: 4
- enabled: true
url: https://raw.githubusercontent.com/TG-Twilight/AWAvenue-Ads-Rule/main/AWAvenue-Ads-Rule.txt
name: AWAvenue 秋风开屏与移动广告规则
id: 5
whitelist_filters:
- enabled: true
url: https://raw.githubusercontent.com/privacy-protection-tools/dead-horse/master/anti-ad-white-list.txt
name: anti-AD 官方防误杀白名单
id: 6
- 感谢你赐予我前进的力量


