經過前面 28 天的開發,BehaviorGuard 已經具備 Process、Network、File、Persistence 等行為偵測功能,也完成了 Correlation Engine(事件關聯引擎)、Response Policy(回應政策)與部分受控環境的自動化回應。
不過,目前大部分資訊都只能透過 Linux Terminal 查看。
例如,當 BehaviorGuard 偵測到可疑行為時,Terminal 會顯示:
========== BehaviorGuard Alert ==========
Rule : BG-NET-001
Severity : HIGH
Process : socat
雖然可以知道系統偵測到了什麼,但如果同時產生許多 Alert,就很難快速掌握整體安全狀況。
因此 Day29,我們決定建立 Security Dashboard(資安監控儀表板),把原本的 JSONL 日誌轉換成可以透過瀏覽器查看的資安監控介面。
今天的重點不只是讓網頁顯示資料,而是進一步讓使用者能查看告警、分析事件關聯,以及追蹤 Response 決策。
在開發 Dashboard 之前,我們先重新檢查 BehaviorGuard 的完整架構。
因為如果 Detection、Correlation 與 Response 沒有真正串接成功,就算 Dashboard 做得再漂亮,也只是顯示不完整的資料。
目前 BehaviorGuard 的架構如下:
Linux Endpoint
│
├── Process Monitor
├── Network Monitor
└── File Monitor
│
▼
Detection Engine
│
▼
Event Pipeline
│
┌──────┴──────┐
▼ ▼
Alert Logger Correlation Engine
│ │
└──────┬──────┘
▼
Response Dispatcher
│
▼
Response Audit
│
▼
JSONL Logs
在實際檢查中,我們確認 response/event_pipeline.py 已經整合多個核心功能。
每當收到一筆告警,系統會產生 Event ID,將事件寫入日誌,再交給 Correlation Engine 與 Response Dispatcher 處理。
其中 Event ID 很重要,因為它能讓我們知道某一筆 Response 到底對應哪一個 Alert。
我們也檢查了兩個主要日誌:
logs/alerts.jsonl
logs/responses.jsonl
當時的測試結果如下:
| 檢查項目 | 結果 |
|---|---|
| Alert JSONL 格式 | 35/35 有效 |
| Response JSONL 格式 | 61/61 有效 |
| Alert Event ID 重複 | 0 |
| Correlation 告警 | 3 筆 |
| Correlation 來源事件遺失 | 0 |
| 無法對應 Alert 的 Response | 2 筆 |
其中兩筆沒有對應 Alert 的 Response,其實具有相同 Event ID,分別是 RESPONSE_DECISION 和 AUTO_POLICY。
這表示它們屬於同一個事件的兩項回應紀錄。至於為什麼找不到原始 Alert,目前還不能完全確認,可能與先前獨立執行的測試有關。
因此,我們保留這些歷史資料,沒有直接刪除或修改日誌。
接著我們啟動 Unified Agent,在隔離測試目錄建立 Shell Script:
mkdir -p /tmp/behaviorguard_test/tmp
echo '#!/bin/sh' > /tmp/behaviorguard_test/tmp/day29_test.sh
BehaviorGuard 成功觸發:
Rule : BG-FILE-003
Name : Suspicious Script Creation
Severity : MEDIUM
Source : FILE
接著 Event Pipeline 產生 Event ID,並寫入 Alert Log。
Response Dispatcher 則產生:
RESPONSE_DECISION → INVESTIGATE
AUTO_POLICY → DRY_RUN
最後透過程式比對,確認 Alert 與 Response 的 Event ID 相同。
這項測試讓我們確認,至少在真實的 File Detection 流程中,從偵測、日誌記錄到 Response Audit 都能正常運作。
今天我們選擇使用 Python Flask 建立 Dashboard 後端。
Flask 是一套輕量級 Web Framework(網頁應用程式框架),可以讓 Python 程式提供 HTTP API,也可以回傳 HTML 網頁。
選擇 Flask 的原因,是因為 BehaviorGuard 本身就是使用 Python 開發。
我們不需要重新設計整套資料處理系統,只要讓 Flask 讀取已經存在的 JSONL 日誌即可。
BehaviorGuard Agent
↓
Detection
↓
alerts.jsonl
responses.jsonl
↓
Flask
↓
HTTP API
↓
JavaScript
↓
Security Dashboard
這裡有四個重要技術:
Flask: 負責處理瀏覽器請求,讀取日誌並回傳資料。
HTML: 負責建立 Dashboard 的網頁結構,例如統計卡片、告警表格與事件調查面板。
CSS: 負責設計深色主題、風險顏色、側邊選單及響應式排版。
JavaScript: 負責呼叫 API、更新資料、切換不同頁面,以及處理點擊告警後的互動。
簡單來說,Flask 提供資料,JavaScript 處理互動,HTML 和 CSS 負責呈現畫面。
我們新增以下目錄:
behaviorguard/
├── agent/
├── detection/
├── correlation/
├── response/
├── logs/
│ ├── alerts.jsonl
│ └── responses.jsonl
└── dashboard/
├── __init__.py
└── app.py
其中 dashboard/app.py 主要負責提供 API。
這次設計了四個端點(Endpoint):
| API | 功能 |
|---|---|
/api/health |
檢查 Dashboard API 是否正常 |
/api/summary |
統計告警數量與風險分類 |
/api/alerts |
提供最近的安全告警 |
/api/responses |
提供 Response Audit 紀錄 |
例如:
@app.get("/api/summary")
def api_summary():
alerts = read_jsonl(ALERT_LOG)
responses = read_jsonl(RESPONSE_LOG)
return jsonify({
"total_alerts": len(alerts),
"total_responses": len(responses)
})
當瀏覽器發出 GET 請求,Flask 就會回傳 JSON 格式的資料。
JSONL 是 JSON Lines 的縮寫。
一般 JSON 檔案可能使用陣列保存多筆資料,而 JSONL 則是一行記錄一個 JSON 物件。
例如:
{"rule":"BG-NET-001","severity":"HIGH"}
{"rule":"BG-FILE-003","severity":"MEDIUM"}
{"rule":"BG-CMD-002","severity":"MEDIUM"}
對持續運作的監控系統來說,JSONL 很方便,因為可以不斷追加新的事件紀錄。
不過,實際讀取時也必須考慮空白行、無效 JSON,以及部分歷史資料缺少欄位的情況。
因此我們的 API 會忽略格式錯誤的紀錄,並對缺少的欄位提供預設顯示值。
第一次成功啟動 Flask 後,我們在 Firefox 輸入:
http://127.0.0.1:5000
結果出現:
404 Not Found
一開始我以為是 Flask 沒有正常運作,但後來發現真正原因是:
我們當時只建立了 API,還沒有建立網頁首頁。
例如:
/api/summary
/api/alerts
/api/responses
這些路徑已經存在,但 / 還沒有對應的 Route。
因此,當瀏覽器要求 / 時,Flask 找不到對應頁面,就回傳 404。
之後我們加入:
from flask import render_template
@app.get("/")
def dashboard_home():
return render_template("index.html")
讓 Flask 在使用者進入首頁時,回傳 index.html。
這個問題也讓我更清楚理解 HTTP 404 的意思:
它不一定代表伺服器故障,也可能只是要求的資源路徑不存在。
開發過程中,我也發現 Dashboard 使用的是:
http://127.0.0.1:5000
而不是 HTTPS。
原因是目前 Flask 使用本機開發伺服器,尚未設定 TLS 憑證。
HTTP 與 HTTPS 最大的差別,是 HTTPS 透過 TLS 提供傳輸加密、完整性保護與伺服器身分驗證。
目前 Flask 綁定:
host="127.0.0.1"
代表只接受 Kali 本機 Loopback(迴送介面)的連線。
在目前單機實驗環境中,可以先使用 HTTP 開發。
但如果未來要讓其他電腦或遠端管理人員存取 Dashboard,就需要進一步加入 HTTPS、身分驗證與存取控制。
因此現在的 Dashboard 明確定位為 Local Read-only Dashboard(本機唯讀儀表板),不直接開放到外部網路。
接著我們開始製作真正的 Dashboard 前端。
新增:
dashboard/
├── app.py
├── templates/
│ └── index.html
└── static/
├── style.css
└── dashboard.js
首頁採用深色系設計,包含五個統計卡片:
當 Dashboard 成功連接 Flask API 後,我們讀取到:
| 統計項目 | 數量 |
|---|---|
| Total Alerts | 36 |
| Critical | 0 |
| High | 14 |
| Medium | 22 |
| Correlations | 3 |
| Response Records | 63 |
這些數字不是寫死在 HTML 裡,而是由 JavaScript 向 Flask API 取得。
因此,未來只要 JSONL 增加新的告警,Dashboard 就能在更新資料時反映新的統計結果。
除了統計卡片,我們還加入 Severity Distribution(風險等級分布)與 Detection Sources(事件來源分布)。
目前來源包含:
其中 UNKNOWN 主要表示紀錄缺少或沒有可辨識的 Source 欄位,並不等於一種新的攻擊類型。
只有統計卡片還不夠。
SOC 分析人員真正需要的是查看每一筆 Alert,了解發生了什麼事。
因此我們建立了 Endpoint Detection 頁面。
告警表格會顯示:
Time
Rule
Source
Severity
Description
例如:
BG-NET-001 NETWORK HIGH
BG-FILE-003 FILE MEDIUM
BG-CMD-002 PROCESS MEDIUM
BG-CORR-006 CORRELATION HIGH
在新版 Dashboard 中,我們也加入搜尋與篩選介面的程式碼。
使用者可以根據 Rule、Process、Command、File Path,以及 Severity 或 Source 篩選紀錄。
另一個頁面是 Response Audit。
它負責顯示:
Time
Rule
Action
Status
Event ID
例如:
BG-CORR-006
AUTO_POLICY
DRY_RUN
或:
BG-CORR-006
RESPONSE_DECISION
REVIEW_REQUIRED
這讓使用者除了知道「系統發現了什麼」,也能進一步知道「系統對這項告警做出了什麼決策」。
需要注意,Response Audit 是歷史紀錄,不能單憑某筆 DRY_RUN 就推論其他受控實驗事件沒有執行實際動作。
我認為 Day29 最有價值的部分,是新增 Alert Investigation(告警調查)。
以前 Dashboard 只能列出告警,現在使用者可以點擊其中一筆事件,查看完整資訊。
例如選擇:
BG-CORR-006
Severity: HIGH
Source: CORRELATION
系統就能顯示這筆告警的 Event ID、時間、規則、描述和其他證據。
對不同種類的事件,也能查看對應資訊:
Process Event: PID、PPID、Process、Command。
Network Event: Local IP、Local Port、Remote IP、Remote Port。
File Event: File Path、SHA256。
Correlation Event: Related Event IDs,以及對應的來源事件。
為了避免把日誌中的文字當成 HTML 執行,我們在前端主要使用 JavaScript 的 textContent 顯示資料,而不是直接把告警內容插入成 HTML。
這是一項基本的網頁安全措施,可以降低因為顯示不可信日誌內容而造成 XSS(跨網站指令碼攻擊)的風險。
在今天的測試中,我們點擊一筆真實的 BG-CORR-006 告警。
Dashboard 成功呈現三筆相關來源事件:
BG-CMD-002
Python Inline Code Execution
↓
BG-FILE-003
Suspicious Script Creation
↓
BG-PERSIST-001
Cron Persistence
↓
BG-CORR-006
Multi-Source Correlation
這條行為鏈代表系統觀察到:
首先出現 Python 命令列程式碼執行事件。
接著,在暫存位置建立 Shell Script。
最後,出現與該腳本路徑相關的 Cron 設定異動。
BehaviorGuard 根據時間窗口、UID 與腳本路徑等條件,判斷這些事件可能屬於同一組可疑行為。
不過,事件關聯並不等於已經證實攻擊者入侵。
它代表系統找到值得調查的證據組合,需要進一步確認真正的因果關係。
這筆 BG-CORR-006 也成功顯示兩項回應紀錄:
AUTO_POLICY
Status: DRY_RUN
Reason: Live detection requires additional approval
以及:
RESPONSE_DECISION
Status: REVIEW_REQUIRED
Reason: High-risk event requires verification
這代表 Dashboard 已經能根據 Event ID,把 Detection Evidence、Correlation Evidence 和 Response Decision 串接在同一個調查畫面。
這也是我認為 BehaviorGuard 與單純顯示 Alert 的練習程式最大的不同。
完成第一版後,我們發現還有一個問題。
雖然左側有 Security Overview、Endpoint Detection、Correlation Analysis、Response Audit 等選單,但初版主要只是靜態介面。
因此,我們進一步修改 JavaScript,讓側邊欄能切換不同內容。
另外,初期的 Alert Investigation 會出現在頁面下方,分析人員必須向下捲動才能查看。
後來我們把它改成右側 Drawer(滑出式調查面板)。
新的設計是:
Dashboard
↓
點擊安全告警
↓
右側開啟 Investigation Drawer
↓
Alert Evidence
↓
Related Security Events
↓
Response Audit Trail
使用者可以透過 Close、Escape 或點擊背景關閉面板。
目前程式也加入了每 5 秒查詢一次 API 的自動更新機制,以及手動 Refresh 按鈕。
不過,這裡需要區分「功能已寫入程式碼」和「功能已完成實測」。
目前已確認新版 Security Overview 成功顯示,先前版本的 Correlation Investigation 也已透過截圖驗證。新版側邊欄、右側 Drawer 和動態更新仍需要進一步操作測試,才能宣稱所有互動功能完全驗收通過。
因為 BehaviorGuard 是資安監控系統,所以 Dashboard 也需要考慮安全性。
目前採用幾個原則。
第一,唯讀設計。
Dashboard 只讀取 JSONL,不提供終止程序、封鎖 IP 或刪除事件的 API。
第二,限定本機。
Flask 目前只監聽 127.0.0.1,不直接對外開放。
第三,歷史資料容錯。
部分早期 Alert 缺少 Event ID 或 Source,因此前端需要正確處理缺失欄位,而不是直接發生錯誤。
第四,不把 API Connected 當成 Agent Online。
Flask 正常運作只代表 Dashboard API 可以連線,不代表 Process、Network 和 File Monitor 正在執行。
目前 Dashboard 顯示的是日誌內容,尚未具備真正的 Agent Heartbeat(心跳回報)功能。
第五,還沒有完整身分驗證。
現在的 Dashboard 適合本機實驗,不適合直接部署在企業網路或公開網際網路。
未來仍需要 HTTPS、登入驗證、存取控制,以及更完整的日誌查詢與分頁機制。
今天從最基本的 Flask API 開始,逐步做出能展示 BehaviorGuard 偵測成果的網頁。
| 功能 | 目前成果 |
|---|---|
| Flask API | 成功啟動並讀取真實 JSONL |
| Security Overview | 已實測成功 |
| Severity Distribution | 已實測成功 |
| Detection Sources | 已實測成功 |
| Recent Security Alerts | 已實測成功 |
| Alert Investigation | 已實測成功 |
| Correlation Evidence | 成功顯示三筆來源事件 |
| Response Audit Trail | 成功顯示兩筆對應紀錄 |
| 側邊欄頁面切換 | 已加入程式,待完整互動驗收 |
| 右側調查 Drawer | 已加入程式,待完整互動驗收 |
| 每 5 秒自動更新 | 已加入程式,待動態測試 |
Day29 最重要的成果,是讓 BehaviorGuard 從 Terminal 中的告警輸出,進一步變成可以查看事件證據與回應決策的 Web Dashboard。
今天讓我學到,EDR 不只是偵測惡意行為,還需要把資料整理成分析人員看得懂、查得到的資訊。
以前看到一筆 Alert,我只知道它觸發了哪一條 Rule。
但今天透過 Dashboard,我可以點開某個 Correlation Event,查看它包含哪些原始事件,並且追蹤 Response Dispatcher 做出了什麼決策。
其中最讓我印象深刻的是 BG-CORR-006。
原本 Process、File、Persistence 是三個不同的監控來源,但透過 Event ID 和 Correlation Engine,我們能把相關證據放在同一個畫面查看。
我也更清楚理解 Flask、HTTP API、JSON、HTML、CSS 與 JavaScript 之間如何分工。
開發時遇到的 404 Not Found,則讓我知道伺服器成功啟動不代表所有網頁路徑都已經存在。
而 HTTP 與 HTTPS 的差別,也提醒我資安產品不只需要保護被監控的端點,自己的管理介面同樣必須考慮傳輸加密、身分驗證與存取安全。
目前 BehaviorGuard 仍然是一套實驗性 EDR 原型,距離真正的企業級產品還有不少差距。
但經過 Day29,我們已經把前面建立的 Detection、Correlation、Response 與 Audit Log 成果整合進同一個可視化介面。
下一篇 Day30,我們將進行 BehaviorGuard 的最終整合驗收、功能展示、系統限制整理與專案總結,回顧這 30 天從零開始打造 Linux 行為偵測與回應系統的完整過程。