You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pysnmp时能否忽略返回报文的SNMP社区字符串?

让pysnmp忽略入站报文社区字符串的解决办法

问题根源

pysnmp默认会校验响应报文的社区字符串与请求时发送的是否一致,你遇到的情况是设备返回的社区字符串为public,和你发送的xxxxxx不匹配,所以被拦截导致无法正常工作。要解决这个问题,就得跳过这个校验逻辑。

具体实现方式

方法一:自定义社区数据类(推荐)

写一个继承自CommunityData的子类,重写校验方法让其直接返回True,以此绕过社区字符串的校验:

from pysnmp.hlapi import CommunityData, SnmpEngine, getCmd, ContextData, ObjectType, ObjectIdentity
from pysnmp.proto.secmod.rfc1902 import CommunityData as BaseCommunityData

class NoCheckCommunityData(BaseCommunityData):
    def verifyOutgoingMsg(self, *args):
        return True  # 跳过出站报文校验(可选,核心是入站校验)

    def verifyIncomingMsg(self, *args):
        return True  # 直接跳过入站报文的社区字符串校验

# 使用自定义类发起SNMP请求
snmp_engine = SnmpEngine()
# 此处填入你实际要发送的社区字符串xxxxxx
community_data = NoCheckCommunityData('xxxxxx')

errorIndication, errorStatus, errorIndex, varBinds = next(getCmd(
    snmp_engine,
    community_data,
    ('目标设备IP', 161),
    ContextData(),
    ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0'))  # 替换为你需要查询的OID
))

if errorIndication:
    print(errorIndication)
else:
    if errorStatus:
        print(f'{errorStatus.prettyPrint()} at {errorIndex and varBinds[int(errorIndex)-1][0] or "?"}')
    else:
        for varBind in varBinds:
            print(f'{varBind[0].prettyPrint()} = {varBind[1].prettyPrint()}')

方法二:直接修改默认校验逻辑(不推荐)

如果不想自定义类,也可以直接替换CommunityData的校验方法,但这种方式会全局生效,在多请求、多线程场景下容易引发问题:

from pysnmp.proto.secmod.rfc1902 import CommunityData

# 替换原有校验方法,直接返回True跳过校验
CommunityData.verifyIncomingMsg = lambda self, *args: True
CommunityData.verifyOutgoingMsg = lambda self, *args: True

# 之后正常使用pysnmp的API即可

注意事项

  • 跳过社区字符串校验会降低SNMP通信的安全性,毕竟社区字符串是SNMPv2c最基础的身份验证机制,能不用尽量不用。
  • 优先排查设备端的配置问题:为什么设备返回的社区字符串是public而非你请求时的xxxxxx?这可能是设备配置错误,或者存在中转代理修改了报文。

内容的提问来源于stack exchange,提问作者Jeremy Palmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:10:56