简介网络协议管理工具 Net-SNMP 的使用说明文档面向需要监控网络设备的系统管理员和运维初学者。文档首先交代了运行 snmpd 代理进程这一查询前提再以 MIB-2 的 system 节点为主线详细说明 snmpwalk 查询命令的常见用法包括版本、团体名、目标地址和 OID 的书写方式并给出真实输出结果覆盖系统描述、对象标识、运行时间等信息便于读者对照理解。除 snmpwalk 外还介绍了 snmpget、snmpset 等工具帮助延伸掌握 SNMP 查询与设置。文档还列出了 system 节点下各子节点的 OID 结构有助于理清 MIB 树形组织并同时展示了使用名称与 OID 两种方式查询的效果用户可举一反三。资源共 1 个 docx 文件约 29KB内容精炼已有 1072 人浏览学习适合作为快速上手的运维速查笔记示例可直接套用适合网络管理员在部署 SNMP 监控时快速查阅。1. net-snmp 使用说明把 snmpd 跑起来才谈得上监控net-snmp 使用说明这类资料网上不少但多数只贴命令不解释返回结构真正上手时照样不知道该查哪个 OID。这份资料不一样的地方在于它把 net-snmp 最常用的七条命令和完整返回样例放在一起而且以 system 子树为例子从根 OID 一路讲到叶子节点怎么加实例后缀。假设你刚接手一批跑着 snmpd 的 Linux 主机想批量知道系统型号、开机时长、磁盘水位snmpwalk 一条命令就能把 system 子树全部拉出来想知道某个接口今天走了多少包snmpget 配合 IF-MIB 的计数器比登录设备翻 show 命令快得多。这篇文章按查询、写入、监控、排错四条线展开新手能照着命令复现熟手可以重点看 OID 转换和 MIB 加载那几个坑。2. 查询命令的边界snmpwalk 拿整棵子树snmpget 拿叶子节点2.1 先认识 OID 与 MIB 的树形结构SNMP 里的 OID 不是一串随意数字它是一棵树的寻址路径。以资料里反复出现的 system 组为例根路径是.iso.org.dod.internet.mgmt.mib-2.system对应数字 OID.1.3.6.1.2.1.1下面每个节点都有固定位置对象OID说明sysDescr.1.3.6.1.2.1.1.1系统描述字符串sysObjectID.1.3.6.1.2.1.1.2设备厂商定义的对象标识sysUpTimeInstance.1.3.6.1.2.1.1.3系统运行时间TimeTickssysContact.1.3.6.1.2.1.1.4联系人字符串sysName.1.3.6.1.2.1.1.5主机名字符串sysLocation.1.3.6.1.2.1.1.6物理位置字符串理解这棵树能省掉大量试错时间。我一般会先记住几个固定锚点.1.3.6.1是 internet 根.1.3.6.1.2.1是 mib-2 标准管理库.1.3.6.1.4.1是企业私有库入口。凡是标准 MIB 里的对象OID 前九位基本都落在.1.3.6.1.2.1后面凡是厂商私有对象一定挂在.1.3.6.1.4.1下面。这个判断在排查时特别有用后面避坑章节还会提到。命令行工具里用数字 OID 还是文字名称都能查底层逻辑是先把名称通过 MIB 库解析成数字再走协议所以「MIB 是否加载」直接决定你能否用文字名称查询。这也是第 5 章避坑的重要前提。2.2 snmpwalk整棵子树一次拉出snmpwalk 的特点是「从指定 OID 开始把所有后代节点一次性遍历」。拿到一台设备我第一步永远是先 walk 一遍 system确认代理活着且 community 正确snmpwalk -v2c -c public localhost .1.3.6.1.2.1.1返回节选SNMPv2-MIB::sysDescr.0 STRING: Linux ubuntu 2.6.27-7-generic #1 SMP Fri Oct 24 06:42:44 UTC 2008 i686 SNMPv2-MIB::sysObjectID.0 OID: NET-SNMP-MIB::netSnmpAgentOIDs.10 DISMAN-EVENT-MIB::sysUpTimeInstance Timeticks: (8137) 0:01:21.37 SNMPv2-MIB::sysContact.0 STRING: Me mesomewhere.org SNMPv2-MIB::sysName.0 STRING: ubuntu SNMPv2-MIB::sysLocation.0 STRING: Right here, right now.参数拆开看-v2c表示用 SNMP 2c 版本也可选 1 或 3监控场景里 2c 最通用-c public是 community相当于口令设备上没配置这个串就直接拒绝localhost是代理地址代理跑在本机所以写 localhost最后的.1.3.6.1.2.1.1是要查询的 OID。注意 OID 和返回值里的.0后缀sysDescr.0表示这是 sysDescr 这个标量对象的实例标量对象在 SNMP 里实例号固定是.0。因为文字名称可读性好同样一条命令也能这么写snmpwalk -v2c -c public localhost system返回结果和数字 OID 完全一致。snmpwalk 适合开局巡检一次把某个组或整棵子树拉下来看全貌但不适合监控脚本频繁调用因为数据量大、带宽和代理 CPU 都有开销。需要精确定点时用 snmpget。2.3 snmpget 与 snmpgetnext精确定位和字典序探路snmpget 是精确查询必须给到叶子节点的完整实例 OID。查 sysName 就是snmpget -v2c -c public localhost .1.3.6.1.2.1.1.5.0 SNMPv2-MIB::sysName.0 STRING: ubuntu-v2c、-c、localhost三个参数和 snmpwalk 完全相同区别在 OID.1.3.6.1.2.1.1.5是节点.0是实例号。很多第一次用的人漏掉.0代理会返回 noSuchObject这不是命令写错是 SNMP 协议里标量对象就是这么寻址的。一次要取多个叶子、减少交互往返时可以用空格分隔多个 OIDsnmpget -v2c -c public localhost .1.3.6.1.2.1.1.1.0 .1.3.6.1.2.1.1.5.0snmpgetnext 则是「不知道叶子叫什么但知道父节点」时用。它按字典序返回当前 OID 的下一个存在节点snmpgetnext -v2c -c public localhost .1.3.6.1.2.1.1 SNMPv2-MIB::sysDescr.0 STRING: Linux ubuntu 2.6.27-7-generic #1 SMP Fri Oct 24 06:42:44 UTC 2008 i686这个结果等同于直接 snmpget.1.3.6.1.2.1.1.1.0因为 sysDescr 是 system 组里字典序第一个叶子。snmpgetnext 在写拓扑发现脚本时特别好用你不需要预先知道设备实现了哪些 MIB 对象从.1.3.6.1.2开始一路 getnext就能把整台设备支持的所有对象摸一遍。资料里特意提到「Oid 也可输入 .1.3.6.1.2因为它是按字典顺序遍历的」指的就是这种探路用法。3. 表对象与写入操作snmptable 查表snmpset 改配置的类型码细节3.1 snmptable把行和列读成一张表标准 MIB 里除了标量对象还有大量表对象典型如 IP 地址表 ipAddrTableOID 是.1.3.6.1.2.1.4.20。用 snmpwalk 去查也能出数据但结果是按列展开的同一个 IP 的行和列散落各处人眼很难拼起来snmpwalk -v2c -c public localhost .1.3.6.1.2.1.4.20 IP-MIB::ipAdEntAddr.127.0.0.1 IpAddress: 127.0.0.1 IP-MIB::ipAdEntAddr.192.168.1.249 IpAddress: 192.168.1.249 IP-MIB::ipAdEntIfIndex.127.0.0.1 INTEGER: 1 IP-MIB::ipAdEntIfIndex.192.168.1.249 INTEGER: 2换成 snmptable 就直观得多snmptable -v2c -c public localhost .1.3.6.1.2.1.4.20 SNMP table: IP-MIB::ipAddrTable ipAdEntAddr ipAdEntIfIndex ipAdEntNetMask ipAdEntBcastAddr ipAdEntReasmMaxSize 127.0.0.1 1 255.0.0.0 0 ? 192.168.1.249 2 255.255.255.0 1 ?snmptable 做的事情其实很简单它知道表对象的列结构先遍历每列的索引再把同一索引下的值拼成一行。所以用它查表的前提是代理返回的列齐全且索引规范如果某列缺失会出现?占位就像上面 ipAdEntReasmMaxSize 那列。这个命令适合人工巡检时快速比对也适合脚本里把输出按行解析。注意它只能用于真正的表对象拿它查 system 这种标量组会直接报错。3.2 snmpset类型码写错就等着 noSuchName 或 wrongTypesnmpset 是 net-snmp 里唯一写操作命令可以改代理上的配置值。资料里的例子是修改 sysContactsnmpset -v2c -c public localhost .1.3.6.1.2.1.1.4.0 s mesomewhere.org最后三段依次是 OID、数据类型码、要写入的值。s表示 STRING因为 sysContact 在 MIB 里的定义就是 DisplayString类型必须匹配。如果这里写成iINTEGER代理会返回 wrongType 或 wrongValue这就是类型码翻车的典型现场。snmpset 支持的类型码如下类型码含义常见用途iINTEGER整数型计数器、状态值uunsigned INTEGER无符号整数tTIMETICKS时间刻度aIPADDRESSIP 地址oOBJID对象标识sSTRING字符串xHEX STRING十六进制串dDECIMAL STRING十进制串bBITS位串Uunsigned int6464 位无符号Isigned int6464 位有符号Ffloat浮点Ddouble双精度另一个容易踩的坑是表对象的写入。资料里给了路由表写入示例snmpset -v2c -c public localhost .1.3.6.1.2.1.4.21.1.3.x i 99这里.1.3.6.1.2.1.4.21.1.3是 ipRouteMetric 列x是行索引表示「更改 ipRouteDest 为 x 那一行的 Metric 值」。实际使用时x 要替换成具体的索引值比如一个 IP 地址对应的字符串。表对象写入比标量复杂索引一旦写错代理要么返回 noSuchName要么在错误行上改了不该动的值。安全做法是先 snmpwalk 确认目标行的完整索引再用 snmpget 验证可写权限最后才 snmpset。多数生产环境里 snmp 写权限默认是关闭的-c community用的是只读串所以 set 之前还要确认代理配置里开了写权限否则会收到 notWritable。4. 监控专用工具snmpdelta 盯增量snmpdf 看磁盘snmptrap 发告警4.1 snmpdelta计数器要的是变化量不是绝对值接口流量、包计数这类对象在 MIB 里都是 Counter32绝对值只会越滚越大直接查没意义要的是两个采样点之间的差值。snmpdelta 就是干这个的snmpdelta -c public -v 1 -Cs -CT localhost IF-MIB:ifInUcastPkts.3 IF-MIB:ifOutUcastPkts.3 localhost ifInUcastPkts.3 ifOutUcastPkts.3 [20:15:59 6/14] 184.00 184.00 [20:16:00 6/14] 158.00 158.00 [20:16:01 6/14] 184.00 184.00命令里IF-MIB:ifInUcastPkts.3表示取 IF-MIB 里 ifInUcastPkts 的第 3 个实例也就是接口索引为 3 的那行后面的.3是接口索引。-Cs和-CT控制输出带时间戳和标签头方便直接灌进监控日志。这个工具适合短时盯流量抖动比如怀疑某接口被广播风暴打了挂在终端上刷几秒就能看到增量是否异常。注意资料里标注这个用法「未验证」不同发行版对-Cs、-CT的行为略有差异拿到手先在 localhost 上试跑一遍再上生产。如果生产环境需要长期趋势还是建议用监控平台周期性 snmpget 后自己算差值snmpdelta 更适合临时排查。4.2 snmpdf远程磁盘一眼看完snmpdf 是一类比较特殊的工具它只做一件事——通过 SNMP 读 HOST-RESOURCES-MIB 或 UCD-SNMP-MIB把远程主机的磁盘、内存、交换分区拉成一张表snmpdf -v 1 -c public localhost Description size (kB) Used Available Used% Physical memory 504412 498912 5500 98% Virtual memory 1480964 591896 889068 39% Swap space 976552 92984 883568 9% / 6728592 3985712 2742880 59% /boot 20482840 8607920 11874920 42% /work 20763980 9236608 11527372 44%和 snmpwalk 自拼 HOST-RESOURCES-MIB 相比snmpdf 直接做了格式化省去手工匹配列和索引的麻烦。限制在于目标设备必须实现了磁盘监控相关的 MIB纯交换机、路由器通常没有这块数据返回就是空的。跑一遍发现没输出先确认目标设备类型别在命令参数上耗时间。实际巡检时我习惯把它和 snmpwalk system 组合用先确认设备活着再看磁盘水位两条命令覆盖最常见的健康检查需求。4.3 snmptrap把故障主动送出去前面几条命令都是「拉」模式snmptrap 是 net-snmp 里少有的「推」模式命令用于主动向管理端发送 Trap 告警。资料里的 v1 格式示例snmptrap -v 1 -c public 监控机IP 1.3.6.1.4.1.99999 本机名 3 0 1.3.6.1.2.1.2.2.1.1.1 i 1字段依次是-v 1用 v1 Trap 格式-c public是 community监控机IP是接收 Trap 的管理端地址1.3.6.1.4.1.99999是企业 OID这里 99999 是演示用的虚拟企业号生产环境换成自己公司的 enterprise 编号本机名是 agent 地址3和0是 generic-trap 类型码和 specific 码是 uptime可留空最后是 varbindOID 类型 值。varbind 是 Trap 的核心载荷这里1.3.6.1.2.1.2.2.1.1.1 i 1表示「接口索引 ifIndex.1 的值为 1」也就是告诉管理端哪个接口出了问题。经验是 v1 Trap 的字段顺序一个都不能错错一个接收端要么丢包要么解析失败。发出去之前先在管理端用tcpdump -i any udp port 162抓包确认收到了再排查格式问题。v2c 的 Trap 格式不同如果管理端要求 v2c用-v 2c时负载部分会按 varbind 列表解析细节差异建议直接看snmptrap --help输出。Trap 场景里最常见的坑不是命令本身而是管理端没开 162 端口、防火墙拦了或 community 对不上这条我在第 5 章的踩坑记录里还会展开。5. snmptranslate 排查实战OID 转换失败与 MIB 加载的四个坑5.1 先搞清楚 snmptranslate 到底在做什么snmptranslate 的价值被严重低估它不查代理只查本地 MIB 库做的是「名称 ↔ 数字」互转和结构查看。数字转名称直接加-Onsnmptranslate -On .1.3.6.1.2.1.1.5.0 .1.3.6.1.2.1.1.5.0名称转数字需要-IR这类选项配合直接写snmptranslate system不会输出数字这是最容易懵的地方snmptranslate -IR -On system .1.3.6.1.2.1.1-IR让命令在已加载的 MIB 库里按名称随机查找省去写完整路径。看过对象定义用-Td它会打印类型、访问权限、描述和数字 OID 一行不漏snmptranslate -Td -IR SNMPv2-MIB::sysName.0输出里能看到这是一个 DisplayString、最大长度 255、访问权限是读改写。这个信息在 snmpset 前查一次能避免类型写错的尴尬。想看某棵子树全貌用-Tp比如snmptranslate -Tp -IR system会输出 system 下所有节点的树状图每个节点带读写权限、类型和取值范围比翻 MIB 源文件快得多。我拿到一份陌生设备的私有 MIB第一动作永远是-Tp打树第二动作才是 walk 实测。5.2 搞懂 -m 和 -M私有 MIB 才找得到名称解析失败九成出在 MIB 没加载。-m指定加载哪些 MIB 模块-M指定搜索目录。资料里的两个参数说明很典型-m MIBLIST指定模块列表-M DIRLIST指定目录列表两者都能覆盖环境变量。snmptranslate -Tl -m 某厂商-SYSTEMUPTIME-MIB-Tl会输出所有已加载对象的完整文字和数字 OID 路径适合确认某个私有 MIB 是否被正确加载。环境的坑在于默认搜索路径之外的 MIB不加-M永远找不到多个私有 MIB 相互引用时只-m指定一个模块依赖缺失照样解析失败。所以加载一类设备的所有 MIB 文件常见做法是export MIBSALL export MIBDIRS/usr/share/snmp/mibs:/opt/custom-mibsMIBSALL表示加载所有能找到的 MIB调试时省心代价是启动稍慢、偶尔出现 OID 重名冲突。生产环境建议收敛到实际用到的几个模块。5.3 四个高频踩坑记录以下四条是按「现象 → 原因 → 解决」整理的实战记录每一条我都踩过。坑一snmpget 叶子节点漏了.0返回 noSuchObject现象snmpget -v2c -c public localhost .1.3.6.1.2.1.1.5返回noSuchObject但 snmpwalk 同一节点能出数。原因标量对象在 SNMP 协议里的实例标识是.0snmpwalk 会自己补snmpget 不会。解决所有用 snmpget 查的叶子OID 末尾补.0.1.3.6.1.2.1.1.5写成.1.3.6.1.2.1.1.5.0。如果返回的是noSuchName而不是noSuchObject说明代理版本或 community 有另一层问题先 snmpwalk 同 OID 对比。坑二snmpwalk 用文字名称报 Unknown Object Identifier现象snmpwalk -v2c -c public localhost system报Unknown Object Identifier但用数字.1.3.6.1.2.1.1能查。原因MIB 库里没有名为 system 的模块或该模块未加载。解决先snmptranslate -IR -On system测试名称能否解析解析不了就export MIBSALL或-m ALL强制加载再不行确认 MIB 文件在-M指定的目录里。坑三snmptranslate 名称转数字卡住不输出现象直接跑snmptranslate system终端什么都不输出。原因名称格式转数字必须配合查找选项资料里明确写了「需要 -I 选项的配合」。解决用snmptranslate -IR -On system-IR是随机访问模式-On输出数字形式。坑四snmpset 类型码写错代理返回 wrongType现象snmpset -v2c -c public localhost .1.3.6.1.2.1.1.4.0 i 12345返回wrongType或wrongValue。原因sysContact 定义是 DisplayString 字符串用i写整数当然不匹配。解决写任何对象前先snmptranslate -Td -IR 对象名看类型定义按定义选类型码。sysContact 用s接口状态这类用i。坑五snmptrap 发出去了管理端没收到现象snmptrap 命令没有任何报错管理平台却静悄悄。原因多半不是命令问题是网络层或接收端配置问题——管理端没监听 162 端口、防火墙丢弃 UDP 162、community 与接收端配置不一致。解决在管理端抓包tcpdump -i any udp port 162看报文是否到达抓不到就查路由和防火墙抓到了就对比报文里的 community 参数。确认网络通之后再回来核对 v1 Trap 字段顺序。6. 进阶验证技巧用 MIB 树把新设备「画」清楚再写脚本拿到一台没接触过的设备我的固定流程是「先画树再 walk最后落 OID」。这个习惯能避免脚本写了一堆数字 OID上线才发现某个节点根本不存在。借助-Tp和-Tl两个选项的组合可以快速完成这个闭环。先加载目标设备的 MIB 并打印树形结构这一步相当于给设备拍 X 光片所有可读写的对象一目了然snmptranslate -Tp -IR 某厂商-SYSTEMUPTIME-MIB输出能看到这个私有 MIB 挂在iso(1).org(3).dod(6).internet(1).private(4).enterprises(1).某厂商(99999)之下企业内部再按产品线展开到具体 OID。用树确认了要采集的节点后接着用 snmpwalk 在目标设备上实测每个叶子的返回类型和实例号把树状结构里标着-R-的只读节点和-RW-的读写节点都验证一遍记录实际返回的数据类型。最后把验证过的数字 OID 固化到监控平台的采集配置每一条都带注释来源snmpget -v2c -c public 192.168.1.100 .1.3.6.1.2.1.1.5.0 # 设备名验证通过 snmpget -v2c -c public 192.168.1.100 .1.3.6.1.2.1.1.3.0 # 运行时长TimeTicks注意单位换算 snmpget -v2c -c public 192.168.1.100 .1.3.6.1.4.1.99999.1.1.0 # 私有 MIB 自定义对象这三个验证点覆盖了标准 MIB、表对象索引和私有 MIB 三种最典型的采集需求。那块手写的验证记录我会一直保留设备固件升级后再跑一遍同样的命令对比返回是否变化。告辞的时候先确认代理配置里 community 支持读再确认防火墙放行了 UDP 161这两步不做后面所有命令都会卡在超时上。从那以后我每次接新设备都强制走一遍「画树、walk、落 OID」三段式流程排查效率高了不少也少了很多黑匣子式瞎试。这套资料里把每条命令的返回样例都贴得很全建议下载后放一台测试机上逐步复现踩过的坑自然就变成你自己的经验了。希望帮到你。本文还有配套的精品资源点击获取