工程

ShellMon 是如何做出来的:实时检测危险 shell 命令

ShellMon 监控你的 SSH 会话,在 rm -rf / 按键送达服务器前拦截。我们怎么做到的,不拖慢终端。

CC Chen Chen· 创始人·2026 年 6 月 1 日·阅读 12 分钟

问题

用户在手机 SSH 会话里粘 rm -rf / 跟桌面一样容易。可能更容易 —— 自动联想、AI 建议、手忙脚乱误触。我们需要一层拦截,在按键到达服务器**之前**生效。

最简单的想法是建一个"危险字符串黑名单"。但 shell 是一门语言,不是一组固定短语。rm -rf /rm -fr /rm --recursive --force /r''m -rf / 表达同一个意图,只是穿着不同的外衣。任何只匹配字面文本的方案,第一个加引号的人就能绕过。

我们考虑过的三种方案

  1. 客户端正则匹配。发送前匹配危险模式。快,但极易绕过 —— r''m -rf / 就能逃过简单匹配。
  2. 服务端包装脚本。在每台服务器上装一个包装脚本。可靠,但要修改每台主机 —— 对于"专门连还没预配置的服务器"的移动客户端来说,这条路根本走不通。
  3. 混合方案:客户端解析 + 规范化。对命令分词、规范化,再匹配一套精心维护的规则集。这是我们最终上线的方案。

检测流水线

检测在设备上分三阶段执行:规范化、分词、匹配。最复杂的工作在规范化器里 —— 展开引号、处理常见转义、按命令分隔符切片,让每段独立判定。

def is_dangerous(command: str) -> tuple[bool, str | None]:
    tokens = shlex.split(canonicalize(command))
    for rule in DANGEROUS_RULES:
        if rule.matches(tokens):
            return True, rule.reason
    return False, None

canonicalize() 去掉成对引号(r''mrm)、合并引号外的反斜杠转义、替换一小组已知安全的环境变量展开,并按 &&;| 切分复合命令,让危险片段无处藏身。每段独立过规则集。规则是数据,不是代码 —— 一个 YAML 包,记录分词模式和给用户看的人类可读理由。

为什么这里模式匹配胜过大模型

我们也考虑过用 LLM 分类危险命令。可行 —— 但慢(每次按键 300-800ms 延迟)、调用量级下成本太高、过度保守:会因为"delete"看起来吓人就把 find . -delete 拦下来。

手工调过的模式匹配延迟在亚毫秒、完全离线、可审计 —— 你能精确读到一条命令为什么被拦。所以我们分工:模式匹配负责**检测**,LLM 负责**解释**。命令被拦后,AI 助手能用自然语言解释为什么,但它绝不在每次按键的热路径上。

Y/n 自动应答

ShellMon 解决的另一个独立问题:apt upgradeDo you want to continue? [Y/n],用户希望它被自动回答而不必一直开着屏幕。难点不是"输入 Y" —— 而是怎么知道会话**在等输入**而不是还在工作。

# 每条我们启动的命令都追加一个哨兵
cmd; __ec=$?; printf '\n__TERMAI_END_%s__%d__\n' "<hex>" "$__ec"

哨兵一物两用。它出现在输出里,我们就知道命令结束了,能不解析提示符就拿到退出码。它**没**出现而输出在某种已知提示符([Y/n](yes/no))上沉默,我们就有把握会话卡在输入上 —— 只有这时自动应答规则才触发。随机化的 hex 让哨兵跟程序输出里碰巧含 "END" 的字串不会冲突。

它抓不住什么

诚实的局限:
  • 自定义二进制。我们检查不了 ./my-script.sh 里在做什么。只检查调用,不检查内容。
  • 管道链。很长的管道中间嵌 grep/awk/jq,能把危险模式藏进去。明显的我们拦得住,对抗式的拦不全。
  • 有心人滥用。一个真的**想**抹掉服务器的用户,总能找到办法。ShellMon 是安全网,不是访问控制。

我们发了什么,接下来做什么

ShellMon 在 TermAI v0.9 上线。之后我们加了可定制规则包、Pro 等级的长任务推送/邮件通知、AI 助手的命令解释集成。

下一步:snippet-aware 模式 —— 如果你跑的是自己片段库里的命令,ShellMon 信任度更高、噪音更少。同时我们把规则集开源到 GitHub,让用户审计并贡献我们遗漏的模式。

Try TermAI

Free on iOS and Android. 3 SSH connections + 20 AI calls/day on the free tier.

CC
Chen Chen — Founder of TermAI

Writes about mobile DevOps, terminal UX, and the surprising depth of "boring" infrastructure.

💬 Discuss this article: Hacker News · Reddit · V2EX
Was this useful? ← Back to blog