跳到主要內容
節省工具箱Jason Tools
專案分享

jt-glogarch:替 Graylog Open 補上記錄歸檔與還原

Jason Cheng 發布 瀏覽 1 次
jt-glogarch:替 Graylog Open 補上記錄歸檔與還原
本文目錄
  1. Graylog Open 的記錄保留難題
  2. 架構
  3. 兩種匯出模式
  4. 兩種匯入(還原)模式
  5. 歸檔管理
  6. 記錄搜尋
  7. 排程與作業歷程
  8. 行為稽核
  9. 通知
  10. 統計報表(Beta)
  11. 告警管理
  12. 穩定性與安全設計
  13. 使用情境
  14. 系統需求與安裝
  15. 部署注意事項
  16. 結論
  17. 參考資料

用 Graylog Open 的客戶,幾乎都會問到同一個問題:記錄要保留多久? 資安規範常要求保留一年以上,但 OpenSearch 的熱資料很貴,Graylog 的 index 保留期通常只設 30 到 90 天,超過就輪替刪掉。

Graylog Enterprise 有 Archive 功能可以把舊記錄歸檔、需要時再還原,但 Open 版沒有。以前遇到這種需求,只能自己寫腳本定期匯出、或是乾脆把 OpenSearch 的快照搬到別的地方,要還原時又是另一番折騰。

所以我做了 jt-glogarch,把 Graylog Open 缺的歸檔與還原補上:定期把記錄匯出成壓縮檔、附上完整性驗證,要調查時再匯回任何一套 Graylog。後來又陸續加上獨立的行為稽核、不必還原就能直接搜尋歸檔、PDF 報表與告警管理。目前版本 v1.17.2,以 AGPL-3.0 授權開源,支援 Graylog Open 6.x 與 7.x。

Graylog Open 的記錄保留難題

沒有歸檔工具時

  • 保留期與成本互相拉扯
    要保留一年,OpenSearch 的磁碟就要準備一年份;縮短保留期,又不符合法規
  • 舊記錄刪了就沒了
    半年前的資安事件要調查,記錄早已隨 index 輪替刪除
  • 稽核記錄自己管自己
    Graylog 內建的 audit log 由 Graylog 本身保存,有 admin 權限的人就能刪改
  • 搬遷、異地備份不方便
    要換新叢集、或把記錄備份到異地,沒有現成的工具

加上 jt-glogarch 之後

  • 熱資料只留近期
    舊記錄壓縮歸檔到便宜的儲存(約 10 倍壓縮),OpenSearch 只負責近期搜尋
  • 隨時還原
    歸檔可以匯回原本或另一套 Graylog,時間、來源、所有欄位原樣保留
  • 完整性可驗證
    每份歸檔都有 SHA256,可選用帶秘鑰的 HMAC 偵測蓄意竄改
  • 獨立的操作軌跡
    透過 nginx 旁路側錄所有 Graylog 操作,存在 Graylog 管理者碰不到的資料庫

架構

jt-glogarch 是一台獨立的服務,從正式環境的 Graylog 匯出記錄、壓縮存檔,需要時再匯入到查詢或災難復原用的 Graylog:

+-----------------+     +------------------+     +-----------------+
|  Graylog Open   |     |   jt-glogarch    |     |  Graylog Open   |
|  (Production)   |     |                  |     |  (Query / DR)   |
|                 |     |  +------------+  |     |                 |
|  Logs --------->|---->|  | .json.gz   |  |---->|  Restored Logs  |
|                 | API |  | Archives   |  | GELF|                 |
|  OpenSearch     | or  |  | + SHA256   |  |  or |  Searchable in  |
|  Indices        | OS  |  +------------+  | Bulk|  Graylog UI     |
+-----------------+     +------------------+     +-----------------+

內部以 Python(FastAPI)撰寫,Web 介面、REST API、排程器與 CLI 共用同一個 SQLite 資料庫,登入直接用 Graylog 的帳號密碼,不另外建使用者資料庫。

儀表板:歸檔總數、記錄總數、壓縮前後大小、可用空間,以及伺服器與最近工作的狀態
儀表板:歸檔總數、記錄總數、壓縮前後大小、可用空間,以及伺服器與最近工作的狀態

兩種匯出模式

項目Graylog APIOpenSearch Direct
速度約 730 筆/秒約 3,300 筆/秒(約 5 倍)
分頁方式時間視窗,避開 10,000 筆的位移上限search_after,沒有上限
依串流篩選可以不行,依 index 匯出
需要Graylog API TokenOpenSearch 帳密
適合只匯出特定串流、OpenSearch 不對外開放的環境大量歷史資料、要求速度的情境

Graylog API 模式

把時間範圍切成每小時一段,逐段透過 Graylog 的搜尋 API 取出記錄,邊讀邊寫入 gzip 檔,不會整批載入記憶體。可以只匯出某個串流,例如只歸檔認證相關的記錄。

為了不拖垮正式環境,匯出期間大約每 15 秒會檢查一次 Graylog 的狀態:GC 後的 heap 超過 70% 就逐頁放慢,發生 Full GC 或達到 90% 才暫停,壓力解除後自動繼續。

OpenSearch Direct 模式

繞過 Graylog 直接讀 OpenSearch,逐個 index 單次掃描並依時間排序,再依小時切成歸檔檔案。正在寫入的 index 會自動略過,可以設定「保留最近 N 份 index」,只歸檔已經輪替出來的。

注意:Graylog 7 的 Data Node 環境,OpenSearch 是由 Graylog 自動管理憑證、不對外提供帳密,外部工具無法直接存取,所以 OpenSearch Direct 匯出與 Bulk 匯入都不能用,只能走 Graylog API 與 GELF。如果還沒安裝,我建議 Graylog 直接接獨立部署的 OpenSearch,不要用 Data Node。

重複資料與斷點續傳

  • 同模式:精確比對時間範圍,不會重複匯出
  • 跨模式:API 和 OpenSearch 模式切換時,已被另一種模式涵蓋的區段會略過
  • 斷點續傳:服務在匯出途中中斷,重新啟動後從上次完成的區段繼續,不漏也不重複

兩種匯入(還原)模式

項目GELFOpenSearch Bulk
路徑經過 Graylog input → 處理 → indexer直接寫入 OpenSearch
速度一般約 5~10 倍
Pipeline、Extractor、串流分流、告警全部沿用完全略過
適合要讓記錄重新經過處理規則原樣還原:災難復原、搬遷、事件調查

兩種模式都會保留原始的 timestamp、source、level 與所有自訂欄位,送出前先跑一輪檢查(目標容量、欄位對應衝突),送完再核對 indexer 有沒有失敗。GELF 模式還可以暫停、繼續、即時調整速率,並依目標 Graylog 的 journal 狀態自動限速。

歸檔管理

歸檔清單上方有一條歸檔時間軸,每天一根長條,高度是當天的記錄數,沒有歸檔的日子會標紅,資料缺口一眼就看得出來。直接在時間軸上拖曳就能選取時間範圍,篩選條件會自動帶入。

歸檔清單:時間軸拖曳選取範圍,可單筆或批次匯入、刪除
歸檔清單:時間軸拖曳選取範圍,可單筆或批次匯入、刪除
  • 自動分檔:預設每 50 MB 一個檔案
  • SHA256 驗證:每份歸檔附 .sha256 檔,可排程定期重新驗證,損毀的會在清單上標示
  • 保留期清理:自動刪除超過保留天數的歸檔,寫入中的檔案不會被誤刪
  • 重新掃描:從磁碟重新同步,找出殘留或遺失的檔案
  • 資料庫備份與重建:glogarch db-backup 線上快照;資料庫壞了也能用 glogarch db-rebuild 從歸檔檔案重建

防竄改(選用)

SHA256 只能偵測「損毀」:如果有人同時改了歸檔檔案和資料庫裡記錄的雜湊值,SHA256 就擋不住。v1.12.0 起可以另外啟用帶秘鑰的 HMAC-SHA256,並把雜湊清單匯出存到主機以外:

sudo -u jt-glogarch glogarch integrity-init       # 產生秘鑰,請備份到主機以外
sudo -u jt-glogarch glogarch integrity-seal       # 封存既有歸檔
sudo -u jt-glogarch glogarch verify               # 區分 TAMPERED(HMAC 不符)與 CORRUPTED(SHA256 不符)
sudo -u jt-glogarch glogarch integrity-manifest -o /mnt/offsite/manifest.json

這個功能預設關閉,有稽核需求的環境再開。要防到 root 層級,秘鑰就不要留在主機上,只在封存、驗證時用環境變數提供。

注意:對已經被竄改的舊歸檔補做封存,只能證明「從現在起」沒有被動過,無法回頭證明過去;秘鑰遺失則退回只有 SHA256 的保護。這是設計上的誠實界線。

記錄搜尋

這是我自己很常用的功能:不必把歸檔匯回 Graylog,直接在歸檔檔案裡找記錄。像「半年前那台主機到底發生什麼事」這種一次性的查證,整段匯回去要好幾十分鐘,這裡幾秒到幾分鐘就有答案。

記錄搜尋:指定時間範圍、關鍵字與欄位條件,搜尋前先預估涵蓋的筆數與時間
記錄搜尋:指定時間範圍、關鍵字與欄位條件,搜尋前先預估涵蓋的筆數與時間
  • 時間範圍必填:歸檔沒有索引,時間範圍是唯一能先排除大部分檔案的依據
  • 關鍵字:比對整筆記錄任何位置,不分大小寫,片語用雙引號
  • 欄位條件:例如 source=fw01 level=4,值必須完全相符
  • 醒目提示:命中的關鍵字與欄位值會標出來
  • 下載結果:CSV 或 JSON Lines,下載的是全部符合的結果,不是只有畫面上那一頁
展開單筆記錄,顯示完整欄位內容
展開單筆記錄,顯示完整欄位內容

它不是查詢引擎:沒有圖表、統計、查詢語言,不支援萬用字元與 OR/NOT。需要完整分析時,還是把那段時間的歸檔匯回 Graylog。另外搜尋會讓路給歸檔,偵測到匯出或匯入正在執行時會自動放慢。

排程與作業歷程

匯出、清理、驗證都可以排程,cron 格式,在網頁上編輯後立即生效,不用重新啟動服務,也都支援「立即執行」。

排程作業:每日匯出、每月清理與驗證
排程作業:每日匯出、每月清理與驗證

我自己的設定大致是:每天凌晨匯出、每月清理超過保留期的歸檔、每月第一個週六重新驗證一次 SHA256。

所有作業都會出現在作業歷程,執行中的會即時顯示進度、目前處理到哪個區段或 index,也可以取消。排程匯出在沒有新資料時,記錄數為 0 是正常的,會以淡色顯示。

作業歷程:執行中的匯出顯示即時進度
作業歷程:執行中的匯出顯示即時進度

行為稽核

法規(ISO 27001、PCI-DSS、個資法等)都要求保留管理者的操作軌跡。但 Graylog 內建的 audit log 是 Graylog 自己保存的,有 admin 權限的人就能刪除或竄改,從稽核的角度並不可信。

jt-glogarch 的做法是讓 nginx 擋在 Graylog 前面,把每一筆 API 呼叫透過 syslog 旁路送給 jt-glogarch,存在 Graylog 管理者沒有權限的資料庫裡:

  • 60 種以上操作分類:串流、pipeline、使用者、搜尋、看板、content pack、lookup table……的建立、修改、刪除
  • 完整的請求內容:看得到改了什麼設定、搜尋了什麼條件
  • 使用者名稱解析:Basic Auth、API Token、瀏覽器工作階段都會對應回實際的 Graylog 使用者,多位管理者共用同一個 IP 也分得出來
  • 敏感行為即時通知:刪除使用者、授予 admin、安裝 content pack 等,立即推播
  • 斷線偵測:每 5 分鐘透過 nginx 主動送一筆測試,沒收到就告警,避免有人悄悄關掉轉送
  • 獨立保留期:預設 180 天,和歸檔的保留期分開設定
行為稽核:記錄誰在什麼時候、從哪裡、對 Graylog 做了什麼
行為稽核:記錄誰在什麼時候、從哪裡、對 Graylog 做了什麼
點選任一筆可看完整的操作明細
點選任一筆可看完整的操作明細

注意:要讓稽核完整,務必封鎖外部直接連 Graylog 的 9000 通訊埠,只允許本機的 nginx 與叢集內的其他 Graylog 節點,否則使用者繞過 nginx 直接連 Graylog,就不會留下記錄。nginx 的設定範本在行為稽核頁面與 README 都有。

通知

支援 Telegram、Discord、Slack、Microsoft Teams、Nextcloud Talk、Zulip、Email 七種管道,可以分別勾選要通知的事件:匯出、匯入、清理完成、錯誤、驗證失敗、敏感操作、稽核管道異常。通知內容可選英文、繁體中文或日文。

通知設定:勾選觸發事件,各管道的 Token、Webhook 預設以遮罩顯示
通知設定:勾選觸發事件,各管道的 Token、Webhook 預設以遮罩顯示

統計報表(Beta)

可以直接從 Graylog 的看板與歸檔統計產生 PDF 報表,有封面、目錄、KPI 摘要、頁首頁尾與頁碼,支援排程產製與 Email 寄送,並附 SHA-256 指紋證明檔案未被修改。

報表有兩種做法:把看板的小工具重建成原生圖表,或直接截圖實際的看板(每個頁籤都會擷取)。

以 Wazuh 看板產生的每日報表
以 Wazuh 看板產生的每日報表

報表需要無頭 Chromium 當渲染引擎,要用時執行 sudo bash scripts/install-report-engine.sh 安裝。

告警管理

v1.17.0 新增的功能,用來批次管理 Graylog 的事件定義與通知方式。事件定義一多,要幫幾百條規則換通知方式,在 Graylog 介面上一條一條改非常痛苦。

  • 依標題標籤快速篩選、多關鍵字搜尋,Shift 點選範圍或全選符合的結果
  • 一次對大量定義加入、移除、替換通知方式,每次變更都先預覽
  • 以作業方式執行並留下記錄,可以在變更紀錄裡復原
  • 健檢:列出啟用中卻沒有人會收到通知的定義、已經沒人用的通知方式、從未或很久沒觸發的定義

所有變更都以登入者自己的 Graylog 帳號執行,套用該帳號原本的權限。

穩定性與安全設計

這套工具的目標是在繁忙的 Graylog 旁邊安靜地跑好幾年,所以花了不少功夫在這些地方:

  • 串流寫入:不會把訊息全部載入記憶體,GB 級的 index 也不會記憶體不足,本身穩定約佔 200 MB
  • OpenSearch 暫時性錯誤自動重試:500、502、503、429 自動退避重試,可設定多台主機容錯
  • 同伺服器並行匯出鎖定、同歸檔並行匯入鎖定
  • 錯誤訊息自動遮蔽密碼與 Token
  • 緊急本機登入:Graylog 離線時,可以用預先設定的 localadmin 帳號登入
  • 健康檢查端點:GET /api/health 免認證,回傳資料庫、磁碟、排程器狀態,可以接 Uptime Kuma 或 Prometheus 監控
  • 硬體規格建議:儀表板會讀取主機的記憶體、CPU 與 Graylog/OpenSearch 的 heap 設定,直接算出這台主機的建議規格

使用情境

情境做法
法規要求保留一年每日排程以 API 模式匯出認證相關的串流,OpenSearch 維持 90 天
半年前的資安事件調查先用記錄搜尋確認範圍,再把那段時間的歸檔以 GELF 匯回 Graylog
舊叢集搬到新叢集OpenSearch Direct 從舊叢集大量匯出,再用 GELF 或 Bulk 匯入新叢集
異地備份歸檔路徑掛載到遠端的 NFS 或其他儲存,每日排程匯出
降低儲存成本OpenSearch 模式只保留最近 N 份 index,舊的歸檔壓縮存放
獨立的操作稽核啟用行為稽核,nginx 旁路側錄所有 Graylog 操作

系統需求與安裝

系統需求

  • Linux(已測試 Ubuntu 22.04、Debian 12、RHEL 9)
  • Python 3.10 以上、pip、git
  • Graylog Open 6.x 或 7.x
  • OpenSearch 2.x(選用,Direct 模式才需要)

規格方面,jt-glogarch 單獨放一台的話 4 GB 記憶體、4 核心就夠;如果和 Graylog、OpenSearch 放在同一台,記憶體才是關鍵,兩個 JVM 的 heap 合計不要超過記憶體的一半,絕對不要讓主機用到 swap。

安裝

安裝腳本會建立系統使用者、目錄、自簽 SSL 憑證與 systemd 服務:

sudo git clone https://github.com/jasoncheng7115/jt-glogarch.git /opt/jt-glogarch
cd /opt/jt-glogarch
sudo bash deploy/install.sh

# 填入 Graylog API 網址與 Token
sudo vi /opt/jt-glogarch/config.yaml

sudo systemctl enable --now jt-glogarch

完成後開啟 https://<伺服器 IP>:8990,用 Graylog 的帳號密碼登入。Graylog 的 API Token 在「System → Users → Edit tokens」產生;要用 Direct 模式,再加上 OpenSearch 的連線資訊。

升級

sudo bash /opt/jt-glogarch/deploy/upgrade.sh

升級前會先把資料庫線上備份到 /var/backups/jt-glogarch/,補上新版本的預設設定值,過程中沒有刪除資料的步驟,可以在服務執行中進行。

離線環境

主機不能連外網的話,可以在另一台能上網、Python 版本與 CPU 架構相同的 Linux 上打包離線安裝包,用 USB 或 scp 帶進去:

# 在可以上網的主機
curl -L -o src.tar.gz https://github.com/jasoncheng7115/jt-glogarch/archive/refs/heads/main.tar.gz
tar xzf src.tar.gz && cd jt-glogarch-main
bash scripts/build-offline-bundle.sh
sha256sum dist/jt-glogarch-*-offline.tar.gz

# 帶到目標主機,核對 sha256 後
tar xzf jt-glogarch-*-offline.tar.gz && cd jt-glogarch-*-offline
sudo bash upgrade-offline.sh

離線包約 370 MB,大部分是報表用的 Chromium。

移除

sudo bash /opt/jt-glogarch/deploy/uninstall.sh

每個刪除動作(歸檔檔案、設定、資料庫、系統使用者)都會逐一詢問,預設都是不刪。

部署注意事項

歸檔路徑與權限

預設存放在 /data/graylog-archives,要放到 NFS 或其他儲存就把它掛載到這個路徑。目錄要讓 jt-glogarch 使用者可以寫入,用 root 建立的目錄 jt-glogarch 會自動修正擁有者。

max_result_window

Graylog API 模式受 OpenSearch 的 index.max_result_window(預設 10000)限制,jt-glogarch 會自動把每次請求控制在上限內,預設的叢集不需要調整。但如果你曾經把它調低,API 匯出可能會出現 Result window is too large,請改回至少 10000。

單一毫秒內超過 10,000 筆的極端突發,API 模式無法切分,通知裡會寫出有多少筆沒讀到,這種情況請改用 OpenSearch Direct 模式。

歸檔多套 Graylog

同一台 jt-glogarch 可以在設定檔裡加入多個 Graylog 來源,各自的 OpenSearch 連線也可以分開設定。如果真的要對同一套 Graylog 跑兩個 jt-glogarch,務必使用不同的歸檔路徑,兩邊的資料庫是各自獨立的。

結論

jt-glogarch 一開始只是想補上 Graylog Open 缺的歸檔功能,做著做著,把我在客戶端實際遇到的需求一個一個加進去:法規要求的保留期、無法被刪改的操作軌跡、不用還原就能查的歸檔、幾百條告警規則的批次管理。

如果你也在用 Graylog Open,又被「記錄要保留多久」困擾,歡迎試用,有問題或建議可以到 GitHub 開 issue。

參考資料

Jason Cheng

Jason Cheng

企業開源技術顧問,專注架構規劃與實務導入

關於作者 →

延伸閱讀