SNMP 是什么协议:管理站、代理与 MIB 怎么配合
SNMP(Simple Network Management Protocol,简单网络管理协议)是 IETF 制定的应用层协议,监控系统用它读取网络设备的运行状态,设备出故障时也能通过它主动报警。它由三部分组成:发起查询的管理站、设备上的代理,以及规定“能读什么”的 MIB。常用版本是 v2c 和 v3,前者用团体名明文认证,后者支持认证和加密。
SNMP 是什么协议?它是 Simple Network Management Protocol 的缩写,中文叫简单网络管理协议,由 IETF 制定,用来监控和管理网络中的设备。交换机、路由器、防火墙、服务器、BMC、UPS 网卡、智能 PDU、精密空调的监控卡,大多内置了 SNMP 代理。监控系统定期向这些代理发请求,读出端口状态、流量计数、CPU、温度等数值;设备出现端口断开、重启、风扇故障时,代理也会主动发一条 Trap 通知监控系统。它跑在 UDP 上,代理在 161 端口接收查询,监控系统在 162 端口接收 Trap。SNMP 最早在 1988 年提出,v1 于 1990 年以 RFC 1157 发布,几十年过去,仍是机房里设备覆盖面很广的监控协议。
SNMP 的三个角色:管理站、代理和 MIB
| 角色 | 是什么 | 例子 |
|---|---|---|
| 管理站(Manager,也叫 NMS) | 发起查询、接收告警、保存数据的一方 | Zabbix、LibreNMS、Prometheus 的 snmp_exporter,或 net-snmp 的命令行工具 |
| 代理(Agent) | 运行在被管设备上,回答查询、发送 Trap | 交换机内置的 SNMP 代理、Linux 的 snmpd、Windows 的 SNMP 服务、UPS 网卡固件 |
| MIB(管理信息库) | 描述设备上有哪些对象可读写的“数据字典” | IF-MIB(端口)、HOST-RESOURCES-MIB(主机资源)、UPS-MIB、各厂商私有 MIB |
| OID(对象标识符) | MIB 里每个对象的编号,相当于它在树上的路径 | 1.3.6.1.2.1.1.5.0 是设备名 sysName |
MIB 把所有对象组织成一棵树,每个节点有一个数字编号,从树根一路数下来就是 OID。这棵树的主干是这样的:
1 iso
└─ 3 org
└─ 6 dod
└─ 1 internet 1.3.6.1
├─ 2 mgmt
│ └─ 1 mib-2 1.3.6.1.2.1 标准 MIB
│ ├─ 1 system 1.3.6.1.2.1.1 设备名、描述、运行时长
│ ├─ 2 interfaces 1.3.6.1.2.1.2 端口表
│ └─ 25 host 1.3.6.1.2.1.25 主机资源:CPU、内存、磁盘、进程
├─ 4 private
│ └─ 1 enterprises 1.3.6.1.4.1 厂商私有 MIB,后接各厂商的企业号
└─ 6 snmpV2
└─ 3 snmpModules 1.3.6.1.6.3 SNMP 自身的对象,包括 v3 的用户和视图
对象分两种:标量只有一个值,OID 末尾加 .0,例如 sysName.0;表格对象每行一个值,OID 末尾接行索引,例如端口表里的 ifDescr.12 是索引为 12 的那个端口的名称。MIB 文件只是把数字翻译成名字的字典,设备返回的永远是“OID = 值”。
以一台 Linux 服务器为例,它上面的 snmpd 就是代理,管理站这样读它的设备名,以及每颗逻辑 CPU 最近一分钟的负载:
# 标量:设备名
snmpget -v2c -c 'Rd-Srv-2026' 10.10.0.31 1.3.6.1.2.1.1.5.0
# SNMPv2-MIB::sysName.0 = STRING: web01
# 表格:hrProcessorLoad,每颗逻辑 CPU 一行,值为最近一分钟的非空闲百分比
snmpwalk -v2c -c 'Rd-Srv-2026' 10.10.0.31 1.3.6.1.2.1.25.3.3.1.2
# HOST-RESOURCES-MIB::hrProcessorLoad.196608 = INTEGER: 7
# HOST-RESOURCES-MIB::hrProcessorLoad.196609 = INTEGER: 12
SNMP 服务是干什么的
在服务器上看到的“SNMP 服务”,就是代理程序:Linux 上是 snmpd,Windows 上服务名为 SNMP(显示名 SNMP Service),另有一个 SNMPTRAP 服务负责接收 Trap。它的作用只有一个:让监控系统能通过网络读到这台机器的状态。没有任何监控系统在用 SNMP 采集这台机器,就没必要开着它。
在 Linux 上让 snmpd 只对监控服务器开放,最少两行配置:
# /etc/snmp/snmpd.conf
# 只监听管理网地址,不监听公网地址
agentaddress udp:10.10.0.31:161
# 只读团体名,只允许监控服务器 10.10.0.10 使用
rocommunity Rd-Srv-2026 10.10.0.10
改完执行 systemctl restart snmpd。Windows Server 用 PowerShell 执行 Install-WindowsFeature SNMP-Service 安装,Windows 10/11 在“可选功能”里添加。微软从 Windows Server 2012 起已把 SNMP 服务列为弃用功能,现在仍可安装,但 Windows 上的新监控方案更多使用 WMI、WinRM 或监控软件自带的 agent。
SNMP 的几种操作:Get、Set、Trap
SNMP 的报文类型很少,这也是它“简单”的地方:
| 操作 | 方向 | 作用 | 从哪个版本开始 |
|---|---|---|---|
| Get | 管理站 → 代理 | 读取一个或几个指定 OID 的值 | v1 |
| GetNext | 管理站 → 代理 | 读取树上“下一个” OID,snmpwalk 就是反复用它遍历整棵子树 | v1 |
| GetBulk | 管理站 → 代理 | 一个请求读回多行,用于批量遍历表格 | v2c |
| Set | 管理站 → 代理 | 修改可写对象,例如关闭端口、修改设备名 | v1 |
| Response | 代理 → 管理站 | 对以上请求的应答 | v1(当时叫 GetResponse) |
| Trap | 代理 → 管理站 | 主动通知事件,发出后不等确认 | v1,v2c 起改用新格式 |
| Inform | 代理 → 管理站 | 需要接收方确认的通知,没收到确认会重发 | v2c |
| Report | 双向 | v3 内部用来报告错误、发现对方的引擎 ID | v3 |
GetBulk 带来的效率差别很明显。读一台 48 口交换机的端口名称表(假设表里正好 48 行):用 GetNext 每次只取一行,48 行要 48 次请求,再加 1 次确认已经走出这张表,一共 49 次往返;用 GetBulk,net-snmp 的 snmpbulkwalk 默认每次取 10 行,5 次往返就够了。管理站要轮询几百台设备时,这个差距直接决定一轮采集要花多久。
轮询和 Trap 互为补充。 轮询按固定间隔读数据,能画出曲线、算出流量,但两次轮询之间发生又恢复的事件可能被漏掉;Trap 在事件发生时立即发出,但它基于 UDP、没有确认,网络拥塞或接收端重启时会丢。常见做法是两者并用:轮询采集指标,Trap 接收实时事件,Trap 丢了还有下一次轮询兜底。
Set 在实际中很少用。 v1、v2c 的团体名明文传输,开放写权限风险很大,厂商开放的可写对象也有限。改配置一般走 SSH 命令行或 NETCONF,SNMP 只配只读权限。
SNMP v1、v2c、v3 有什么区别
| 对比项 | v1 | v2c | v3 |
|---|---|---|---|
| 标准 | 1990 年,RFC 1157 | 1996 年,RFC 1901 等 | 2002 年,RFC 3411~3418 |
| 身份验证 | 团体名,明文传输 | 团体名,明文传输 | 用户名加认证密码(USM),HMAC-MD5、HMAC-SHA,较新的实现支持 SHA-2 |
| 加密 | 无 | 无 | 可选,DES 或 AES |
| 访问控制 | 团体名加来源 ACL | 同 v1 | VACM 视图,可以按用户限定能读哪些 OID 子树 |
| 计数器 | 只有 32 位 | 新增 64 位的 Counter64 | 同 v2c |
| 批量读取 | 无 | GetBulk | GetBulk |
| 通知 | Trap | Trap、Inform | Trap、Inform |
| 错误处理 | 一次请求里有一个 OID 不存在,整个请求报错 | 只在不存在的那个 OID 位置返回 noSuchObject 等异常值,其余照常返回 | 同 v2c |
| 现在的定位 | 基本淘汰 | 独立管理网内的主流选择 | 跨网络或合规要求高时使用 |
几点补充:
- v2c 的“c”是 community(团体)。 团体名就是一个共享口令,在请求里明文携带,抓包就能看到。很多设备出厂默认的只读团体名是 public、读写团体名是 private,上线前必须改掉。
- 64 位计数器是放弃 v1 的硬理由。 端口字节计数器 ifHCInOctets 这类 64 位对象只能用 v2c 或 v3 读取。32 位的字节计数器到约 43 亿字节就归零,万兆口跑满时约 3.4 秒转一圈,1 分钟、5 分钟的常规轮询间隔根本接不住。
- v3 有三种安全级别。 noAuthNoPriv 只有用户名,不认证也不加密;authNoPriv 认证但不加密;authPriv 既认证又加密,经过不受信任的网络时用这一级。v3 的每个代理有一个引擎 ID,用户的密钥由密码和引擎 ID 共同生成,修改引擎 ID 后,已配置的用户通常要重新创建。
SNMP 在机房监控中的位置
机房里不只有 SNMP 一种采集方式,各有各的分工:
| 方式 | 主要对象 | 擅长 | 和 SNMP 的关系 |
|---|---|---|---|
| SNMP | 交换机、路由器、防火墙、UPS、PDU、服务器 | 通用的状态与计数器采集,网络设备普遍支持 | — |
| IPMI、Redfish | 服务器 BMC | 电源控制、温度、风扇、硬件日志、远程控制台 | 不少 BMC 也提供 SNMP 只读和 Trap,但功能少于 IPMI、Redfish |
| Syslog | 网络设备、服务器 | 文本日志,排障时还原事件经过 | 与 Trap 互补:Trap 报“出事了”,日志说清“怎么出的事” |
| NetFlow、sFlow、IPFIX | 路由器、交换机 | 谁和谁在通信、各占多少流量 | SNMP 只能给出端口的总量 |
| 流式遥测(Telemetry、gNMI) | 较新的数据中心交换机 | 设备主动推送,采集频率可以到秒级 | 适合大规模、高频率采集,正在承担一部分原本由 SNMP 轮询完成的工作 |
| Modbus | 动环:配电柜、空调、温湿度传感器 | 读取工业设备的寄存器 | 部分动环采集器可以把 Modbus 数据以 SNMP 方式提供给上层平台 |
| 主机 agent(Zabbix agent、node_exporter) | 服务器操作系统 | 进程、文件系统、应用指标,比 SNMP 细 | 能装 agent 的服务器一般优先用 agent |
放到 IDC 的日常里,SNMP 主要承担三件事:
- 端口流量采集。 定时读取交换机每个端口的 64 位字节计数器,两次读数的差值换算成带宽,画出流量曲线,按 5 分钟采样算出 95 值,作为带宽计费和扩容的依据。
- 设备健康状态。 读取交换机的 CPU、内存、温度、风扇和电源状态,UPS 的负载率和电池剩余时间,超过阈值就告警。
- 事件通知。 接收端口 linkDown、linkUp 和设备 coldStart 等 Trap,第一时间知道哪台设备出了问题。
它不擅长的事也很明确:分析流量内容要用端口镜像或流统计,修改配置用 SSH 或 NETCONF,服务器内部的应用指标交给 agent。
用 SNMP 要注意的安全问题
- 改掉默认团体名,不用 public、private 这类容易猜到的名字,只配置只读权限。
- 限定来源。 设备上用 ACL 只允许监控服务器访问,代理只监听管理网地址。
- UDP 161 不对公网开放。 暴露在外的 SNMP 代理不仅会被猜团体名,还会被拿去做反射放大攻击。
- 跨网络用 v3 authPriv,再用 VACM 视图只开放需要的子树,例如只开放 system 和 interfaces,不开放路由表和 ARP 表。
- 关掉不用的代理。 服务器上没有系统在采集,就停掉 snmpd 或 Windows 的 SNMP 服务:
# Linux:确认 snmpd 是否在监听,不用就停掉并取消开机启动
ss -ulnp 'sport = :161'
systemctl disable --now snmpd
在管理系统里怎么落地
在 IDC 的管理系统里,SNMP 通常只负责“读”。Toplink DCIM 的交换机管理就是这样分工的:SNMP 仅用于只读采集交换机数据,端口开关、VLAN、限速这些配置通过 SSH 或 Telnet 下发,Juniper 系列还支持 NETCONF,所以交换机上只需开放 SNMP 只读权限。DCIM 还提供实时流量图、异常检测和网络 TOP 排行,用来定位高占用节点;流量计费与 95 计费再按周期统计出站、入站、总流量或 95 峰值,用量达到设定比例时自动通知,超量后可以自动限速或关闭端口。
常见问题
SNMP 和 Zabbix、Prometheus 是什么关系?
SNMP 是协议,Zabbix、Prometheus 是监控系统。监控系统在 SNMP 里扮演管理站的角色,用它采集交换机、UPS 这类没法安装软件的设备,同时也支持 agent、HTTP 接口等其他采集方式。
有了 Ping 监控,还需要 SNMP 吗?
需要。Ping 只能告诉你设备通不通、时延多少;SNMP 能读出端口状态、流量、CPU、温度、电源这些内部信息。一个端口断了、一个电源坏了,设备照样 ping 得通,只有 SNMP 能发现。两者通常一起用。
SNMP 轮询间隔设多少合适?
端口流量常用 1 分钟或 5 分钟,95 计费一般按 5 分钟采样;CPU、温度等状态 1~5 分钟;MAC 地址表、ARP 表、路由表这类大表开销大,放到 15 分钟以上或按需读取。间隔越短数据越细,采集端和设备的负担也越重。