这周的底色是给 wenkangnas.local (192.168.1.4) 做一轮体检和加固:从一次 DSM 自动更新重启引出来的虚拟机没自启、告警邮件失效,到磁盘 SMART、快照、一个 PHP 漏洞的应急停用。另外 OpenClaw 网关的内存问题继续追,AI 工具这边把前端外包的流程补完整,周末给电视查了个加载圈的问题。

NAS 凌晨自动重启之后:VM 没自启、告警邮件早就坏了

10-18 一早发现 NAS 凌晨被 DSM 自动更新重启过,VMM 先把所有虚拟机正常关掉,开机后只有设了自启的 iStoreOS 和 OpenClaw 起来,一台 Windows 虚拟机没设自启,一直是关的。让 AI 顺着巡检,当天做了这些:

  • 给那台 Windows 虚拟机打开自启并开机;开起来以后群晖的 fileindexd 内存从 6.2 GB 自己降到了 2.5 GB。
  • 告警邮件从 9 月 22 日起就发不出去了,失败了 7600 多次:NAS 用的是 Outlook 的 SMTP,微软早就停用了用户名密码登录。更夸张的是失败数的来源——一个每 5 分钟跑一次的 VPN 路由维护任务开着"每次运行都发邮件",一天 288 封。我把它改成只在出错时通知。
  • 换发信账号折腾了一圈:先试 Gmail(NAS 上直连它的 SMTP 不通),最后换成国内邮箱的 SMTP,直连可达,用 DSM 网页上的"发送测试邮件"实测收到。DSM 命令行设置 SMTP 密码时,字段名是 pass 而不是常见的 password,且字符串参数要带 JSON 引号。
  • 一个教训:调 DSM 接口时有一次让接口程序崩溃,在卷上落了一个 core 文件,里面可能留着刚设的邮箱密码,AI 事后找出来删了。往命令行里传过密码的话,要查一下有没有 core dump。
  • OpenClaw 那台 VM 的内存最后定在 6 GB;代价是 Windows 虚拟机开着时就不能再开 Win10,否则 NAS 会开始频繁用 swap。

sata3 的 CRC 错误:历史快照里翻出时间线

AI 报告里说 sata3 有 31 次历史 CRC 错误,我问"这是什么时候的事"。DSM 从 2021 年起大约每周存一份 SMART 快照(/var/log/smart_result/*.txz),AI 把它们翻了一遍:这块盘 2022 年 6 月装进来时 CRC 就已经是 31,之后四年一次没涨,所以不是线缆或背板问题,不用处理;但盘里自带的错误日志记录了今年 6 月 8 日的 3 次读不出扇区(UNC),重映射和待处理扇区仍然是 0。

之后让它安排了一次 SMART 扩展自检,晚上自动开始。第二天 10-19 我看到 sata3 的写延迟明显高于另外三块,一度以为盘有问题,用 sudo smartctl 读了才发现是自检还没跑完(剩 30%),自检和正常读写抢磁头。跑完后结果是"没有错误",延迟回到正常(空闲时测的,没测到高负载)。

AI 还提了一条推断:这块标称 WD Red 的盘,固件版本格式、序列号和 SMART 数据格式都不像 WD 原厂,更像改标的翻新盘,建议排第一个换。这只是根据数据格式判断,没有拆盘核实。

NAS 加固:快照、权限、给 AI 单独建账号

10-19 我让 AI 以"有没有被攻击风险"的角度审了一遍 NAS(只读,4 个子任务并行)。结论是没发现被入侵的迹象,但有一批要收拾的东西,我当场处理了其中大部分:

  • Web 目录里躺着的 32 个 .bak 和旧版本目录,会被当静态文件原样返回——其中一份是带密钥的配置备份。全部挪到只有自己能访问的目录;那份备份里的密钥按"已泄露"处理,要轮换。
  • 把不需要的 Web 管理类套件卸掉,Cloudflare 隧道里一条已经 502 的入口和一条没人用的私网路由删掉。
  • 防火墙里有一条规则对所有来源放行,改成只对内网和 VPN 网段放行。
  • Web 目录权限:AI 先说"全是 777",核实后实际只有 15 个文件或目录是所有人可写,它自己更正了。
  • 13 个共享文件夹装上 Snapshot Replication:每天 04:00 拍一次、保留 14 天,每张快照锁定 7 天不可删除(连管理员也删不掉,这是防勒索的关键)。注意卷已经用了 91%,删大文件后空间要等快照过期才能释放。快照计划的 API 没有文档,是从套件的前端 JS 里反推出来的参数格式:先在一个共享上试通,再推到其他的。
  • 给 AI 单独建了一个账号:只能用 SSH 密钥登录(密码是随机串,设完就丢,没人知道),在应用权限里禁止登录 DSM 网页,有免密 sudo,另外加了一个开机脚本,DSM 更新如果冲掉 sudo 规则或"禁止密码登录"那段 sshd 配置,开机时会补回来。好处是我自己的账号可以换成只存在密码管理器里的长密码,日志里也能分清哪些操作是 AI 做的。代价要说清楚:这把私钥没有口令,等于 NAS 的 root。

还有一个意外发现:旧密码以明文躺在共享记忆库、几个 README 和 shell 历史里,记忆库会保留旧版本,所以只能换密码,不能靠删。

PHP 漏洞应急:停掉 PHP 8.2,修好后再启动

10-21 晚上看到一条 PHP 两个核心 RCE 的消息(会话里搜到的 CVE-2026-109618 / 109619,我没独立核实),让 AI 看 NAS 受不受影响。从局域网探测:任意不存在的 .php 路径返回 500、同名 .html 返回 404,说明有 PHP 处理器;SSH 上去确认所有 php-fpm 都是 8.2.30(修复版是 8.2.35),DSM 还没推更新。查了 web 目录最近两天的改动、上传目录有没有新的 .php、/tmp 里有没有可执行文件,没发现被利用的迹象。

处理方式我选了最彻底的一种:直接停用 PHP 8.2 套件(synopkg stop PHP8.2),依赖它的 Calendar 一起停。验证:PHP 站点返回 502、DSM 管理界面正常。10-22 群晖把套件更新到 8.2.35 后,先确认版本再启动两个套件,页面 200,FastCGI 超时仍是我之前手动改的 300 秒,没被 Web Station 刷回去。启动后只用 curl 看了页面能打开,没有实际用站点功能走一遍。

OpenClaw 网关:内存、自愈脚本和通知渠道

延续上周的内存问题,这周追了好几轮:

  • 泄漏的线索:两次网关卡住约 4 分钟(10-17 和 10-18 早上)都发生在 agent 调用 web_fetch 之后,卡完堆和外部内存涨一截就不回落。我把两个早间任务改成用脚本取数据,禁止用 web_fetch;10-19 的检查里网关没再卡、内存平稳,这支持了推测,但还不是证明。另一个看似可疑的 web_search 对了一遍历史采样后排除了:它只在网关重启后第一次调用时涨约 32 MB,是一次性的加载开销。
  • 记忆索引自愈脚本连续失败:重建其实成功了,失败在重建之后的检查——这台 2 核 VM 上 openclaw memory 光启动就要 90 秒,原来的超时根本不够。调大超时、让失败原因显示出来;另外发现脚本里一个 jq 写法会让它每晚都以为索引过期,白白做一次 700 MB 的备份加重建,一并修了。
  • 备份目录 78 GB:从来没清理过,保留最近 7 份。清完 du 显示降到 5.6 GB,磁盘却只多出约 5 GB——AI 的解释是备份之间共享未改动的数据块,所以 78 GB 本来就是虚高(这个解释我没单独验证)。
  • 微信推送 9 天里 5 天没送达:机器人只能在我最近一次给它发消息后约 24 小时内主动推送,超时报错但任务状态仍显示 ok。5 个定时任务全部改投 Telegram。
  • heartbeat 的小插曲:我要求每次都发消息,用来确认 OpenClaw 还活着;AI 发现 OpenClaw 自带的 heartbeat 提示词写着"没事就回复 NO_REPLY",压过了 HEARTBEAT.md 里的规定。换成自定义提示词后,确认走的是 Codex 订阅的额度(不是按量计费),又从 3 小时一次改成 1 小时一次。
  • 命令行 openclaw 其实是旧版本,网关是新版,修成都指向新版。

48 小时的正式复核点是 10-20 14:39,结果不在这周的素材里,我没记,所以**“泄漏已修好"这个结论我还不能下**。

反向代理后面的网关报 proxy_attribution_required

10-20 通过 NAS 反代访问 OpenClaw 网关突然返回 proxy_attribution_required,根因是代理没传 X-Forwarded-For 加上 trustedProxies 写得太宽,两个条件叠加。整个排查和修法写成了一篇:群晖反向代理后面的网关报 proxy_attribution_required。

去掉脆弱的网页逆向中转,换成 codex exec 的 HTTP 服务

NAS 上自己写的聊天中转页,后端之一是靠网页登录 cookie 的逆向中转,要定时重新登录加看门狗维持,最脆弱。我想把它去掉,只用 codex -p / grok -p。AI 先纠正了一点:codex -p 是 --profile,非交互要用 codex exec。方案是不在 NAS 上跑 codex(PHP 以 web 用户 shell out 调用,凭据放不对地方、一次调用 10–60 秒会占满 PHP-FPM),而是在 192.168.1.244 上起一个小的 HTTP 中转,里面调 codex exec,PHP 只是多一个 backend 转发。

测了纯文本、带图、联网搜索和 3 个并发(并发上限设 2,第三个请求排队约 10 秒),路由矩阵全部通过,然后把调用它的几个脚本逐个迁过去。另外验证时撞到 nginx 的 FastCGI 超时被 Web Station 刷回 60 秒,用一个已有的修复脚本恢复成 300 秒。这一节我只核对了会话的前半段,后面几个调用方的收尾我没细看。

AI 工具:前端外包补完、密钥搬进环境变量、一个读代码的结论

  • OpenCode 的 K3 --variant medium 确认可用(会话记录里有 variant:"medium"),拿一份"4 盘位家用存储服务器状态页"的泛化 brief 加合成 mock 数据做外包测试:第一轮 3.5 分钟,唯一硬伤是 375px 下横向溢出;第二轮 2.3 分钟按 12 条反馈全修好。真实的 NAS 数据是我在本地灌进成品页面的。
  • 额度用完的识别:OpenCode 额度耗尽时进程不退出,错误只写进它自己的内部日志,不在屏幕输出里。所以做了个看门狗,每 5 秒查一次内部日志,实测 6 秒内识别并切到下一个后端。随后修了它的两个弱点:只认内部日志里 ERROR 级别的那一条(页面文案里恰好有"usage limit reached"也不会误杀),以及换后端时用 brief 加反馈重新发起而不是指望接上前一个后端的会话。
  • 明文密钥:opencode 的配置里躺着明文 API key 和记忆库 token,一并换成环境变量占位符,实际的值放 Mac 钥匙串(Linux 机器放权限 600 的文件);一个 opencode() shell 函数只在启动它时注入,并且从 Claude Code 里调起时不注入——这样 AI 自己拉起的 opencode 连不上记忆库,符合我的预期。Claude Code 会把 ~/.zshrc 里的函数复制进它的 shell 快照,这一点之前没注意到。
  • herdr-plus 能不能复用:读完源码结论是不能直接用(Go vs Python,用途也不同),但它修过一个启动竞态——新 pane 的 shell 没起好就发命令,第一个字符会被吞(claude 变 laude)。做法是等屏幕连续两次读到相同内容、敲命令、校验回显、不对就 ctrl+u 重敲。我让它把这段移植到自己的 aiboard 里。这个竞态是读代码推断出来的,没复现;移植后的验证结果不在我看到的素材里。

NetBird 重启后又连不上:macOS 的"允许在后台"把它关了

netbird up 一直报找不到 /var/run/netbird.sock。LaunchDaemon 的 plist 没问题、也设了开机自启,但 sudo sfltool dumpbtm 里这条后台项目的状态是 [enabled, disallowed, notified]——系统设置 → 登录项与扩展 → 允许在后台里它被关掉了,开机时系统直接跳过,日志最后一次写入停在 9 月 9 日。手动 sudo launchctl bootstrap system /Library/LaunchDaemons/netbird.plist 能临时拉起来,要永久修好只能手动在系统设置里打开开关(没有命令行可以开;sfltool resetbtm 会把所有后台项目都重置,没用)。我打开开关后复查变成 [enabled, allowed],守护进程在跑,peer 都在线。真正重启验证还没做。 之前 ToDesk 后台服务掉过的事很可能也是同一个原因。

电视上的影视 app 每次都转圈

周日用 adb 查了电视上 TVBox 系 app 启动时的加载圈:是真关机加冷启动要初始化运行环境,一个"精简配置能提速"的判断被录屏对比推翻了,升级到新版后从约 4 秒降到约 2.75 秒。写成了一篇:电视上的影视 app 每次打开都转圈。

其它零碎

  • 下载 Windows 11 ARM64 英文版 ISO(给 Mac 上的 VMware Fusion 用):让 Codex 用 ego-browser 在微软官方页面选好版本语言,拿到下载地址后改成多线程分块下载(约 40 MB/s,8.5 GB),最后用微软公布的 SHA-256 校验通过。
  • ego-browser 的速度测试:让 Claude Code 连着跑 13 个浏览器操作(登录、拖拽、悬停、canvas 画图、抓页面、并行开 4 个标签等),一共 16.8 秒。但我在 GUI 上什么也没看到——它是在自己独立的任务空间里跑的,需要切到那个空间才看得见;它开了 ego lite 慢速重跑也没有定论,我这边的"看不到"这条没解决。