Grafana 發送異常通知(監控 WAF 異常流量)
前言
在前幾篇文章中,我記錄了 如何安裝 Grafana 以及 將事件器的 Log 整合至 Grafana 進行集中管理,當然除了日誌,如果希望監控其它指標,比如伺服器效能,也都可以統一傳送至 Grafana 方便進行管理,但這些我就不再一一介紹了。
另外當系統出現異常時,提供即時通知是非常重要的功能,本文將分享如何在 Grafana 中設定異常通知功能,Grafana 支援多種異常通知方式,包括 LINE、郵件、API、Teams 等,這裡會分享我自己使用的兩種方式:【LINE 通知】和【呼叫外部 API】。
接下來,我將詳細說明這兩種通知方式的設定步驟。
設定通知渠道 Alerting → Contact points
- 設定 LINE 通知。
- Name:輸入通知類型的識別名稱。
- Integration:選擇 LINE。
- Token:要通知的 LINE 群組 Token,請先到 LINE Notify 取得。
- Optional LINE Settings (非必要)
- Title:要在 LINE 通知顯示的標題(可使用樣板)。
- Description:要在 LINE 通知顯示的內容(可使用樣板)。
- Notification settings
- Disable resolved message:這個項目關閉。
- 設定 API 通知。
- Name:輸入通知類型的識別名稱。
- Integration:選擇 Webhook。
- URL:發生事件要呼叫的 API 網址。
- Optional Webhook Settings (非必要)
- Http Method:選擇 POST 或 PUT。
- Authorization Header - Scheme:你的授權(自定義)。
- 若指定使用 API ,當觸發異常通知事件時,收到的請求格式如下參考。
{ "receiver": "API", "status": "firing", "alerts": [ { "status": "firing", "labels": { "LINEGroup": "Standard", "LINEGroup2": "Standard", "alertname": "DatasourceError", "datasource_uid": "b5219f7d-83bc-4971-90cb-768998609e3b", "grafana_folder": "Alert-WAF", "ref_id": "A", "rulename": "每 10 鐘超過 50 次攻擊" }, "annotations": { "description": "測試站台違反 WAF 規則超過指定上限,請協助確認", "summary": "==== 詳細違反規則說明如下 ====\n WAF : [no value]\n 次數 : [no value]" }, "startsAt": "2023-12-12T17:30:10+08:00", "endsAt": "0001-01-01T00:00:00Z", "generatorURL": "http://pex-test.primeeagle.net:3333/alerting/grafana/e6e62239-f924-4ccf-bc6a-be9b14622ae8/view?orgId=1", "fingerprint": "2aa447ec40d366b6", "silenceURL": "http://pex-test.primeeagle.net:3333/alerting/silence/new?alertmanager=grafana\u0026matcher=LINEGroup2%3DStandard\u0026matcher=LINEGroup%3DStandard\u0026matcher=alertname%3DDatasourceError\u0026matcher=datasource_uid%3Db5219f7d-83bc-4971-90cb-768998609e3b\u0026matcher=grafana_folder%3DAlert-WAF\u0026matcher=ref_id%3DA\u0026matcher=rulename%3D%E6%AF%8F+10+%E9%90%98%E8%B6%85%E9%81%8E+50+%E6%AC%A1%E6%94%BB%E6%93%8A\u0026orgId=1", "dashboardURL": "", "panelURL": "", "values": null, "valueString": "" } ], "groupLabels": { "alertname": "DatasourceError", "grafana_folder": "Alert-WAF" }, "commonLabels": { "LINEGroup": "Standard", "LINEGroup2": "Standard", "alertname": "DatasourceError", "datasource_uid": "b5219f7d-83bc-4971-90cb-768998609e3b", "grafana_folder": "Alert-WAF", "ref_id": "A", "rulename": "每 10 鐘超過 50 次攻擊" }, "commonAnnotations": { "description": "測試站台違反 WAF 規則超過指定上限,請協助確認", "summary": "==== 詳細違反規則說明如下 ====\n WAF : [no value]\n 次數 : [no value]" }, "externalURL": "http://pex-test.primeeagle.net:3333/", "version": "1", "groupKey": "{}/{LINEGroup=\"Standard\"}:{alertname=\"DatasourceError\", grafana_folder=\"Alert-WAF\"}", "truncatedAlerts": 0, "orgId": 1, "title": "[FIRING:1] DatasourceError Alert-WAF (Standard Standard b5219f7d-83bc-4971-90cb-768998609e3b A 每 10 鐘超過 50 次攻擊)", "state": "alerting", "message": "**Firing**\n\nValue: [no value]\nLabels:\n - alertname = DatasourceError\n - LINEGroup = Standard\n - LINEGroup2 = Standard\n - datasource_uid = b5219f7d-83bc-4971-90cb-768998609e3b\n - grafana_folder = Alert-WAF\n - ref_id = A\n - rulename = 每 10 鐘超過 50 次攻擊\nAnnotations:\n - description = 測試站台違反 WAF 規則超過指定上限,請協助確認\n - summary = ==== 詳細違反規則說明如下 ====\n WAF : [no value]\n 次數 : [no value]\nSource: http://pex-test.primeeagle.net:3333/alerting/grafana/e6e62239-f924-4ccf-bc6a-be9b14622ae8/view?orgId=1\nSilence: http://pex-test.primeeagle.net:3333/alerting/silence/new?alertmanager=grafana\u0026matcher=LINEGroup2%3DStandard\u0026matcher=LINEGroup%3DStandard\u0026matcher=alertname%3DDatasourceError\u0026matcher=datasource_uid%3Db5219f7d-83bc-4971-90cb-768998609e3b\u0026matcher=grafana_folder%3DAlert-WAF\u0026matcher=ref_id%3DA\u0026matcher=rulename%3D%E6%AF%8F+10+%E9%90%98%E8%B6%85%E9%81%8E+50+%E6%AC%A1%E6%94%BB%E6%93%8A\u0026orgId=1\n" }
- 本文使用 NetCore 來接收 Webhook 的請求,參考範例程式如下。
[ApiController] [Route("api/[controller]")] public class TestController : ControllerBase { // 使用 HttpPost 取得 FormBody Model [HttpPost] public IActionResult Post([FromBody] System.Text.Json.JsonElement model) { var json = model.ToString(); // 按照日期 yyyyMMddHHmmss 將檔案存到本機 Log 資料夾,若資料夾不存在請先建立 var fileName = DateTime.Now.ToString("yyyyMMddHHmmss"); if (Directory.Exists("Log") == false) Directory.CreateDirectory("Log"); System.IO.File.WriteAllText($"Log/{fileName}.json", json); return Ok(json); } }
通知樣板 Alerting → Contact points
非必要,若有需要自定義通知格式,包含標題、內容等等,皆可在 Alerting → Contact points → Notification templates 定義樣板內容,底下是本文設定的範例,我有使用到【AlertName】、【Description】、【Summary】,顯示的區域可以在本文末的參考畫面查看。
{{ define "WAFStandardTemplate" }}{{range .Alerts}}通知類型 : {{.Labels.alertname}}
{{.Annotations.description}}
{{if gt (len .Annotations.summary) 0}}{{.Annotations.summary}}{{end}}
{{end}}
{{end}}
通知規則 Alerting -> Alert rules
- 輸入要通知的規則名稱 (Enter alert rule name),請注意這邊只是設定收集規則,並不會真的發送通知,若要發送通知請完成此處設定後,繼續往下進行通知政策的設定。
- 定義查詢和警報條件 (Define query and alert condition),共分成 A、B、C 三個區域,各區域說明如下。
- A:找出通知資料的條件,例如收集近 10 分鐘,攻擊數量的加總。
- 設定收集資料區間,我選的是最近十分鐘。
- 設定查詢數量,根據實際要篩選的條件進行設定。
- 數量彙總,目的是為了將篩選出來的資料列轉換成下一步要通知的格式。
- B:通知條件前處理,主要的目的與步驟 C 比較的資料前處理,以下圖為例,會將條件 A 查詢結果的數量進行加總,若查詢結果包含非數值的資料列,會將該筆設定為 0。
- C:閾值,要通知的條件值,例如,超過 10 次就通知,另外請注意,這裡是通知條件,所以設定完成後記得點選右上角的設定。
- 都完成上述的設定,可以使用底下的 preview 功能確認是否有滿足通知條件。
- 設定評估行為 (Set evaluation behavior)。
- Folder:通知規則的資料夾,這邊依照自己的需求分類即可,ex. Alert Evaluation。
- Evaluation group:同一個評估群組多久收集一次資料,當滿足這個時間條件時,僅會將狀態改成 padding,並不會真的發送 (仍需考量 Padding 和通知政策內的設定) ,但我個人是在這邊設定真正要發送的時間。
- Pending period:這裡指的當符合收集條件後,必須持續維持多久的時間才會滿足發送條件,也就是 firing。
- Alert state if no data or all values are null:若沒有定期通知的需求,沒資料請將此處設定改成 OK,否則會按照通知政策設定的時間間隔,定期的發送通知(包含正常狀態)。
- 新增註釋 (Add annotations):非必要,發送通知需要附加的訊息,依實際需求設定即可。
- 通知配置(Configure notifications):當滿足條件時會夾帶的標籤設定,可透過此處與通知政策結合,達到指定發送群組的需求,完成設定後可點選 Preview routing 來確認是否有匹配到通知群組。
通知政策 Alerting -> Notification policies
請注意這邊非常重要,不注意設定你會查問題查很久,預警規則 (Alert rules) 的設定只是收集資料而已,實際發送是還是會跟這邊的設定值有關係,並且此處的設定會牽扯到是否間隔多久才會通知,但預設值其實蠻久的,若不調整預設值,會造成你的發送區間若還在預設值內,則不會重新發送,各欄位設定如下說明。
- Matching labels:搭配 Alert rules 內的設定,便可以達到指定通知群組的效果。
- Contact point:要通知的渠道,這邊可選擇一開始的設定。
- Continue matching subsequent sibling nodes:若同一個警告有符合多個通知 Label,則必須開啟此欄位,否則通知完第一個政策後就會停止了。
- Override general timings
- Group wait:為傳入警報建立的新群組發送初始通知之前的等待時間。如果為空,將從父策略繼承。
- Group interval:發送第一個通知後,為該群組發送一批新警報的等待時間。如果為空,將從父策略繼承,多個通知會套用此設定。
- Repeat interval:成功發送警報後重新發送警報的等待時間,建議與 Alert rules 內的 Evaluation group 時間設定一樣或者多一分鐘(避免重複發送), 這個最重要了,有點雷,預設是 4 個小時,卡在這邊超久,而且搭配警告設定那邊,若不把無資料的設定關閉,會每隔四個小時自動發出一個沒有數值的通知。
留言
張貼留言
您好,我是 Lawrence,這裡是我的開發筆記的網誌,如果你對我的文章有任何疑問或者有錯誤的話,歡迎留言讓我知道。