前言:最近在闲鱼80收了台JD AX1800 Pro玩,512MB RAM+64G EMMC,刷了QWRT,感觉只跑科学上网有点浪费了,于是整了一个让局域网每台设备都能同时用上Tailscale特别是MagicDNS,在此记录一下流程。
大致流程:用户请求 → iptables重定向(53→5353) → AdGuardHome过滤/分流 → 域名匹配/ts.net/ → Tailscale DNS(100.100.100.100),其他 → Clash DNS(127.0.0.1:1053)
场景需求
在跨境网络环境中实现:
- 国内直连/国外代理智能分流(Clash)
- Tailscale组网设备的无缝访问
- 全网广告过滤(AdGuardHome)
- MagicDNS短域名支持
核心组件
组件 | 监听地址 | 功能说明 |
---|---|---|
Clash | 127.0.0.1:1053 | DNS智能分流 |
Tailscale | 100.100.100.100:53 | MagicDNS解析 |
AdGuardHome | 0.0.0.0:5353 | DNS过滤+请求路由 |
详细配置步骤
一、Tailscale配置
# 安装Tailscale
opkg install tailscale
# 启动服务并配置路由
tailscale up \
--advertise-routes=192.168.77.0/24 \ # 换成你的IP
--accept-dns=true \
--advertise-exit-node
二、Clash配置
参见:全网最详细的解锁 SSH ShellCrash 搭载 mihomo 内核搭配 AdGuard Home 安装和配置教程 | mihomo 和 sing-box 教程合集
据此配置后,Clash的DNS监听1053端口。
三、AdGuardHome配置
同样参见上面的教程,先配置好AGH。
上游DNS设置:
[/ts.net/]100.100.100.100
127.0.0.1:1053
启动脚本 /root/AdGuardHome/start_agh.sh
:
#!/bin/sh
sleep 10 # 等待网络初始化
# 启动AdGuardHome
/root/AdGuardHome/AdGuardHome -s start
# IPv4规则
iptables -t nat -A PREROUTING -p tcp -d 100.100.100.100 --dport 53 -j RETURN
iptables -t nat -A PREROUTING -p udp -d 100.100.100.100 --dport 53 -j RETURN
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5353
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5353
# IPv6规则
ip6tables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5353
ip6tables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5353
把这个启动脚本放在ShellClash的自动任务 / OpenWRT的启动项即可。
四、Tailscale MagicDNS解决方案
按照上述方案配置,客户端可以获得完整的Tailscale域名(xxx.yyy.ts.net)DNS结果,但MagicDNS依然无法使用(xxx)。
接下来我们可以使用如下脚本,通过AGH提供的API添加一些DNS Rewrite规则,将xxx.lan映射到xxx.yyy.ts.net,即可确保在所有客户端上都能与MagicDNS等效了。
通过定时任务维护CNAME记录:
#!/bin/sh
set -euo pipefail
# Configuration
AGH_URL="http://localhost:3000/control"
AGH_USER="<your-agh-username>"
AGH_PASS="<your-agh-password>"
DOMAIN_SUFFIX="<your-tailscale-domain-suffix>.ts.net"
# Check Tailscale availability
if ! tailscale status >/dev/null 2>&1; then
echo "Error: Tailscale is not running. Exiting."
exit 1
fi
# Get current Tailscale hosts
hosts=$(tailscale status | awk '/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $1, $2}')
if [ -z "$hosts" ]; then
echo "Error: No Tailscale hosts found. Exiting."
exit 1
fi
# Get current AdGuard Home rewrite rules
current_rules_json=$(curl -s -u "$AGH_USER:$AGH_PASS" "$AGH_URL/rewrite/list")
if ! echo "$current_rules_json" | jq -e . >/dev/null 2>&1; then
echo "Error: Failed to fetch valid rewrite rules from AdGuard Home. Exiting."
exit 1
fi
# Rule processing function
process_rule() {
local domain="$1"
local answer="$2"
local current_entry=$(echo "$current_rules_json" | jq --arg d "$domain" '.[] | select(.domain == $d)')
if [ -z "$current_entry" ]; then
echo "Adding rule: $domain → $answer"
if ! curl --fail -sS -u "$AGH_USER:$AGH_PASS" -X POST \
-H "Content-Type: application/json" \
-d "{\"domain\":\"$domain\", \"answer\":\"$answer\"}" \
"$AGH_URL/rewrite/add"; then
echo "Error: Failed to add rule $domain"
exit 1
fi
else
local current_answer=$(echo "$current_entry" | jq -r '.answer')
if [ "$current_answer" != "$answer" ]; then
echo "Updating rule: $domain from $current_answer → $answer"
if ! curl --fail -sS -u "$AGH_USER:$AGH_PASS" -X PUT \
-H "Content-Type: application/json" \
-d "{\"target\": {\"domain\": \"$domain\", \"answer\": \"$current_answer\"}, \"update\": {\"domain\": \"$domain\", \"answer\": \"$answer\"}}" \
"$AGH_URL/rewrite/update"; then
echo "Error: Failed to update rule $domain"
exit 1
fi
fi
fi
}
# Process each Tailscale host
echo "$hosts" | while read -r ip hostname; do
echo "Processing host: $hostname ($ip)"
# Create FQDN rule
process_rule "$hostname.lan" "${hostname}.${DOMAIN_SUFFIX}"
done
echo "All rules processed successfully."
到这里就折腾完了,所有设备都可以享受到Tailscale+MagicDNS,也可以自由使用Clash。