如何创建自定义MiB(含自定义OID)以通过Python脚本传输数据
SNMP自定义MIB开发与Python实践建议
一、自定义MIB核心落地步骤
不用纠结晦涩的ASN.1标准细节,按以下流程快速实现自定义OID分支与变量:
- 编写极简MIB文件:采用SMIv2格式,测试阶段可先用私有实验OID(比如
1.3.6.1.4.1.424242,正式环境需向IANA申请企业编号),示例如下:MY-MIB DEFINITIONS ::= BEGIN IMPORTS enterprises FROM RFC1155-SMI; myEnterprise OBJECT IDENTIFIER ::= { enterprises 424242 } myCustomBranch OBJECT IDENTIFIER ::= { myEnterprise 1 } myCustomTempVar OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS read-write STATUS current DESCRIPTION "自定义温度变量" ::= { myCustomBranch 1 } myCustomMsgVar OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-write STATUS current DESCRIPTION "自定义字符串变量" ::= { myCustomBranch 2 } END - 加载MIB到SNMP服务器:
- Linux(Net-SNMP):将MIB文件放到
/usr/share/snmp/mibs/,修改snmpd.conf添加权限配置:
重启view all included .1.3.6.1.4.1.424242 access notConfigGroup "" any noauth exact all none nonesnmpd服务生效。 - Windows:将MIB文件放到
C:\Windows\System32\mibs,打开SNMP管理器加载该MIB,在权限配置中允许访问自定义OID分支。
- Linux(Net-SNMP):将MIB文件放到
- 绑定变量与业务逻辑:
- Linux下用Net-SNMP的
pass_persist指令(比pass更高效),在snmpd.conf中添加:
对应的pass_persist .1.3.6.1.4.1.424242 /usr/bin/python3 /path/to/your/snmp_handler.pysnmp_handler.py核心框架:import sys import sqlite3 def get_db_data(oid): # 从数据库读取对应OID的数据 conn = sqlite3.connect('snmp_data.db') cursor = conn.cursor() cursor.execute("SELECT value FROM snmp_vars WHERE oid=?", (oid,)) result = cursor.fetchone() conn.close() return result[0] if result else "0" def set_db_data(oid, value): # 将数据写入数据库 conn = sqlite3.connect('snmp_data.db') cursor = conn.cursor() cursor.execute("REPLACE INTO snmp_vars(oid, value) VALUES(?, ?)", (oid, value)) conn.commit() conn.close() def handle_request(): while True: req = sys.stdin.readline().strip() if not req: break if req == "GET": oid = sys.stdin.readline().strip() value = get_db_data(oid) if oid.endswith("1"): # 对应myCustomTempVar print("TYPE Integer32") else: # 对应myCustomMsgVar print("TYPE DisplayString") print(f"VALUE {value}") elif req == "SET": oid = sys.stdin.readline().strip() value = sys.stdin.readline().strip() set_db_data(oid, value) print("SUCCESS") sys.stdout.flush() if __name__ == "__main__": handle_request() - Windows下可直接用Python的
pysnmp搭建自定义代理,替代系统SNMP服务,避免复杂的扩展API配置。
- Linux下用Net-SNMP的
二、Python开发工具推荐
- pysnmp:纯Python实现的SNMP全功能库,支持自定义代理、MIB解析、SNMPv1/v2c/v3,适合快速迭代。无需依赖系统SNMP服务,直接搭建轻量代理的示例:
from pysnmp.entity import engine, config from pysnmp.entity.rfc3413 import cmdrsp, context from pysnmp.carrier.asyncore.dgram import udp # 模拟数据库数据 snmp_data = { ".1.3.6.1.4.1.424242.1.1": 25, ".1.3.6.1.4.1.424242.1.2": "Test Message" } def handle_get(snmp_engine, ctx_id, ctx_name, var_binds, cb_ctx): # 处理GET请求,返回模拟数据 result = [] for oid, _ in var_binds: oid_str = str(oid) result.append((oid, snmp_data.get(oid_str, 0))) return cmdrsp.getResponse(snmp_engine, ctx_id, ctx_name, var_binds, result) def handle_set(snmp_engine, ctx_id, ctx_name, var_binds, cb_ctx): # 处理SET请求,更新模拟数据 for oid, value in var_binds: snmp_data[str(oid)] = value return cmdrsp.setResponse(snmp_engine, ctx_id, ctx_name, var_binds, var_binds) # 初始化SNMP引擎与服务 snmp_engine = engine.SnmpEngine() config.addTransport(snmp_engine, udp.domainName, udp.UdpTransport().openServerMode(('0.0.0.0', 161))) config.addV1System(snmp_engine, 'my-area', 'public') snmp_context = context.SnmpContext(snmp_engine) # 注册请求处理函数 cmdrsp.GetCommandResponder(snmp_engine, snmp_context, handle_get) cmdrsp.SetCommandResponder(snmp_engine, snmp_context, handle_set) # 启动服务 snmp_engine.transportDispatcher.jobStarted(1) try: snmp_engine.transportDispatcher.runDispatcher() except: snmp_engine.transportDispatcher.closeDispatcher() raise - net-snmp-python:Net-SNMP的Python绑定,适合与系统SNMP服务深度交互,快速完成MIB加载、OID读写操作。
三、实用学习资源
- Net-SNMP官方文档:重点看《Writing MIB Modules》和《pass_persist Tutorial》章节,跳过复杂理论,直接看代码示例。
- 《SNMP网络管理》(第二版):经典入门书籍,跳过ASN.1语法部分,重点学习MIB定义、代理开发的核心逻辑。
- pysnmp官方示例库:直接参考仓库中的代理实现、MIB操作示例,比文档更直观。
四、任务落地建议
- 优先用
pysnmp搭建轻量自定义代理,跳过系统SNMP服务的复杂配置,快速验证自定义OID的读写逻辑。 - 数据入库:用
sqlite3/psycopg2等Python库将处理后的数据存入数据库,在SNMP代理的处理函数中直接读取数据库数据返回。 - 数据发送:用
pysnmp的客户端模块,将数据SET到目标应用的指定OID上,若目标应用是SNMP代理,直接写入其自定义OID即可。
内容的提问来源于stack exchange,提问作者Get init
相关产品推荐
相关产品推荐

