Skip to content

Ubuntu系统下的snmp客户端以及服务端安装以及配置

基本介绍

  • snmp(Simple Network Management Protocol,简单网络管理协议),该协议的实现以及应用是采用C/S模型的特殊模式:代理/管理站模型。

  • 代理是指提供snmp协议服务的网络设备,可以提供设备网络状态,配置信息,并且可以向管理站提供网络事件告警,响应来自网络的各种请求信息

  • 管理站是类似于客户端角色,会向不同的代理请求获取数据返回

  • 协议通过UDP端口161(代理端端口)和162(管理站trap进程开放端口)进行通信

  • 代理会提供大量的对象标识符(OID-Object Identifiers),一个OID是一个唯一的键值对,每个OID都对应了不同的系统信息

  • OID都非常长,使得人们难以记住,人们就设计了一种将数字OID翻译为人们可读的格式,翻译映射保存在“管理信息基础"(Management Infomation Base,MIB)的无格式文本文件里

  • snmp有两种数据交互方式,请求和trap,请求是指管理站向代理设备发送GET请求,获取相应的网络信息,是主动形式的网络监控,trap是指配置代理让其监测到某个特殊事件的时候主动向管理站发送告警

  • 有三个常用版本:SNMPv1SNMPv2cSNMPv3,其中SNMPv1SNMPv2c被广泛应用,但是由于这些协议的不安全特性,通常只使用只读访问,SNMPv3是具有安全性的通信协议,v1v2c采用相同的团体字认证参数(默认该参数是public,生产环境下需要进行修改),v3版本采用基于用户账号密码的方式进行认证

软件依赖

  • snmpdsnmp服务端软件,提供开放端口用于提供给客户端请求的返回数据(系统状态信息等)

  • snmpsnmp客户端软件,用于向服务端发送请求获取对方的系统状态信息

  • snmp-mibs-downloader:用来下载更新本地mib库的软件

执行命令如下,改行命令之后会安装上一系列snmp相关的工具,如snmpwalk, net-snmp-create-v3-user,snmptranslate

shell
$ sudo apt install snmp snmpd snmp-mibs-downloader libsnmp-dev
$ sudo apt install snmp snmpd snmp-mibs-downloader libsnmp-dev

基本配置与操作

查看snmpd状态

shell
$ sudo systemctl status snmpd
$ sudo systemctl status snmpd

配置管理MIB

代理端更新mib库,更新到代理库的信息会可以查看/var/lib/snmp/mibs或者/var/lib/mibs

shell
$ sudo download-mibs
$ sudo download-mibs

开启MIB数据库的OID和可读字符串的转换,把最后一行mibs注释

$ sudo vim /etc/snmp/snmp.conf
mibs: 
修改为
# mibs:
$ sudo vim /etc/snmp/snmp.conf
mibs: 
修改为
# mibs:

查看MIB库的OID映射关系

shell
$ snmptranslate -Tz                
"org"			"1.3"
"dod"			"1.3.6"
"internet"			"1.3.6.1"
"directory"			"1.3.6.1.1"
"mgmt"			"1.3.6.1.2"
"mib-2"			"1.3.6.1.2.1"
"system"			"1.3.6.1.2.1.1"
"sysDescr"			"1.3.6.1.2.1.1.1"
"sysObjectID"			"1.3.6.1.2.1.1.2"
"sysUpTime"			"1.3.6.1.2.1.1.3"
"sysUpTimeInstance"			"1.3.6.1.
$ snmptranslate -Tz                
"org"			"1.3"
"dod"			"1.3.6"
"internet"			"1.3.6.1"
"directory"			"1.3.6.1.1"
"mgmt"			"1.3.6.1.2"
"mib-2"			"1.3.6.1.2.1"
"system"			"1.3.6.1.2.1.1"
"sysDescr"			"1.3.6.1.2.1.1.1"
"sysObjectID"			"1.3.6.1.2.1.1.2"
"sysUpTime"			"1.3.6.1.2.1.1.3"
"sysUpTimeInstance"			"1.3.6.1.

当执行snmp采集程序的时候程序会查询固定位置的MIB文件,如果存在,则翻译,所以如果有自定义的MIB文件,直接放入到指定位置即可获取到翻译后的查询,默认MIB文件的位置如下

shell
$ snmpwalk --help
  -M DIR[:...]          look in given list of directories for MIBs
    (default: $HOME/.snmp/mibs:/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf)
$ snmpwalk --help
  -M DIR[:...]          look in given list of directories for MIBs
    (default: $HOME/.snmp/mibs:/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf)

测试基本的信息获取

snmp1snmpv2c

snmpwalk是安装snmp服务时候附加安装的工具,可用于测试snmp服务的访问

-v参数是用于指定版本

-c参数指定团体字认证参数,由于默认是public,所以可以直接使用该参数

localhost是指定代理服务器的地址,由于现在代理和管理站安装在同一台机器,所以使用localhost作为代理的地址

.1.3.6.1.2.1.1.1表示的是OID的参数信息,该参数表示系统主机信息

下面两条命令的输出是一样的

shell
$ snmpwalk -v 1 -c public localhost .1.3.6.1.2.1.1.1
$ snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.1.1
SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64
$ snmpwalk -v 1 -c public localhost .1.3.6.1.2.1.1.1
$ snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.1.1
SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64

如果想获取更多信息,需要把OID的参数改短一些

比如改成.1.3.6.1.2,获取到的数据就更多了,snmp获取信息的时候是采用前缀匹配的形式,当指定的OID越短,匹配的信息也就越多

shell
$ snmpwalk -v 1 -c public localhost .1.3.6.1.2      
SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (234221) 0:39:02.21
SNMPv2-MIB::sysContact.0 = STRING: Me <me@example.org>
SNMPv2-MIB::sysName.0 = STRING: gong
SNMPv2-MIB::sysLocation.0 = STRING: Sitting on the Dock of the Bay
SNMPv2-MIB::sysServices.0 = INTEGER: 72
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORID.1 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.2 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORID.6 = OID: TCP-MIB::tcpMIB
SNMPv2-MIB::sysORID.7 = OID: UDP-MIB::udpMIB
SNMPv2-MIB::sysORID.8 = OID: IP-MIB::ip
SNMPv2-MIB::sysORID.9 = OID: SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance
SNMPv2-MIB::sysORID.10 = OID: NOTIFICATION-LOG-MIB::notificationLogMIB
SNMPv2-MIB::sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
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
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.9 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.10 = Timeticks: (0) 0:00:00.00
HOST-RESOURCES-MIB::hrSystemUptime.0 = Timeticks: (451727) 1:15:17.27
HOST-RESOURCES-MIB::hrSystemDate.0 = STRING: 2022-9-25,11:0:56.0,+8:0
HOST-RESOURCES-MIB::hrSystemInitialLoadDevice.0 = INTEGER: 393216
HOST-RESOURCES-MIB::hrSystemInitialLoadParameters.0 = STRING: "BOOT_IMAGE=/vmlinuz-5.15.0-48-generic root=UUID=ef5920a3-64eb-4d3f-b794-156d2d97cef9 ro quiet splash vt.handoff=7
"
HOST-RESOURCES-MIB::hrSystemNumUsers.0 = Gauge32: 2
HOST-RESOURCES-MIB::hrSystemProcesses.0 = Gauge32: 461
HOST-RESOURCES-MIB::hrSystemMaxProcesses.0 = INTEGER: 0
End of MIB
$ snmpwalk -v 1 -c public localhost .1.3.6.1.2      
SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (234221) 0:39:02.21
SNMPv2-MIB::sysContact.0 = STRING: Me <me@example.org>
SNMPv2-MIB::sysName.0 = STRING: gong
SNMPv2-MIB::sysLocation.0 = STRING: Sitting on the Dock of the Bay
SNMPv2-MIB::sysServices.0 = INTEGER: 72
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORID.1 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.2 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORID.6 = OID: TCP-MIB::tcpMIB
SNMPv2-MIB::sysORID.7 = OID: UDP-MIB::udpMIB
SNMPv2-MIB::sysORID.8 = OID: IP-MIB::ip
SNMPv2-MIB::sysORID.9 = OID: SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance
SNMPv2-MIB::sysORID.10 = OID: NOTIFICATION-LOG-MIB::notificationLogMIB
SNMPv2-MIB::sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
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
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.9 = Timeticks: (0) 0:00:00.00
SNMPv2-MIB::sysORUpTime.10 = Timeticks: (0) 0:00:00.00
HOST-RESOURCES-MIB::hrSystemUptime.0 = Timeticks: (451727) 1:15:17.27
HOST-RESOURCES-MIB::hrSystemDate.0 = STRING: 2022-9-25,11:0:56.0,+8:0
HOST-RESOURCES-MIB::hrSystemInitialLoadDevice.0 = INTEGER: 393216
HOST-RESOURCES-MIB::hrSystemInitialLoadParameters.0 = STRING: "BOOT_IMAGE=/vmlinuz-5.15.0-48-generic root=UUID=ef5920a3-64eb-4d3f-b794-156d2d97cef9 ro quiet splash vt.handoff=7
"
HOST-RESOURCES-MIB::hrSystemNumUsers.0 = Gauge32: 2
HOST-RESOURCES-MIB::hrSystemProcesses.0 = Gauge32: 461
HOST-RESOURCES-MIB::hrSystemMaxProcesses.0 = INTEGER: 0
End of MIB

返回数据详解

主要格式是SNMPv2-MIB::{OID[可读字符串]}.{细分点,从0开始} = {数据格式}: {数据信息}

SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64
SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64

修改OID参数,注意前缀匹配导致的获取数据返回

shell
$ snmpwalk -v 3 -u gong -a SHA -A authtest -x AES -X privtest -l authPriv localhost sysORDescr.10
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.

 
$ snmpwalk -v 3 -u gong -a SHA -A authtest -x AES -X privtest -l authPriv localhost sysORDescr   
SNMPv2-MIB::sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
$ snmpwalk -v 3 -u gong -a SHA -A authtest -x AES -X privtest -l authPriv localhost sysORDescr.10
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.

 
$ snmpwalk -v 3 -u gong -a SHA -A authtest -x AES -X privtest -l authPriv localhost sysORDescr   
SNMPv2-MIB::sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.

snmp3

由于v3版本采用基于用户的认证方式,所以需要先创建一个测试用户用于认证

创建用户的过程当中需要停止snmpd服务

shell
$ sudo systemctl stop snmpd
$ sudo systemctl stop snmpd

创建用户的命令格式如下,net-snmp-create-v3-user是安装软件时libsnmp-dev包提供的

shell
$ net-snmp-create-v3-user [-ro] [-A authpass] [-X privpass] [-a MD5|SHA|SHA-512|SHA-384|SHA-256|SHA-224] [-x DES|AES] [username]
$ net-snmp-create-v3-user [-ro] [-A authpass] [-X privpass] [-a MD5|SHA|SHA-512|SHA-384|SHA-256|SHA-224] [-x DES|AES] [username]

-ro参数表示该用户只读

-A指定用户密码短语,至少为8个字符,用于生成身份验证密钥

-X至少为8字符,用于生成加密密钥

-a指定用户身份验证类型,该指定会使用不同的算法进行运算

-x指定加密验证类型

创建一个用户如下, 采用认证参数authtest,认证加密算法采用SHA,加密参数privtest,加密算法采用AES,指定用户名称gong

shell
$ sudo net-snmp-create-v3-user -ro -A authtest -a SHA -X privtest -x AES gong
adding the following line to /var/lib/snmp/snmpd.conf:
   createUser gong SHA "authtest" AES "privtest"
adding the following line to /usr/share/snmp/snmpd.conf:
   rouser gong
$ sudo net-snmp-create-v3-user -ro -A authtest -a SHA -X privtest -x AES gong
adding the following line to /var/lib/snmp/snmpd.conf:
   createUser gong SHA "authtest" AES "privtest"
adding the following line to /usr/share/snmp/snmpd.conf:
   rouser gong

依据提示的信息去查看对应修改的文件

shell
$ cat /var/lib/snmp/snmpd.conf
#发现最后一行是刚刚填写的认证信息
...
createUser gong SHA "authtest" AES "privtest"
$ cat /var/lib/snmp/snmpd.conf
#发现最后一行是刚刚填写的认证信息
...
createUser gong SHA "authtest" AES "privtest"
shell
$ cat /usr/share/snmp/snmpd.conf
# 最后一行是如下
rouser gong
$ cat /usr/share/snmp/snmpd.conf
# 最后一行是如下
rouser gong

重启服务并且进行验证

参数中指定版本,用户名称,认证算法SHA,认证参数authtest,加密算法AES,加密参数privtest

-l指定安全级别,可选参数有noAuthNoPriv,authNoPriv,authPriv,由于创建的用户同时指定了认证和加密,所以现在该参数填写authPriv

由于MIB库的存在,OID参数也可以传递可读字符串

shell
$ sudo systemctl restart snmpd
$ snmpwalk -v 3 -u gong -a SHA -A authtest -x AES -X privtest -l authPriv localhost sysDescr
$ sudo systemctl restart snmpd
$ snmpwalk -v 3 -u gong -a SHA -A authtest -x AES -X privtest -l authPriv localhost sysDescr

访问信息范围控制

有些时候我们需要获取一些信息,但是执行命令的时候发现获取不到,但是知道应该是有这个信息的

比如现在需要获取网卡信息

执行命令如下,网卡信息对应的OID.1.3.6.1.2.1.31.1.1.1.1或者ifName

shell
$ snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.31.1.1.1.1
IF-MIB::ifName = No more variables left in this MIB View (It is past the end of the MIB tree)
$ snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.31.1.1.1.1
IF-MIB::ifName = No more variables left in this MIB View (It is past the end of the MIB tree)

主要是配置文件当中限制了代理可以返回的信息,修改/etc/snmp/snmpd.conf

#找到下面两行配置
view   systemonly  included   .1.3.6.1.2.1.1
view   systemonly  included   .1.3.6.1.2.1.25.1

# 添加一行,不要开放太多信息,需要实际按需开放
view   systemonly  included   .1.3.6.1.2.1.31.1.1.1.1

# 或者图省事也可以添加一行,这样就开放了所以信息了,生产环境需要慎重
view   systemonly  included   .1
#找到下面两行配置
view   systemonly  included   .1.3.6.1.2.1.1
view   systemonly  included   .1.3.6.1.2.1.25.1

# 添加一行,不要开放太多信息,需要实际按需开放
view   systemonly  included   .1.3.6.1.2.1.31.1.1.1.1

# 或者图省事也可以添加一行,这样就开放了所以信息了,生产环境需要慎重
view   systemonly  included   .1

重启服务

shell
$ sudo systemctl restart snmpd
$ sudo systemctl restart snmpd

执行命令,查看输出,发现获取数据成功

shell
$ snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.31.1.1.1.1
IF-MIB::ifName.1 = STRING: lo
IF-MIB::ifName.2 = STRING: enp3s0
IF-MIB::ifName.3 = STRING: wlp4s0
$ snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.31.1.1.1.1
IF-MIB::ifName.1 = STRING: lo
IF-MIB::ifName.2 = STRING: enp3s0
IF-MIB::ifName.3 = STRING: wlp4s0

snmp1, snmp2c配置共同体认证参数

修改/etc/snmp/snmpd.conf,其中默认的认证参数是public,这个参数由于是默认的,公开的,不安全,所以需要修改为别的参数

# 修改以下
rocommunity  public default -V systemonly
rocommunity6 public default -V systemonly
# 变成
rocommunity  changed default -V systemonly
rocommunity6 changed default -V systemonly
# 修改以下
rocommunity  public default -V systemonly
rocommunity6 public default -V systemonly
# 变成
rocommunity  changed default -V systemonly
rocommunity6 changed default -V systemonly

重启服务

shell
$ sudo systemctl restart snmpd
$ sudo systemctl restart snmpd

测试使用 public认证参数,发现无响应

shell
$ snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.2021
Timeout: No Response from localhost
$ snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.2021
Timeout: No Response from localhost

测试使用 changed参数,可以正常使用

shell
$ snmpwalk -v 2c -c changed localhost sysDesc
SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64
$ snmpwalk -v 2c -c changed localhost sysDesc
SNMPv2-MIB::sysDescr.0 = STRING: Linux gong 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64

开放服务远程访问

查看端口开放,发现只能本地访问

shell
$ sudo netstat -anp |grep 161
udp        0      0 127.0.0.1:161           0.0.0.0:*                           210652/snmpd        
udp6       0      0 ::1:161                 :::*                                210652/snmpd
$ sudo netstat -anp |grep 161
udp        0      0 127.0.0.1:161           0.0.0.0:*                           210652/snmpd        
udp6       0      0 ::1:161                 :::*                                210652/snmpd

修改/etc/snmp/snmpd.conf

# 修改
agentaddress  127.0.0.1,[::1]
# 变成
agentaddress  0.0.0.0,[::1]
# 修改
agentaddress  127.0.0.1,[::1]
# 变成
agentaddress  0.0.0.0,[::1]

重启服务后查看端口

shell
$ sudo netstat -antup |grep 161
udp        0      0 0.0.0.0:161             0.0.0.0:*           106387/snmpd        
udp6       0      0 ::1:161                 :::*                106387/snmpd
$ sudo netstat -antup |grep 161
udp        0      0 0.0.0.0:161             0.0.0.0:*           106387/snmpd        
udp6       0      0 ::1:161                 :::*                106387/snmpd

MIB常见映射参考

.1.3.6.1.2.1.31.1.1.1.1ifName网卡信息

.1.3.6.1.2.1.2.2.1.10ifInOctets网卡入口流量

.1.3.6.1.2.1.2.2.1.16: ifOutOctets网卡出口流量

.1.3.6.1.2.1.1.1.0: sysDesc系统信息

.1.3.6.1.2.1.25.1.1.0: hrSystemUptime系统运行时间

.1.3.6.1.2.1.25.3.3.1.2: hrProcessorLoad CPU利用率

.1.3.6.1.2.1.25.4.2.1.2: hrSWRunName进程信息

snmptrap相关

snmptrapd是一个snmp trap接收服务程序,会监听162端口,可以配置相应的处理规则

安装

$ sudo apt install snmptrapd
$ sudo apt install snmptrapd

编辑/etc/snmp/snmptrapd.conf增加一行

authCommunity log,execute,net public
authCommunity log,execute,net public

表示配置认证参数为public具备权限 记录,可执行,传递

启动snmptrapd

$ sudo systemctl start snmptrapd
$ sudo systemctl start snmptrapd

查看启动状态

$ systemctl status snmptrapd
$ systemctl status snmptrapd

同时也可以关闭后台程序,直接执行命令

$ sudo snmptrapd -LOw -f udp:162 udp6:162
$ sudo snmptrapd -LOw -f udp:162 udp6:162

如果有自定义位置配置文件,可以执行命令如下

$ sudo snmptrapd -C -c custom-snmptrapd.conf -df -Lo
$ sudo snmptrapd -C -c custom-snmptrapd.conf -df -Lo
  • -C : 表示不使用net-snmp默认路径下的配置文件
  • -c : 指定自定义路径snmptrapd.conf文件
  • -d : 显示收到和发送的数据报,通过这个选项可以看到数据报文
  • -f : 默认情况下,snmptrapd是在后台中运行的,加上这个选项,表示在前台运行
  • -L : 指定日志记录在哪里,后面的o表示直接输出到屏幕上,如果是跟着f表示日志记录到指定的文件中

如果启动过程中报错如下,表示snmptrapd程序没有读取到配置文件,需要赋予权限

八月 02 13:55:42 gong snmptrapd[132705]: Warning: no access control information configured.
八月 02 13:55:42 gong snmptrapd[132705]:   (Config search path: /etc/snmp:/usr/share/snmp:/usr/lib/x86_64-linux-gnu/snmp:/var/lib/snmp/.snmp)
八月 02 13:55:42 gong snmptrapd[132705]: This receiver will *NOT* accept any incoming notifications.
八月 02 13:55:42 gong snmptrapd[132705]: Warning: no access control information configured.
八月 02 13:55:42 gong snmptrapd[132705]:   (Config search path: /etc/snmp:/usr/share/snmp:/usr/lib/x86_64-linux-gnu/snmp:/var/lib/snmp/.snmp)
八月 02 13:55:42 gong snmptrapd[132705]: This receiver will *NOT* accept any incoming notifications.

解决

$ sudo chmod a+r /etc/snmp/snmptrapd.conf
$ sudo systemctl restart snmptrapd
$ sudo chmod a+r /etc/snmp/snmptrapd.conf
$ sudo systemctl restart snmptrapd

测试启动,如下指定配置文件位置,把输出定位到终端,修改监听端口为163

$ sudo snmptrapd -C -c /etc/snmp/snmptrapd.conf -f -Lo udp:163 udp6:163
$ sudo snmptrapd -C -c /etc/snmp/snmptrapd.conf -f -Lo udp:163 udp6:163

新启动一个终端,输入命令

$ sudo snmptrap -v 2c -c public 127.0.0.1:163 "aaa" .1.3.6.1.2.1.1.3 .1.3.6.7 s "test from snmptrap tool."
$ sudo snmptrap -v 2c -c public 127.0.0.1:163 "aaa" .1.3.6.1.2.1.1.3 .1.3.6.7 s "test from snmptrap tool."
  • -v 2c表示采用2c版本
  • -c public表示认证参数public
  • 127.0.0.1:163表示trap上报地址是本机的163端口
  • aaa表示snmp的主机名称,该位置参数可以填写一个空字符串
  • .1.3.6.1.2.1.1.3是第一个oid,用来表示企业OID,目前该oid表示sysUpTime
  • .1.3.6.7 s "test from snmptrap tool."表示上报的oid.1.3.6.7,上传类型是字符串,后面的test ....是值

查看snmptrapd终端输出如下

$ sudo snmptrapd -C -c /etc/snmp/snmptrapd.conf -f -Lo udp:163 udp6:163
NET-SNMP version 5.9.1
2023-08-02 14:24:15 localhost [UDP: [127.0.0.1]:51226->[127.0.0.1]:163]:
SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-MIB::sysUpTime  SNMPv2-SMI::dod.7 = STRING: "test from snmptrap tool."
$ sudo snmptrapd -C -c /etc/snmp/snmptrapd.conf -f -Lo udp:163 udp6:163
NET-SNMP version 5.9.1
2023-08-02 14:24:15 localhost [UDP: [127.0.0.1]:51226->[127.0.0.1]:163]:
SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-MIB::sysUpTime  SNMPv2-SMI::dod.7 = STRING: "test from snmptrap tool."

如果设备上没有配置MIB,输出可能会是如下

2023-08-02 14:36:17 localhost [UDP: [127.0.0.1]:51589->[127.0.0.1]:163]:
iso.3.6.1.6.3.1.1.4.1.0 = OID: iso.3.6.1.2.1.1.3        iso.3.6.7 = STRING: "test from snmptrap tool."
2023-08-02 14:36:17 localhost [UDP: [127.0.0.1]:51589->[127.0.0.1]:163]:
iso.3.6.1.6.3.1.1.4.1.0 = OID: iso.3.6.1.2.1.1.3        iso.3.6.7 = STRING: "test from snmptrap tool."

可以看到接收到的数据格式是SNMPv2-MIB::snmpTrapOID.0 = OID: {企业OID} {字段OID} = {类型}: {参数值}

关于读取磁盘信息超过2T字节数的问题

产生原因

使用snmp获取磁盘信息的时候,查询OID.1.3.6.1.4.1.2021.9.1.6MIB数据库翻译映射字符串是UCD-SNMP-MIB::dskTotal

如果某块划分磁盘的大小大于2T,导致snmp获取磁盘最大容量大小是2147483647(231次方减1,约等于2T)

可以猜测磁盘信息存储的时候采用了int32类型存储,一位标志位,范围是-21474836482147483647

最终产生数值越界问题

解决方案

snmp5.5+版本(目前在Ubuntu 18Centos 7当中安装的snmpd版本都是5.7.*),是已经修复了该缺陷的版本

通过引入64bitmibs解决,引入的新mib如下

UCD-SNMP-MIB::dskTotalLow,UCD-SNMP-MIB::dskTotalHigh,

UCD-SNMP-MIB::dskAvailLow,UCD-SNMP-MIB::dskAvailHigh,

UCD-SNMP-MIB::dskUsedLow,UCD-SNMP-MIB::dskUsedHigh

计算磁盘总容量,磁盘可用容量,磁盘已使用容量上都各存在LowHigh结尾的信息

举例

目前有一个系统,最大一块磁盘的容量大小是66016187002^32 < 6601618700 < 2^64,约等于6T

获取所有磁盘和分区信息

shell
$ snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.3
UCD-SNMP-MIB::dskDevice.1 = STRING: /dev/sde3
UCD-SNMP-MIB::dskDevice.2 = STRING: /dev/sda
UCD-SNMP-MIB::dskDevice.3 = STRING: /dev/sdb
UCD-SNMP-MIB::dskDevice.4 = STRING: /dev/sdd
$ snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.3
UCD-SNMP-MIB::dskDevice.1 = STRING: /dev/sde3
UCD-SNMP-MIB::dskDevice.2 = STRING: /dev/sda
UCD-SNMP-MIB::dskDevice.3 = STRING: /dev/sdb
UCD-SNMP-MIB::dskDevice.4 = STRING: /dev/sdd

采用如下命令读取信息,发现最大磁盘量是2147483647(即2T),这个与实际不符合,snmp可能为了保证旧版本的兼容性没有更改或者移除这个OID

shell
$ snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.6
UCD-SNMP-MIB::dskTotal.1 = INTEGER: 465993216
UCD-SNMP-MIB::dskTotal.2 = INTEGER: 2147483647
UCD-SNMP-MIB::dskTotal.3 = INTEGER: 2147483647
UCD-SNMP-MIB::dskTotal.4 = INTEGER: 460838992
$ snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.6
UCD-SNMP-MIB::dskTotal.1 = INTEGER: 465993216
UCD-SNMP-MIB::dskTotal.2 = INTEGER: 2147483647
UCD-SNMP-MIB::dskTotal.3 = INTEGER: 2147483647
UCD-SNMP-MIB::dskTotal.4 = INTEGER: 460838992

这个时候获取修复版本新增的OID信息

shell
# 获取低32位的磁盘容量数值
$ snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.11
UCD-SNMP-MIB::dskTotalLow.1 = Gauge32: 465993216
UCD-SNMP-MIB::dskTotalLow.2 = Gauge32: 2306651404
UCD-SNMP-MIB::dskTotalLow.3 = Gauge32: 2306651404
UCD-SNMP-MIB::dskTotalLow.4 = Gauge32: 460838992

# 获取高32位的磁盘容量数值,即数值在2^32到2^64位之间的数值
snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.12
UCD-SNMP-MIB::dskTotalHigh.1 = Gauge32: 0
UCD-SNMP-MIB::dskTotalHigh.2 = Gauge32: 1
UCD-SNMP-MIB::dskTotalHigh.3 = Gauge32: 0
UCD-SNMP-MIB::dskTotalHigh.4 = Gauge32: 0
# 获取低32位的磁盘容量数值
$ snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.11
UCD-SNMP-MIB::dskTotalLow.1 = Gauge32: 465993216
UCD-SNMP-MIB::dskTotalLow.2 = Gauge32: 2306651404
UCD-SNMP-MIB::dskTotalLow.3 = Gauge32: 2306651404
UCD-SNMP-MIB::dskTotalLow.4 = Gauge32: 460838992

# 获取高32位的磁盘容量数值,即数值在2^32到2^64位之间的数值
snmpwalk -v 2c -c public localhost  .1.3.6.1.4.1.2021.9.1.12
UCD-SNMP-MIB::dskTotalHigh.1 = Gauge32: 0
UCD-SNMP-MIB::dskTotalHigh.2 = Gauge32: 1
UCD-SNMP-MIB::dskTotalHigh.3 = Gauge32: 0
UCD-SNMP-MIB::dskTotalHigh.4 = Gauge32: 0

发现UCD-SNMP-MIB::dskTotalLow存储的数值目前是大于2^31 - 1的,推测该字段应该是采用UInt32位存储,取值范围0到4294967295(小于2^32 - 1),所以该字段最大存储磁盘容量是4T

所以当磁盘最大容量可能超过4T的时候计算磁盘容量需要叠加计算两个OID的数值

比如现在计算第二块磁盘UCD-SNMP-MIB::dskDevice.2,磁盘分区为/dev/sda的磁盘,理论上这个修复版本的最大计算磁盘容量大约是2^32 T

磁盘容量 = UCD-SNMP-MIB::dskTotalLow.2的值 + ( UCD-SNMP-MIB::dskTotalHigh.2的值 * 2^32)
磁盘容量 = UCD-SNMP-MIB::dskTotalLow.2的值 + ( UCD-SNMP-MIB::dskTotalHigh.2的值 * 2^32)

套入具体数值计算如下

6601618700 = 2306651404 + (1 * 2^32)
6601618700 = 2306651404 + (1 * 2^32)

snmpwalk报错Error: OID not increasing

默认情况下snmpwalk会检查返回的OID的序号,判断接收到的OID是否比上一个大,以免无限期的循环查询

有些时候需要获取全部数据,但是不方便修改agent,所以需要关闭这个检查

shell
$ snmpwalk --help
..
-C APPOPTS   Set various application specific behaviours:
    p:  print the number of variables found
    i:  include given OID in the search range
    I:  don't include the given OID, even if no results are returned
    c:  do not check returned OIDs are increasing
    t:  Display wall-clock time to complete the walk
    T:  Display wall-clock time to complete each request
    E {OID}:  End the walk at the specified OID
$ snmpwalk --help
..
-C APPOPTS   Set various application specific behaviours:
    p:  print the number of variables found
    i:  include given OID in the search range
    I:  don't include the given OID, even if no results are returned
    c:  do not check returned OIDs are increasing
    t:  Display wall-clock time to complete the walk
    T:  Display wall-clock time to complete each request
    E {OID}:  End the walk at the specified OID

执行的时候需要在命令后面加上参数-Cc

参考阅读

snmp官方wiki

snmp原理与实战

Last updated:

Released under the MIT License.