最近在一台运行 ASUSWRT-Merlin(梅林固件)的华硕 EA6400 上部署 AdGuard Home(以下简称 AGH),遇到了两个比较典型的问题:
- AdGuard Home 可以手动启动,但无法通过自身的
-s start实现开机自启。 - 路由器本身可以通过代理访问 GitHub,但 AdGuard Home 更新过滤规则时仍然失败。
最终两个问题都解决了。下面记录完整过程,方便以后在老版本梅林固件上部署 AdGuard Home 时参考。
一、环境说明
本文环境大致如下:
- 路由器:ASUS EA6400
- 固件:ASUSWRT-Merlin / 梅林固件
- BusyBox:1.25.1
- AdGuard Home:v0.107.79
- AdGuard Home 安装位置:外接存储
/tmp/mnt/ext4/agh/AdGuardHome/ - AGH Web 管理端口:
3001 - AGH DNS 端口:
8053 - 代理:KoolShare + Hysteria
最终的网络结构为:
局域网设备
│
▼
dnsmasq :53
│
▼
AdGuard Home :8053
│
└── 规则更新 HTTPS
│
▼
路由器代理
│
▼
Hysteria
│
▼
GitHub / 规则源
二、问题一:AdGuard Home 无法通过自身命令开机启动
首先进入 AdGuard Home 所在目录:
cd /tmp/mnt/ext4/agh/AdGuardHome
检查 AGH 状态:
./AdGuardHome -c AdGuardHome.yaml -s status
当时显示服务处于 stopped 状态。
尝试直接启动:
./AdGuardHome -c AdGuardHome.yaml -s start
但是启动失败,原因是 AGH 的服务管理器尝试调用:
/etc/init.d/AdGuardHome
而梅林固件环境中并不存在这个 init.d 服务文件。
错误信息类似:
/etc/init.d/AdGuardHome: not found
手动启动 AGH
实际上 AGH 本身是可以正常运行的,因此可以直接后台启动:
./AdGuardHome -c AdGuardHome.yaml >/tmp/AdGuardHome.log 2>&1 &
然后检查进程:
ps w | grep '[A]dGuardHome'
检查端口:
netstat -lnp 2>/dev/null | grep -E ':3001|:8053'
正常情况下可以看到:
AdGuardHome :3001
AdGuardHome :8053
这说明 AGH 本身没有问题,问题只是没有合适的梅林启动方式。
三、梅林固件应该使用 /jffs/scripts/services-start
对于 Merlin 固件,不应该照搬 OpenWrt 的 /etc/init.d/ 方案。
梅林提供了自定义启动脚本:
/jffs/scripts/services-start
先检查原来的脚本:
cat /jffs/scripts/services-start
原来的内容是:
#!/bin/sh
/koolshare/bin/ks-services-start.sh start
但是实际执行时发现:
/koolshare/bin/ks-services-start.sh: not found
检查 /koolshare/bin/ 后可以看到大量 KoolShare 相关程序,但并不存在这个启动脚本。
因此不能简单地直接执行它。
兼容处理
最终采用了条件判断:
if [ -x /koolshare/bin/ks-services-start.sh ]; then
/koolshare/bin/ks-services-start.sh start
fi
这样如果以后该文件存在就执行,如果不存在也不会导致整个启动脚本报错。
四、AdGuard Home 的开机启动脚本
最终使用的 /jffs/scripts/services-start 如下:
#!/bin/sh
# KoolShare 原启动脚本(存在才执行)
if [ -x /koolshare/bin/ks-services-start.sh ]; then
/koolshare/bin/ks-services-start.sh start
fi
# 更新系统 CA:/etc 为只读,使用 bind mount 覆盖
if [ -f /jffs/cacert.pem ]; then
mount --bind /jffs/cacert.pem /etc/ssl/certs/ca-certificates.crt
fi
# AdGuard Home
AGH_DIR="/tmp/mnt/ext4/agh/AdGuardHome"
AGH_BIN="$AGH_DIR/AdGuardHome"
AGH_CONF="$AGH_DIR/AdGuardHome.yaml"
AGH_LOG="/tmp/AdGuardHome.log"
# 等待外置存储挂载
i=0
while [ ! -x "$AGH_BIN" ] && [ $i -lt 60 ]; do
sleep 1
i=$((i + 1))
done
# 启动 AdGuard Home
if [ -x "$AGH_BIN" ]; then
if ! pidof AdGuardHome >/dev/null 2>&1; then
"$AGH_BIN" -c "$AGH_CONF" >>"$AGH_LOG" 2>&1 &
fi
fi
exit 0
然后设置执行权限:
chmod 755 /jffs/scripts/services-start
手动测试:
/jffs/scripts/services-start
检查 AGH:
ps w | grep '[A]dGuardHome'
检查监听端口:
netstat -lnp 2>/dev/null | grep -E ':3001|:8053'
确认正常后再重启路由器进行最终测试。
五、问题二:路由器能访问 GitHub,但 AGH 更新规则失败
开机自启解决之后,又遇到了另一个问题。
AdGuard Home 更新过滤规则失败。
第一反应很容易认为是:
“路由器没有走代理,所以访问 GitHub 失败。”
但实际检查后发现并不是这样。
检查 Hysteria
路由器上运行着 Hysteria:
ps w | grep -E '[x]ray|[h]ysteria|[n]aive|[s]s-redir|[s]s-local|[c]dns|[c]hinadns|[s]martdns'
可以看到类似:
hysteria -c /koolshare/ss/hysteria.json -l error --disable-update-check
Hysteria 本地监听:
127.0.0.1:23456
:::3333
同时检查 iptables:
iptables -t nat -L OUTPUT -n
可以看到 KoolShare 已经存在针对路由器自身流量的代理规则,例如:
REDIRECT tcp ... match-set router dst redir ports 3333
SHADOWSOCKS_EXT ...
因此,路由器自身并不是完全没有经过代理。
六、curl 测试证明代理完全正常
直接从路由器测试 GitHub:
curl -I https://github.com
结果:
HTTP/1.1 200 OK
这说明路由器本身访问 GitHub 是正常的。
然后测试规则经常使用的域名:
curl -I https://raw.githubusercontent.com
结果却出现:
curl: (60) SSL certificate problem:
unable to get