Python SNMP 模块

2025年03月17日 | 阅读 9 分钟

SNMP,即简单网络管理协议,是 SDN 的必要工具,也是通过软件控制设备的最佳选择。除此之外,应用程序内访问是 SNMP 的主要目的。毫无疑问,所有监控系统都利用 SNMP 来监控和控制服务器和网络设备。如果能在脚本中拥有 SNMP 带来的巨大能力,那将是惊人的。因此,在本教程中,我们将讨论在 Python 编程语言中利用 SNMP。

但在开始之前,让我们先讨论 SNMP。

理解 SNMP

SNMP,也称为简单网络管理协议,是管理服务器和远程设备(代理)之间通信的标准方式。SNMP 的目标是让管理器理解(甚至更改)代理上的数据。例如,管理器可以检查哪些接口已启动、哪些接口已关闭,或者更改远程设备的主机名。

SNMP module in Python

我们的脚本使管理站上的 Python 程序能够控制执行 SNMP 代理的远程设备。

SNMP 代理将管理器可以读取或更改的大部分详细信息准备在一个特殊的表中,即 MIB。MIB 是一种树状结构,树中的每个节点都用一个数字表示。例如,1.3.6.1.2.1.1 表示系统的描述。如果我们中的一些人想知道这串数字从何而来,这就是整个树结构!每个数字都与一个名称相关联。因此,我们可以将其转换为更具说明性的 iso.org.dod.internet.mgmt.mib-2.system.sysDescr

现在,让我们借助 Python PySNMP 模块来讨论在 Python 编程语言中使用 SNMP。

理解 PySNMP 模块

PySNMP 是一个用于 Python 的开源模块。与 telnet 或 HTTP 不同,Python 原生不实现 SNMP。毕竟,只有网络和系统工程师才需要工厂中的 Python 开发人员。PySNMP 在弥补原生 Python 缺失方面做得很好。通常,PySNMP 模块允许我们以代理或管理器的身份使用任何版本的 SNMP。创建代理意味着我们正在构建应用程序或设备。但是,我们只会讨论在管理远程设备中使用 PySNMP

此外,我们将了解 Python 中 PySNMP 的不同功能。本教程的主要目标是创建一个可以让我们轻松操作的快速 Python 程序。在该程序中,我们将拥有我们所需的所有 SNMP 操作。

那么,让我们开始吧。

准备环境

首先,我们必须安装 PySNMP 模块。我们可以使用 pip 安装程序,借助以下命令安装所需的模块。

语法

该模块将以 Python 和 pip 的版本安装到系统中。

验证安装

为了检查模块是否已正确安装到系统中,我们可以尝试导入模块并执行程序。

安装完成后,创建一个新的 Python 文件并在其中输入以下语法。

示例

现在,保存文件并在命令提示符下使用以下命令运行该文件。

语法

如果程序运行没有出现任何导入错误,则表示模块已正确安装。否则,建议重新安装模块并参考其官方文档。

理解 Python SNMP Get 操作

SNMP 的 Get 操作使我们能够检索 MIB 中单个对象的值。我们还可以利用它来获取单个对象的列表。我们可以开始编写 get() 函数,如下所示:

示例

说明

从上面的代码片段中,我们可以观察到 PySNMP 高级 API 的利用。我们定义了一个简单的函数 get(),它首先需要一个目标(IP 或远程设备名称)。然后,它需要我们想要获取的对象 ID (oids) 列表,之后需要一组用于会话身份验证的凭据。如果需要,我们还可以指定一个不同的 UDP 端口,并使用一个现有的 SNMP 引擎或自定义上下文。我们可能需要对同一设备上的所有操作使用相同的引擎,这可以节省资源。然而,对于一个简单的代码片段来说,这并不是必需的,所以我们可以忽略引擎和上下文。

该函数为 SNMP 会话生成一个处理程序,并从中获取详细信息。为了执行此操作,它依赖于我们必须创建的两种方法:construct_object_typesfetch

构建对象类型

正如我们之前讨论的,拥有更多的能力意味着更多的复杂性。因此,hlapi.getCmd() 函数需要一些特殊的 hlapi.ObjectType 对象,而不是简单的字符串 OID 列表。因此,construct_object_type 函数根据 PySNMP 的需要创建。如果我们没有时间,我们可以简单地将其复制并粘贴到代码中。然而,这应该是一个非常简单的函数;让我们看看:

示例

说明

上面的代码片段返回一个列表,可以通过在前面加上 * 来扩展,就像我们在 get() 方法中那样。

获取数据

fetch() 函数是 Python SMP 教程的杰作。通常,我们编写它以便可以将其重新用于基于 PySNMP 的其他函数,例如 get-bulk。它只是根据 count 变量在处理程序上多次循环。如果出现任何错误,进程将停止,并返回 RuntimeError 消息。在任何其他情况下,它将数据存储在字典列表中。

示例

说明

在上面的代码片段中,我们构建了 try-except 方法来出于特定原因停止迭代。在用户指定的计数高于我们实际拥有的对象数量的情况下,我们只需停止并返回我们目前获得的数据。这就是构造的目的。

为什么要返回一个字典列表?在每次 get 操作中,我们可以获取各种对象 ID。因此,每个字典都将包含对象 ID 作为键,MIB 中 OID 的值作为该键的值。在单个 get 中需要多个 OID 的情况下,我们将返回一个包含多个键的字典。但为什么要使用列表呢?使用 get 操作,我们只能获取一次数据。然而,正如我们将在 get bulk 中看到的那样,我们可能需要在不同实例上多次获取类似的详细信息。让我们考虑一个例子以更好地理解。假设我们需要检查所有接口上的错误:信息始终是错误;但是,我们有不同的实例(每个接口一个)。我们可以使用列表将其可视化,其中每个数据元素都是一个表示实例的字典。

注意:fetch() 函数依赖于我们必须创建的另一个函数:cast()。此函数将从 PySNMP 接收到的数据转换为 int、float 或 string。

让我们考虑以下代码片段:

示例

说明

在上面的代码片段中,我们定义了一个函数,其中使用了 try-except 方法来检查是否出现任何错误。

提供凭据

PySNMP 库的身份验证系统强大且相当直接。没有理由在其之上编写额外的层,因此我们可以直接使用它。get() 函数以及其余函数在凭据变量中都有一个特殊的身份验证对象。如果我们使用 SNMPv2c 或 SNMPv3,此对象会有所不同。

在 SNMPv2c(或更低版本)的情况下,我们必须指定社区。我们可以使用 CommunityData 对象来完成,如下所示:

语法

相反,SNMPv3 很复杂。这是因为它使用具有两个密码和两个协议的用户:第一个用于身份验证,另一个用于加密。因此,我们必须指定用户名、身份验证密码、身份验证协议、加密密码和加密协议。我们可以使用 UsmUserData 类来完成。

让我们考虑以下示例以更好地理解。

示例

说明

在上面的代码片段中,我们使用了 UsmUserData 类并输入了所需的详细信息。这比看起来要简单;我们必须知道远程设备的协议。但是,我们中的一些人可能会参考 UsmUserData 的完整官方文档。

获取主机名

现在,让我们测试 get() 函数。我们将使用它来检索设备的主机名,即对象 1.3.6.1.2.1.1.5.0。我们可以简单地编写以下代码片段:

示例

输出

{'1.3.6.1.2.1.1.5.0': 'R1.sdn.local'}

说明

在上面的代码片段中,我们打印了 get() 函数获取设备主机名的结果。

注意:这里,我们没有得到一个字典列表,而只是一个字典。这是故意的,get() 函数将始终如此。通常,我们知道该函数只执行一次;它不能创建多个实例。因此,我们返回从 fetch() 获得的第一个元素。

理解 Python SNMP Get Bulk 操作

get_bulk() 方法检索同一对象 ID 的多个实例,例如每个接口一个。当处理表(如接口一的路由表)时,此函数变得可支持。它非常直接,功能与 get() 方法类似。但它需要一些额外的详细信息:从哪个对象开始以及需要获取的实例数量。我们在 start_fromcount 中提供它们。

让我们考虑以下代码片段来理解 get_bulk() 函数的工作原理。

示例

说明

在上面的代码片段中,我们定义了 get_bulk() 函数,其中指定了处理程序。最后,我们返回了 fetch() 函数。因此,我们期望得到一个字典列表,所以我们不必像使用 get() 函数那样只提取第一个字典。

理解 Python SNMP Get Bulk Auto

get_bulk_auto() 函数是 get_bulk() 函数的改进版本。假设我们想使用 get_bulk() 遍历设备接口。我们怎么知道接口的数量呢?这变得必要,因为 SNMP 需要知道迭代多少次。我们无法提前知道这一点;但是,我们可以使用 SNMP 作为选项来查找此信息。

我们可以使用 get_bulk_auto() 函数来告诉代码从另一个 OID 检索 count 变量。因此,我们可以指定一个对象 ID 而不是指定一个数字。该函数将对该对象执行 get 操作并将其用作 count

让我们考虑以下示例以更好地理解。

示例

说明

在上面的代码片段中,我们定义了 get_bulk_auto() 函数,并使用 get() 指定了 count 变量,并返回 get_bulk() 函数。

使用 Python SNMP Get Bulk & Get Bulk Auto

让我们考虑执行以下代码片段。

示例

输出

1.3.6.1.2.1.2.2.1.2.1=FastEthernet1/0
1.3.6.1.2.1.31.1.1.1.18.1=
1.3.6.1.2.1.2.2.1.2.2=FastEthernet0/0
1.3.6.1.2.1.31.1.1.1.18.2=
1.3.6.1.2.1.2.2.1.2.3=FastEthernet0/1
1.3.6.1.2.1.31.1.1.1.18.3=Test Desc
1.3.6.1.2.1.2.2.1.2.4=Serial2/0
1.3.6.1.2.1.31.1.1.1.18.4=
1.3.6.1.2.1.2.2.1.2.5=Serial2/1
1.3.6.1.2.1.31.1.1.1.18.5=
1.3.6.1.2.1.2.2.1.2.6=Serial2/2
1.3.6.1.2.1.31.1.1.1.18.6=
1.3.6.1.2.1.2.2.1.2.7=Serial2/3
1.3.6.1.2.1.31.1.1.1.18.7=
1.3.6.1.2.1.2.2.1.2.9=Null0
1.3.6.1.2.1.31.1.1.1.18.9=