工程

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