跳到主要內容
節省工具箱Jason Tools
經驗分享

LibreNMS 接收 SNMP Trap 與告警設定

Jason Cheng 發布
LibreNMS 接收 SNMP Trap 與告警設定
本文目錄
  1. 運作流程
  2. 安裝與設定 snmptrapd
  3. 設備端設定
  4. 測試
  5. Trap 寫進 Eventlog 的內容
  6. 把 Trap 變成告警
  7. 常見問題
  8. 結論
  9. 參考資料

LibreNMS 平常是用輪詢(polling)每 5 分鐘去問設備一次狀態,但有些事情等不了 5 分鐘:設備重新開機、介面斷線、UPS 轉電池。這類事件,設備可以主動送 SNMP Trap 通知監控系統。

LibreNMS 本身就能處理 SNMP Trap,但需要另外設定 snmptrapd,收進來之後也不會自動變成告警。這篇依官方文件整理從接收、解析到設定告警規則的完整流程,也修正了一些網路上常見、但其實不正確的寫法。

運作流程

設備 ──SNMP Trap (UDP 162)──> snmptrapd ──> /opt/librenms/snmptrap.php ──> Eventlog ──(告警規則)──> Alert
角色說明
snmptrapdNet-SNMP 的 Trap 接收程式,監聽 UDP 162
snmptrap.phpLibreNMS 的 Trap 處理入口,依 Trap 的 OID 交給對應的處理程式(handler)
EventlogTrap 處理的結果寫進裝置的事件記錄
告警規則Eventlog 不會自動告警,要自己寫規則

LibreNMS 內建了上百個 Trap 處理程式(GitHub 上 LibreNMS/Snmptrap/Handlers 目錄),常見的開機、介面上下線、各廠牌的硬體事件都有。

安裝與設定 snmptrapd

安裝

apt install snmptrapd

snmptrapd.conf

編輯 /etc/snmp/snmptrapd.conf,依官方文件加入:

disableAuthorization yes
authCommunity log,execute,net your-community
traphandle default /opt/librenms/snmptrap.php
  • traphandle default:關鍵設定,把所有 Trap 交給 LibreNMS 處理
  • authCommunity:允許使用這個 community 的 Trap 執行 log、execute、net 動作
  • disableAuthorization yes:停用存取控制,任何 community 的 Trap 都會被接受

disableAuthorization yes 方便測試,但正式環境建議拿掉,改由 authCommunity 限制只接受指定的 community,並用防火牆限制只有設備的網段能送 Trap 到 162/UDP。

載入 MIB

snmptrapd 需要 MIB 才能把 OID 解析成名稱。沒設定的話,Eventlog 會出現這樣的訊息:

Misconfigured MIBS or MIBDIRS for snmptrapd, check https://docs.librenms.org/Extensions/SNMP-Trap-Handler/ :
librenms01 UDP: [192.168.1.20]:54630->[192.168.1.20]:162 iso.3.6.1.2.1.1.3.0 7:1:20:31.18 iso.3.6.1.6.3.1.1.4.1.0 iso.3.6.1.6.3.1.1.5.1

意思是 Trap 有收到,但 snmptrapd 沒辦法解析,只能看到一串 OID。這種情況 LibreNMS 的處理程式也對應不到,所以只會留下這筆系統訊息,不會產生對應的事件。

依官方文件,用 systemd 的 override 指定 LibreNMS 內建的 MIB 目錄:

mkdir -p /etc/systemd/system/snmptrapd.service.d
cat > /etc/systemd/system/snmptrapd.service.d/mibs.conf <<'EOF2'
[Service]
Environment=MIBDIRS=+/opt/librenms/mibs:/opt/librenms/mibs/cisco
Environment=MIBS=+IF-MIB
EOF2

systemctl daemon-reload
systemctl enable snmptrapd
systemctl restart snmptrapd

# 確認環境變數有生效
systemctl show snmptrapd --property=Environment
  • MIBDIRS:MIB 檔案的目錄,不會遞迴,有需要的廠牌目錄要一個一個加,例如 /opt/librenms/mibs/cisco
  • MIBS:要載入的 MIB,只列你需要的,例如介面上下線要 IF-MIB,BGP 要再加 BGP4-MIB

注意:官方文件特別說明不要用 -m ALL 載入全部 MIB,snmptrapd 通常會因為 MIB 數量太多而載入失敗。網路上有些教學在 snmptrapd.conf 寫 mibs +ALL 或另外安裝 snmp-mibs-downloader,在 LibreNMS 的環境不需要,LibreNMS 本身就附了 MIB。

確認有在監聽

ss -ulpn | grep 162

162 是特權通訊埠,snmptrapd 要以 root 執行。

設備端設定

在交換器、防火牆、UPS 等設備上設定:

  • SNMP 版本(v2c 或 v3)與 community/帳號
  • Trap 目的地:LibreNMS 主機的 IP,通訊埠 162/UDP
  • 要送哪些 Trap(介面上下線、開機、硬體事件等)

注意:設備必須已經加入 LibreNMS 監控,Trap 才會對應到裝置並寫進它的 Eventlog。LibreNMS 是依送出 Trap 的來源 IP 找裝置的。

測試

最直接的方式是讓設備真的產生 Trap,例如拔插一條網路線(介面上下線)。也可以從 LibreNMS 主機自己送一個 coldStart Trap 給自己(前提是 LibreNMS 主機本身也在監控清單裡):

snmptrap -v 2c -c your-community localhost '' 1.3.6.1.6.3.1.1.5.1
  • '':uptime 留空,自動帶入系統的開機時間
  • 1.3.6.1.6.3.1.1.5.1:coldStart,代表設備剛開機

MIB 設定正確的話,Eventlog 會出現:

Eventlog 收到 coldStart Trap,type 為 reboot
Eventlog 收到 coldStart Trap,type 為 reboot

要看 snmptrapd 收到的原始 Trap,可以依官方文件在 ExecStart 加上 -tLf /var/log/snmptrap/traps.log 記錄到檔案,除錯時很有用。

Trap 寫進 Eventlog 的內容

這部分網路上的說法很多,我直接看了 LibreNMS 的原始碼,常見的幾種如下:

Trapeventlog.type訊息範例等級
coldStartrebootSNMP Trap: Device xxx cold booted警告(4)
warmStartrebootSNMP Trap: Device xxx warm booted警告(4)
linkDowninterfaceSNMP Trap: linkDown up/down GigabitEthernet1/0/1嚴重(5)
linkDown(同時記錄)interfaceInterface went Down : GigabitEthernet1/0/1 (TRAP)嚴重(5)
linkUpinterfaceSNMP Trap: linkUp up/up GigabitEthernet1/0/1正常(1)
沒有處理程式的 Traptrap依設定記錄 Trap OID資訊(2)
MIB 設定錯誤systemMisconfigured MIBS or MIBDIRS...資訊(2)

幾個要特別注意的地方:

  • 介面上下線的 type 是 interface,不是 link。網路上很多範例寫 eventlog.type = 'link',這樣的規則永遠不會觸發
  • 不是所有 Trap 訊息都以 SNMP Trap: 開頭,例如上表的 Interface went Down : ... (TRAP)
  • linkDown 訊息裡的 up/down 是「管理狀態/運作狀態」:up/down 是線斷了,down/down 是管理者手動關閉
  • 各廠牌的處理程式 type 各自不同,以自己環境的 Eventlog 實際出現的 type 為準:到「Logs → Eventlog」依 Type 篩選看看

沒有處理程式的 Trap

沒有對應處理程式的 Trap,預設會記錄成 type 為 trap 的事件,可以在「全域設定 → 外部整合 → SNMP Traps Integration」調整,或用指令:

# unhandled:只記錄沒有處理程式的 Trap(預設)/all:全部記錄/none:不記錄
lnms config:set snmptraps.eventlog 'unhandled'

# 記錄 Trap 的完整內容(預設只記錄 Trap OID)
lnms config:set snmptraps.eventlog_detailed true

把 Trap 變成告警

Eventlog 只是記錄,要自己建立告警規則才會通知。到「告警 → 告警規則 → 建立新的告警規則」,可以用規則產生器,也可以直接寫 SQL 條件。

一定要加時間條件

告警規則每次輪詢都會重新判斷。Eventlog 的舊記錄不會消失,規則如果只寫 eventlog.type = "reboot",只要曾經重新開機過一次,這個告警就會一直成立,永遠不會恢復。

官方文件的做法是加上時間的巨集,只看最近一段時間的事件:

eventlog.type = "reboot" AND eventlog.datetime >= macros.past_10m

macros.past_10m 是 10 分鐘前的時間,可用的有 5、10、15、30、60 分鐘。

LibreNMS 收到 Trap 處理完之後,會立刻對這台裝置執行一次告警規則判斷,不用等下一次輪詢,所以告警幾乎是即時的。時間範圍則決定告警要維持多久:我習慣用 10 分鐘,至少會經過一次輪詢再恢復。時間過了之後告警會自動恢復,如果不想收到恢復通知,可以在規則裡關掉。

規則範例

設備重新開機:

eventlog.type = "reboot" AND eventlog.datetime >= macros.past_10m

介面斷線(排除管理者手動關閉):

eventlog.type = "interface" AND eventlog.message REGEXP "linkDown up/down" AND eventlog.datetime >= macros.past_10m

up/down 代表管理狀態是開、運作狀態是斷,也就是線真的斷了;手動關閉的是 down/down,不會被這條規則抓到。只看關鍵的上行介面,可以再加上介面名稱的條件。

依事件等級:

eventlog.severity >= 5 AND eventlog.message REGEXP "TRAP|SNMP Trap" AND eventlog.datetime >= macros.past_10m

等級 5 是嚴重,搭配訊息條件只抓 Trap 來源的事件。

沒有處理程式的 Trap(先觀察用):

eventlog.type = "trap" AND eventlog.datetime >= macros.past_10m

適合導入初期看看設備到底送了哪些 Trap,再決定要不要針對它寫正式的規則。

寫規則的原則

  • 優先用 eventlog.type,再用 eventlog.message 補充條件
  • 訊息比對用關鍵字,不要比對整段文字(裝置名稱、介面名稱都會變)
  • 規則先套用在一兩台設備測試,確認不會一直誤報,再擴大範圍

常見問題

狀況檢查
Eventlog 完全沒有記錄ss -ulpn | grep 162 有沒有在聽、防火牆、設備的 Trap 目的地與 community
只看到 Misconfigured MIBS or MIBDIRSMIB 沒設定好,檢查 systemd override 與 MIBS 是否包含需要的 MIB
有收到但沒對應到裝置設備沒加入 LibreNMS,或送 Trap 的來源 IP 和監控用的 IP 不同
告警一直不恢復規則沒有加 eventlog.datetime >= macros.past_Nm
eventlog.type = 'link' 不會觸發介面的 type 是 interface

結論

LibreNMS 收 SNMP Trap 的關鍵設定只有三個:traphandle 指到 snmptrap.php、systemd 指定 MIB 目錄、設備加入監控。收進來之後只是 Eventlog,要告警就自己寫規則,而且一定要加時間條件。

網路上流傳的規則範例,很多 type 是猜的,寫之前先到 Eventlog 看看實際的 type 與訊息,比照著寫最準。

參考資料

Jason Cheng

Jason Cheng

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

關於作者 →

延伸閱讀