如何使用Net-SNMP工具套件管理和监控服务器
介绍
作为系统管理员的很大一部分工作是收集有关您的服务器和基础架构的准确信息。 有许多工具和选项可用于收集和处理此类信息。 其中许多是建立在称为 SNMP 的技术之上的。
SNMP 代表简单网络管理协议。 这是服务器可以共享有关其当前状态的信息的一种方式,也是管理员可以修改预定义值的渠道。 虽然协议本身非常简单,但实现 SNMP 的程序结构可能非常复杂。
在之前的指南中,我们讨论了 SNMP 协议的基础知识 和 如何在 Ubuntu 14.04 服务器 上安装和配置 SNMP 组件。 在本指南中,我们将介绍我们一直在使用的 net-snmp
套件附带的许多工具的基本用法。
我们将讨论如何利用我们在上一个指南中设置的配置来实际收集信息和操作远程主机。 本教程假设您设置了两台主机,就像它们在 安装和配置指南 的结尾处一样。
使用 SNMP 客户端命令
我们一直在使用的 net-snmp
工具套件包含相当多的实用程序,可用于在远程主机上查询或设置 OID 值。 幸运的是,大多数工具都利用了一组共享语法并具有相似的使用模式。 我们将在下面介绍一些更流行的基本用法。
出于本指南的目的,我们假设您熟悉提供 net-snmp
命令所需的身份验证部分。 我们将在下面的部分中将所有身份验证信息称为 authentication_info
。
如果您已经 为您的客户端 设置了 snmp.conf 配置,如此处所述,您可以删除命令的这一部分,因为将从您的配置文件中读取身份验证详细信息。
如果您没有 snmp.conf
文件,则需要将每个命令中的“authentication_info”替换为连接到远程守护程序所需的信息。 对于我们在本系列中设置的 demo
帐户,可以使用以下值:
-u demo -l authPriv -a MD5 -x DES -A my_new_password -X my_new_password
如果您在不同的环境中,请在运行这些命令时替换您自己的值。
现在您已经知道了您需要的身份验证详细信息,让我们熟悉一些可用的命令。
使用 SnmpGet 检索单个 OID 值
这可能是使用 SNMP 查询信息的最基本命令。 使用前面讨论的基本身份验证标志,snmpget
命令可用于读取用户有权访问的任何 OID 的值。
基本用法是指定一个已知的数字 OID。 例如,我们可以通过键入以下内容来检索系统描述:
snmpget authentication_info host 1.3.6.1.2.1.1.1.0
由于我们在上一篇指南中在经理计算机上安装了 snmp-mibs-downloader
包,因此我们还可以通过名称引用常见的 OID。 例如,我们可以通过键入以下内容获得相同的信息:
snmpget authentication_info host sysDescr.0
使用 SnmpGetNext 检索下一个可用的 OID 值
此命令用于获取给定 OID 之后的值。 由于 MIB 数据库是可步行的层次结构,因此可以按顺序检索其值。 通过利用此属性,我们可以从树中的任何对象中找出下一个对象的值(和 OID 标签)。
例如,我们在上面看到了如何获取系统描述。 要找出下一个 OID 及其值,我们可以调用相同的命令,但这次使用 snmpgetnext
命令:
snmpgetnext authentication_info host sysDescr.0
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
这将返回系统 ObjectID,它是树中的下一个顺序对象。 我们可以使用返回的 OID 一遍又一遍地重复此操作以获取每个顺序对象:
snmpgetnext authentication_info host sysObjectID.0
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (114216) 0:19:02.16
这些可以像以前一样使用字符串 OID 或数字 OID。
使用 SnmpWalk 检索 MIB 层次结构的一部分
要获取指定 OID 下的所有 OID,可以使用 snmpwalk
命令。 这将返回指定点下方存在的整个树。
例如,我们可以通过键入以下内容获取树的 system
部分中的所有值:
snmpwalk authentication_info host system
SNMPv2-MIB::sysDescr.0 = STRING: Linux target 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (126926) 0:21:09.26 SNMPv2-MIB::sysContact.0 = STRING: admin@example.com SNMPv2-MIB::sysName.0 = STRING: target SNMPv2-MIB::sysLocation.0 = STRING: Sitting on the Dock of the Bay SNMPv2-MIB::sysServices.0 = INTEGER: 72 . . .
此命令通过自动向主机发出 SNMP getNext 请求来运行,直到它可以在请求的值下构建整个树。
如果您希望基本上检索整个 MIB 树,可以在根目录下发出命令:
snmpwalk authentication_info host .
这将返回提供的用户可以访问的整个树。
这可以与 grep
一起用于搜索特定的 OID 名称。 例如,您可能知道 sysUpTime.0
OID 返回 SNMP 守护程序在远程主机上运行的长度,但您可能对服务器本身在线的时间感到好奇。
我们可以使用 snmpwalk
命令获取 OID 的整个层次结构,然后使用 grep 对其进行过滤以查找名称中包含“正常运行时间”的任何内容。 我们将使用 -i
标志在搜索中关闭区分大小写:
snmpwalk authentication_info host . | grep -i uptime
您将收到如下所示的响应:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (113856) 0:18:58.56 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: (9741455) 1 day, 3:03:34.55 NOTIFICATION-LOG-MIB::nlmLogVariableID."default".1.1 = OID: DISMAN-EVENT-MIB::sysUpTimeInstance NET-SNMP-AGENT-MIB::nsModuleName."".8.1.3.6.1.2.1.1.3.127 = STRING: mibII/sysUpTime
在尝试了其中一些值之后,我们可以发现 hrSystemUptime.0
OID 包含正确的正常运行时间值。 现在,只要我们想知道那台机器已经启动了多长时间,我们就可以使用该 OID:
snmpget authentication_info host hrSystemUptime.0
HOST-RESOURCES-MIB::hrSystemUptime.0 = Timeticks: (9795352) 1 day, 3:12:33.52
如您所见,snmpwalk
对于发现值的正确 OID 非常有帮助。
使用 SnmpTranslate 在数字和字符串 OID 之间进行转换
套件中最有用的命令之一实际上并不与远程主机通信。 相反,它只是帮助我们发现有关 MIB 层次结构的信息。
使用 snmptranslate
实用程序,我们可以轻松地将数值结果转换为其文本表示:
snmptranslate 1.3.6.1.2.1.1.1.0
SNMPv2-MIB::sysDescr.0
这给出了定义文本名称的 MIB 模块,以及 OID 本身的名称。
我们还可以使用该工具向另一个方向进行翻译。 当我们发现系统正常运行时间的文本 MIB (hrSystemUptime.0
) 时,我们可能很好奇树上定义的位置。 我们可以通过 -On
标志来获取数字地址。
请记住在收到有关 OID 的信息时包含提供的 MIB 模块:
snmptranslate -On HOST-RESOURCES-MIB::hrSystemUptime.0
.1.3.6.1.2.1.25.1.1.0
您还可以使用此工具获取有关任何点的许多其他详细信息。 例如,使用 -Td
标志,您可以获得完整的描述,并在底部包含路径:
snmptranslate -Tp 1.3.6.1.2.1.1.1.0
SNMPv2-MIB::sysDescr.0 sysDescr OBJECT-TYPE -- FROM SNMPv2-MIB -- TEXTUAL CONVENTION DisplayString SYNTAX OCTET STRING (0..255) DISPLAY-HINT "255a" MAX-ACCESS read-only STATUS current DESCRIPTION "A textual description of the entity. This value should include the full name and version identification of the system's hardware type, software operating-system, and networking software." ::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) system(1) sysDescr(1) 0 }
您可以通过传递 -O_
参数来修改输出的显示方式,其中“_”替换为输出格式。 您可以在 snmpcmd
手册页的“输出选项”部分查看完整列表,但一些更常见的选择是:
输出标志 | 描述 | 例子 |
---|---|---|
-OA | 以 ASCII 字符串显示 | SNMPv2-MIB::sysDescr.0 |
-的 | 显示 OID 的完整文本路径 | .iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0 |
-在 | 显示 OID 的完整数字路径 | .1.3.6.1.2.1.1.1.0 |
-Os | 仅显示结束的文本 OID 表示 | sysDescr.0 |
请注意,上述格式化选项也可以与该套件中的大多数其他工具一起应用,以按照您的意愿格式化输出。
使用 SnmpTable 检索带有格式化输出的表格数据
使用 SNMP 存储的一些信息实际上是表格的。 尽管 snmpwalk
具有显示所有相关数据的能力,但格式对于某些用途并不理想。
例如,如果我们在 udpTable
OID 上使用 snmpwalk
:
snmpwalk authentication_info host udpTable
我们会得到这个:
UDP-MIB::udpLocalAddress.0.0.0.0.161 = IpAddress: 0.0.0.0 UDP-MIB::udpLocalAddress.0.0.0.0.35679 = IpAddress: 0.0.0.0 UDP-MIB::udpLocalPort.0.0.0.0.161 = INTEGER: 161 UDP-MIB::udpLocalPort.0.0.0.0.35679 = INTEGER: 35679
但是,如果我们使用 snmptable
发出相同的请求:
snmptable authentication_info host udpTable
我们会得到一个格式很好的表格,如下所示:
udpLocalAddress udpLocalPort 0.0.0.0 161 0.0.0.0 35679
对于人类读者来说,这是更好的格式并且更容易使用。
使用 SnmpSet 修改值
此命令用于将值写入 OID。 到目前为止,其他命令都用于获取信息,而此命令用于修改主机上的数据。
虽然 snmpset
命令从其他命令继承了大部分语法,但它需要一些额外的信息来设置值。 基本语法如下所示:
snmpset authentication_info host OID_to_modify data_type new_value
上面的大多数字段都是不言自明的。 但是,数据类型需要更多解释。 每种类型都由一个字符表示。 可能的类型列表如下:
- i:整数
- u:无符号整数
- s:字符串
- x:十六进制字符串
- d:十进制字符串
- n:空对象
- o:对象 ID
- t:时间滴答
- a:IP 地址
- b:位
由于我们已经下载了 snmp-mibs-downloader
包,因此大多数情况下您可以通过输入 =
而不是类型标识符之一来摆脱困境。
为了演示此命令,我们可以注释掉代理计算机上 snmpd.conf
文件中设置的值之一。 在配置文件中指定值本质上是对其进行硬编码,从而阻止您使用常规 SNMP 方法更改值。
在代理计算机上,打开 /etc/snmp/snmpd.conf
文件:
sudo nano /etc/snmp/snmpd.conf
注释掉 sysLocation
指令:
#sysLocation Sitting on the Dock of the Bay
保存并关闭文件。 现在重新启动服务:
sudo service snmpd restart
现在,在我们的管理机器上,我们可以通过键入此命令将 sysLocation
OID 设置为“Earth”。 请注意指定数据类型为字符串的“s”:
snmpset authentication_info host sysLocation.0 s "Earth"
SNMPv2-MIB::sysLocation.0 = STRING: Earth
我们可以通过优化我们的位置来测试 =
类型说明符是否会正确设置值类型:
snmpset authentication_info host sysLocation.0 = "New York City"
SNMPv2-MIB::sysLocation.0 = STRING: New York City
它已正确地将我们的值解释为常规字符串。
使用 SnmpBulkGet 和 SnmpBulkWalk 高效地发出请求
发出重复的 snmpget
和 snmpwalk
请求在重复使用时会产生相当多的网络流量。
为了减少这个问题,创建了两个名为 snmpbulkget
和 snmpbulkwalk
的配套命令。 这些会将所有返回值打包在单个事务中,而不是为每个返回的 OID 值打包一个事务。 您还可以一次传入多个 OID。
要使用 snmpbulkget
,您需要传入一个或多个 OID 或分支,然后您将返回数据包中适合的其他 OID 的尽可能多的值:
snmpbulkget authentication_info host system
SNMPv2-MIB::sysDescr.0 = STRING: Linux target 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (429891) 1:11:38.91 SNMPv2-MIB::sysContact.0 = STRING: call now SNMPv2-MIB::sysName.0 = STRING: target SNMPv2-MIB::sysLocation.0 = STRING: New York City SNMPv2-MIB::sysServices.0 = INTEGER: 72 SNMPv2-MIB::sysORLastChange.0 = Timeticks: (0) 0:00:00.00 SNMPv2-MIB::sysORID.1 = OID: SNMP-MPD-MIB::snmpMPDCompliance SNMPv2-MIB::sysORID.2 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
需要注意的一点是 snmpbulkget
的操作类似于 snmpgetnext
命令,这意味着它忽略了作为参数给出的对象。 在上面的例子中,我们没有提供一个特定的对象,而是提供了一个分支。 您可以将 snmpbulkget
视为 snmpwalk
调用,但结果将在一个数据包中。
snmpbulkwalk
命令以类似的方式操作,但会继续发出 BulkGet
命令,直到检索到整个子树。
结论
如您所见,使用 net-snmp
套件,您可以通过多种方式检索和操作数据。 通过编写这些操作的脚本或在应用程序中利用这些实用程序,您可以构建复杂的监控和管理环境。