【问题标题】:python net-snmp loading mibspython net-snmp 加载 mibs
【发布时间】:2011-12-16 22:28:23
【问题描述】:

我正在使用 net-snmp 的 python 库对各种开关进行一些长查询。我希望能够加载新的 mib——但我找不到任何有关如何执行此操作的文档。

PySNMP 似乎相当复杂,需要我为每个 mib 创建 Python 对象(这对我来说无法扩展);所以我坚持使用 net-snmp 的库(除了加载 mib 之外,这些库还不错)。

我知道我可以将 -m-M 选项与 net-snmp 命令行工具一起使用,并且有关于预编译 net-snmp 套件的文档(./configuremake 等)与所有的 mib(我也假设进入库);如果 Python 库不提供加载 mib 的功能,我是否可以至少配置 net-snmp 以提供我的 Python 库访问 mib 而无需重新编译?

【问题讨论】:

  • 我想你从来没有从其他来源找到过这个问题的答案?我遇到了同样的问题。

标签: python net-snmp mib pysnmp


【解决方案1】:

毕竟我找到了答案。来自snmpcmd(1) 手册页:

   -m MIBLIST
          Specifies a colon separated  list  of  MIB  modules  (not
          files)  to load for this application.  This overrides (or
          augments) the environment variable  MIBS,  the  snmp.conf
          directive  mibs,  and the list of MIBs hardcoded into the
          Net-SNMP library.

这里的关键部分是您可以像使用-m 命令行选项一样使用MIBS 环境变量...并且对此的支持是在库级别实现的。这意味着如果你在启动 Python 之前定义了MIBS 环境变量,它将影响netsnmp 库的行为:

$ python 
Python 2.7.2 (default, Oct 27 2011, 01:40:22) 
[GCC 4.6.1 20111003 (Red Hat 4.6.1-10)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import netsnmp
>>> os.environ['MIBS'] = 'UPS-MIB:SNMPv2-SMI'
>>> oid = netsnmp.Varbind('upsAlarmOnBattery.0')
>>> netsnmp.snmpget(oid, Version=1, DestHost='myserver', Community='public')
('0',)
>>> 

请注意,您必须在调用任何netsnmp 模块函数之前设置os.environ['MIBS'](因为这将加载库并且在此之后的任何环境更改都不会影响)。

您也可以(显然)在 Python 之外设置环境变量:

$ export MIBS='UPS-MIB:SNMPv2-SMI'
$ python
>>> import netsnmp
>>> oid = netsnmp.Varbind('upsAlarmOnBattery.0')
>>> netsnmp.snmpget(oid, Version=1, DestHost='myserver', Community='public')
('0',)
>>> 

【讨论】:

  • 太棒了!我还发现,除此之外,你可以修改它搜索的MIB目录,使用环境变量MIBDIRS
  • 我只想说非常感谢您提到在加载库之前导出 env 变量。我在使用 easy-snmp 时遇到了问题,它似乎没有处理我导出的 MIB 变量,所以我尝试了与您推荐的相同的方法,它没有问题。唯一的区别是我必须在导入库本身之前导出变量。
【解决方案2】:

如果正确配置 net-snmp,从技术上讲,您不必初始化或导出任何环境变量。

(请注意,我使用的是 Ubuntu 12.04.1 LTS,所以我真的不必从源代码编译 net-snmp,尽管我将涵盖我为完整性所做的全部内容,但这应该只是如果您想将一些 MIB 设置为由 net-snmp 或其 Python 绑定自动插入。)

首先我做了sudo apt-get install libsnmp-base libsnmp-python libsnmp15 snmp

这将安装 net-snmp 及其库以及 Python 绑定。它还在/usr/share/mibs/netsnmp/ 中安装了一些默认的MIB(仅适用于net-snmp)。如果您想获取一堆其他 IETF/IANA MIB,请执行以下操作:

sudo apt-get install snmp-mibs-downloader

正如您所料,它会将大量其他标准 MIB(包括 IF-MIB 等)下载到 /var/lib/mibs/iana/var/lib/mibs/ietf 以及 /usr/share/mibs/iana/usr/share/mibs/ietf。如果您想再次下载 MIB,snmp-mibs-downloader 软件包还会为您提供 /usr/bin/download-mibs 命令。

接下来,使用snmpconf 命令设置您的net-snmp 环境:

$ snmpconf -h
/usr/bin/snmpconf [options] [FILETOCREATE...]
options:
  -f           overwrite existing files without prompting
  -i           install created files into /usr/share/snmp.
  -p           install created files into /home/$USER/.snmp.
  -I DIR       install created files into DIR.
  -a           Don't ask any questions, just read in current
               current .conf files and comment them
  -r all|none  Read in all or none of the .conf files found.
  -R file,...  Read in a particular list of .conf files.
  -g GROUP     Ask a series of GROUPed questions.
  -G           List known GROUPs.
  -c conf_dir  use alternate configuration directory.
  -q           run more quietly with less advice.
  -d           turn on debugging output.
  -D           turn on debugging dumper output.

我使用了snmpconf -p 并浏览了菜单项。该过程基本上会查找现有的 snmp.conf 文件(默认为/etc/snmp/snmp.conf)并将这些文件与新创建的配置文件合并,该文件将放入由-p 选项指定的/home/$USER/.snmp/snmp.conf。从那里开始,您实际上只需要告诉snmpconf 在哪里寻找 MIB,但是脚本提供了许多有用的选项,用于在snmp.conf 中生成配置指令。

完成snmpconf 后,您应该有一个主要工作的环境。这是我的(非常简单的)/home/$USER/.snmp/snmp.conf 的样子:

###########################################################################
#
# snmp.conf
#
#   - created by the snmpconf configuration program
#

###########################################################################
# SECTION: Textual mib parsing
#
#   This section controls the textual mib parser.  Textual
#   mibs are parsed in order to convert OIDs, enumerated
#   lists, and ... to and from textual representations
#   and numerical representations.

# mibdirs: Specifies directories to be searched for mibs.
#   Adding a '+' sign to the front of the argument appends the new
#   directory to the list of directories already being searched.
#   arguments: [+]directory[:directory...]

mibdirs : +/usr/share/mibs/iana:/usr/share/mibs/ietf:/usr/share/mibs/netsnmp:/home/$USERNAME/.snmp/mibs/newmibs

# mibs: Specifies a list of mibs to be searched for and loaded.
#   Adding a '+' sign to the front of the argument appends the new
#   mib name to the list of mibs already being searched for.
#   arguments: [+]mibname[:mibname...]

mibs +ALL

一些陷阱:

  1. net-snmp 加载此配置文件时,它不会进行递归目录搜索,因此您必须提供 MIB 所在目录的绝对路径。
  2. 如果您选择告诉net-snmp 加载这些目录中的所有 300 多个 MIB,它可能会减慢您的 SNMP 查询速度,并且由于某些 MIB 会要么是过时的、错误的,要么是尝试从不存在的 MIB 导入定义,或者包没有下载。您的选择是:告诉snmpconf 您希望如何处理这些错误,或者找出丢失或过时的内容并自己下载 MIB。如果你选择后者,你可能会发现自己陷入了 MIB 兔子洞,所以请记住这一点。就个人而言,我建议您将它们全部加载,然后向后工作以仅加载对轮询特定设备有意义的给定 MIB。
  3. 您在snmp.conf 的搜索路径中指定的目录顺序很重要,尤其是在某些 MIB 引用或依赖于其他 MIB 时。我犯了一个错误,我只需在iana 目录中获取一个MIB 文件并将其移动到ietf 目录中即可。我确信有一种方法可以以编程方式找出哪些 MIB 依赖于其他 MIB,并使它们在一个目录中愉快地共存,但我不想浪费大量时间来解决这个问题。

这个故事的寓意是,如果你有一个适当的 snmp.conf,你应该能够做到这一点:

$ python
>>> import netsnmp
>>> oid = netsnmp.VarList(netsnmp.Varbind('dot1qTpFdbPort'))
>>> res = netsnmp.snmpwalk(oid, Version=2, DestHost='10.0.0.1', Community='pub')
>>> print res
('2', '1')
>>>

仅供参考,我省略了一堆 STDERR 输出,但如果您愿意,可以通过 snmp.conf 配置指令再次配置您的环境以将 STDERR 转储到日志文件。

希望这会有所帮助。

【讨论】:

  • 感谢您的详细解释。我不知道snmpconf(但我现在知道了!) - 然而,我真正想要的是能够以编程方式控制 python 中的哪些 mib 文件(不仅仅是目录)。还是谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多