在前面的 Malcolm 架構介紹中,我們已經知道 Malcolm 是一套整合多種開源工具的網路流量分析平台,可以接收 PCAP 封包檔案、Zeek 日誌及 Suricata 警示,再將資料整理成方便查詢與分析的形式。
不過,資料被產生出來之後,還有一個問題:這些日誌是如何進入 Malcolm 的分析管線?
這次從官方 GitHub 原始碼的 filebeat 目錄開始,觀察 Malcolm 如何處理不同來源的日誌。
官方原始碼:cisagov/Malcolm/filebeat
Filebeat 是 Elastic 生態系中的輕量級日誌收集與傳送程式,主要負責讀取檔案或接收指定來源的資料,進行必要的欄位處理,再將資料送往下游元件。
在 Malcolm 中,Filebeat 的任務包括:
這裡需要先區分幾個元件。
| 元件 | 主要職責 | 白話理解 |
|---|---|---|
| Zeek | 分析網路通訊並產生日誌 | 記錄網路上發生了什麼事 |
| Suricata | 偵測符合規則的網路威脅並產生事件 | 找出可能符合攻擊特徵的流量 |
| Filebeat | 收集與傳送日誌 | 負責把資料送進處理管線 |
| Logstash | 解析、轉換、正規化及路由資料 | 整理不同來源的資料,讓後續系統容易處理 |
| Valkey | 提供 Redis 相容的資料結構與佇列功能 | 暫存待處理的通知或工作 |
| OpenSearch | 儲存及索引資料,提供搜尋能力 | 讓分析人員查詢及分析事件 |
以上是各元件的主要分工,實際處理程序仍須依照個別資料管線判斷。
如果只從使用者介面觀察 Malcolm,看到的會是搜尋結果、儀表板與網路連線紀錄。但從 filebeat 目錄往下看,就能理解資料在進入主要分析系統之前,如何被讀取、分類及傳送。
這也是研究 Malcolm 原始碼很重要的一個方向:不只知道平台有哪些元件,更要知道它們如何互相配合。
打開官方的 filebeat 目錄,可以看到數個 YAML 設定檔、supervisord.conf、requirements.txt,以及用來處理上傳檔案和其他工作流程的腳本。
這些檔案並不是重複的設定,而是對應不同的資料來源與處理需求。
| 設定檔 | 主要用途 | 資料來源或處理方式 |
|---|---|---|
filebeat-logs.yml |
收集 Malcolm 的主要分析日誌 | Zeek、Suricata、檔案掃描日誌、網路介面統計等 |
filebeat-zeek-files-logs.yml |
專門處理 Zeek 的檔案紀錄 | 讀取 json_streaming_files 類型日誌,整理檔案相關通知 |
filebeat-nginx.yml |
收集 Web 服務日誌 | NGINX access log 與 error log |
filebeat-tcp.yml |
提供一般 TCP 日誌輸入 | 接收自訂 TCP 訊息,可依設定解析 JSON |
filebeat-syslog-tcp.yml |
接收 TCP Syslog | 解析 Syslog 格式的訊息 |
filebeat-syslog-udp.yml |
接收 UDP Syslog | 解析 Syslog 格式的訊息 |
supervisord.conf |
管理多個工作程序 | 決定各個 Filebeat 程序與相關背景工作的啟動方式 |
原始碼參考:
這是這個目錄值得注意的設計。
Malcolm 的 docker-compose.yml 定義了 Filebeat 服務,而 supervisord.conf 則在容器內管理多個程序。除了主要日誌收集程序以外,還可以看到 NGINX、一般 TCP、TCP Syslog、UDP Syslog,以及 Zeek 檔案日誌等不同程序。
Supervisor 是一種程序管理工具,可以在同一個容器內啟動及管理多個程式。
每個 Filebeat 程序可以使用自己的設定檔、資料目錄與啟用條件。因此,不能因為 Docker 中只有一個名為 filebeat 的服務,就認為所有資料都是由同一份 Filebeat 設定處理。
這種拆分方式有幾個優點:
這裡的 registry 是 Filebeat 用來記錄檔案讀取狀態的機制,協助它在重新啟動後延續先前的讀取進度。
不過,這種拆分不代表每一類資料都具有完全獨立的故障處理能力;下游 Logstash、OpenSearch 或共用的檔案儲存出現問題時,仍可能影響多個資料管線。
理解設定檔的分工後,下一步是觀察各個輸入設定如何讀取資料。
在 Malcolm 裡,Filebeat 不只讀取單一種類的日誌,而是同時處理網路分析工具輸出、平台自身日誌,以及外部系統傳入的訊息。
在 filebeat-logs.yml 中,可以看到兩組重要的 Zeek 輸入設定。
一組讀取上傳或整理後的日誌,例如 /zeek/current/*.log;另一組則讀取即時產生的日誌,例如 /zeek/live/spool/logger-*/*.log。
兩者的目的不同:
current:提供已整理到指定目錄、等待收集的日誌。live:提供即時運作期間持續產生的日誌。Filebeat 透過 filestream input 監控這些檔案。filestream 是 Filebeat 用來讀取檔案內容並追蹤讀取狀態的輸入類型。
設定中還可以看到掃描週期、檔案讀取狀態、符號連結,以及忽略特定日誌內容的規則。例如,部分 Zeek 日誌以 # 開頭的內容是標頭或欄位說明,不是一般事件紀錄,因此可以透過 exclude_lines 排除。
這表示 Filebeat 不只是把整個檔案原封不動送出去,也會根據資料來源的格式決定如何讀取。
Suricata 的輸出則透過 EVE JSON 日誌進入 Filebeat。
在 filebeat-logs.yml 裡,可以看到兩組不同的輸入:
eve-upload:讀取上傳封包經過 Suricata 處理後產生的 EVE JSON。eve-live:讀取即時分析所產生的 EVE JSON。EVE 是 Suricata 的事件輸出格式,JSON 則是一種結構化資料格式。相較於只有一整段文字的日誌,JSON 可以將來源 IP、目的 IP、事件類型及其他資訊放在各自的欄位中,方便後續處理。
值得注意的是,設定中對這兩類輸入使用了 filestream,並且將 on_eof 設為 false。
EOF 是 End of File,也就是目前讀取位置已經到達檔案結尾。設為 false 代表不能只因為讀到當下的檔案結尾,就認定後續不會再有資料。
對於仍可能繼續寫入的日誌,這樣的設定可以避免過早把檔案視為已完成。
除了 Zeek 與 Suricata,Malcolm 也提供其他日誌輸入方式。
| 資料來源 | 設定方式 | 適合的用途 |
|---|---|---|
| NGINX | filebeat-nginx.yml |
觀察 Web 存取及錯誤情況 |
| TCP Syslog | filebeat-syslog-tcp.yml |
接收經由 TCP 傳送的 Syslog |
| UDP Syslog | filebeat-syslog-udp.yml |
接收經由 UDP 傳送的 Syslog |
| 一般 TCP | filebeat-tcp.yml |
接收符合設定格式的自訂日誌 |
| 網路介面統計 | filebeat-logs.yml |
收集網路介面相關的統計資料 |
Syslog 是許多網路設備、伺服器與應用程式使用的日誌傳輸格式或機制。提供 TCP 與 UDP 兩種輸入,代表 Malcolm 可以依設備支援的傳輸方式接收資料。
一般 TCP 輸入則更有彈性,可以透過環境變數設定訊息格式。從設定檔可以看到,若指定資料為 JSON,Filebeat 就會執行相應的 JSON 欄位解析處理。
但要注意:設定檔支援某個輸入方式,不代表安裝完成後就能直接從外部設備連線。 是否啟用該程序、Docker 是否發布對應連接埠,以及主機防火牆和網路路由,都是實際部署時必須確認的事項。