# Monitoring
[TOC]
## 為何要監控
### 概念
- 當系統有問題時可以即時得知,降低損失,確保系統的可用性
- 系統存在未知的錯誤,造成系統 crash
- 系統資源不足/過剩
- 系統效能調校
- 資安問題,被駭客利用系統資源進行惡意行為
- 使用有效率的方式監控,降低成本
- 在單個系統上,可以快速監控多個指標
- 當有多個系統需要管理,採用中心化的方式進行管理
### 範例
- 背景
- 在我接任系網管的一個月,系辦助理打給我並很著急地說:『 啊啊啊資管系網連不進去了 ==』
- 如何運用監控工具及早定位問題以解決?
- 這時候我們(系統管理員)可以利用各種工具監控系統,及早發現系統中的問題,並更容易地找出問題來源以快速解決
- 
- <a href='https://askubuntu.com/questions/1224927/cpu-100-with-kswapd0-process-although-no-swap-is-needed'>source</a> : 可以觀察到系統的 cpu 被用於執行挖礦程式的腳本
- 
- 可以觀察到系統持續幫此區塊鏈做驗證
- 最後依據上述資訊成功找到系網服務的問題
- 因系上主機存在因 ssh 設定問題,導致被利用 ssh burst 攻擊成功,並植入後門和挖礦程式(`Multios.Coinminer.Miner`)
- 因系統的資源皆被惡意程式用於執行挖礦腳本,故導致正常的服務無法或是需要等待一段時間才能正常執行
- 如何在未來能夠避免問題已經發生一段時間,然而系統管理員卻無法即時解決?
- 利用各種監控工具監控系統,當發生異常事件就即時通知
## Linux Server 常用的監控工具
### process
- top
- 查看當前系統中的 process 的資訊
- 包含 pid, 資源使用量 等等
- 
- htop
- 是另外一個類似 top 的監控工具,它的功能與操作介面比 top 更完整,可以用上下滑動和點擊等等的方式和介面互動
- 可以顯示每個 process 完整的 command 和參數
- 可以一次選擇多個 process 進行處理
- 
- 欄位介紹
1. 系統 CPU usage
- 
2. 系統 Mem usage
- 
3. 系統負載
- 
- Tasks : 各別代表的是 process, thread and running thread 的數量
- Load Average(LA) : 各別代表的是系統在最近 1分鐘、5分鐘、15 分鐘內,平均有多少個 thread 需要 CPU
5. process 資訊
- 
### disk
- lsblk
- short for “list block devices”
- is a powerful tool that provides detailed information about block devices.
- block devices
>random access to data organized in fixed-size blocks.
- 可以隨機存取指定的固定大小的 blocks 上面的資料
- such as lvm, hard drives, solid-state drives, and other storage-related devices.
- 
- Linux 磁碟以及分割區名稱可能和其它的作業系統有所不同。以下是基本的命名規則:
1. The first hard disk detected is named `/dev/sda`.
2. The second hard disk detected is named /dev/sdb, and so on.
3. 每個磁碟分割區的名字在磁碟名稱後面附加一個十進制數字: sda1 以及 sda2 表示 sda 的第一個及第二個分割區。
- df
- file system 的當前 disk usage
- 
- `-h`
- --human-readable
- print sizes in powers of 1024 (e.g., 1023M)
- iotop
- iotop watches I/O usage information output and displays a table of current I/O usage by processes or threads on the system.
- 
### memory
- free
- 顯示目前系統使用和未使用的 memory and swap
- 
### general
- vmstat
- 快速觀察 process, memory, disk I/O, cpu 等系統整體狀況
- 用法:`vmstat [options] [delay [count]]`
- 
- `procs`
- r: The number of runnable processes (running or waiting for run time).
- b: The number of processes blocked waiting for I/O to complete.
- `memory`
- swpd:已使用 mem
- free:空閒 mem
- buff:
- cache:
- `swap`
- si(swap in)
- so(swap out)
- `io`
- bi:Blocks received from a block device
- bo: Blocks sent to a block device
- `system`
- in:The number of interrupts per second
- cs:The number of context switches per second.
- `cpu`
- us:Time spent running non-kernel code.
- sy:Time spent running kernel code.
- id:Time spent idle.
- wa:Time spent waiting for IO.
- st:Time stolen from a virtual machine.
### network
- netstat
## SNMP
### 介紹
- SNMP (Simple Network Management Protocol) 是一個應用層的網路協定,主要被用於監控網路設備,也可以用於更改設備的設定
### 架構
- 
1. SNMP Manager / NMS(Network Management Station)
- SNMP Manager 上會安裝 SNMP Manager Software
- 利用 SNMP Manager Software 發送 request,向 SNMP Agent 查詢/設定被管理裝置的相關資訊和狀態
2. Agent Device
- Agent Device(如:router, switch) 上會安裝 SNMP Agent Software
- SNMP Agent Software 負責蒐集設備和系統上的資訊,並持續監聽是否需回應 SNMP Manager 的 request
- SNMP Agent Software 會區分 Master Agent 和 Subagent,這部分<a href='#directivesmessages'>下面</a>會再提到
- SNMP Agent Software 以變數方式呈現 Agent Device 的相關資訊,每個變數皆有其唯一的物件識別碼(Object Identifier, OID)
- 而 OID 是以階層方式被描述於管理資訊庫(MIB)
3. MIB (Management Information Base)
- 背景
- SNMP 本身沒有定義 Agent 一定要提供哪些可供查詢的資料,或是以哪一種方式去查詢,但是有提供了 MIB 這個擴充的設計讓 Agent 自己去定義
- 這樣可以讓 Manager 能有固定且易讀的方式,去讀取對應的資料
- MIB 以階層式來描述所有被管理的物件
- 這些被管理的物件被稱為 SNMP Object
- 因此,MIB 為一樹狀結構(MIB Tree),每一節點都有編號 - OID (Object Identifier)
- 
- <a href='https://docstore.mik.ua/orelly/networking_2ndEd/snmp/ch02_05.htm'>source</a>
- 每一個非葉節點代表一個管理群組(如第一層的 `0 - ITU-T`, `1 - ISO`, `2 - Joint`),通常不會儲存 value,只用來分層,區分不同類型的資料
| **比較** | **ITU-T Assigned (0)** | **ISO Assigned (1)** | **Joint ISO/ITU-T Assigned (2)** |
|---------------------|--------------------------------|-----------------------------------|---------------------------------------|
| **管理的組織** | <a href='https://www.itu.int/en/ITU-T/Pages/default.aspx'>ITU-T</a> (ITU Telecommunication Standardization Sector)<br/>(前身為 CCITT) | <a href='https://www.iso.org/home.html'>ISO</a> (International Organization for Standardization) | Jointly ISO and ITU-T |
| **主要負責內容** | Telecommunication standards | General standards (e.g., networking) | Collaborative or shared standards (e.g., ASN.1) |
- 葉節點為 SNMP Object 的 value(如 `ipAdEntAddr` 是該設備所有 interface 的 ip address)。
- 例子
1. OID : `.1.3.6.1.2.1.4.20.1.1`
- 該台 Server 所有 interface 的 ip address
- `mgmt` 的 `mib-2` subtree (`.1.3.6.1.2.1`)
- 經由 <a href='https://www.iab.org/'>IAB(Internet Architecture Board)</a>核准,定義的標準化管理物件。
- 包含基本的網絡資訊,例如:tcp 連線狀況、network interface 的資訊等
- 為跨廠商通用的管理對象所設計,所以只要支援 SNMP,即使是不同廠商也會實作此 subtree 的內容
- 
- <a href='https://docstore.mik.ua/orelly/networking_2ndEd/snmp/ch02_05.htm'>source</a>
- 定義於 <a href='https://datatracker.ietf.org/doc/html/rfc1213'>RFC 1213</a>
2. OID : `.1.3.6.1.4.1.2021.4.5.0`
- 該台 Server 的 Mem 總大小
- `private` subtree (`.1.3.6.1.4`)
- 經由廠商自定義的管理物件,讓廠商可以提供適用他們設備的資料
- 例如:Cisco Router (`.1.3.6.1.4.1.9`), Net-SNMP (`.1.3.6.1.4.1.2021`)
- <a href='http://www.net-snmp.org/'>Net-SNMP</a>
- 開源的實作 SNMP 的工具集
- 常見於 Unix and Unix-like operating systems
- 如何找到 MIB tree 的結構
- 可以去<a href='https://www.alvestrand.no/objectid/top.html'>這個網站</a>查看通用的版本
- 如果是各家廠商的,要自己去查他們定義的標準
- <a href='http://www.net-snmp.org/docs/mibs/UCD-SNMP-MIB.txt'>NET-SNMP</a>
- <a href='http://www.cisco.com/public/sw-center/netmgmt/cmtk/mibs.shtml'>cisco</a>
### directives/messages
- 
- <a href='https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol'>source</a>
- Manager 和 Agent 之間可以透過傳送以下幾種不同的 directives/messages 的 request 溝通:
- 補充:SNMP Master Agent, Subagent
- 背景:若僅有 SNMP Master Agent,會有以下的問題
1. 當 Manager 想要一次查詢多個 Agent 的資料,它會需要等待多個設備查詢完後,才能得到結果
2. 當大部分的 Agent 只允許讓內網存取,Manager 無法直接存取到這些在內網的 Agent
- Master Agent
- 作為 Subagent 和 Manager 之間的橋樑,讓 Manager 可以和此介面溝通,就可以存取到所有的 Subagent
- 因此,當 Manager 向 Master Agent 拿資料,Master Agent 會再去和對應的 Subagent 拿
- (Master Agent 也可以作為 Subagent 蒐集資料)
- Subagent
- 真正在 Deivce 上面蒐集和管理資料的 SNMP Agent
1. GET Request
- 從 SNMP Manager 向 Agent 發送 request(UDP 161)
- 讀取指定的一個 OID 的節點的值
- 例如下圖:查詢 B 節點的 OID,會回傳 B 節點的值
- 
2. GET NEXT Request
- 從 SNMP Manager 向 Agent 發送 request(UDP 161)
- 讀取指定的一個 OID 的節點的下一層有值的節點的值
- 例如下圖:查詢 A 節點的 OID,會回傳 B 節點的值
- 
- 用於遍歷未知的 MIB 結構
3. GET BULK Request
- 從 SNMP Manager 向 Agent 發送 request(UDP 161)
- 可以在一次的 request 中存取多個 OID,減少網絡流量
- 針對每一個 OID,會遞迴地查詢其 subtree
- 例如下圖:查詢 A 節點的 OID,會回傳 B, C, D 節點的值
- 
4. SET Request
- 從 SNMP Manager 向 Agent 發送 request(UDP 161)
- 設定 OID 對應的值
- 可以修改 Agent 設定檔裡面的值(不會對設備造成直接影響)
也可以修改設備的系統設定,對設備造成直接影響(e.g. 設定某張網路介面卡啟動或關閉)
5. TRAPS Request
- 從 Agent 向 SNMP Manager 發送 request(UDP 162)
- 當被監控的設備發生異常事件時,Agent 對 SNMP Manager 發出的 request
- 重新啟動
- 網路連線斷開
- 欲存取設備的 SNMP request 未通過身份驗證
6. INFORM Request
- 從 Manager/Agent 向 SNMP Manager 發送 request(UDP 162)
- 和 TRAPS 一樣,都是由 Agent 向 Manager 發出的 request
- 不同在於,作為 Receiver 的 Manager 會送包含 ack 的 response,而作為 Sender 的 Agent 會檢查 ack,若沒收到則會重新發出 request,確保 Receiver 有接收到
### 傳輸原理
- 
- <a href='https://arc.net/l/quote/qufdvfpu'>source</a>
- SNMP Manager 經由 UDP 傳送 GET/SET request 至 SNMP Agent 的 port 161
- SNMP Agent 經由 UDP 傳送 TRAP/INFORM request 到 SNMP Manager 的 port 162
### SNMP 封包格式
- 
- SNMP v3 的格式差別主要在多了 Security Parameters,<a href='#SNMP-版本'>下方</a>會再提到
- <a href='https://www.tsnien.idv.tw/Internet_WebBook/chap16/16-3%20SNMP%20%E5%8D%94%E5%AE%9A.html'>source</a>
1. 訊息標頭(Message Header)
- 訊息標頭包含兩個欄位:
1. 版本(Version):表示該 SNMP 封包的版本,0 表示 SNMPv1;1 表示 SNMPv2。
2. 共同體(Community):表示某由同一群 SNMP Manager, Agent 組成的群體名稱,預設值為 `public`
2. SNMPv1 一般協定資料單元
- SNMPv1 的 PDU(Protocol Data Unit)包含有:Get、GetNext、Response 與 Set PDU 格式,它們的 PDU 格式都是相同,各欄位功能如下:
1. PDU Type:表示本 PDU 的命令型態:
- 0 → Get-Request
- 1 → Get-Next-Request
- 2 → Set Request
- 3 → Get-Response
2. Request ID:當 SNMP Manager 下達某一命令,都會針對每一命令編碼一個 Request ID(隨機變數),SNMP Agent 回應時,再針對對應的 Request ID 回應訊息。Manager 可以依此確保每個 request 都有正確收到 response。
3. Error Status:存放發生錯誤訊息。如果 SNMP Manager 所下達的命令無法達成時,Agent 便依照錯誤狀態回應給 SNMP Manager。
4. Error Index:Set-Response PDU 存放錯誤發生的索引位置,表示錯誤是發生在哪一個 OID。
5. 管理物件:每一管理物件以(Object-n, Value-n)來表示。
- 範例(封包內容未經過編碼前):
- Get Request
```=
SNMP Message:
Version: 1
Community: public
PDU Type: GetRequest
Request ID: 12345
Error Status: 0
Error Index: 0
Variable Bindings:
- Name (OID): 1.3.6.1.2.1.1.1.0
Value: NULL
```
- Get Response
```=
Version: 1
Community: public
PDU Type: GetResponse
Request ID: 12345
Error Status: 0
Error Index: 0
Variable Bindings:
- Name: 1.3.6.1.2.1.1.1.0
Value: "Linux server version 5.4.0"
```
### SNMP 版本
1. SNMPv1
- SNMP 的第一個版本
- agent 僅使用 community string 作為 request 的驗證
- transport layer 的 protocol 僅能使用 UDP
- It is described in RFCs 1155 and 1157.
2. SNMPv2c
- SNMP v2 中的其中一個分支版本
- agent 仍僅使用 community string 作為 request 的驗證(這也是為什麼叫做 `v2c`)
- transport layer 的 protocol 可以選擇用 tcp 或是 udp
- 提供新的 directives : GET BULK, Inform
- It is described in RFC 1901, RFC 1905, and RFC 1906.
3. SNMPv3
- 支援可以使用雜湊演算法做 authentication
- 支援可以使用對稱式加密演算法將傳輸的內容加密
- transport layer 的 protocol 可以選擇用 tcp 或是 udp
- It is described in RFC 1905, RFC 1906, RFC 2571, RFC 2572, RFC 2574, and RFC 2575.6.
#### 補充
- 基於查詢的效率、安全性,目前會比較推薦 v2c 和 v3
- 因為 v2c 在大多數的設備,包含比較古老的設備,都有支援
- 而 v3 可以提升資料傳輸的安全性,當設備在外網也可以存取到的情況下,提供更好的防護
### 安全等級
1. noAuthNoPriv
- 沒有 authentication
- 沒有 privacy (加密)
- 僅用 community string 驗證身份
- 範例
- `snmpget -v2c -c public 198.19.249.116 1.3.6.1.2.1.1.1.0`
- 
2. authNopriv
- 有 authentication(基於 MD5 或是 SHA 系列的雜湊演算法)
- 沒有 privacy (加密)
- 範例
- `snmpget -v3 -u lsa_authnopriv -l authNoPriv -a MD5 -A testtest 198.19.249.116 1.3.6.1.2.1.1.1.0`
- 
3. authPriv
- 有 authentication(基於 MD5 或是 SHA 系列的 hash 演算法)
- 有 privacy(基於 DES 或是 AES 系列的對稱式加密演算法)
- 範例
- `snmpwalk -u lsa_authpriv -l authPriv -a SHA-512 -x AES -A myAuthPassword -X myPrivPassword 198.19.249.116 1.3.6.1.2.1.4.20.1.1.127.0.0.1`
- 
### Linux 中常用的 OID
:::spoiler
+ Network Interface Statistics
| OID | 說明 |
| -------- | -------- |
.1.3.6.1.2.1.2.2.1.2|List NIC names
.1.3.6.1.2.1.2.2.1.10|Get Bytes IN
.1.3.6.1.2.1.2.2.1.10.4|Get Bytes IN for NIC 4
.1.3.6.1.2.1.2.2.1.16|Get Bytes OUT
.1.3.6.1.2.1.2.2.1.16.4|Get Bytes OUT for NIC 4
+ 系統基本資訊
| OID | 說明 |
| -------- | -------- |
.1.3.6.1.2.1.1.1.0 | 系統基本資訊
.1.3.6.1.4.1.2021.10.1.3.1 | 系統 1 分鐘平均負載(load)
.1.3.6.1.4.1.2021.10.1.3.2 | 系統 5 分鐘平均負載(load)
.1.3.6.1.4.1.2021.10.1.3.3 | 系統 15 分鐘平均負載(load)
.1.3.6.1.2.1.1.3.0 | 系統持續運行時間(uptime)|
+ CPU
| OID | 說明 |
| -------- | -------- |
.1.3.6.1.4.1.2021.11.9.0 | 使用者 CPU 用量(百分比)
.1.3.6.1.4.1.2021.11.10.0 | 系統 CPU 用量(百分比)
.1.3.6.1.4.1.2021.11.11.0 | 閒置 CPU 量(百分比)
.1.3.6.1.4.1.2021.11.50.0 | 使用者 CPU 用量(時間)
.1.3.6.1.4.1.2021.11.52.0 | 系統 CPU 用量(時間)
+ 記憶體
OID | 說明|
| -------- | -------- |
.1.3.6.1.4.1.2021.4.5.0 | 實體記憶體大小
.1.3.6.1.4.1.2021.4.6.0 | 實體記憶體用量
.1.3.6.1.4.1.2021.4.11.0 | 實體記憶體剩餘量
.1.3.6.1.4.1.2021.4.3.0 | 交換空間(swap)大小
.1.3.6.1.4.1.2021.4.4.0 | 交換空間(swap)剩餘量
.1.3.6.1.4.1.2021.4.27.0 | Available Mem
+ 磁碟
| OID | 說明 |
| -------- | -------- |
|.1.3.6.1.4.1.2021.9.1.2 | 磁碟掛載路徑 |
|.1.3.6.1.4.1.2021.9.1.3 | 磁碟設備路徑 |
|.1.3.6.1.4.1.2021.9.1.6 | 磁碟大小 |
| .1.3.6.1.4.1.2021.9.1.7 | 磁碟剩餘空間 |
| .1.3.6.1.4.1.2021.9.1.8 | 磁碟使用量|
| .1.3.6.1.4.1.2021.9.1.9 | 磁碟使用量百分比|
| .1.3.6.1.4.1.2021.9.1.10 | 磁碟 inode 使用量 |
| .1.3.6.1.4.1.2021.9.1.100 | 磁碟剩餘空間是否不足
:::
- sources
- <a href='https://arc.net/l/quote/nernbxea'>Linux SNMP OID’s for CPU, Memory and Disk Statistics</a>
- {%preview https://github.com/net-snmp/net-snmp/blob/master/agent/mibgroup/ucd-snmp/memory.h %}
### Demo
- `snmpwalk -u lsa_authpriv -l authPriv -a SHA-512 -x AES -A myAuthPassword -X myPrivPassword <agent-id> 1.3.6.1.2.1.2.2.1.2`
- 
### Lab
#### 安裝
- snmp manager : `sudo apt install snmp snmp-mibs-downloader`
- 這個 snmp 套件(Net-SNMP)提供了一些工具讓我們可以和 SNMP Agent 溝通
- 
- `snmpget`
- `snmpgetnext`
- `snmpwalk`
- 使用 GET NEXT Request,查詢該 OID 以及它的 subtree 中的所有節點的值
- `snmpset`
- `snmptrap`
- ...
- snmp agent : `sudo apt install snmpd`
- 
- 這個套件會作為 SNMP Agent 持續監聽是否有需要回覆的 SNMP Request
#### 設定
- SNMP Agent 設定檔 : `sudo vi /etc/snmp/snmpd.conf`
- 這邊的設定主要是要讓我們之後可以從 manager 進行設定
1. 讓 Agent 可以接收從非本地來的 request
```=
# Listen for connections on all interfaces (both IPv4 *and* IPv6)
agentaddress udp:161,udp6:[::1]:161
```
2. 建立 SNMP User,讓 Manager 可以有權限送 request 給 Agent
- 2.1 透過 Net-SNMP 的實作 SNMP USM (User-based Security Model) 的工具來新增 User(<b>推薦</b>)
1. 先暫停 SNMP Agent : `sudo systemctl stop snmpd`
2. 利用工具新增 User : `sudo net-snmp-create-v3-user -a <authentication-password> -x <encryption-password> <username>`
- e.g. `sudo net-snmp-create-v3-user -a testtest -x testtest test`
- 2.2 透過修改 `/etc/snmp/snmpd.conf`(<b>不推薦</b>)
- 為何不推薦?
- 修改<b>已建立</b>的 User 的資訊會有問題
- 原因:當你在 static config (`/etc/snmp/snmpd.conf`) 修改了<b>已建立</b>的 User 的資訊(密碼、驗證或加密的方式),即使你重新啟動 snmpd (`sudo systemctl restart snmpd`),新的 User 資訊也不會被載入到 runtime config (`/var/lib/snmp/snmpd.conf`)
:::spoiler 設定方法
```=
# Define a user with authentication and encryption (priv)
createUser test SHA testtest AES testtest
# grant privilege to user
rwuser test priv
```
- 當建立使用者,可以選擇該使用者要用哪一種雜湊和對稱式加密演算法,以及對應的密鑰
- 可以給予對應的使用者讀或寫的權限
- `rwuser` : 可以讀寫
- `rouser` : 僅能讀
- 可以在最後一個參數指定要強迫該使用者的 Secruity Level
- `noauth`:不需要驗證或加密
- `auth`:需要驗證,但不需要加密。
- `priv`:需要驗證並啟用加密。
- 在藉由重新啟動 snmpd 套用此設定後,可以將 User 的資訊從此檔案中刪除
>SNMPv3 AUTHENTICATION
Note that these particular settings don't actually belong here.
They should be copied to the file /var/lib/snmp/snmpd.conf
- 因為 snmp 在啟動的時候,會把兩種密碼用雜湊將 密碼 + snmp engine id (每一個 snmp agent 理論上各自會有一個唯一值) 產生一個雜湊值並儲存於 runtime config (`/var/lib/snmp/snmpd.conf`),而不是用明文儲存密碼避免安全性問題
:::
3. 套用設定檔 : `sudo systemctl restart snmpd`
4. 開啟防火牆的 161 port
#### 測試
- `snmpwalk -u <username> -l authPriv -a <authentication-protocol> -x <encryption-protocol> -A <authentication-password> -X <encryption-password> <agent-ip> <OID>`
- `-u` : The SNMPv3 username to authenticate as.
- `-l` : The security level to authenticate with.
- `-a` : The authentication protocol to use.
- `-x` : The privacy (encryption) protocol to use.
- `-A` : The authentication passphrase for the supplied username.
- `-X` : The privacy passphrase from the supplied username.
- e.g. `snmpwalk -u test -l authPriv -A testtest -X testtest localhost .1.3.6.1.4.1.2021.4.5.0`
#### 其他設定
- Agent 啟用 community string
- 藉由設定 `rocommunity`, `rocommunity6`, `rwcommnuity`, `rwcommunity6`
- 參數 : `community [default|hostname|network/bits] [oid | -V view]`
- View
- Agent 可以定義 View 對應的 OID
- 將 OID 抽象為一個 View 的 group,方便後續設定使用
- e.g.
```=
view systemonly included .1.3.6.1.2.1.1
rocommunity public default -V systemonly
```
- Agent 作為 Master Agent 或是 Subagent
- 藉由設定 `maaster`
- 參數 : `on|yes|agentx|all|off|no`
- `on`, `yes`, `agentx`, `all` = 作為 Master Agent
- `off`, `no` = 作為 Subagent
- e.g.
```=
master on
```
- Agent 的 custom script
- 用於擴展我們自己定義的客製化的 MIB tree
- 藉由設定 `pass`
- 參數:`OID [command]`
- e.g.
- `/etc/snmp/snmpd.conf`
```=
pass .1.3.6.1.4.1.53864.1.1 /bin/sh /etc/snmp/exampleScript.sh
```
- `/etc/snmp/exampleScript.sh`
```=
#!/bin/sh -f
PLACE=".1.3.6.1.4.1.53864.1.1"
REQ="$2" # Requested OID
# GET requests - check for valid instance
case "$REQ" in
$PLACE.1.0| \
$PLACE.2.0) RET=$REQ ;;
esac
# "Process" GET* requests - return hard-coded value
echo "$RET"
case "$RET" in
$PLACE.1.0) echo "string"; echo "Life, the Universe, and Everything"; exit 0 ;;
$PLACE.2.0) echo "ipaddress"; echo "127.0.0.1"; exit 0 ;;
esac
```
- 
## Cacti
### 介紹
- <a href='https://www.cacti.net/'>官網</a>
- Cacti 是一個 <a href='https://zh.wikipedia.org/zh-tw/LAMP'>LAMP stack Web Application</a>,提供網頁介面讓使用者可以藉由頁面上顯示的文字資料、<b>圖表去快速監控多個設備的多個不同的資料狀況。</b>
- 
### Data Sources
- Cacti 的 Data Sources 可以是藉由 SNMP host,或是自己撰寫腳本去做彈性的使用
- Data Sources store information about the composition of RRDTools's Round Robin Archives (RRAs).
- RRDTool
- 主要是在產生 time-series 的圖檔(如流量,負載
- 學習成本較高
- Round Robin Archives
- are small Time Series Databases that store and aggregate information from device.
- 是一種 Round Robin Database,可以自動覆寫舊數據,確保資料庫的大小是固定的。因此它特別適合長時間的數據監控,因為它不會無限制地增長。
- Time Series Databases
- 反應一個系統或行為隨著時間如何變化的一組資料
- 每筆資料都會有時間的紀錄
- 資料通常不需要做修改和刪除,僅需新增
### 安裝
#### 方法一
- 自行安裝和設定所需的套件
:::spoiler 詳細步驟
#### Install php7.4
- 安裝 php 以及需要的套件
- 目前 cacti 在 php8 上有一些 issue,可以先用 php7.4
- `sudo apt-get install software-properties-common`
- `sudo add-apt-repository ppa:ondrej/php`
- `sudo apt-get update`
- `sudo apt-get install -y php7.4 php7.4-cli php7.4-json php7.4-common php7.4-mysql php7.4-zip php7.4-gd php7.4-mbstring php7.4-curl php7.4-xml php7.4-bcmath php7.4-xml php7.4-ldap php7.4-mbstring php7.4-gd php7.4-gmp php7.4-snmp php7.4-intl`
##### Install MariaDB
- 安裝資料庫
- `sudo apt install -y mariadb-server mariadb-client`
#### Update DB settings
- 為了滿足 cacti 預設對系統的使用的資料庫的最低使用需求,故需調整一些參數
- `sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf`
1. 新增以下設定到 `[mysqld]`
```conf=
[mysqld]
max_heap_table_size=128M
tmp_table_size=128M
innodb_buffer_pool_size=2048M
innodb_doublewrite=OFF
innodb_flush_log_at_timeout=3
innodb_read_io_threads=32
innodb_write_io_threads=16
innodb_io_capacity=5000
innodb_io_capacity_max=10000
```
2. 更改 `collation-server`
```conf=
collation-server = utf8mb4_unicode_ci
```
- `sudo systemctl restart mariadb`
#### Create a db and a user for cacti
- `sudo mysql`
- `CREATE DATABASE cacti;`
- `GRANT ALL ON cacti.* TO cactiuser@localhost IDENTIFIED BY 'cactiuser';`
- `GRANT SELECT ON mysql.time_zone_name TO cactiuser@localhost;`
- `FLUSH PRIVILEGES;`
- `EXIT`
#### Install snmp
- `sudo apt install -y snmp rrdtool librrds-perl`
#### Install cacti
- `sudo apt install wget`
- `wget https://www.cacti.net/downloads/cacti-latest.tar.gz`
- `tar -zxvf cacti-latest.tar.gz`
- `sudo mv cacti-1* /opt/cacti`
- `sudo mysql cacti < /opt/cacti/cacti.sql`
- `sudo mysql mysql < /usr/share/mysql/mysql_test_data_timezone.sql`
- `sudo chown -R www-data:www-data /opt/cacti/`
#### cacti settings
- 針對 cacti 的需求,更改 php 的設定
- `sudo vi /etc/php/7.4/apache2/php.ini`
```ini=
memory_limit = 512M
max_execution_time = 60
date.timezone = Asia/Taipei
```
- `sudo vi /etc/php/7.4/cli/php.ini`
```ini=
memory_limit = 512M
max_execution_time = 60
date.timezone = Asia/Taipei
```
- cacti 是藉由 crontab 來定期執行監控的腳本,因此需幫 cacti 寫一個 crontab 設定檔(cacti 預設是五分鐘去執行一次腳本,更新監控的資料,<b style="color:red;">所以你新增一個 graph 不會馬上就有資料!!!</b>)
- `sudo vi /etc/cron.d/cacti`
- `*/5 * * * * www-data php /opt/cacti/poller.php > /dev/null 2>&1`
#### Web Server settings
- 最後,我們幫 cacti 寫一個 apache2 的設定檔,讓我們可以藉由 Apache2 使用 cacti 的網頁介面
- `sudo vi /etc/apache2/sites-available/cacti.conf`
```conf=
Alias /cacti /opt/cacti
<Directory /opt/cacti/>
Options +FollowSymLinks
AllowOverride None
<IfVersion >= 2.3>
Require all granted
</IfVersion>
<IfVersion < 2.3>
Order Allow,Deny
Allow from all
</IfVersion>
</Directory>
```
- `sudo a2ensite cacti`
- `sudo systemctl reload apache2`
:::
#### 方法二
- 透過自動化的安裝腳本,僅需依提示輸入一些參數即可完成安裝
- 參數除了時區需填入 `Asia/Taipei` 以外,其他使用預設的即可
:::spoiler 詳細步驟
- `sudo apt update && sudo apt install git`
- `git clone https://github.com/tommygood/cacti-install-wizard.git`
- `cd cacti-install-wizard/`
- `sudo ./cacti-setup-wizard-debian-Ubuntu.sh`
:::
#### 結果
- 存取 http://server-ip/cacti
- <b>預設帳密皆為 `admin`</b>
:::spoiler 結果
- 
- 
- 
:::
### 新增設備和圖表的設定/範例
:::spoiler
1. 依照 main console 的步驟(建立 device -> 建立 graph)建立欲觀察的資料和圖表
- 
2. 建立想觀察的 device 的設定檔
- 點選右上角的 +
- 
- 填入設備的資訊: hostname、snmp 資訊等
- 
3. 利用對應欲監控的設備廠商/應用程式(e.g. NET-SNMP, Apache2)和資料的 template 建立 graph
- 
4. 到 management -> graphs 觀察建立的圖表
- 
:::
## Nagios
### 介紹
- <a href='https://www.nagios.org/'>官網</a>
- 主要用於透過 Web UI <b>快速觀察服務是否正常啟動</b>,且可以支援用多種方式(不限於 SNMP)去檢查服務的狀態,用於及時通知異常狀況
- 
### 特色
- Monitoring of network services (via SMTP, POP3, HTTP, PING, etc).
- Monitoring of host resources (processor load, disk usage, etc.).
- Notifications when problems occur and get resolved (via email, pager, or user-defined method).
- Ability to define event handlers for proactive problem resolution.
- Optional web interface for viewing current network status, notification and problem history, log file, etc.
### 安裝
- 可以直接參考<a href='https://www.virtono.com/community/tutorial-how-to/how-to-install-nagios-on-ubuntu-22-04/'>此教學</a>
### 如何設定要監控的目標
1. 先到 nagios 的主設定檔新增要監控的目標 : `sudo vi /usr/local/nagios/etc/nagios.cfg`
2. 新增該目標的設定檔 : `sudo vi /usr/local/nagios/etc/objects/<你要監測的目標>.cfg`
- 2.1 先新增該目標要監控的 host
- 2.2 再新增該目標要監控該 host 的哪些服務
3. 新增欲監測該目標的服務<b>是否正常</b>的指令 : `sudo vi /usr/local/nagios/etc/objects/commands.cfg`
- 我們可以利用 nagios 提供的 library(執行檔存放在 `/usr/local/nagios/libexec`) 去監測目標的服務是否正常
- 預設可用的 library 如下,包含 `check_http`、`check_ping` 等等
- 
- `check_http`
- 常用的 library,用於監控網頁
- `-S` : 除了監控 http 網頁,也可以加上 `-S` 可以用於監控 https 網頁
- `-e` : 用來設定網頁回傳的 status code 預期為多少
- 
4. 檢查設定檔的語法是否正確 : `sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg`
5. 重新啟動 nagios : `sudo systemctl restart nagios`
#### 範例
- e.g. 我想要監控我的 cacti 網站,url 為 http://198.19.249.194/cacti 的 status code 是否為 200
1. `sudo vi /usr/local/nagios/etc/nagios.cfg`
```=
cfg_file=/usr/local/nagios/etc/objects/cacti.cfg
```
2. `sudo vi /usr/local/nagios/etc/objects/cacti.cfg`
```=
define host {
use linux-server
host_name cacti-server ; 欲監控的設備的 host
alias Cacti Monitoring Server
address 198.19.249.194
max_check_attempts 5
check_period 24x7
notification_interval 30
notification_period 24x7
}
define service {
use generic-service
host_name cacti-server ; 這邊要和上面的 host 名稱相同
service_description Check HTTP Response for Cacti
check_command check_http_cacti ; 這邊要對應到下方的 ”檢查是否服務狀態正常“ 的指令
max_check_attempts 500000
check_interval 1s
retry_interval 1
notification_interval 30
notification_period 24x7
contacts nagiosadmin ; 若沒有通過檢查,要通知哪一個 user
}
```
3. `sudo vi /usr/local/nagios/etc/objects/commands.cfg`
```conf=
define command {
command_name check_http_cacti
command_line $USER1$/check_http -H 198.19.249.194 -u /cacti/ -e 200 ; 利用 check_http library 去檢查是否 http://198.19.249.194/cacti/ 的 status code 等於 200,才是正常的狀態
}
```
4. `sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg`
- 確認沒有 Error
6. `sudo systemctl restart nagios`
7. 存取 http://你的-nagios-server-ip/nagios ,並點選左邊選單的 service 檢查,即可看到剛剛新增的監控服務
- 
## Prometheus
### 架構
- 
- <a href='https://github.com/prometheus/prometheus'>source</a>
- 為 pull/push 架構,主要比較常使用 pull 的模式
- pull : 在欲監控的系統上開放一個 endpoint,用於讓 Prometheus Server 主動蒐集資料
- push : 由欲監控的系統主動送出已經蒐集好的資料給 Prometheus Server
1. 藉由不同種類的 exporter 持續蒐集 metrics
- metrics:一個測量軟體系統的效能的標準,通常是數值
3. prometheus server 將這些 metrics 存到它自己的 time series database
4. 使用者利用 promql 可以非常彈性地查詢到對應的資料/圖表
- 在整合多個不同種類的微服務的資料有效率
### promql
- PromQL (Prometheus Query Language)
- Prometheus 提供的查詢資料的語法,可以自己寫一套公式計算想要的監控數值
- 範例
1. 可被使用的 memory 百分比
- `(node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached_bytes)/ node_memory_MemTotal_bytes * 100`
- 
3. 已經使用的 memory 百分比
- `(node_memory_MemTotal_bytes - (node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached_bytes )) / node_memory_MemTotal_bytes * 100`
- 
## Grafana
- <a href='https://grafana.com/'>官網</a>
- 提供查詢、視覺化不同來源的 time series data 的功能
- 可以很容易地就建立各種不同類型的客製化的圖表
- 
- <a href='https://grafana.com/oss/grafana/'>source</a>
## Librenms
- <a href='https://www.librenms.org/'>官網</a>
- 用於監控設備網路流量、系統資訊的框架
### 特色
- 可以使用 Librenms 提供的 application template,快速針對不同應用程式去做監控
- e.g. Apache2, MySQL
- 可以使用 Service 功能,串接 Nagios 的 plugin,提供更多擴充功能
- 可以基於 CDP, FDP, LLDP, OSPF, BGP, SNMP and ARP 去尋找、監控設備
- 支援 Distributed Polling:將查詢設備資料的工作分散到多台 Librenms Server,在需監控的設備的數量較多時可以提升查詢效率,也可以提高可用性避免單點失敗
- 可以作為 Log Server,儲存和分析 syslog
### 使用範例
- traffic
- 
- disk usage
- 
## Zabbix
- <a href='https://www.zabbix.com/'>官網</a>
### 特色
- 比較適合用於監控系統、應用程式
### 架構
- 
1. 透過 zabbix agent/snmp agent 蒐集 metrics
- zabbix agent 相對 snmp agent 有以下特點
1. zabbix agent 支援傳輸加密,而 snmp agent 需使用/支援 snmp v3 其設定也較複雜
2. 某些網路設備不支援 zabbix agent,仍需使用 snmp agent
3. zabbix agent 預設可以更容易取得各種常見的應用程式(e.g. Nginx)的 log、設定檔,而不用太多額外的設定
3. (optional)再將資料傳給 zabbix proxy
4. 最後將資料傳給 zabbix server 儲存和解析 metrics
### 使用範例
- 
## 作業
- <a href='https://hackmd.io/oWEnGceJTtS7I34BcbMHNw'>作業六</a>
## Ref
- <a href='https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-an-snmp-daemon-and-client-on-ubuntu-18-04'>DigitalOcean - how-to-install-and-configure-an-snmp</a>
- <a href='https://www.geeksforgeeks.org/simple-network-management-protocol-snmp/'>GeeksforGeeks - simple-network-management-protocol-snmp</a>
- <a href='https://www.cc.ntu.edu.tw/chinese/epaper/0047/20181220_4707.html'>NTU CC - snmp 介紹</a>
- <a href='https://hackmd.io/@ncnu-opensource/SyPad81KL'>LSA 111 - Monitoring 講義</a>
- <a href='https://datatracker.ietf.org/doc/html/rfc1155'>RFC 1155</a>
- <a href='https://www.cacti.net/info/cacti'>cacti</a>
- <a href='https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/toc.html'>nagios v4 doc</a>
- <a href='https://medium.com/starbugs/do-you-understand-htop-ffb72b3d5629'>htop 介紹</a>
- <a href='https://linux-kernel-labs.github.io/refs/heads/master/labs/block_device_drivers.html'>linux-kernel-lab - block devices</a>
- <a href='https://github.com/prometheus/prometheus'>prometheus</a>
- <a href='https://www.alvestrand.no/objectid/1.3.6.1.2.html'>1.3.6.1.2 - IETF Management</a>
- <a href='https://www.tsnien.idv.tw/Internet_WebBook/chap16/16-1%20SNMP%20%E5%8D%94%E5%AE%9A%E7%B0%A1%E4%BB%8B.html'>翻轉工作室 - SNMP</a>
- <a href='https://www.ibm.com/docs/en/zos/2.4.0?topic=11-snmp-agents-subagents'>IBM - SNMP agents and subagents</a>
- <a href='https://github.com/ahmednawazkhan/guides/blob/master/snmp/creating-custom-mib.md'>creating-custom-mib</a>