前言
目前我的想法是
- 先找 snmp packages 並嘗試透過 cross-compiler build snmp packages
- 使用 pc build 一版 x86 版本的 snmpd
- 學習 PC 如何透過 snmp client 來驗證 snmpd
本文目前只有詳細介紹第1點
snmp for arm-linux platform
準備工作
- 下載 net-snmp 5.8 source code package
- 透過 cross-compiler build snmpd binary
- 學習 snmpd.conf 的設定
- 移植到 arm-linux 進行測試
- 遇到問題與除錯方法
- 使用 snmp client 來驗證正確
1. 下載 net-snmp 5.8 source code package
- 到下載頁面:http://www.net-snmp.org/download.html
- 目前版本到達
v5.8
,也可下載 Long Term Support (LTS) 版本v5.7.3
- 我們這次使用
v5.8
作為目標版本
2. 透過 cross-compiler build snmpd binary
目前我參考的 porting 網站有許多,覺得這個最好
configure 的 option
- 如下表所示 (其他的要去 manpage 查詢)
options | details |
---|---|
--host=arm-linux |
運行平台 |
--target=arm-linux |
目標平台 |
--build=i686-linux |
編譯平台 |
--with-cc=arm-linux-gcc |
cross-compiler tool |
--with-ar=arm-linux-ar |
打包工具 |
--prefix=/usr/local/net-snmp |
安裝目錄 |
--disable-shared |
不編譯共享庫 |
--disable-scripts |
不要安裝 mib2c 等版本 |
--with-endianness=little |
using little endian |
--enable-mini-agent |
最小化構建 agent |
--disable-deprecated |
不編譯放棄使用的功能 |
--without-logfile |
指定 snmpd 不輸出 log 文件 (可以使用 --with-logfile 指定默認 log 檔案的位置) |
--disable-minimalist |
刪除所有非基本的代碼功能 |
--enable-debugging |
打開除錯訊息 |
--disable-testing-code |
不使用測試代碼 (某些代碼不被使用) |
--with-openssl=/opt/hardhat |
openssl library 路徑 (支援加密) |
--disable-ipv6 |
不使用 ipv6 |
--disable-manuals |
不安裝 manpage 說明頁 |
--disable-ucd-snmp-compatibility |
不需要相容 ucd-snmp |
--disable-snmptrapd-subagent |
不需要支援 snmptrapd 的子代理 |
--disable-embedded-perl |
在 snmp agent 和 snmptrapd 禁用 embedded perl 預設啟用 |
--disable-applications |
是否關閉 snmpget 等功能,根據自己的需求選擇 |
--with-default-snmp-version="3" |
指定預設 snmp protocal version |
--enable-as-needed |
僅鏈接需要的library |
- 根據以上,我組態設定為
1
./configure --prefix=/var/net-snmp --build=i686-linux --host=arm-linux --with-default-snmp-version="2" --with-sys-contact="timmyliu@weintek.com" --with-sys-location="location" --with-logfile="/var/log/snmpd.log" --with-copy-persistent-files="no" --without-opaque-special-types --without-rpm --without-perl-modules --disable-manuals --disable-ipv6 --disable-ucd-snmp-compatibility --disable-embedded-perl --disable-snmptrapd-subagent --disable-scripts -enable-mfd-rewrites --enable-shared=no --enable-mini-agent --with-cc=arm-none-linux-gnueabi-gcc --with-ar=arm-none-linux-gnueabi-ar
看不清所有設定的話,可以寫成:1
2
3
4
5
6
7
8
9
10
11./configure --prefix=/var/net-snmp \
--build=i686-linux --host=arm-linux \
--with-default-snmp-version="2" --with-sys-contact="timmyliu@weintek.com" \
--with-sys-location="location" --with-logfile="/var/log/snmpd.log" \
--with-copy-persistent-files="no" --without-opaque-special-types \
--without-rpm --without-perl-modules \
--disable-manuals --disable-ipv6 --disable-ucd-snmp-compatibility \
--disable-embedded-perl --disable-snmptrapd-subagent --disable-scripts \
-enable-mfd-rewrites --enable-shared=no --enable-mini-agent \
--with-cc=arm-none-linux-gnueabi-gcc \
--with-ar=arm-none-linux-gnueabi-ar
- configure summary
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20---------------------------------------------------------
Net-SNMP configuration summary:
---------------------------------------------------------
SNMP Versions Supported: 1 2c 3
Building for: linux
Net-SNMP Version: 5.8
Network transport support: Callback Unix Alias TCP UDP IPv4Base SocketBase TCPBase UDPIPv4Base UDPBase
SNMPv3 Security Modules: usm
Agent MIB code: default_modules => snmpv3mibs mibII/snmp_mib mibII/system_mib mibII/sysORTable mibII/vacm_vars mibII/vacm_conf
MYSQL Trap Logging: unavailable
Embedded Perl support: disabled
SNMP Perl modules: disabled
SNMP Python modules: disabled
Crypto support from: internal
Authentication support: MD5 SHA1
Encryption support: DES AES
Local DNSSEC validation: disabled
---------------------------------------------------------
之後就執行 make
- 如果之前有 build 過的話就執行
make clean && make
build 成功的話會看到下面兩行
1
2chmod a+x net-snmp-config
touch net-snmp-config-x透過
ll -h agent/snmpd
看一下 size1
2weintek-timmy@weintek-timmy:~/Timmy/GitHub/net-snmp-5.8$ ll -h agent/snmpd
-rwxrwxr-x 1 weintek-timmy weintek-timmy 2.3M 12月 4 15:58 agent/snmpd*
使用strip進行程式瘦身
看你是 soft-float 還是 hard-float compiler,以這個例子我們是使用 arm-none-linux-gnueabi-
來編譯,那我們就使用 arm-none-linux-gnueabi-strip
來瘦身1
2
3
4weintek-timmy/Timmy/GitHub/net-snmp-5.8$ arm-none-linux-gnueabi-strip agent/snmpd -timmy:~
weintek-timmy/Timmy/GitHub/net-snmp-5.8$ ll -h agent/snmpd -timmy:~
-rwxrwxr-x 1 weintek-timmy weintek-timmy 696K 12月 4 16:04 agent/snmpd*
weintek-timmy/Timmy/GitHub/net-snmp-5.8$ -timmy:~
從 2.3M 瘦身成 696K
3. 學習 snmpd.conf 的設定
具體配置方式可以參考這裡的第五部份,然而我會從那個網站中將設定的方式紀錄於此
複製 EXAMPLE.conf 到原本的資料夾中,用此製作一份新的 config file
1
cp EXAMPLE.conf snmpd.conf
開啟外網 access 權限
原本預設的 snmpd.conf 通常都是使用 localhost (127.0.0.1),如果要使用外網訪問的話,就要修改1
2
3
4
5
6# AGENT BEHAVIOUR
#
# Listen for connections from the local system only
# agentAddress udp:127.0.0.1:161
# Listen for connections on all interfaces (both IPv4 *and* IPv6)
agentAddress udp:161,udp6:[::1]:161
如果把 #agentAddress upd:127.0.0.1:161
解開的話就會變成使用 localhost listen
- 設定共同體名稱 (community)
我們使用 EXAMPLE.conf 中的 com2sec/group/view/access 的說明,大約是預設文件的第 65 行
首先我們定義一個首共同體名稱(community),這裡我們使用 public,以及可以訪問這個 public 的用戶名(sec name),這裡是 notConfigUser。public 相當於用戶 notConfigUser 的密碼
在 snmpd.conf 檔案中加入以下 (可使用 “#” 來加入註解)1
2# sec.name source community
com2sec notConfigUser default public
- 定義 gpoup 名稱 (組名)
之後我們定義一個組名 (groupName) 這裡是 notConfigGroup,以及 group 的安全級別(也就是 snmp version) 並把 notConfigUser 這個用戶加到這個 group 中。
在 snmpd.conf 檔案中加入以下1
2
3# groupName securityModel securityName
group notConfigGroup v1 notConfigUser
group notConfigGroup v2c notConfigUser
- 定義可試圖 (view) 名稱
我們加入 all 這個名稱,可視範圍為 .1,在 snmpd.conf 檔案中加入以下1
2# name incl/excl subtree mask(optional)
view all included .1
並且註解1
2view systemonly included .1.3.6.1.2.1.1
view systemonly included .1.3.6.1.2.1.25.1
- 定義可試圖操作
最後定義 notConfigUser 這個組在 all 這個可視圖中內可做的操作,我們在此定義了 notConfigGroup 內的成員可以對 .1 這個可視範圍做 「唯讀」 操作。1
2# group context sec.model sec.level prefix read write notif
access notConfigGroup "" any noauth exact all none none
接下來設置系統資訊
設置區域
1
sysLocation "New Taipei City, Taiwan"
設置聯絡人
1
sysContact Me <me@example.org>
設置監控主機
1
2設置讀寫帳戶
conf=
1
2
3
4
5
6### 4. 移植到 arm-linux 進行測試
* 先從 agent 目錄下 copy 出 snmpd 執行檔
* 在 embedded-linux 目標機器上創建 snmpd.conf 的設定文件 (我習慣在PC上面先建置好再透過 `scp` 拷貝到裝置內)
```sh=
scp agent/snmpd snmp.conf root@192.168.2.98:/root/之後執行
./snmpd -c snmpd.conf –f –Le –d
(大部份都要除錯,很少第一次成功)
5. 除錯與問題處理
遇到 cannot file module 與 snmpd.conf: unknown token 的問題
執行時遇到問題1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29[root@cMT-15C2 /root]# ./snmpd -c snmpd.conf -f -Le -d
Created directory: /var/net-snmp
Created directory: /var/net-snmp/mib_indexes
MIB search path: /root/.snmp/mibs:/var/net-snmp/share/snmp/mibs
Cannot find module (SNMPv2-MIB): At line 0 in (none)
Cannot find module (IF-MIB): At line 0 in (none)
Cannot find module (IP-MIB): At line 0 in (none)
Cannot find module (TCP-MIB): At line 0 in (none)
Cannot find module (UDP-MIB): At line 0 in (none)
Cannot find module (SNMP-VIEW-BASED-ACM-MIB): At line 0 in (none)
Cannot find module (SNMP-COMMUNITY-MIB): At line 0 in (none)
Cannot find module (SNMP-FRAMEWORK-MIB): At line 0 in (none)
Cannot find module (SNMP-MPD-MIB): At line 0 in (none)
Cannot find module (SNMP-USER-BASED-SM-MIB): At line 0 in (none)
snmpd.conf: line 96: Warning: Unknown token: proc.
snmpd.conf: line 98: Warning: Unknown token: proc.
snmpd.conf: line 100: Warning: Unknown token: proc.
snmpd.conf: line 110: Warning: Unknown token: disk.
snmpd.conf: line 111: Warning: Unknown token: disk.
snmpd.conf: line 112: Warning: Unknown token: includeAllDisks.
snmpd.conf: line 122: Warning: Unknown token: load.
snmpd.conf: line 149: Warning: Unknown token: iquerySecName.
snmpd.conf: line 152: Warning: Unknown token: defaultMonitors.
snmpd.conf: line 154: Warning: Unknown token: linkUpDownNotifications.
snmpd.conf: line 166: Warning: Unknown token: extend.
snmpd.conf: line 167: Warning: Unknown token: extend-sh.
snmpd.conf: line 199: Warning: Unknown token: master.
Error opening specified endpoint "udp:161"
Server Exiting with code 1
這個問題分兩部份
- Cannot find module…
- snmpd.conf: line …: Warning: Unknown token: …
處理 snmpd.conf: line ...: Warning: Unknown token: ...
的問題
如果仔細去看他的 warning 的話,其實很簡單,他就是認不出這些設定檔,原因是因為這些設定可能因為執行 ./configure 的時候 disable 掉了,反正不設他就會使用預設的參數,所以我們就全部註解掉
- 將 proc 的設定註解
- 將 disk / includeAllDisks 註解
- 將 load 註解
- 將 iquerySecName / defaultMonitors / linkUpDownNotifications 註解
- 將 extend / extend-sh / master 註解
- 將 trapsink 註解
傳到裝置上再執行一次
1 | [root@cMT-15C2 /root]# ./snmpd -c snmpd.conf -f -Le -d |
處理 cannot find module 問題
問題點從 message 就大概可以知道 MIB module 需要匯入,而路徑是 /var/net-snmp/share/snmp/mibs
所以我們就先建立新的資料夾1
mkdir -p /var/net-snmp/share/snmp/mibs
然後進入 PC source code 的 mibs 將裏面的 module 撈出來給裝置1
2
3cd ~net-snmp-5.8/mibs
scp * root@192.168.2.98:/var/net-snmp/share/snmp/mibs/
再執行一次1
2
3[root@cMT-15C2 /root]# ./snmpd -c snmpd.conf -f -Le -d
Error opening specified endpoint "udp:161"
Server Exiting with code 1
還有最後一個問題
處理 Error opening specified endpoint “udp:161”
因為我們之前使用 ./configure
的時候加入了一個參數 --disable-ipv6
,所以我們必須將 udp的 ipv6設定移掉
修改 snmpd.conf
,將 udp6:[::1]:161
移掉
1 | # orig: agentAddress udp:161,udp6:[::1]:161 |
還有其他可能性,但大部份都是 conf 檔要放對位置
6. 使用 snmp client 來驗證正確
若使用指令 ./snmpd -c snmpd.conf -f -Le -d
啟動之後出現 NET-SNMP version 5.8
表示已經運行,這時候我們使用 snmpwalk
試試看
PC 端:
1
2snmpget -v 2c -c public 192.168.2.98 sysDescr.0
SNMPv2-MIB::sysDescr.0 = STRING: Linux cMT-15C2 4.1.15+ #629 PREEMPT Fri Aug 10 18:14:50 CST 2018 armv7l
裝置端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Received 43 byte packet from UDP: [192.168.1.21]:59770->[192.168.2.98]:161
0000: 30 29 02 01 01 04 06 70 75 62 6C 69 63 A0 1C 02 0).....public...
0016: 04 12 1B C8 08 02 01 00 02 01 00 30 0E 30 0C 06 ...........0.0..
0032: 08 2B 06 01 02 01 01 01 00 05 00 .+.........
Sending 114 bytes to UDP: [192.168.1.21]:59770->[192.168.2.98]:161
0000: 30 70 02 01 01 04 06 70 75 62 6C 69 63 A2 63 02 0p.....public.c.
0016: 04 12 1B C8 08 02 01 00 02 01 00 30 55 30 53 06 ...........0U0S.
0032: 08 2B 06 01 02 01 01 01 00 04 47 4C 69 6E 75 78 .+........GLinux
0048: 20 63 4D 54 2D 31 35 43 32 20 34 2E 31 2E 31 35 cMT-15C2 4.1.15
0064: 2B 20 23 36 32 39 20 50 52 45 45 4D 50 54 20 46 + #629 PREEMPT F
0080: 72 69 20 41 75 67 20 31 30 20 31 38 3A 31 34 3A ri Aug 10 18:14:
0096: 35 30 20 43 53 54 20 32 30 31 38 20 61 72 6D 76 50 CST 2018 armv
0112: 37 6C
我們可以再寫一個 snmpwalk 來抓取系統狀態1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24weintek-timmy1 192.168.2.98 -c public system -timmy:~$ snmpwalk -v
SNMPv2-MIB::sysDescr.0 = STRING: Linux cMT-15C2 4.1.15+ #629 PREEMPT Fri Aug 10 18:14:50 CST 2018 armv7l
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (55157) 0:09:11.57
SNMPv2-MIB::sysContact.0 = STRING: Me <me .org>
SNMPv2-MIB::sysName.0 = STRING: cMT-15C2
SNMPv2-MIB::sysLocation.0 = STRING: \"New Taipei City, Taiwan\"
SNMPv2-MIB::sysServices.0 = INTEGER: 72
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORID.1 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.2 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORID.3 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.5 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORDescr.1 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.2 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.3 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.5 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORUpTime.1 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.2 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (0) 0:00:00.00
SNMP OID 使用
我們使用 snmpwalk
來取得目前 mib 可以使用的 module
只要輸入 snmpwalk -v 2c -c public 192.168.2.98
就可以 printf 出可以獲得的訊息
Linux 常用的 OID
Load
function | OID |
---|---|
1 minute Load | .1.3.6.1.4.1.2021.10.1.3.1 |
5 minute Load | .1.3.6.1.4.1.2021.10.1.3.2 |
15 minute Load | .1.3.6.1.4.1.2021.10.1.3.3 |
CPU
function | OID |
---|---|
percentage of user CPU time | .1.3.6.1.4.1.2021.11.9.0 |
raw user cpu time | .1.3.6.1.4.1.2021.11.50.0 |
percentages of system CPU time | .1.3.6.1.4.1.2021.11.10.0 |
raw system cpu time | .1.3.6.1.4.1.2021.11.52.0 |
percentages of idle CPU time | .1.3.6.1.4.1.2021.11.11.0 |
raw idle cpu time | .1.3.6.1.4.1.2021.11.53.0 |
raw nice cpu time | .1.3.6.1.4.1.2021.11.51.0 |
內部儲存資訊
function | OID |
---|---|
Total Swap Size | .1.3.6.1.4.1.2021.4.3.0 |
Available Swap Space | .1.3.6.1.4.1.2021.4.4.0 |
Total RAM in machine | .1.3.6.1.4.1.2021.4.5.0 |
Total RAM used | .1.3.6.1.4.1.2021.4.6.0 |
Total RAM Free | .1.3.6.1.4.1.2021.4.11.0 |
Total RAM Shared | .1.3.6.1.4.1.2021.4.13.0 |
Total RAM Buffered | .1.3.6.1.4.1.2021.4.14.0 |
Total Cached Memory | .1.3.6.1.4.1.2021.4.15.0 |
Disk 相關
The snmpd.conf needs to be edited. Add the following (assuming a machine with a single ‘/’ partition):
disk / 100000 (or)
includeAllDisks 10% for all partitions and disks
The OIDs are as follows
function | OID |
---|---|
Path where the disk is mounted | .1.3.6.1.4.1.2021.9.1.2.1 |
Path of the device for the partition | .1.3.6.1.4.1.2021.9.1.3.1 |
Total size of the disk/partion (kBytes) | .1.3.6.1.4.1.2021.9.1.6.1 |
Available space on the disk | .1.3.6.1.4.1.2021.9.1.7.1 |
Used space on the disk | .1.3.6.1.4.1.2021.9.1.8.1 |
Percentage of space used on disk | .1.3.6.1.4.1.2021.9.1.9.1 |
Percentage of inodes used on disk | .1.3.6.1.4.1.2021.9.1.10.1 |
系統運行時間
function | OID |
---|---|
System Uptime | .1.3.6.1.2.1.1.3.0 |
PS: linux 系统也可直接用 uptime 命令獲得系統資訊
網路設備相關
function | OID | 功能說明 |
---|---|---|
ifIndex | 1.3.6.1.2.1.2.2.1.1.0 |
端口索引編號 |
ifDescr | 1.3.6.1.2.1.2.2.1.2.0 |
端口描述 |
ifType | 1.3.6.1.2.1.2.2.1.3.0 |
端口類型 |
ifMtu | 1.3.6.1.2.1.2.2.1.4.0 |
最大傳輸封包字節數 |
ifSpeed | 1.3.6.1.2.1.2.2.1.5.0 |
端口速度 |
ifPhysAddress | 1.3.6.1.2.1.2.2.1.6.0 |
MAC address |
ifOperStatus | 1.3.6.1.2.1.2.2.1.8.0 |
操作狀態 |
ifLastChange | 1.3.6.1.2.1.2.2.1.9.0 |
上次狀態更新時間 |
ifInOctets | 1.3.6.1.2.1.2.2.1.10.0 |
輸入字節數 |
ifInUcastPkts | 1.3.6.1.2.1.2.2.1.11.0 |
輸入非廣播封包數 |
ifInNUcastPkts | 1.3.6.1.2.1.2.2.1.12.0 |
輸入廣播封包數 |
ifInDiscards | 1.3.6.1.2.1.2.2.1.13.0 |
輸入封包丟棄數 |
ifInErrors | 1.3.6.1.2.1.2.2.1.14.0 |
輸入封包錯誤數 |
ifInUnknownProtos | 1.3.6.1.2.1.2.2.1.15.0 |
輸入未知協議封包數 |
ifOutOctets | 1.3.6.1.2.1.2.2.1.16.0 |
輸出字節數 |
ifOutUcastPkts | 1.3.6.1.2.1.2.2.1.17.0 |
輸出非廣播封包數 |
ifOutNUcastPkts | 1.3.6.1.2.1.2.2.1.18.0 |
輸出廣播封包數 |
ifOutDiscards | 1.3.6.1.2.1.2.2.1.19.0 |
輸出封包丟棄數 |
ifOutErrors | 1.3.6.1.2.1.2.2.1.20.0 |
輸出封包錯誤數 |
ifOutQLen | 1.3.6.1.2.1.2.2.1.21.0 |
output queue size |
流量輸出是用計數器,數目會改變,單位是 byte, 32 位
如果流量大過出現土寄不正確的情形,就需要在編譯時加上 enable-mfd-rewrites
參數,來支援 64 位的計數器
reference
- https://www.cnblogs.com/quliuliu2013/p/7520241.html
- http://www.cnblogs.com/oloroso/p/4595123.html
- http://jyhshin.pixnet.net/blog/post/44844463-net-snmp-porting
- https://blog.csdn.net/gujintong1110/article/details/51791097
- https://my.oschina.net/yisenn/blog/14679
- https://my.oschina.net/yisenn/blog/14626