深入浅出:SNMP实践与MIB设计指南
1. SNMP请求处理与权限配置
在使用SNMP(简单网络管理协议)时,有时会遇到代理拒绝请求的情况。比如配置文件如下:
rocommunity public
syslocation "the den"
syscontact me@myaddr.com
这里设置了只读社区字符串,没有设置读写社区字符串,所以没有权限设置任何值。需要配置一个读写社区名称,在
snmptd.conf
文件中添加如下行来配置读写社区字符串
writer
:
rwcommunity writer
之后,需要让SNMP代理注意到这个更改。以root身份向代理发送
SIGHUP
信号,使其重新读取配置:
killall -s HUP snmpd
再次尝试
snmpset
命令:
$ snmpset -c writer localhost sysContact.0 s "me@myself.com"
Error in packet.
Reason: notWritable (that object does not support modification)
Failed object: SNMPv2-MIB::sysContact.0
代理再次拒绝了请求。这次的原因不太明显,Net - SNMP代理如果对象的值已在
snmptd.conf
文件中配置,会拒绝设置新值的请求。这不是SNMP标准的一部分,只是Net - SNMP的工作方式。如果想让这些值可写,需要使用本地
snmpset
命令设置它们的值,而不是使用配置文件。
2. 设置sysName
由于
sysContact
和
sysLocation
在配置文件中定义,不可写,尝试设置
sysName
,因为没有为其配置值。
$ snmpset -c writer localhost sysName.0 s "NewName"
SNMPv2-MIB::sysName.0 = STRING: NewName
snmpset
命令要求使用读写社区字符串,并指定对象实例的名称、类型和新值。
s
表示写入字符串值,若写入整数变量,类型应为
i
。要查看完整的类型列表,可阅读
snmpset
的手册页。设置的值的类型必须与要设置的对象的类型匹配。
现在查看
sysContact
、
sysName
和
sysLocation
的值:
$ snmpget -c public localhost sysContact.0 sysName.0 sysLocation.0
SNMPv2-MIB::sysContact.0 = STRING: me@myaddr.com
SNMPv2-MIB::sysName.0 = STRING: NewName
SNMPv2-MIB::sysLocation.0 = STRING: "the den"
3. SNMP陷阱
除了响应SET和GET等SNMP请求外,网络中支持SNMP的设备还可以自发发送本地事件通知。这些通知可以作为SNMP陷阱(traps)或通知(informs)发送。陷阱是不期望响应的数据报,通知是对陷阱的改进,因为它期望得到确认响应,并且当陷阱接收者未及时确认时会重新发送。陷阱发送者可以通过
snmptrap
命令的参数设置超时时间和重试次数。
4. 使用snmptrapd接收陷阱
可以使用
snmptrapd
接收陷阱。在Net - SNMP 5.2.1版本中,只需打开一个单独的终端窗口,以root身份执行以下命令:
snmptrapd -Os -Le -f
但从5.3版本开始,
snmptrapd
的安全性得到加强,不再默认接受任何社区名称的陷阱。在后续版本中,需要在
/etc/snmp
目录下创建一个
snmptrapd.conf
文件,并包含一行指定要接受的社区。使用
public
社区,
snmptrapd.conf
文件内容如下:
authCommunity log public
现在可以执行上述
snmptrapd
命令来查看接收到的陷阱。该命令通常在后台运行,接收陷阱、格式化并写入日志文件。使用
-f
参数让
snmptrapd
在前台运行,
-Le
参数将输出发送到标准错误输出,
-Os
参数让
snmptrapd
只打印OID的最后一个符号部分,节省空间并使输出更易读。
使用单独的命令窗口通过
snmptrap
命令发送陷阱,需要以root身份运行
snmptrapd
,因为它要监听UDP端口162。快速测试可执行以下命令之一:
snmptrap -c public localhost "" coldStart
或
snmptrap -c public localhost "" .1.3.6.1.6.3.1.1.5.1
snmptrapd
的默认输出格式如下:
2007-02-14 20:43:26 localhost.localdomain [127.0.0.1]:
sysUpTimeInstance = Timeticks: (4694125) 13:02:21.25
snmpTrapOID.0 = OID: cold Start
要注意这里使用的是SNMPv2,SNMPv1陷阱的发送格式不同且更复杂。
coldStart
陷阱在技术上意味着网络管理软件在配置不变的情况下重新启动,通常只有运行代理的系统重新启动时才会发生,很多用户将其视为重启指示符,但代理每次重启时也会发送。
如果在
snmptrapd.conf
文件中配置陷阱目标并重启代理,
snmptrapd
将接收到一个陷阱。在
snmptrapd.conf
文件中添加以下行:
trap2sink localhost public
然后杀死代理并重新启动,或发送另一个
SIGHUP
信号,
snmptrapd
将显示已接收到
coldStart
陷阱。再次重启代理后,
snmptrapd
将显示:
2007-02-14 12:06:17 localhost.localdomain [127.0.0.1]:
sysUpTimeInstance = Timeticks: (33324) 0:05:33.24 snmpTrapOID.0 = OID:
nsNotifyShutdown
2007-02-14 12:06:37 localhost.localdomain [127.0.0.1]:
sysUpTimeInstance = Timeticks: (36) 0:00:00.36 snmpTrapOID.0 = OID: coldStart
snmpTrapEnterprise.0 = OID: netSnmpAgentOIDs.10
可以通过时间戳找到每个陷阱的开始。这里接收到了两个陷阱:
nsNotifyShutdown
和
coldStart
。
nsNotifyShutdown
不是SNMP规范中定义的陷阱,而是在
NET - SNMP - AGENT - MIB.txt
文件中定义的,它是Net - SNMP企业陷阱之一,其OID位于MIB树的
private.enterprises
部分。
5. 携带数据的陷阱:linkUp和linkDown
之前看到的
coldStart
和
nsNotifyShutdown
陷阱不携带任何额外数据,只表明发生了关闭或启动事件。而通用陷阱
linkDown
和
linkUp
不同,它们包含额外信息:
linkDown NOTIFICATION-TYPE
OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
STATUS current
DESCRIPTION
"A linkDown trap signifies that the SNMP entity, acting
in an agent role, has detected that the ifOperStatus
object for one of its communication links is about to
enter the down state from some other state (but not
from the notPresent state). This other state is
indicated by the included value of ifOperStatus."
::= { snmpTraps 3 }
linkUp NOTIFICATION-TYPE
OBJECTS { ifIndex, ifAdminStatus, ifOperStatus }
STATUS current
DESCRIPTION
"A linkUp trap signifies that the SNMP entity, acting in an
agent role, has detected that the ifOperStatus object for
one of its communication links left the down state and
transitioned into some other state (but not into the
notPresent state). This other state is indicated by the
included value of ifOperStatus."
::= { snmpTraps 4 }
每个陷阱定义中的
OBJECTS
行是将在陷阱中发送的参数列表。第一个是
ifIndex
,它是MIB - 2中
interfaces
部分的接口表的索引,其他参数定义了接口的管理和操作状态。查看系统中的
ifTable
:
$ snmpwalk -c public localhost ifTable
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: eth0
IF-MIB::ifType.1 = INTEGER: softwareLoopback(24)
IF-MIB::ifType.2 = INTEGER: ethernetCsmacd(6)
IF-MIB::ifMtu.1 = INTEGER: 16436
IF-MIB::ifMtu.2 = INTEGER: 1500
IF-MIB::ifSpeed.1 = Gauge32: 10000000
IF-MIB::ifSpeed.2 = Gauge32: 0
IF-MIB::ifPhysAddress.1 = STRING:
IF-MIB::ifPhysAddress.2 = STRING: 0:10:5a:ce:72:c3
IF-MIB::ifAdminStatus.1 = INTEGER: up(1)
IF-MIB::ifAdminStatus.2 = INTEGER: up(1)
IF-MIB::ifOperStatus.1 = INTEGER: up(1)
IF-MIB::ifOperStatus.2 = INTEGER: down(2)
IF-MIB::ifInOctets.1 = Counter32: 4501945
IF-MIB::ifInOctets.2 = Counter32: 312184
IF-MIB::ifInUcastPkts.1 = Counter32: 21113
IF-MIB::ifInUcastPkts.2 = Counter32: 2865
IF-MIB::ifInDiscards.1 = Counter32: 0
IF-MIB::ifInDiscards.2 = Counter32: 0
IF-MIB::ifInErrors.1 = Counter32: 0
IF-MIB::ifInErrors.2 = Counter32: 0
IF-MIB::ifOutOctets.1 = Counter32: 4503127
IF-MIB::ifOutOctets.2 = Counter32: 312697
IF-MIB::ifOutUcastPkts.1 = Counter32: 21129
IF-MIB::ifOutUcastPkts.2 = Counter32: 3471
IF-MIB::ifOutDiscards.1 = Counter32: 0
IF-MIB::ifOutDiscards.2 = Counter32: 0
IF-MIB::ifOutErrors.1 = Counter32: 0
IF-MIB::ifOutErrors.2 = Counter32: 0
IF-MIB::ifOutQLen.1 = Gauge32: 0
IF-MIB::ifOutQLen.2 = Gauge32: 0
IF-MIB::ifSpecific.1 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.2 = OID: SNMPv2-SMI::zeroDotZero
尝试发送一个
linkDown
陷阱:
snmptrap -c public localhost "" linkDown \
ifIndex i 2 \
ifAdminStatus i 1 \
ifOperStatus i 2
snmptrapd
显示:
2007-02-14 12:48:15 localhost.localdomain [127.0.0.1]:
sysUpTimeInstance = Timeticks: (10483057) 1 day, 5:07:10.57 snmpTrapOID.0
= OID: linkDown ifIndex = INTEGER: 2 ifAdminStatus = INTEGER: up(1)
ifOperStatus = INTEGER: down(2)
这个陷阱表明接口2(从上面的
ifTable
遍历可知是
eth0
)在管理上是启用的,但在操作上是关闭的。由于该机器只有一个以太网接口,不太可能看到此类陷阱,但当接口恢复时会看到
linkUp
陷阱:
2007-02-14 12:52:15 localhost.localdomain [127.0.0.1]:
sysUpTimeInstance = Timeticks: (10507037) 1 day, 5:11:10.37 snmpTrapOID.0
= OID: linkUp ifIndex = INTEGER: 2 ifAdminStatus = INTEGER: up(1)
ifOperStatus = INTEGER: up(1)
6. SNMP的应用总结
通过上述操作,可以看到SNMP能做很多事情。可以在自己的计算机上安装、配置和启动Net - SNMP代理,使用Net - SNMP提供的
snmpget
、
snmpwalk
和
snmptable
命令探索SNMP能提供的关于联网机器的信息,使用SNMP修改系统的一个设置(
sysName
),还能发送和接收一些陷阱。标准协议的好处是来自多个来源的软件可以互操作,可以尝试使用其他来源的MIB浏览器,如http://www.mibble.org 。SNMP可用于发现网络上的设备、根据IP地址识别设备类型,甚至重新配置设备选项。
7. 设计SNMP MIB的目标
如果已经了解了SNMP接口的作用和用途,接下来将看到如何将特定设备的信息添加到这个接口中。设计SNMP MIB主要涉及以下几个方面:
- 申请企业编号
- 设计MIB
- 创建MIB文件
- 验证MIB
以Laddie应用的
ZONE
结构为例,其定义如下:
typedef struct
{
int id; // ID number of alarm [1-5]
char name[ZONE_NAME_LEN]; // the alarm name
int enabled; // 1 if enabled
int edge; // 1 if alarm on low to high transition
int latching; // 1 if should latch the alarm
int input; // is the latest raw input from the alarm
int alarm; // 1 if in alarm
int count; // count of alarms on this pin
}
ZONE;
设计并实现MIB后,在SNMP接口中查看的信息如下:
$ snmptable -c public -v2c myappliance ladAlarmTable
SNMP table: LAD-MIB::ladAlarmTable
ladAlarmZoneName ladAlarmEnable ladAlarmLatching ladAlarmState ladAlarmCount
Garage Door true 0 0 7
Motion Detector true 0 0 2281
Front Door true 0 0 0
Kitchen Window true 0 0 0
Refrigerator true true 0 0
在设计SNMP视图的表格时,没有包含
id
、
edge
和
input
列,因为
edge
和
input
信息过于硬件特定,在这个接口中并非必要,
id
列不会由SNMP代理返回,但在需要访问特定行时将用作警报表的索引。
8. 获取企业编号
每个MIB都需要锚定到整个命名空间,如果设计私有MIB,需要自己的企业编号。这些编号由IANA(互联网号码分配机构)分配,每个公司或组织只需要一个企业编号,因为IANA授予管理该编号下子树的权限。
获取IANA的企业编号可能需要一些时间,所以应尽早开始申请。申请后,IANA会告知大约需要一个月的处理时间。在IANA处理请求时,可以设计和实现MIB。
申请过程很简单,使用喜欢的网页浏览器访问IANA网站(http://www.iana.org ),点击菜单中的“Application Forms”,在下一页选择“Private Enterprise Numbers (SNMP)”,会出现一个在线表单需要填写。
网页底部有一个指向当前注册编号列表的链接,可以查看有哪些公司或组织已经获得了编号。一些知名公司的编号如下:
| 公司名称 | 企业编号 |
| ---- | ---- |
| IBM | 2 |
| Cisco | 9 |
| Hewlett Packard | 11 |
开始申请时,需要提供以下信息:
- 公司或组织名称
- 公司地址
- 公司电话号码
- 联系人姓名
- 联系人地址
- 联系人电话号码
- 联系人电子邮件地址
- 传真号码
通过以上步骤,我们可以逐步掌握SNMP的使用和MIB的设计,为网络管理和设备监控提供有力的支持。
9. 设计MIB的具体步骤
在获得企业编号后,就可以开始设计MIB了。设计MIB是一个细致的过程,需要根据实际需求和设备的特性来规划MIB树的结构。
9.1 确定MIB树的根节点
以之前提到的Laddie应用为例,使用申请到的企业编号作为MIB树的起始点。假设企业编号为23528,那么Laddie MIB将在这个编号下展开。
9.2 规划子节点
根据
ZONE
结构的信息,确定需要在MIB中展示的内容。例如,
ladAlarmTable
就是一个重要的子节点,它对应着
ZONE
结构中的相关信息。
LAD-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, INTEGER, IpAddress, Counter32, Gauge32, TimeTicks, Opaque,
NOTIFICATION-TYPE
FROM SNMPv2-SMI
TEXTUAL-CONVENTION
FROM SNMPv2-TC;
ladMIB MODULE-IDENTITY
LAST-UPDATED "202401010000Z"
ORGANIZATION "Your Company"
CONTACT-INFO "Your contact information"
DESCRIPTION "The MIB for Laddie application"
REVISION "202401010000Z"
DESCRIPTION "Initial version"
::= { enterprises 23528 }
ladAlarmTable OBJECT-TYPE
SYNTAX SEQUENCE OF LadAlarmEntry
ACCESS not-accessible
STATUS current
DESCRIPTION
"The table containing alarm information"
::= { ladMIB 1 }
LadAlarmEntry OBJECT-TYPE
SYNTAX LadAlarmEntrySyntax
ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry in the ladAlarmTable"
INDEX { ladAlarmIndex }
::= { ladAlarmTable 1 }
LadAlarmEntrySyntax ::= SEQUENCE {
ladAlarmIndex INTEGER,
ladAlarmZoneName DisplayString,
ladAlarmEnable TruthValue,
ladAlarmLatching INTEGER,
ladAlarmState INTEGER,
ladAlarmCount Counter32
}
ladAlarmIndex OBJECT-TYPE
SYNTAX INTEGER
ACCESS read-only
STATUS current
DESCRIPTION
"The index of the alarm entry"
::= { LadAlarmEntry 1 }
ladAlarmZoneName OBJECT-TYPE
SYNTAX DisplayString
ACCESS read-only
STATUS current
DESCRIPTION
"The name of the alarm zone"
::= { LadAlarmEntry 2 }
ladAlarmEnable OBJECT-TYPE
SYNTAX TruthValue
ACCESS read-write
STATUS current
DESCRIPTION
"Indicates whether the alarm is enabled"
::= { LadAlarmEntry 3 }
ladAlarmLatching OBJECT-TYPE
SYNTAX INTEGER
ACCESS read-write
STATUS current
DESCRIPTION
"Indicates whether the alarm should latch"
::= { LadAlarmEntry 4 }
ladAlarmState OBJECT-TYPE
SYNTAX INTEGER
ACCESS read-only
STATUS current
DESCRIPTION
"The current state of the alarm"
::= { LadAlarmEntry 5 }
ladAlarmCount OBJECT-TYPE
SYNTAX Counter32
ACCESS read-only
STATUS current
DESCRIPTION
"The count of alarms on this pin"
::= { LadAlarmEntry 6 }
END
上述代码展示了一个简单的MIB文件示例,定义了
ladAlarmTable
及其相关的子节点。
10. 创建MIB文件
创建MIB文件时,需要遵循MIB定义的语法规则。MIB文件通常使用ASN.1(抽象语法标记1)来编写。
10.1 导入必要的模块
在文件开头,需要导入一些必要的模块,如
SNMPv2-SMI
和
SNMPv2-TC
,这些模块提供了基本的类型和定义。
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, INTEGER, IpAddress, Counter32, Gauge32, TimeTicks, Opaque,
NOTIFICATION-TYPE
FROM SNMPv2-SMI
TEXTUAL-CONVENTION
FROM SNMPv2-TC;
10.2 定义MIB模块
使用
MODULE-IDENTITY
来定义MIB模块的基本信息,包括更新时间、组织、联系人信息等。
ladMIB MODULE-IDENTITY
LAST-UPDATED "202401010000Z"
ORGANIZATION "Your Company"
CONTACT-INFO "Your contact information"
DESCRIPTION "The MIB for Laddie application"
REVISION "202401010000Z"
DESCRIPTION "Initial version"
::= { enterprises 23528 }
10.3 定义对象类型
使用
OBJECT-TYPE
来定义各个对象的类型、访问权限、状态和描述等信息。
ladAlarmTable OBJECT-TYPE
SYNTAX SEQUENCE OF LadAlarmEntry
ACCESS not-accessible
STATUS current
DESCRIPTION
"The table containing alarm information"
::= { ladMIB 1 }
11. 验证MIB文件
创建好MIB文件后,需要对其进行验证,确保其语法正确且符合SNMP的规范。
11.1 使用工具验证
可以使用一些工具来验证MIB文件,如Net-SNMP提供的
smilint
工具。
smilint your_mib_file.mib
如果MIB文件存在语法错误,
smilint
会输出相应的错误信息,根据这些信息进行修改。
11.2 测试MIB文件
在验证通过后,可以使用SNMP工具来测试MIB文件。例如,使用
snmptable
命令来查看
ladAlarmTable
的信息。
snmptable -c public -v2c your_device ladAlarmTable
12. 总结与展望
通过以上步骤,我们完成了从SNMP的基本操作到MIB设计的全过程。SNMP作为一种强大的网络管理协议,为网络管理员和IT专业人员提供了便捷的设备管理和监控手段。
在实际应用中,可以根据不同的需求进一步扩展MIB的功能。例如,添加更多的表格和对象,以满足对设备更细致的监控和管理。同时,也可以结合其他技术,如自动化脚本和监控系统,实现更高效的网络管理。
希望本文能帮助读者更好地理解和应用SNMP,在网络管理和设备监控方面发挥更大的作用。未来,随着网络技术的不断发展,SNMP也将不断演进,为网络管理带来更多的可能性。
graph LR
A[申请企业编号] --> B[设计MIB]
B --> C[创建MIB文件]
C --> D[验证MIB文件]
D --> E[测试MIB文件]
这个流程图展示了设计和实现MIB的主要步骤,从申请企业编号开始,依次进行设计、创建、验证和测试,形成一个完整的流程。
超级会员免费看
9712

被折叠的 条评论
为什么被折叠?



