只要指向 syslog,AI 就會自動判定設備種類並開始監控 #
新設備一開始傳送 syslog 的瞬間,LLM 就會讀取日誌樣本,自動判定「這是 Windows 用戶端」或「這是防火牆」。系統會套用適當的監控範本,並立即開始監控。無需人工登錄設備。
傳統監控部署中最繁瑣的部分 #
在部署監控工具時,最耗費心力的工作並非初期設定,而是「逐台設備進行登錄的作業」。
無論是 Zabbix 還是其他 SIEM,每次要將新設備納入監控,都需要進行「主機登錄 → 選擇範本 → 剖析器設定 → 測試 → 上線部署」。若是 10 台設備,需要 2-3 人日;若是 100 台設備,則需要 20-30 人日。而且每次新增或移除設備時,這項工作都要重複一次。
BASTION 徹底省去了這整個步驟。
機制全貌 #
以下 5 個步驟完全自動執行。
| 步驟 | 執行內容 | 執行時機 |
|---|---|---|
| 1. 日誌送達 | 新設備傳送 syslog。rsyslog 會依主機名稱自動建立目錄 | 即時 |
| 2. 偵測新主機 | 與先前的主機清單比對,發現新目錄 | 每天一次(cron) |
| 3. LLM 分類 | 將日誌樣本送交 LLM,自動判定設備種類 | 偵測到新主機時 |
| 4. 套用範本 | 依分類結果,在設備登錄檔中登錄適當的監控範本 | 分類完成時 |
| 5. 開始監控 | 範本會在下一次定期分析(每 15 分鐘一次)中自動被呼叫 | 下一次 cron 執行時 |
也就是說,設備開始傳送 syslog 後,最快 15 分鐘內監控報告就會送達 Slack。
步驟 1:由 rsyslog 自動產生目錄 #
BASTION 的 rsyslog 會根據收到的 syslog 主機名稱,為每個發送主機自動建立目錄。
/var/log/remote/ Hostname-A/2026/04/Security-Auditing.log Hostname-B/2026/04/sshd.log Hostname-C/2026/04/filterlog.log ...
新設備一開始傳送 syslog,目錄就會出現,完全不需要變更任何設定。這正是所有自動化的起點。
步驟 2:自動偵測新主機 #
偵測腳本每天執行一次,將目錄清單與先前的清單進行比對。
這裡的關鍵思路是一種反直覺的做法:不去管理「該監控什麼」,而是管理「該排除什麼」。既有的伺服器與網路設備(已在 summarize.sh 中以個別剖析方式處理的設備)會被納入排除清單,其餘則一律視為「新用戶端」。
# Exclusion list (hostname patterns for servers/NW equipment) EXCLUDE_HOSTS="existing-server1|existing-server2|existing-fw|..." # Subtract exclusion list from /var/log/remote/ host list # → Remaining items are new clients
系統會根據偵測結果通知 Slack。
| 情況 | 通知內容 |
|---|---|
| 出現新主機 | 「發現新用戶端開始傳送日誌。正在自動分類並開始監控」 |
| 日誌中斷 | 「此用戶端已停止傳送日誌。請確認 NXLog 的狀態」 |
| 48 小時以上無動靜 | 「日誌已 48 小時以上未更新」 |
| 無變化 | 不發送通知(僅記錄日誌) |
步驟 3:由 LLM 自動分類 #
這是核心所在。偵測到新主機後,系統會從該主機的日誌檔案中擷取樣本(前 5 個檔案 × 最後 20 行),送交 LLM 進行分類。
分類項目 #
分類共分為以下 9 種類別。
| 類別 | 設備種類 | 日誌特徵(LLM 觀察的重點) |
|---|---|---|
| win_client | Windows 用戶端 | Security-Auditing、LogonType 2/10、PowerShell |
| win_server | Windows Server | Security-Auditing、Kerberos TGT/TGS、Directory Service |
| linux | Linux 伺服器 | sshd、sudo、systemd、kernel |
| firewall | 防火牆 | filterlog、block/pass、NAT、VPN |
| switch | L2/L3 交換器 | link up/down、STP、loop |
| loadbalancer | 負載平衡器 | backend、frontend、health check |
| webserver | 網頁伺服器 | HTTP status、GET/POST、access_log 格式 |
| router | 路由器 | BGP、OSPF、routing |
| unknown | 無法分類 | 不符合以上任何一項 → 上呈由人工處理 |
送交 LLM 的分類請求 #
系統會直接向 GPUStack(本地 LLM 伺服器)的 OpenAI 相容 API 發送請求。提示詞中包含主機名稱、日誌檔案清單與日誌樣本,並指示以 JSON 格式回傳分類結果。
# Classification request (overview)
curl -s -X POST "${GPUSTACK_URL}/v1/chat/completions" \
-H "Authorization: Bearer ${API_KEY}" \
-d '{
"model": "qwen2.5-14b-instruct",
"messages": [{
"role": "system",
"content": "You are a device classifier. Classify this host..."
}, {
"role": "user",
"content": "Hostname: XXX\nLog files: ...\nSample: ..."
}],
"temperature": 0.1
}'
# → Response example
{
"category": "win_client",
"confidence": "high",
"os_detail": "Windows 10/11 desktop",
"reasoning": "Security-Auditing logs with LogonType 2..."
}系統會從 LLM 的回應中擷取 JSON 部分,並登錄至設備登錄檔。
實作過程中踩到的坑:透過 OpenClaw 呼叫會導致全部被分類為 unknown #
最初是透過 OpenClaw(AI 代理平台)來呼叫 LLM,但分類提示詞中「win_client」「firewall」等關鍵字,卻與 AGENTS.md(系統提示詞)中的關鍵字對應規則產生衝突,導致 LLM 回傳的是工具呼叫字串,而非執行分類。解決方法很簡單:僅在分類這一環節繞過 OpenClaw,改用 curl 直接呼叫 GPUStack API。同時也將提示詞改為英文,以消除關鍵字干擾。
另一個坑:bash heredoc 與管道 stdin 的衝突 #
在以 Python 撰寫 JSON 擷取邏輯時,bash 的 heredoc(<<'EOF')搶走了管道的標準輸入,導致 Python 的 json.load(sys.stdin) 試圖讀取的竟是 Python 程式碼本身,因而始終回傳空的分類結果。將 Python 的部分移到外部腳本後便解決了此問題。這個錯誤在邏輯上完全正確卻無法執行——百分之百可重現、毫無輸出,耗費了不少除錯時間。
步驟 4:以範本為基礎的監控 #
設備登錄檔 #
分類結果會累積儲存於一個 JSON 檔案(設備登錄檔)中。
{
"devices": [
{
"hostname": "CLIENT-001",
"category": "win_client",
"template": "win_client.sh",
"confidence": "high",
"os_detail": "Windows 10/11 desktop",
"active": true
},
...
],
"exclude_hosts": ["existing-server1", "existing-fw", ...],
"last_scan": "2026-04-21T06:00:00+09:00"
}監控範本 #
系統會為每個類別準備範本腳本,每個範本提供兩項功能。
# templates/win_client.sh
# Summary output (called from summarize.sh)
template_summarize_win_client() {
# Count authentication anomalies, PowerShell, USB, account changes
}
# Detailed analysis (called from analyze-detail.sh)
template_detail_win_client() {
# Per-endpoint failed logon details, privileged logon details, LOLBin detection...
}在既有的 summarize.sh(定期分析腳本)末端,新增了一段讀取設備登錄檔並動態呼叫範本的程式碼區塊。
# Appended to end of summarize.sh
jq -r '.devices[] | select(.active==true) | ...' device-registry.json \
| while read HOST CATEGORY TEMPLATE; do
source "templates/${TEMPLATE}"
template_summarize_${CATEGORY} "$HOST" ...
done既有的硬編碼區段維持不動,僅透過附加的區段新增功能。
步驟 5:完全自動化的成果 #
第一次掃描便自動偵測到 14 台 Windows 用戶端。LLM 讀取每台端點的日誌樣本後,判定「Security-Auditing 日誌中含有登入事件 → Windows 用戶端」。系統隨即自動套用 win_client 範本,並立即開始針對 4 個類別(驗證異常、PowerShell 執行、USB 連接、帳號變更)進行監控。
LLM 分類準確度 #
在 14 台設備中,有 13 台被正確分類,信心度均為 high。有 1 台被分類為「win_server」,信心度同樣是 high,但實際上是 Windows 用戶端。研判原因是主機名稱中含有暗示為伺服器的文字。
由於 win_client 與 win_server 共用同一個監控範本,因此實務上並無影響。不過,若日後分類準確度變得重要,我們也考慮加入一項覆寫功能,可手動修正設備登錄檔中的 category 欄位。
與既有監控並存 #
BASTION 已在 summarize.sh 中針對防火牆、驗證基礎設施、負載平衡器、交換器、網頁伺服器等硬編碼了分析流程。自動分類的對象,是排除這些既有設備之後剩下的設備。
我們不會冒著破壞既有運作中功能的風險。未來或許可以將既有的硬編碼部分也轉換為範本並加以整合,但目前是採取「雙層結構」:「既有設備=硬編碼」與「新設備=自動套用範本」。
未來擴充計畫 #
目前有 win_client 與 generic(unknown)2 種範本,但今後將隨著每次客戶部署陸續新增更多範本。
| 範本 | 狀態 | 主要監控項目 |
|---|---|---|
| win_client / win_server | 已實作 | 驗證異常、PowerShell、USB、帳號變更 |
| generic(用於 unknown) | 已實作 | error/warning/critical 計數 |
| linux | 規劃中 | SSH 驗證、sudo 執行、systemd 服務、OOM |
| firewall | 規劃中 | 阻擋次數、攻擊來源 IP、連接埠分布、VPN |
| switch | 規劃中 | Link down、STP 變化、迴圈、風暴 |
隨著範本庫的擴充,只需「指向 syslog」即可涵蓋的設備範圍也隨之擴大,這將直接累積成為競爭優勢。
總結 #
BASTION 的自動設備分類功能會完全自動執行以下流程:rsyslog 自動產生目錄 → 偵測主機 → LLM 日誌分類 → 自動套用範本 → 開始監控。只要設定好 syslog 的傳送目的地,設備種類判定、監控規則選擇、設備異動管理便會全部自動完成。
這是一套從結構上徹底消除傳統監控部署最大瓶頸——「逐台設備登錄與設定」——的機制。無論是 10 台還是 100 台設備,人工作業量都相同(僅需設定一行 syslog 傳送目的地)。「設備在無人察覺的情況下被排除在監控範圍之外」這種問題,從結構上便不可能發生。
BASTION 是一項在封閉網路中提供 AI 資安監控的服務。
