1. 簡介
pysnmp
是一個純 Python 實現的 SNMP(Simple Network Management Protocol)庫,支持 SNMPv1、SNMPv2c 和 SNMPv3 協議。用于:
- 查詢(GET)和修改(SET)網絡設備的管理信息。
- 遍歷(WALK)設備的 MIB(Management Information Base)樹。
- 實現 SNMP Agent(服務器)或 Manager(客戶端)。
2. 安裝
pip install pysnmp pysnmp-mibs # 安裝核心庫和 MIB 支持
3. 基本用法
3.1 SNMP GET 請求
from pysnmp.hlapi import *# 定義 SNMP 參數
community = 'public' # 社區名(SNMPv1/v2c)
ip_address = '192.168.1.1' # 目標設備 IP
port = 161 # 默認 SNMP 端口
oid = '1.3.6.1.2.1.1.1.0' # OID(例如:系統描述)# 發起 GET 請求
error_indication, error_status, error_index, var_binds = next(getCmd(SnmpEngine(),CommunityData(community),UdpTransportTarget((ip_address, port), timeout=2, retries=2),ContextData(),ObjectType(ObjectIdentity(oid)))
)# 處理響應
if error_indication:print(f"Error: {error_indication}")
elif error_status:print(f"Error Status: {error_status}")
else:for var_bind in var_binds:print(f"{var_bind[0]} = {var_bind[1]}")
3.2 SNMP WALK 遍歷
from pysnmp.hlapi import *error_indication, error_status, error_index, var_bind_table = next(nextCmd(SnmpEngine(),CommunityData('public'),UdpTransportTarget(('192.168.1.1', 161)),ContextData(),ObjectType(ObjectIdentity('1.3.6.1.2.1.1')), # 遍歷系統組lexicographicMode=False) # 按字典順序遍歷
)if error_indication:print(f"Error: {error_indication}")
else:for var_bind_row in var_bind_table:for var_bind in var_bind_row:print(f"{var_bind[0]} = {var_bind[1]}")
3.3 SNMP SET 操作
from pysnmp.hlapi import *error_indication, error_status, error_index, var_binds = next(setCmd(SnmpEngine(),CommunityData('private', mpModel=1), # 使用寫權限的社區名UdpTransportTarget(('192.168.1.1', 161)),ContextData(),ObjectType(ObjectIdentity('1.3.6.1.2.1.1.5.0'), OctetString('NewDeviceName')))
)if error_indication:print(f"Error: {error_indication}")
elif error_status:print(f"SET Error: {error_status}")
else:print("SET 操作成功")
4. SNMPv3 配置
SNMPv3 支持認證和加密:
from pysnmp.hlapi import *user = 'user1'
auth_key = 'authkey123'
priv_key = 'privkey123'error_indication, error_status, error_index, var_binds = next(getCmd(SnmpEngine(),UsmUserData(user,authKey=auth_key,privKey=priv_key,authProtocol=usmHMACSHAAuthProtocol, # 認證協議privProtocol=usmAesCfb128Protocol), # 加密協議UdpTransportTarget(('192.168.1.1', 161)),ContextData(),ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')))
)
5. MIB 管理
使用 MIB 名稱代替原始 OID:
from pysnmp.hlapi import *
from pysnmp.smi import compiler# 加載 MIB 文件
compiler.addMibCompiler(compiler.DirMibSource('/path/to/mibs'))
ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0).resolveWithMib()# 查詢
error_indication, error_status, error_index, var_binds = next(getCmd(SnmpEngine(),CommunityData('public'),UdpTransportTarget(('192.168.1.1', 161)),ContextData(),ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
)
6. 高級主題
6.1 異步操作
使用 AsyncCommandGenerator
實現異步請求:
from pysnmp.hlapi.asyncio import *async def snmp_get():snmp_engine = SnmpEngine()error_indication, error_status, error_index, var_binds = await getCmd(snmp_engine,CommunityData('public'),UdpTransportTarget(('192.168.1.1', 161)),ContextData(),ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')))# 處理結果...import asyncio
asyncio.run(snmp_get())
6.2 SNMP Agent 實現
創建簡單的 SNMP Agent:
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, contextsnmp_engine = engine.SnmpEngine()
config.addV1System(snmp_engine, 'my-area', 'public')
config.addTransport(snmp_engine, udp.domainName, udp.UdpTransport().openServerMode(('0.0.0.0', 161)))context.SnmpContext(snmp_engine)
cmdrsp.GetCommandResponder(snmp_engine, context.SnmpContext(snmp_engine))snmp_engine.transportDispatcher.jobStarted(1)
try:snmp_engine.transportDispatcher.runDispatcher()
except KeyboardInterrupt:snmp_engine.transportDispatcher.closeDispatcher()
7. 常見問題
Q1: 超時或無響應
- 檢查目標設備的 SNMP 服務是否啟用。
- 檢查防火墻是否允許 UDP 161 端口通信。
Q2: OID 不存在
- 使用
snmpwalk
或 MIB 瀏覽器確認目標設備支持的 OID。
Q3: 權限不足
- 確保使用正確的社區名(如
private
用于寫操作)。 - 對于 SNMPv3,檢查用戶認證和加密參數。
Q4: MIB 加載失敗
- 確認 MIB 文件路徑正確,或手動下載 MIB 文件。
通過以上步驟,可以快速上手 pysnmp
進行基本的 SNMP 操作。更詳細的文檔請參考 pysnmp 官方文檔。