使用pysnmp v3执行walk时遇‘Ciphering services not available’错误
SNMPv3 pysnmp脚本报错:Ciphering services not available
问题详情
我能通过命令行成功执行以下SNMPv3的snmpwalk命令:
snmpwalk -v3 -m +MY-MIB-ROOT -m +MY-MIB -l authPriv -u MYUSER -a SHA -A "XXXXXXXX" -x AES -X "XXXXXXXX" 1.2.3.4 .1.3.6.1.4.1.52330.6.1.2
尝试用pysnmp编写Python脚本实现相同功能,代码如下:
import asyncio from pysnmp.hlapi.v3arch.asyncio import * from pysnmp.smi import builder, view, compiler import logging logging.basicConfig(level=logging.DEBUG) # snmpwalk -v3 -m +MY-MIB-ROOT -m +MY-MIB -l authPriv -u MYUSER -a SHA -A "XXXXXXXX" -x AES -X "XXXXXXXX" 1.2.3.4 .1.3.6.1.4.1.52330.6.1.2 # Load MIBs mibBuilder = builder.MibBuilder() compiler.addMibCompiler(mibBuilder, sources=['file:///usr/share/snmp/mibs']) mibViewController = view.MibViewController(mibBuilder) loadedModules = mibBuilder.mibSymbols.keys() print("loadedModules:", loadedModules) async def run(varBinds): snmpEngine = SnmpEngine() while True: print("A") errorIndication, errorStatus, errorIndex, varBindTable = await bulkCmd( snmpEngine, UsmUserData( 'MYUSER', 'XXXXXXXX', 'XXXXXXXX', authProtocol=usmHMACSHAAuthProtocol, privProtocol=usmAesCfb128Protocol, ), await UdpTransportTarget.create(('1.2.3.4', 161)), ContextData(), 0, 50, *varBinds ) if errorIndication: print(errorIndication) break elif errorStatus: print( f"{errorStatus.prettyPrint()} at {varBinds[int(errorIndex) - 1][0] if errorIndex else '?'}" ) else: for varBind in varBindTable: oid = varBind.__getitem__(0) print(oid) varBinds = varBindTable if isEndOfMib(varBinds): break return asyncio.run( run([ObjectType(ObjectIdentity('1.3.6.1.4.1.52330.6.1.2'))]) )
但运行脚本时出现错误:
Ciphering services not available
运行环境为Red Hat Enterprise Linux release 9.4(Plow)的虚拟环境,已安装的依赖版本如下:
$ pip list Package Version ------------------ --------- certifi 2024.8.30 charset-normalizer 3.3.2 idna 3.10 Jinja2 3.1.4 MarkupSafe 2.1.5 pip 24.2 ply 3.11 pyasn1 0.6.1 pycryptodomex 3.20.0 pysmi 1.5.0 pysnmp 7.1.4 requests 2.32.3 setuptools 53.0.0 urllib3 2.2.3
解决方案
这个错误是因为pysnmp无法自动识别已安装的pycryptodomex加密后端,需要手动注册并调整脚本逻辑。
1. 注册加密后端
在脚本开头添加代码,强制让pysnmp使用pycryptodomex作为加密引擎:
from pysnmp.security import crypto from pycryptodomex import Cryptodome # 注册Cryptodome加密后端 crypto.setCryptoEngine(Cryptodome)
2. 修复MIB加载逻辑
原脚本未显式加载指定MIB,调整代码确保MY-MIB-ROOT和MY-MIB被正确加载:
# 替换原MIB加载代码 mibBuilder = builder.MibBuilder() compiler.addMibCompiler(mibBuilder, sources=['file:///usr/share/snmp/mibs']) # 显式加载目标MIB mibBuilder.loadModules('MY-MIB-ROOT', 'MY-MIB') mibViewController = view.MibViewController(mibBuilder)
3. 优化UsmUserData参数
使用关键字参数明确指定认证/加密密钥,避免参数顺序混淆:
UsmUserData( 'MYUSER', authKey='XXXXXXXX', privKey='XXXXXXXX', authProtocol=usmHMACSHAAuthProtocol, privProtocol=usmAesCfb128Protocol, )
修改后的完整脚本
import asyncio from pysnmp.hlapi.v3arch.asyncio import * from pysnmp.smi import builder, view, compiler from pysnmp.security import crypto from pycryptodomex import Cryptodome import logging # 注册加密后端 crypto.setCryptoEngine(Cryptodome) logging.basicConfig(level=logging.DEBUG) # 加载指定MIB mibBuilder = builder.MibBuilder() compiler.addMibCompiler(mibBuilder, sources=['file:///usr/share/snmp/mibs']) mibBuilder.loadModules('MY-MIB-ROOT', 'MY-MIB') mibViewController = view.MibViewController(mibBuilder) loadedModules = mibBuilder.mibSymbols.keys() print("loadedModules:", loadedModules) async def run(varBinds): snmpEngine = SnmpEngine() while True: errorIndication, errorStatus, errorIndex, varBindTable = await bulkCmd( snmpEngine, UsmUserData( 'MYUSER', authKey='XXXXXXXX', privKey='XXXXXXXX', authProtocol=usmHMACSHAAuthProtocol, privProtocol=usmAesCfb128Protocol, ), await UdpTransportTarget.create(('1.2.3.4', 161)), ContextData(), 0, 50, *varBinds ) if errorIndication: print(errorIndication) break elif errorStatus: print(f"{errorStatus.prettyPrint()} at {varBinds[int(errorIndex)-1][0] if errorIndex else '?'}") else: for varBind in varBindTable: oid, value = varBind print(f"{oid.prettyPrint()} = {value.prettyPrint()}") varBinds = varBindTable if isEndOfMib(varBinds): break asyncio.run(run([ObjectType(ObjectIdentity('1.3.6.1.4.1.52330.6.1.2'))]))
额外排查点
- 确认虚拟环境中
pycryptodomex安装正常,可执行pip show pycryptodomex检查路径 - 卸载可能冲突的旧加密库(如
pycrypto) - 检查RHEL 9.4的SELinux策略,确保脚本无加密操作权限限制
内容的提问来源于stack exchange,提问作者Tino
相关产品推荐
相关产品推荐

