按 security-reports/ 的隐私审查台账逐项收口。纯脱敏与表述泛化, 不含任何业务逻辑变更;实测结论与排查步骤一字未动。 P1(可定位到具体设备/个人) - scripts/verify-b2.mjs:NA_URL 去掉硬编码缺省值(原指向一台真实机器),改为必填。 这是全仓库唯一「拿着就能连到某台真机」的常量。 - 测试账户名 pdverify → na-test(docs/VM-VERIFICATION.md 7 处、docs/console-plan.md 1 处) - 虚拟机与宿主的真实网段 → RFC 5737 文档保留段 192.0.2.x(含 CLOSE_WAIT 记录) - 跨项目名与私人称呼 → 中性表述(docs/PRD.md、docs/DEVELOPMENT.md、docs/console-plan.md 等) P2(低风险设备指纹) - 虚拟化产品及其 CLI / 访客工具名 → 中性表述(12 个文件 + 1 个工作流注释) - 测试目录 C:\nodeagent-test → C:\na-test - NAS 设备型号与系统名 → NAS 设备 / NAS 系统(docs/DEPLOY-LINUX.md、scripts/install-linux.sh、README.md) - 真机 CPU 型号、真机物理分辨率、代理软件品牌与监听端口、杀软品牌 → 泛化 - 单元测试示例段去掉真机 IP 尾八位:acl-v11 / net-scripts 的 fixture 与断言同步更新 - .gitignore 补 config.json / agent.json(含真实密钥与节点地址,绝不入库) - 顺带移除混入技术文档的「不构成投资建议」字样(与文档主题无关) 验证:pnpm test:unit 340/340 通过;独立扫描器对 235 个跟踪文件做 17 类模式 全量扫描,命中 0。
10 KiB
跨机接管的边界与局限
本文记录 Mac(控制端)能对被控端做什么、做不到什么,以及为什么。 素材来自 2026-09-27 对一台真实 Windows 机的诊断过程(案例见文末)。
一、能力边界总览
| 能力层级 | Mac 端可否 | 说明 |
|---|---|---|
| 读取状态 | ✅ 完全可 | 进程 / 服务 / 网络 / 文件 / 注册表 / 事件日志 —— 只要命令能查 |
| 执行命令 | ✅ 完全可 | system.shell.exec 跑任意 PowerShell(管理员权限下) |
| 改文件 | ✅ 完全可 | fs.write 原子写,可改配置 / 脚本 |
| 改系统设置 | ⚠️ 多数可 | 注册表、服务、计划任务、防火墙规则等可用命令改 |
| 改网络配置 | ⚠️ 高风险 | 能做,但可能把自己弄断(详见 §2.1) |
| 操作 GUI | ❌ 基本不可 | 鼠标键盘默认禁用,且即使开启也难判读界面状态(详见 §2.2) |
| 需要人工判断的决策 | ❌ 不可 | 选哪个代理节点、订阅是否有效 —— AI 无从判断(详见 §2.3) |
| 物理动作 | ❌ 不可 | 插拔网线、按电源键、换硬盘 |
二、核心局限(按严重程度排序)
2.1 「自断生路」悖论 —— 最根本的局限
问题:agent 自身依赖网络(Mac ↔ Windows 走 TCP 8765)。 而被诊断的问题往往正是网络。此时若贸然修改网络配置:
改网络配置 → 网络中断 → agent 连接断开 → Mac 彻底失联 → 无法回滚
具体危险操作:
- 禁用网卡 / IPv6 绑定(
Disable-NetAdapterBinding) - 修改 IP / 网关 / DNS(
Set-NetIPConfiguration) - 重启网卡(
Restart-NetAdapter) - 修改防火墙规则(可能连 8765 一起挡了)
- 重启系统(重启后 agent 要等自启 + 网络恢复,期间完全失联)
为什么不能靠「改完再改回来」兜底: 一旦断开,Mac 端没有任何通道能把配置改回去 —— 除非:
- Windows 侧有人在(那就失去「无人值守」的意义了)
- 或被控端配置了计划任务自愈(定时检查并恢复,属于后续可做的加固)
缓解思路(建议后续实现):
- 配置变更前自动备份 + 超时未确认则自动回滚(类似路由器固件的「确认式配置」)
- 关键网络操作走「两阶段提交」:先改、再 ping 验证、失败则回滚
2.2 无 GUI 交互能力
问题:input.*(鼠标键盘)出于安全考虑默认禁用;即使开启,AI 也难以完成 GUI 任务。
| 场景 | 为什么做不到 |
|---|---|
| 代理软件换节点 / 更新订阅 | 需在代理客户端界面里点选,且节点可用性关乎上游服务,AI 无法判断 |
| UAC 提权弹窗 | 需人点「是」,agent 无法代点(安全设计) |
| 安装向导(下一步 → 完成) | 界面状态判读不可靠 |
| 浏览器登录 / 扫码 | 需要人的凭据与设备 |
AI 能做的替代:用命令行等价操作绕过 GUI(如 netsh、注册表、服务命令)。
但第三方 GUI 软件的内部状态(如代理客户端里"当前选中哪个节点")通常没有命令行接口。
2.3 无法替代「人的判断」
有些问题不是能不能执行,而是该不该执行:
- 代理订阅是否过期、节点是否可用 —— 需要人的账号与常识
- 哪个软件该装、哪个进程能杀 —— 需要业务判断
- 用户看到的报错在什么操作后出现 —— AI 无法感知复现路径
2.4 观测窗口的时点性
| 限制 | 影响 |
|---|---|
| 只能看当下快照 | 间歇性问题(如抖动、偶发超时)容易漏判 |
| 无法 7×24 盯 | AI 只在被调用时"看一眼",问题在两次调用之间发生就看不到 |
| 应用层内部状态不可见 | 如 WorkBuddy 的"当前正在等哪个请求",AI 只能从日志反推 |
缓解(✅ 已于 v2.0.0 实现):monitor.* 定时采样并落盘,事后回看摘要 —— 正是为治
这类间歇性问题而做(原先只写"具备实现基础",现已成为能力):
# 对某端口连续采样(每 2 秒一针),中途无需一直连着
nodeagent --node win invoke monitor.start --args '{"source":"port","target":"127.0.0.1:8765","interval_ms":2000,"id":"probe"}'
# …过一段时间再回来…
nodeagent --node win monitor report probe # 直接给出:断了几次 / 最长断多久 / 延迟值域
配套能力:
log.query—— 日志在被控端侧过滤后只回匹配行,不必把几万行整份拉回system.audit.anchor—— 定期把审计链头锚定到链外,防「有 root 者整链重写」
仍未解决的:应用层内部状态("当前在等哪个请求")依旧只能从日志反推 ——
monitor 采的是外部可观测量,读不到进程内部语义。
2.5 破坏性操作的不可逆
- 删文件:
fs.write是覆盖写,无回收站语义 - 改注册表:无版本控制
- 改服务/任务:原配置不保留
缓解思路:所有写操作前自动备份到带时间戳的副本(可作为后续加固项)。
三、协作模式建议
| 类别 | 交给 Mac 端远程 | 必须人工 |
|---|---|---|
| 状态诊断(进程/服务/网络/日志) | ✅ | |
| 执行命令、改文件、改配置 | ✅(需评估断网风险) | |
| 网络配置变更 | ⚠️ 仅在有回滚保障时 | 无保障时人工 |
| GUI 软件操作(代理客户端等) | ✅ | |
| 需要账号/凭据/判断的决策 | ✅ | |
| 重启、物理操作 | ✅ |
一句话:能"看"和"算"的尽量远程,涉及"断自己后路"和"需要人判断"的交给人工。
四、本次真实案例(2026-09-27)
报障:Windows 上的 WorkBuddy 反复提示 Response timed out (no data received). Retrying automatically...
诊断手段:全程经 nodeagent 从 Mac 远程执行,未触碰 Windows。
查到的关键事实:
| 观察项 | 结果 | 判读 |
|---|---|---|
| 网络适配器 | Ethernet Up / 1 Gbps | 链路正常 |
| 国内网络(百度) | HTTP 200 / 0.24s | 基础联网正常 |
copilot.tencent.com |
HTTP 200 / 0.35s(IPv4) | 后端可达 |
| 代理客户端 + 代理内核进程 | 均在运行 | 代理软件活着 |
| 代理内核监听 | 0.0.0.0:<代理端口> |
代理端口在听 |
| 系统代理 | ProxyEnable=0,但 ProxyServer 残留 127.0.0.1:<代理端口> |
⚠️ 配置矛盾 |
| 走该代理端口访问外网 | 超时(HTTP 000 / 20s) | ⚠️ 上游节点不通 |
resolveProxy RPC |
耗时 1737ms(慢) | ⚠️ 代理解析卡顿 |
| MarketplaceInitGate | 15s 安全超时后强放行 | ⚠️ 启动期被拖慢 |
| WorkBuddy 连接 | 4 条 IPv6 到腾讯(已建立) | 部分链路正常 |
TCP CloseWait |
24 条 | 偏多,疑似连接被中途中断 |
结论(高度可能):
系统存在**「代理配置残留但未启用,且代理内核上游节点实际不通」**的矛盾状态 ——
WorkBuddy 解析代理慢 + 部分请求走了不通的代理链路 → Response timed out。
为什么 AI 没有直接修:
- 需要的动作是「在代理客户端界面换可用节点 / 更新订阅」→ 属 GUI + 人工判断(§2.2 / §2.3)
- 若改为「清空系统代理残留」→ 属网络配置变更,虽有价值但需用户确认(§2.1 风险)
建议的下一步(人工为主):
- 打开代理客户端 → 测试节点延迟 → 换一个可用节点(或更新订阅)
- 确认代理客户端的「自动配置系统代理」策略与实际需求一致
- 观察是否仍有
Response timed out;若仍有,可让 AI 持续采样再定位
五、结论
nodeagent 的定位不是"替代人",而是"把人从重复的状态检查与命令执行里解放出来"。
- 它擅长:可观测、可脚本化、无副作用的事 —— 诊断、查询、批量执行
- 它回避:断后路、需判断、需凭证的事 —— 这是设计取舍,不是缺陷
明确这条边界,才能既用好它,又不至于在关键故障时因为"以为能远程修"而耽误时间。
杀软误拦(主流杀毒软件)
现象:远程接管类工具的典型特征(未知 exe + 建计划任务 + 开防火墙 + 常驻监听 + 注入键鼠/截屏)
必然触发杀软拦截。实测:主流杀软会拦下 install.ps1 执行、计划任务注册,或直接处置 node.exe,
表现为「下载成功但装不上」或「装上后 agent 起不来」。
逐项放行清单(把下面这些都加进杀软的信任/白名单,而不是整机关防护):
| 对象 | 说明 |
|---|---|
| 安装目录 | 解压出来的整个文件夹(含 node.exe、agent.mjs、install.ps1) |
node.exe |
被控端自带的 Node 运行时(免装 Node 就是因为这个文件) |
agent.mjs |
agent 主体(常驻监听 8765) |
计划任务 nodeagent |
开机/登录自启任务;杀软的「启动项拦截」会静默拦掉它 |
| 入站端口 8765/TCP | install.ps1 已建防火墙规则;杀软的独立网络防护可能仍拦 |
| PowerShell 脚本执行 | 杀软的「系统加固」会拦脚本解释执行;至少放行上面的安装目录 |
| 键鼠/截屏行为 | 开启 allow_input 后才会出现;若被拦,screen.capture/input.* 会失败 |
自检命令(在 Windows 上跑,确认三件事:任务在不在、进程活不活、端口听没听):
Get-ScheduledTask -TaskName 'nodeagent*' -ErrorAction SilentlyContinue | Select-Object TaskName, State
Get-Process node -ErrorAction SilentlyContinue | Select-Object Id, Path
netstat -ano | findstr :8765
Invoke-WebRequest 'http://127.0.0.1:8765' -UseBasicParsing -TimeoutSec 2 # 有响应即端口通
排查顺序:先看任务与进程(被杀软处置则两者都缺)→ 再看端口(进程在但端口不通 = 防火墙/杀软网络防护)
→ 最后从控制端用 nodeagent discover 或 ping 确认两台机器确实在同一网络。
⚠️ 最后一环最容易忽略:真机踩过 —— 控制端换了 Wi-Fi(酒店/热点)后仍在扫旧网段, 排查半天「失联」,实际是两台机器不在同一网络。先用
ipconfig/ifconfig对齐网段再谈其他。