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

jt-snmpd:取代 Windows 內建 SNMP 服務,擴充 LibreNMS 監控資料

Jason Cheng 發布 瀏覽 1 次
jt-snmpd:取代 Windows 內建 SNMP 服務,擴充 LibreNMS 監控資料
本文目錄
  1. 開發緣由
  2. LibreNMS 新增的監控資料
  3. 安全性設計
  4. 效能影響
  5. 安裝
  6. LibreNMS 啟用 SMART 探索模組
  7. 已驗證環境
  8. 結論
  9. 參考資料

微軟已開始將 Windows 內建的 SNMP 服務標記為棄用,未來版本可能直接移除。但說實話,它本來能經由 SNMP 提供的資料就比 Linux 少很多,像是磁碟 I/O、磁碟溫度、SMART 這些,一項都沒有。

為了避免以後 Windows 主機沒有 SNMP 可用,同時把 LibreNMS 能撈到的數據補齊,我另外開發了一套完全相容 SNMP 協定的 jt-snmpd,安裝完即可使用。

最重要的一點:LibreNMS 伺服器完全不用改。不用外掛、不用在被監控端放其它 agent 腳本,它講的就是標準 MIB,LibreNMS 會把它當成一般的 Windows 裝置探索到。目前版本 v1.1.3,以 GPL-3.0-or-later 授權釋出。

開發緣由

Windows 內建的 SNMP Service 已經不再積極開發,除了「以後可能沒得用」,它本身還有幾個讓我一直很在意的問題:

  • 資料太少
    沒有磁碟 I/O、沒有溫度、沒有 SMART,LibreNMS 上 Windows 主機的頁面跟 Linux 一比就空蕩蕩的
  • 連接埠一大堆假介面
    它把每一個 NDIS 篩選器驅動程式都當成獨立介面輸出,一台筆電就冒出九個連接埠,真正的網路卡反而不好找
  • 介面索引會變動
    換驅動、拔插網路卡後索引會重編號,LibreNMS 的歷史圖表就對不上了
  • 安全面不理想
    支援 SET、沒有速率限制,而且來源檢查發生在封包解析之後

與其等到哪天微軟真的拿掉它再來煩惱,不如現在就做一套比它更好用的。

LibreNMS 新增的監控資料

改使用 jt-snmpd 之後,LibreNMS 多拿到的資料:

  • 設備清單
    主機板、CPU、記憶體、磁碟等等,從 SMBIOS 解析
  • 磁碟 SMART 與溫度
    含韌體宣告的門檻值
  • 磁碟 I/O
    原本沒有磁碟 I/O,無法看出每顆磁碟的效能
  • 四組記憶體數據
    較原本的 SNMP 多出 Cached 與 Swap
  • 連接埠
    只抓出真正的網路卡,名稱正確,而且不會變動
  • System 頁
    多出更多重要效能指標

下面這張表是在同一台機器上,先後跑兩種 agent 的實測對照。硬體、作業系統與 LibreNMS 完全相同,唯一的變數是誰在服務 UDP 161。受測機器是一台 Dell Latitude E5270 筆電,Windows 10 22H2。

LibreNMS 頁面內建 SNMPjt-snmpd說明
設備(entPhysical)08從 SMBIOS 解析機箱、主機板、CPU、DIMM、磁碟
應用程式 › SMART06agent 自己以 IOCTL 讀 SMART,經 NET-SNMP-EXTEND-MIB 送出
健康情況 › 感測器02磁碟溫度與 ACPI 溫度區,都帶韌體宣告的門檻值
健康情況 › 磁碟 I/O02IOCTL_DISK_PERFORMANCE
健康情況 › 記憶體24另加 Cached 與 Swap
System 圖表38補上處理器細項、Context Switches、Interrupts、I/O、Swap I/O
連接埠92刻意較少:只輸出實體介面
OID 總數7,582767刻意較少:預設關閉 LibreNMS 用不到的資訊揭露

注意最後兩列,數字變少是刻意的,下面會說明原因。

溫度感測器

內建服務完全不回報感測器,所以 LibreNMS 根本不會建立「溫度」頁籤。改用 jt-snmpd 後,磁碟溫度與 ACPI 溫度區(主機板韌體自己定義的量測點,通常對應 CPU 周邊或機殼)都會出現,而且帶著韌體宣告的上下限,LibreNMS 可以直接拿來設警報。本文首圖就是這組對照:上半部是內建 SNMP,連溫度頁籤都沒有;下半部是 jt-snmpd。

首圖中那幾次掉到 0 °C,是拍攝過程中把 UDP 161 交給另一個 agent 的那幾分鐘,感測器沒有資料可回報,不是真的量到 0 度。

磁碟 SMART

SMART 完全透過 SNMP 送達,被監控端不需要再裝 smartctl 或任何輔助腳本。比較特別的是:沒量到的屬性一律保持 null,不填 0。因為在「重新配置磁區」填 0,意思是「這顆碟很健康」,那是謊言。

SMART 對照:內建 SNMP 沒有 SMART 應用程式,jt-snmpd 經 SNMP 送出 SMART 屬性
SMART 對照:內建 SNMP 沒有 SMART 應用程式,jt-snmpd 經 SNMP 送出 SMART 屬性

連接埠

同一台筆電,內建服務列出 9 個連接埠,其中大部分是 WFP Native MAC Layer LightWeight Filter 這類篩選器驅動程式。jt-snmpd 只輸出 2 張實體網路卡,名稱也直接是「乙太網路」「Wi-Fi」。

另外,介面索引(ifIndex)改以 NET_LUID 為主鍵長期保存,更新驅動或拔插網路卡後不會重新編號,LibreNMS 的歷史資料不會失去對應。

連接埠對照:內建 SNMP 把篩選器驅動程式都列成介面,jt-snmpd 只輸出實體網路卡
連接埠對照:內建 SNMP 把篩選器驅動程式都列成介面,jt-snmpd 只輸出實體網路卡

記憶體

內建服務只提供實體與虛擬記憶體兩組,jt-snmpd 另外提供快取記憶體(Cached)與 Swap,跟 Linux 主機在 LibreNMS 上看到的一致。

記憶體對照:jt-snmpd 多出 Cached 與 Swap
記憶體對照:jt-snmpd 多出 Cached 與 Swap

OID 數量減少的原因

內建服務回應 7,582 個 OID,jt-snmpd 只有 767 個。差距裡有將近四千個是已安裝軟體、執行中處理程序、連線表這三類資訊。我查過 LibreNMS 原始碼,這三類在 LibreNMS 裡沒有任何取用端,送出去也不會變成任何頁面,只是白白揭露主機資訊,所以預設關閉。

唯一有用到的是 ARP 表(LibreNMS 的 ArpTable 模組),需要的話可以在設定裡開啟。

安全性設計

監控工具要裝在幾百台主機上,它本身就不能變成弱點。這部分我花的時間其實比功能還多:

  • 唯讀不是設定,是根本沒有那條路徑
    只提供 GET,不支援 SET。處理寫入的程式碼根本不存在,SET 請求直接丟棄且不回應
  • 前置解析閘門
    來源 ACL、封包大小上限、每個來源的速率限制、外層 TLV 檢查,全部在 BER 解碼之前完成。解碼器是攻擊面最大的一塊,未授權的封包碰不到它
  • 完全不對外連線
    安裝時不上網抓東西,執行時也不會主動連出去
  • 最小權限
    服務只保留必要的三項特權,設定檔目錄的 ACL 重設為只有 SYSTEM 與 Administrators
  • 支援 SNMPv3
    預設 SHA-256 + AES-128,只提供 authPriv,金鑰以 DPAPI 加密保存,可與 v2c 並存

刻意不實作的功能

有兩件事是刻意不做的,也一併說明:

  • 不讀 CPU 核心溫度
    CPU 核心溫度要讀 MSR,那必須有核心驅動。業界慣用的 WinRing0 已經列入 Microsoft 易受攻擊驅動封鎖清單,為了一個溫度值在數百台主機裝一個能任意讀寫實體記憶體的驅動,等於把監控工具變成提權管道
  • 量不到就不回報
    採集失敗時該列直接從快照消失,不回 0、不回前一次的值。監控資料寧可缺,也不能假

效能影響

這是導入前最常被問的問題。實測在 7,000 倍真實輪詢速率下,固定基準工作負載只退化 0.41%。單次完整 walk 約 12.5 ms CPU 時間,以 LibreNMS 每 5 分鐘輪詢一次來算,實際佔用約 0.004%,可以放心裝在正式環境。

安裝

MSI 已經把需要的東西全部包在裡面,安裝時不會上網抓任何東西,也不需要事先安裝 Windows 內建的 SNMP Service。

如果機器上已經有內建服務在跑,安裝程式會沿用它的 community 與 sysContact / sysLocation,然後把它停用(停用,不是移除),解除安裝 jt-snmpd 時會自動還原。

注意:安裝檔未經 Authenticode 簽章,點兩下安裝時 SmartScreen 會出現警告,UAC 的發行者會顯示為「不明」。每個版本都附 .sha256,安裝前請先核對雜湊值。WDAC / AppLocker 環境的處理方式,請見專案文件的「程式碼簽章」一節。

方式一:圖形介面安裝

安裝程式會逐步詢問安裝路徑與監控設定,其中管理網段與 community 兩項是必填,它們決定誰查得到這台主機。管理網段沒填就無法繼續,因為空清單等於只回應本機,裝好了卻沒有在監控。

安裝程式的監控設定:管理網段與 community 為必填
安裝程式的監控設定:管理網段與 community 為必填

事後要改設定,編輯 C:\ProgramData\jt-snmpd\config.json 再重新啟動服務即可。

方式二:命令列與 AD 群組原則派送

要大量部署時,用命令列無人值守安裝,/qn 表示不顯示任何介面:

msiexec /i jt-snmpd-1.1.3-x64.msi /qn MANAGEMENTNETWORKS=10.0.0.0/24 COMMUNITY=your-community

同一個 MSI 與同一組屬性,也直接適用於 AD 群組原則(GPO)軟體派送,安裝過程以 SYSTEM 身分執行,不會有任何提示。

以 GPO 派送時,請把 MSI 放在網域內的共用資料夾,並確認電腦帳戶對該資料夾有讀取權限。從內部共用資料夾安裝不會帶網頁標記(Mark of the Web),所以也不會遇到 SmartScreen 警告。

安裝後啟用 SNMPv3

安裝程式不會問 SNMPv3,這是刻意的。MSI 屬性會被寫進 msiexec 記錄檔,也會進 Windows 事件記錄 1033 與 11707,密碼一旦交給安裝程式,就會以明文留在每一台被派送的機器上。

所以 SNMPv2c 在安裝完就能用,SNMPv3 則是第二個步驟,在被監控的主機上執行:

cd "C:\Program Files\jt-snmpd"
.\jt-snmpd.exe user add librenms
sc stop jt-snmpd && sc start jt-snmpd

密碼是互動輸入的,而且只保存 localized key、不保存密碼本身。這時候 v2c 與 v3 都會回應,正好讓你逐台切換驗證;等所有輪詢器都換過去,再在 config.json 設定 "v3_only": true 並重新啟動服務,就完全不再接受 SNMPv2c。

LibreNMS 啟用 SMART 探索模組

LibreNMS 本身不用改,但有一個設定要打開:SMART 用到的「應用程式」探索模組預設是關閉的。沒啟用時 jt-snmpd 照樣供應資料,只是沒有人來取,裝置的「應用程式」分頁就不會出現 SMART。

  1. 以管理員身分登入 LibreNMS,點右上角的齒輪圖示,選「全域設定」
  2. 上方分頁選「探索」,展開「探索模組」
  3. 找到「應用程式」(applications),把它打開
  4. 回到裝置頁面按「重新探索裝置」,或等下一次排程探索

若偏好命令列,建議用下面這行,只針對 Windows 裝置開啟,交換器與防火牆就不會每輪多跑一次註定撲空的 walk:

lnms config:set os.windows.discovery_modules.applications true

注意:如果某台裝置曾經在裝置頁的 Modules 開關動過「應用程式」,會留下一筆裝置層設定,而且裝置層優先於全域設定。關掉留下的那個「否」會一直壓過全域的「是」,從全域設定頁上看不出來,遇到單台不出現 SMART 時請先檢查這裡。

已驗證環境

  • Windows 10 / Windows 11
  • Windows Server 2016、Windows Server 2022,網域控制站也實機測過
  • AD 群組原則派送安裝

專案另外附有 797 項自動測試與 40 項實機生命週期檢查,資安檢測結果(Bandit、相依套件弱點掃描)也都公開在文件裡。

結論

這個專案的起點很單純:微軟要把 Windows 內建 SNMP 拿掉了,那我的 LibreNMS 怎麼辦?但做下去之後發現,與其做一個「替代品」,不如直接把它一直以來缺的東西補起來。

對我來說最有感的是磁碟 SMART 與溫度。以前 Windows 主機的硬碟要壞了,往往是使用者先發現;現在跟 Linux 主機一樣,LibreNMS 上就能看到趨勢、設警報。而 LibreNMS 端完全不用動,換掉 agent 就生效,導入成本幾乎為零。

專案以 GPL-3.0-or-later 授權釋出,這是我個人維護的專案,有問題或功能建議歡迎到 GitHub 開 issue。

參考資料

Jason Cheng

Jason Cheng

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

關於作者 →

延伸閱讀