星期三, 二月 07, 2007

SNMP access control (1)

前面已经了解了 SNMP 及其 MIBs,并且使用了一些工具来查看 MIB 树。但是问题是,我只能看到 system 这一分支的情况,即:
snmpwalk -v2c -c public localhost system
但是 interfaces 就不行,这样如何监控网络的流量呢?而使用 snmpget 也得不到需要的 IF-MIB:: 中的信息,使用 snmpgetnext 得到的也不正确。snmpgetnext 应该是得到下一个(NEXT)节点的信息,例如:
sh$ snmpwalk -v2c -c demo 192.168.0.98 system | head -n 2
SNMPv2-MIB::sysDescr.0 = STRING: Linux localhost.localdomain 2.6.14.2 #1 SMP Thu Jan 11 15:39:36 EST 2007 i686
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
sh$ snmpget -v2c -c demo 192.168.0.98 SNMPv2-MIB::sysDescr.0
SNMPv2-MIB::sysDescr.0 = STRING: Linux localhost.localdomain 2.6.14.2 #1 SMP Thu Jan 11 15:39:36 EST 2007 i686
sh$ snmpgetnext -v2c -c demo 192.168.0.98 SNMPv2-MIB::sysDescr.0
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
这里 -c demo 是一个 community name,而且这里也不是使用的 localhost 而是 192.168.0.98 这样的地址,这是因为更改了 snmpd.conf 的缘故,实际上,如果不更改而使用默认的 snmpd.conf,那么只能使用 -c public localhost,否则只能得到诸如:"Timeout: No Response from 192.168.0.98."这样的信息。这些会在下面讲到。

根据 net-snmp FAQ "I can see the system group, but nothing else. Why?" 上的说明,无法得到 interfaces 这个子树的原因是由于 agent 的 access control 的缘故。那么在
netsnmp FAQ "How do I configure access control?"

et-snmp FAQ "I don't understand the new access control stuff - what does it mean?"
这两个部分说明了如何来配置 agent 的 access control。

我们现在只考虑 SNMPv2,不考虑 SNMPv3。那么 access control 要解决的问题就是,我要让哪些人(who)可以获取哪些子树(what)。与此相关的几个语句是 com2sec, group, view 和 access。

那么先来看看 access 语句,它就是定义哪些人可以获取哪些子树的语句。其语法为:
access {group} "" any noauth exact {read-tree} {write-tree} {notify-tree}
这里 {group} 就是将要用 group 语句来定义的组,{read-tree} {write-tree} {notify-tree} 就是将要用 view 来定义的子树。所以 group 就是哪些人,view 就是哪些子树

于是用 group 来定义哪些人:
# com2sec notConfigUser  default       public
# group notConfigGroup v1 notConfigUser
# group notConfigGroup v2c notConfigUser
com2sec mynet 192.168.0.0/24 demo
group gmynet v1 mynet
group gmynet v2c mynet
为了更清楚的说明,这里我将原来的注释掉了。v1/v2c 是 serurityModel,就是在 snmpwalk/snmpget 这些命令使用时使用的参数如 -v2c(-v 2c)。所以我们的 group 为 gmynet,它与 mynet 这个名字(security name)是一个映射关系,而为了简便起见,也可以直接定义 group 为 mynet,而不用绕这么多圈子:
group   mynet     v1              mynet
group mynet v2c mynet
com2sec 即 community to security,实际上定义了一个基于 地址的访问控制,另外它大概还有一个将 SNMPv2/SNMPv1 的名字映射过来的作用,如上的 demo,这样在 snmpwalk/snmpget 时使用 -v2c 这样的参数时可以使用 -c demo。按照上面的方式定义之后,就只能使用上面的 snmpwalk/snmpget -v2c -c demo 192.168.0.98 这样的形式,而不能再使用 -c public localhost 了,否则就得到"Timeout: No Response from localhost"这样的出错。

然后用 view 来定义可以查看哪些子树:
view    interface included       .1.3.6.1.2.1.2
view system included .1.3.6.1.2.1.1
view system included .1.3.6.1.2.1.25.1.1
可以利用 snmptranslate 来得到 numeric 树,
sh$ snmptranslate -On IF-MIB::interfaces
.1.3.6.1.2.1.2
sh$ snmptranslate -On SNMPv2-MIB::system
.1.3.6.1.2.1.1
也可以直接使用 MIB 定义。

那么 access 的定义就应该如下:
access  mynet ""  any  noauth  exact  system  none  none
access mynet "" any noauth exact interface none none
这样,按道理就应该可以得到 interfaces 的值了。记得要使 agent 重新读取配置文件,在 RHEL4 下面使用 /etc/init.d/snmpd restart 即可。

但实际上却不行:
sh$ snmpwalk -v2c -c demo 192.168.0.98 interfaces
IF-MIB::interfaces = No Such Object available on this agent at this OID
sh$ snmpget -v2c -c demo 192.168.0.98 IF-MIB::ifDescr.1
IF-MIB::ifDescr.1 = No Such Object available on this agent at this OID
但是如果使用如下的设置却可以:
view    all       included       .1
access mynet "" any noauth exact all none none

sh$ snmpwalk -v2c -c demo 192.168.0.98 interface
IF-MIB::ifNumber.0 = INTEGER: 4
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifIndex.4 = INTEGER: 4
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: eth0
IF-MIB::ifDescr.3 = STRING: eth1
IF-MIB::ifDescr.4 = STRING: sit0
IF-MIB::ifType.1 = INTEGER: softwareLoopback(24)
IF-MIB::ifType.2 = INTEGER: ethernetCsmacd(6)
IF-MIB::ifType.3 = INTEGER: ethernetCsmacd(6)
IF-MIB::ifType.4 = INTEGER: tunnel(131)
IF-MIB::ifMtu.1 = INTEGER: 16436
IF-MIB::ifMtu.2 = INTEGER: 1500
IF-MIB::ifMtu.3 = INTEGER: 1500
IF-MIB::ifMtu.4 = INTEGER: 1480
IF-MIB::ifSpeed.1 = Gauge32: 10000000
IF-MIB::ifSpeed.2 = Gauge32: 100000000
IF-MIB::ifSpeed.3 = Gauge32: 10000000
IF-MIB::ifSpeed.4 = Gauge32: 0
IF-MIB::ifPhysAddress.1 = STRING:
IF-MIB::ifPhysAddress.2 = STRING: 0:2:b3:b0:59:36
IF-MIB::ifPhysAddress.3 = STRING: 0:2:b3:b0:59:4a
IF-MIB::ifPhysAddress.4 = STRING: 0:0:0:0:59:4a
IF-MIB::ifAdminStatus.1 = INTEGER: up(1)
IF-MIB::ifAdminStatus.2 = INTEGER: up(1)
IF-MIB::ifAdminStatus.3 = INTEGER: down(2)
IF-MIB::ifAdminStatus.4 = INTEGER: down(2)
IF-MIB::ifOperStatus.1 = INTEGER: up(1)
IF-MIB::ifOperStatus.2 = INTEGER: up(1)
IF-MIB::ifOperStatus.3 = INTEGER: down(2)
IF-MIB::ifOperStatus.4 = INTEGER: down(2)
IF-MIB::ifInOctets.1 = Counter32: 381118
IF-MIB::ifInOctets.2 = Counter32: 125019173
IF-MIB::ifInOctets.3 = Counter32: 0
IF-MIB::ifInOctets.4 = Counter32: 0
IF-MIB::ifInUcastPkts.1 = Counter32: 4308
IF-MIB::ifInUcastPkts.2 = Counter32: 1069602
IF-MIB::ifInUcastPkts.3 = Counter32: 0
IF-MIB::ifInUcastPkts.4 = Counter32: 0
IF-MIB::ifInDiscards.1 = Counter32: 0
IF-MIB::ifInDiscards.2 = Counter32: 0
IF-MIB::ifInDiscards.3 = Counter32: 0
IF-MIB::ifInDiscards.4 = Counter32: 0
IF-MIB::ifInErrors.1 = Counter32: 0
IF-MIB::ifInErrors.2 = Counter32: 0
IF-MIB::ifInErrors.3 = Counter32: 0
IF-MIB::ifInErrors.4 = Counter32: 0
IF-MIB::ifOutOctets.1 = Counter32: 383414
IF-MIB::ifOutOctets.2 = Counter32: 1770179210
IF-MIB::ifOutOctets.3 = Counter32: 0
IF-MIB::ifOutOctets.4 = Counter32: 0
IF-MIB::ifOutUcastPkts.1 = Counter32: 4340
IF-MIB::ifOutUcastPkts.2 = Counter32: 1319881
IF-MIB::ifOutUcastPkts.3 = Counter32: 0
IF-MIB::ifOutUcastPkts.4 = Counter32: 0
IF-MIB::ifOutDiscards.1 = Counter32: 0
IF-MIB::ifOutDiscards.2 = Counter32: 0
IF-MIB::ifOutDiscards.3 = Counter32: 0
IF-MIB::ifOutDiscards.4 = Counter32: 0
IF-MIB::ifOutErrors.1 = Counter32: 0
IF-MIB::ifOutErrors.2 = Counter32: 0
IF-MIB::ifOutErrors.3 = Counter32: 0
IF-MIB::ifOutErrors.4 = Counter32: 0
IF-MIB::ifOutQLen.1 = Gauge32: 0
IF-MIB::ifOutQLen.2 = Gauge32: 0
IF-MIB::ifOutQLen.3 = Gauge32: 0
IF-MIB::ifOutQLen.4 = Gauge32: 0
IF-MIB::ifSpecific.1 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.2 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.3 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.4 = OID: SNMPv2-SMI::zeroDotZero

sh$ snmpget -v2c -c demo 192.168.0.98 IF-MIB::ifDescr.1
IF-MIB::ifDescr.1 = STRING: lo
sh$ snmpget -v2c -c demo 192.168.0.98 IF-MIB::ifDescr.2
IF-MIB::ifDescr.2 = STRING: eth0
sh$ snmpgetnext -v2c -c demo 192.168.0.98 IF-MIB::ifDescr.2
IF-MIB::ifDescr.3 = STRING: eth1
那么最初的配置有什么问题呢?

无论如何,为安全起见,只做如下的 access:
sh$ snmptranslate .1.3.6.1.2.1
SNMPv2-SMI::mib-2
sh$ snmptranslate -Of .1.3.6.1.2.1
.iso.org.dod.internet.mgmt.mib-2

sh$ cat /etc/snmp/snmpd.conf
view system included .1.3.6.1.2.1
access mynet "" any noauth exact system none none

没有评论: