Add Cudy TR3000 report: AdGuard Home querylog filling RAM, shared ratelimit

This commit is contained in:
2026-10-30 13:57:58 -04:00
parent be6e692179
commit 96c63df205

View File

@@ -0,0 +1,128 @@
# Cudy TR3000:AdGuard Home 查询日志占满内存、限流过严
- 日期:2026-10-30
- 设备:Cudy TR3000 256MB v1(`cudy-tr3000.tail694d4.ts.net`,远程)
- 系统:OpenWrt 25.12.6 r33311-981c978eff,mediatek/filogic
- AdGuard Home:0.107.79
- 相关报告:[`2026-10-28-cudy-tr3000-wwan-watchdog.md`](2026-10-28-cudy-tr3000-wwan-watchdog.md)
## 背景
反馈“AdGuard DNS 好像崩溃了”。排查时 AdGuard Home 进程正常运行,路由器上解析也正常,但发现两个会导致 DNS 不稳定甚至整机卡死的问题:
1. 查询日志写在内存里(tmpfs),6.5 小时涨到 112 MB,可用内存只剩约 20 MB。
2. 限流 `ratelimit: 20` 按网段计算,所有局域网设备共用一个额度,高峰期已超过上限。
## 现象
| 时间 | 可用内存 | `querylog.json` | 说明 |
|---|---|---|---|
| 17:31 | 86 MB | 112 MB | 开机 6.5 小时,负载约 2.9 |
| 17:53 | 20 MB | 121 MB | |
| 17:54 – 17:56 | — | 122 MB | SSH 和 Tailscale ping 均超时约 1 分钟,负载升到 9.9;没有重启 |
| 17:57(修复后) | 234 MB | 0.2 MB | `/tmp` 从 135 MB 降到 5.4 MB |
开机后的 6.5 小时里路由器重启过一次,原因查不到:没有 pstore,当前日志中也没有 OOM 记录。按查询日志的增长速度,内存迟早会被耗尽,那次重启很可能就是这个原因,但没有证据。
17:54 的卡顿还有一个人为因素:排查时一条 `tail -20000 querylog.json` 命令超时被中断,但路由器上的 `tail` 进程没有退出,一直以 R 状态占用 CPU。它还持有已删除的 `querylog.json`,导致删除后约 112 MB 内存迟迟没有释放。手动 `kill` 后内存才回来。以后在路由器上分析大文件,要先复制一小段出来再处理,并确认远端进程已退出。
## 原因
### 1. 查询日志:几乎都是 EasyTier 解析对端域名
开机至 17:30 共 166000 条查询:
| 域名 | 次数 |
|---|---|
| `cloud.zhe-yuan.top` | 119301 |
| `home.zhe-yuan.top` | 18438 |
| `backup.zhe-yuan.top` | 16155 |
| 其他所有域名 | 约 12100 |
| 客户端 | 次数 | 设备 |
|---|---|---|
| `fd84:1963:e466::7c3` | 100529 | intel-nuc8i5beh |
| `127.0.0.1` / `::1` | 29596 / 29520 | 路由器自身 |
| `fd84:…:ec56:…` | 6148 | Windows-Dev-Kit |
| `fd84:…:ed94:…` | 207 | Galaxy-Z-Fold8 |
这三个域名正是 EasyTier 的对端地址(`/etc/easytier/config.toml` 的 `[[peer]]`)。`easytier-cli connector` 显示这些连接器一直处于 `Connecting`,每次重试都会重新解析域名。NUC 上的 EasyTier 应该也是同样情况。
上游 TTL 正常(`cloud` 约 300 s,`home` 约 250 s),AdGuard 都是从缓存回答,所以对上游没有压力。问题在于每条查询都写进了日志:
- `querylog.interval: 90d`:查询日志保留 90 天,实际上不会轮转。
- 日志目录在 `/var/lib/adguardhome`,也就是 tmpfs(内存)。
- 每条记录约 700 字节(包含完整的 base64 应答)。
平均每秒约 7 条,每小时约 17 MB。
### 2. 限流:所有局域网客户端共用一个额度
```yaml
ratelimit: 20
ratelimit_subnet_len_ipv4: 24
ratelimit_subnet_len_ipv6: 56
```
限流按 IPv4 /24 或 IPv6 /56 计算,整个局域网(`192.168.156.0/24`、`fd84:1963:e466::/48` 内的 /56)只有每秒 20 次的共用额度。抽样的 3000 条记录里,局域网客户端的高峰是每秒 24 次,主要来自 NUC 的 EasyTier 解析。被限流的查询直接丢弃且不写日志,其他设备会偶尔解析失败而查不到记录。
## 修改内容
备份:`/root/adguardhome.yaml.bak`
`/etc/adguardhome/adguardhome.yaml`:
```diff
dns:
- ratelimit: 20
+ ratelimit: 0
querylog:
- ignored: []
- interval: 90d
+ ignored:
+ - cloud.zhe-yuan.top
+ - home.zhe-yuan.top
+ - backup.zhe-yuan.top
+ interval: 6h
- ignored_enabled: false
+ ignored_enabled: true
```
另外停止 AdGuard Home 后删除了旧的 `querylog.json`,然后重启服务。
- **`interval: 6h`**:AdGuard Home 轮转时保留 `querylog.json` 和 `querylog.json.1` 两个文件,最多约 12 小时的记录。去掉 EasyTier 的查询后,每 6.5 小时约 12000 条、约 9 MB,最坏情况约 20 MB。
- **忽略三个 EasyTier 对端域名**:只是不写入查询日志,统计和解析不受影响。
- **`ratelimit: 0`**:关闭限流。防火墙 `wan` 区(`wan`、`wan6`、`wwan2`、`wwan5`、`wwan26`、`wwan56`)的入站是 `REJECT`,外网访问不到 53 端口;能访问的只有 `lan` 和 `meshvpn`(Tailscale、ZeroTier),都是自己的设备。
`/etc/adguardhome/adguardhome.yaml` 在软件包的 conffiles 里,sysupgrade 会保留,不需要加进 `/etc/sysupgrade.conf`。
## 验证
```
$ nslookup example.com 127.0.0.1
Address: 104.20.23.154
$ nslookup google.com 192.168.156.65
Address: 2607:f8b0:4009:812::200e
$ df -h /tmp
tmpfs 242.7M 5.4M 237.3M 2% /tmp
$ free
Mem: total 497044 used 207988 free 216488 shared 5568 available 233988
```
AdGuard Home 重启后约 15 秒才开始监听 53 端口(当时负载较高),这期间 DNS 不可用。
## 未处理
- **EasyTier 连接器反复重连**:路由器和 NUC 上的 EasyTier 一直在重试连接 `wss://*.zhe-yuan.top:0/easytier/` 等对端,持续占用 CPU(`easytier-core` 约 30%)。组网本身可用(各对端都已 p2p 直连),所以这次只是不记日志,没有改 EasyTier。后续可以查一下这几个对端为什么连不上。
- **iPad 显示“无互联网连接”**:iPad 能正常关联(-44 dBm,HE-MCS 11)、拿到 DHCP(换了私有地址后是 `192.168.156.123`),路由器也能 ping 通它。但在观察的时间里,conntrack 里没有它发起的任何连接,也没有 DNS 查询,nft 计数 20 秒内只有 7 个包。也就是说 iPad 没有在尝试上网,原因还没查清,不确定和本次问题有关。需要在 iPad 上实际打开网页时同步抓包,并检查是否有 VPN、DNS 描述文件或 iCloud 专用代理。
## 回滚
```sh
/etc/init.d/adguardhome stop
cp /root/adguardhome.yaml.bak /etc/adguardhome/adguardhome.yaml
/etc/init.d/adguardhome start
```