我想要的不是一台机器人,而是一套安全的托管系统
我想要的不是一台机器人,而是一套安全的托管系统
发布时间:2026-05-09
我最近在整理一个问题:如果让 Hermes 这类 Agent 真正接管服务器运维,到底怎样才算安全?
单纯让它能 SSH 上去,其实不难。难的是另一件事:
我希望它足够自动化,能替我处理日常问题;但又不能因为“全托管”,变成一把没有保险的万能钥匙。
所以这次我把思路重新梳理成了一套“安全全托管”的组网方案。
---
先定一个原则:全托管不等于全权限
很多人一听“让 Agent 托管服务器”,第一反应就是:给它 root,完事。
这当然最省事,但也最危险。
真正可持续的做法应该是:
Agent 有能力做事,但权限分层、操作可审计、入口可撤销。
也就是说,Hermes 可以替我巡检、重启服务、修小问题、写文档、发告警;但涉及删数据、改 SSH、防火墙、大迁移、数据库恢复这类高风险动作时,仍然要进入审批链路。
这不是不信任 Agent,而是把它当成一个正式运维系统来设计。
---
整体架构:主控 + 私有内网 + 被托管节点
我倾向的架构很简单:
Telegram / 用户指令
↓
Hermes 主控节点
↓
Headscale / Tailscale 私有内网
↓
被托管服务器
主控节点负责:
- 接收 Telegram 指令
- 生成一次性接入命令
- 维护节点清单
- 执行 SSH 运维
- 跑定时巡检
- 记录事件日志
- 写入文档中心
- 在异常时发告警
被托管节点只保留必要组件:
- 一个低权限运维用户
- 一组 sudo 白名单
- 一个状态上报器
- 可选的本地 worker
这样做的好处是:大多数机器不需要常驻一个复杂 Agent,只要能被主控通过内网安全访问即可。
---
新机器接入:一条命令,但不是永久后门
我希望新机器接入体验尽量简单,最好就是一条命令:
HERMES_JOIN_TOKEN="j_xxxxx" bash <(curl -fsSL https://sh.example.com/hmi)
但这里有一个关键点:
脚本本体不能携带长期秘密。
脚本只是公开逻辑,负责安装依赖、读取 token、请求主控、执行初始化。真正敏感的东西,比如组网 auth key、节点上报 token、策略配置,都应该由主控临时下发。
这个 join token 应该满足几个条件:
- 一次性
- 默认 30 分钟过期
- 用完立即失效
- 可手动撤销
- 绑定托管等级
- 绑定节点标签
- 不写进长期文档
也就是说,即使这条命令泄露了,它的危害窗口也很小。
---
授权分三层:join token、node token、admin token
我把授权拆成三类。
第一类:join token
只用于新机器首次接入。
它像一张临时门票,拿它可以向主控领取接入配置,但只能用一次。接入完成后,主控立刻把它标记为已使用。
第二类:node token
节点接入后,后续用 node token 上报状态。
它的权限应该非常低:只能汇报“我是谁、状态如何、服务有没有挂”,不能拿其他节点配置,也不能执行管理动作。
第三类:admin token / 管理登录态
这个只留在主控或 Web 管理端,不应该下发到任何被托管节点。
如果后面做 Web 管理端,也应该用登录态、管理员密码、CSRF 防护和操作审计,而不是把一个裸 token 塞得到处都是。
---
托管等级:A、B、C 三档
为了避免一上来就给过高权限,我把节点托管分成三档。
A 档:观察托管
适合刚接入的新机器。
Hermes 可以:
- 查状态
- 看日志
- 盘点资产
- 写文档
- 发告警
但不能改配置、重启服务、删文件。
B 档:日常托管
这是我认为最适合长期使用的默认档。
Hermes 可以处理低风险运维动作,比如:
- 重启指定服务
- 重启指定容器
- 验证后 reload Caddy/Nginx
- 清理可确认的日志
- 补充 swap
- 更新巡检文档
但它需要做到:变更前备份,变更后验证,操作写日志。
C 档:应急全托管
只在救援、迁移、严重故障时临时开启。
比如修 SSH、修防火墙、恢复备份、迁移服务、处理数据库问题。
C 档必须是临时的,用完要收权。
---
sudo 白名单比 root 全权限更适合长期托管
长期来看,我不希望默认给 Hermes:
hermes ALL=(ALL) NOPASSWD: ALL
这太粗暴。
更合理的方式是为 B 档准备一组白名单,例如允许它执行:
systemctl statussystemctl restart指定服务docker psdocker logsdocker restart指定容器journalctldffreess
这样 Hermes 能处理日常故障,但不能随意删除数据、格式化磁盘、改 SSH 或改防火墙默认策略。
真正危险的动作,仍然进入 Telegram 审批。
---
组网层:只解决“怎么连上”,不代表全网互信
我更倾向用 Headscale + Tailscale 做私有内网。
但 VPN 不是万能安全边界。它只解决“怎么连上”,不应该被当成“连上就全信任”。
我会把节点分成几类:
- admin:我的手机、电脑、Hermes 主控
- managed:普通被托管服务器
- worker:备用 worker 或 AI 源节点
- infra:文件中心、监控、数据库
默认规则应该是:
admin -> managed:22
master-hermes -> managed:22
worker -> master-hermes:指定 webhook/API
managed -> infra:必要服务端口
其他默认拒绝
关键点是:
worker 不应该能横扫所有机器,普通服务器之间也不应该默认互通。
这样即使某台节点出问题,也不至于一台失守,全网裸奔。
---
Web 管理端要不要做?可以,但不要一开始做重
我觉得 MVP 阶段不需要复杂后台。
最开始用 Telegram 命令就够:
/join new
/join list
/join revoke <id>
/nodes
/node <name>
/trust <name> A|B|C
因为实际操作里,我更常用 Telegram 直接说:
生成一条 B 档 worker 接入命令。
然后主控直接回一条一次性命令。
Web 管理端可以放到第二阶段,定位成“看板 + 低风险管理”:
- 节点列表
- token 生成/撤销
- 托管等级切换
- 巡检结果
- 操作日志
- 风险提醒
但高危操作仍然应该走 Telegram 审批,而不是在网页上随手点一下就执行。
---
自动巡检和自愈:先小步自动化
接入后,主控可以定期做几类事情。
比如:
- 每 5 分钟检查节点心跳
- 每 15 分钟检查服务状态
- 每天生成资产快照
- 每周跑安全基线检查
自愈也要分级。
低风险可以自动做:
- 服务挂了,重启指定服务
- 容器异常,重启指定容器
- Caddy 配置验证通过后 reload
- 日志爆量时清理已确认日志
中风险可以自动做但必须汇报:
- 补 swap
- 重启 Docker
- 回滚最近配置
- 切换备用上游
高风险必须先审批:
- 删除数据
- 数据库恢复
- 改 SSH
- 改防火墙
- 大迁移
- 重启整机
---
文档不是收尾,是系统的一部分
这套方案里,文档不是“做完顺手写一下”,而是托管系统的一部分。
每台机器接入后,主控应该自动生成机器文档:
server/<hostname>/
├── README.md
├── inventory.md
├── hardening.md
├── network-and-ingress.md
└── next-steps.md
服务也要按服务维度单独记录:
service/<service-name>.md
这样以后维护时,可以通过机器名、服务名、域名、入口、项目名任一锚点反查,不会每次都重新问“这服务在哪台机器”。
敏感信息则统一打码,不写明文密码、token、cookie、数据库密码。
---
我最终想要的状态
这套方案最终不是为了炫技,而是为了达到一种很舒服的运维体验:
- 新机器一条命令接入
- 平时自动巡检
- 小问题自动修
- 中风险动作自动修后汇报
- 高风险动作等我确认
- 所有操作有记录
- 所有资产有文档
- 节点丢了能撤权
- 主控能继续调度备用 worker
也就是:
我只提需求,Hermes 负责接管;但系统边界始终清楚。
这才是我想要的“安全全托管”。
不是把 root 密码丢给一个机器人,而是把 Agent 放进一套有权限、有审计、有撤销机制的运维系统里。
这样它才真的能长期用,而不是只在一次演示里看起来很酷。
