简单网络管理协议

<image>

简单网络管理协议（SNMP，Simple Network Management Protocol）构成了互联网工程工作小组（IETF，Internet Engineering Task Force）定义的Internet协议族的一部分。该协议能够支持网络管理系统，用以监测连接到网络上的设备是否有任何引起管理上关注的情况。它由一组网络管理的标准组成，包含一个应用层协议（application layer protocol）、数据库模式（database schema），和一组资料物件。

## 概论和基础观念

在典型的SNMP用法中，有许多系统被管理，而且是有一或多个系统在管理它们。每一个被管理的系统上有运行一个叫做代理者（agent）的软件元件，且透过SNMP对管理系统报告资讯。

基本上，SNMP代理者以变数呈现管理资料。管理系统透过GET，GETNEXT和GETBULK协定指令取回资讯，或是代理者在没有被询问的情况下，使用TRAP或INFORM传送资料。管理系统也可以传送配置更新或控制的请求，透过SET协定指令达到主动管理系统的目的。配置和控制指令只有当网络基本结构需要改变的时候使用，而监控指令则通常是常态性的工作。

可透过SNMP存取的变数以阶层的方式结合。这些分层和其他元数据（例如变数的类型和描述）以管理信息库（MIBs）的方式描述。

## SNMP基本元件

一个SNMP管理的网络由下列三个关键元件组成：

- 网络管理系统（NMSs，Network-management systems）
- 被管理的设备（managed device）
- 代理者（agent）

一个网络管理系统执行应用程序，以该应用程序监视并控制被管理的设备。也称为管理实体（managing entity），网络管理员在这儿与网络装置进行互动。网络管理系统提供网络管理需要的大量运算和记忆资源。一个被管理的网络可能存在一个以上的网络管理系统。

一个被管理的设备是一个网络节点，它包含一个存在于被管理的网络中的SNMP代理者。被管理的设备透过管理信息库（MIB）收集并储存管理资讯，并且让网络管理系统能够透过SNMP代理者取得这项资讯。

代理者是一种存在于被管理的设备中的网络管理软件模组。代理者控制本地机器的管理资讯，以和SNMP相容的格式传送这项资讯。

## SNMP架构

从体系结构上来讲，SNMP框架由主代理、子代理和管理站组成。

### 主代理

主代理是一个在可执行SNMP的网络元件上运作的软件，可回应从管理站发出的SNMP要求。它的角色类似客户端/服务器结构（Client/Server）术语中的服务器。主代理依赖子代理提供有关特定功能的管理资讯。

如果系统当前拥有多个可管理的子系统，主代理就会传递它从一个或多个子代理处收到的请求。这些子代理在一个子系统以及对那个子系统进行监测和管理操作的界面内为关心的物件建模。主代理和子代理的角色可以合并，在这种情况下我们可以简单的称之为代理（agent）。

### 子代理

子代理是一个在可执行SNMP的网络元件上运作的软件，执行在特定子系统的特定管理信息库（MIB，Management Information Base）中定义的资讯和管理功能。子代理的一些能力有：

- 搜集主代理的资讯
- 配置主代理的参数
- 回应管理者的要求
- 产生警告或陷阱

对协定和管理资讯结构的良好分离使得使用SNMP来监测和管理同一网络内上百的不同子系统非常简单。MIB模型运行管理OSI参考模型的所有层，并可以扩展至诸如数据库，电子邮件以及J2EE参考模型之类的应用。

### 管理站

管理者或者管理站提供第三个元件。它和一个客户端/服务器结构下的用户端一样工作。它根据一个管理员或应用程序的行为发出管理操作的请求，也接收从代理处获得的TRAP。

## SNMP协议

### SNMP第一版和SMI规格的资料型态

SNMP第一版SMI指定许多SMI规格的资料型态，它们被分为两大类：

- 简单资料型态
- 泛应用资料型态

### SNMP第二版和管理资讯结构

SNMP第二版SMI在RFC 2578之中描述，它在SNMP第一版的SMI规格资料型态上进行增加和强化，例如位元串（bit strings）、网络位址（network addresses）和计数器（counters）。

SNMP协定在OSI模型的应用层（第七层）运作，在第一版中指定五种核心PDU：

- GET REQUEST
- GET NEXT REQUEST
- GET RESPONSE
- SET REQUEST
- TRAP

其他PDU在SNMP第二版加入，包含：

- GETBULK REQUEST
- INFORM

### SNMP第二版SMI资讯模块

SNMP第二版SMI也指定了资讯模块来详细说明一群相关连的定义。有三种SMI资讯模块：MIB模块、回应状态、能力状态。

### SNMP第三版

SNMP第三版由RFC 3411-RFC 3418定义，主要增加SNMP在安全性和远端配置方面的强化。

SNMP第三版提供重要的安全性功能：

- 信息完整性：保证封包在传送中没有被窜改。
- 认证：检验信息来自正确的来源。
- 封包加密：避免被未授权的来源窥探。

## 开发和使用

### 第一版

SNMP的第一个RFC系列出现在1988年：

- RFC 1065：基于TCP/IP网络的管理信息的结构和认定
- RFC 1066：以基于TCP/IP网络的网络管理为基础的管理信息
- RFC 1067：一个简单网络管理协议

这些协议被废除经由：

- RFC 1155：基于TCP/IP网络的管理信息的结构和认定
- RFC 1156：以基于TCP/IP网络的网络管理为基础的管理信息
- RFC 1157：一个简单网络管理协议

SNMP协议工作在OSI模型的应用层（第七层）。它（在第一版中）指定了四种核心协议数据单元（PDU）：

- GET，用来得到一条管理信息
- GETNEXT，用来反复得到管理信息的序列
- SET，用来给一个被管理的子系统制造一个变化
- TRAP，用来报告一个关于被管理子系统的警告或其他异步事件

典型的，SNMP为代理使用UDP端口161，为管理站使用UDP端口162。

第一版因为其脆弱的安全性而备受争议。客户端的认证使用明码传送。在80年代，SNMP第一版被设计出来的时期，互联网标准的认证/安全并不被主要的协议设计团体所重视。

### 第二版

SNMP第二版（RFC 1441–RFC 1452）修订了第一版并且包含了在性能、安全、机密性和管理者之间通信这些领域的改进。它引入了GETBULK以取代反复的GETNEXT，藉以在单个请求中获取大量的管理数据。然而，SNMP第二版的新安全系统被认为过于复杂，而不被广泛接受。

SNMP v2c（基于社群的SNMP第二版）定义于RFC 1901–RFC 1908，一开始也非正式的被称为SNMP第1.5版。SNMPv2c包含SNMP第二版除了受争议的新SNMP第二版安全模型以外的部分，并以SNMP第一版的简单的基于社群的安全性方案取而代之。

SNMP v2u（基于使用者的SNMP第二版）定义于RFC 1909–RFC 1910。这是一个SNMP第一版和SNMP第二版的折衷方案，试图提供比SNMP第一版更好的安全性，又不遭遇SNMP第二版的高复杂度。这产生一个被商业化的变种，称为SNMP v2*，而且它的机制最后被SNMP第三版的两个安全性框架之一采用。

### SNMP第一版和SNMPv2c的互操作性

在目前的指定中，SNMP第二版和SNMP第一版在两个关键领域不相容：讯息格式和协议操作。SNMPv2c讯息使用和SNMP第一版不同的标头和协议数据单元（PDU）格式。SNMPv2c也使用两个没有在SNMP第一版指定的协议操作。此外，RFC 1908定义两个可能的SNMP第一版/第二版共存策略：代理服务器代理（proxy agents）和双语网络管理系统（bilingual network-management systems）。

### 第三版

Internet工程工作小组（IETF）把在RFC3411-RFC3418（STD0062）中定义的SNMP第三版作为2004年的标准版本。IETF将先前的版本定为“Obsolete”或“Historical”。

实际上，SNMP实现通常支持多个版本：典型的SNMPv1、SNMPv2c以及SNMPv3。参见RFC3584“Internet标准网络管理框架第一、二、三版间的共存”。

SNMP第三版提供三项重要的服务：认证、隐私和存取控制。

## 使用举例

### SNMP v1 v2c

- 监控装置正常运行时间 (sysUpTimeInstance)
- 操作系统版本清单 (sysDescr)
- 收集界面资讯 (ifName, ifDescr, ifSpeed, ifType, ifPhysAddr)
- 测量网络界面吞吐量 (ifInOctets, ifOutOctets)
- 查询远端ARP快取 (ipNetToMedia)

下面的输出作为在一个路由器上的snmpwalk的例子展示了设备的基本信息：

```bash
 snmpwalk -c public punch system

 SNMPv2-MIB::sysDescr.0 = STRING: Cisco Internetwork Operating System Software IOS (tm) C2600
 Software (C2600-IO3-M), Version 12.2(15)T5, RELEASE SOFTWARE (fc1)
 TAC Support: http://www.cisco.com/tac

 Compiled Thu 12-Jun-03 15:49 by eaarm
 SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.9.1.187
 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (835747999) 96 days, 17:31:19.99
 SNMPv2-MIB::sysContact.0 = STRING: wikiuser
 SNMPv2-MIB::sysName.0 = STRING: punch
 SNMPv2-MIB::sysLocation.0 = STRING: test
 SNMPv2-MIB::sysServices.0 = INTEGER: 78
 SNMPv2-MIB::sysORLastChange.0 = Timeticks: (0) 0:00:00.00
```

### SNMP v3

由于 SNMP v3 加强了安全设计，存取上要提供较多资讯

#### 透过工具指令存取

在 Shell 环境下安全取得一台主机所有 CPU Core 使用状况的方法：

- -l authPriv 表示要认证也要传输加密
- -a 为认证密码保护方式 -A 为认证密码
- -x 为传输加密方式 -X 为传输密钥
- 1.3.6.1.2.1.25.3.3.1.2 表示要监视所有 CPU Core 使用状况

```bash
snmpwalk -v 3 -l authPriv -u user \
   -a SHA -A userpass \
   -x AES -X userpass \
   10.33.1.1 \
   1.3.6.1.2.1.25.3.3.1.2

HOST-RESOURCES-MIB::hrProcessorLoad.196608 = INTEGER: 7
HOST-RESOURCES-MIB::hrProcessorLoad.196609 = INTEGER: 8
```

#### 透过 PHP 存取

```php
if (function_exists('snmp3_get')) {
	$result = snmp3_real_walk(
		'10.33.1.1',         // 要監視的主機
		'user',                  // 存取 SNMP 服務的帳號
		'authPriv',              // 安全等級 (要認證也要傳輸加密)
		'SHA',                   // 認證密碼的保護方式
		'userpass',              // 認證用密碼
		'AES',                   // 傳輸加密方式
		'userpass',              // 傳輸用密鑰
		'1.3.6.1.2.1.25.3.3.1.2' // 監看所有 CPU core 的負載狀況，編號為 CPU 負載狀況的 OID
	);
	print_r($result);
}

Array
(
    [HOST-RESOURCES-MIB::hrProcessorLoad.196608] => INTEGER: 7
    [HOST-RESOURCES-MIB::hrProcessorLoad.196609] => INTEGER: 11
)
```

### 经常监视的数据

处理器、内存、储存设备、网络环境为最常被监视的项目，这些项目的细节资讯如下表：

项目｜存取方式｜OID｜MIB

处理器

使用者占用时间比｜GET｜.1.3.6.1.4.1.2021.11.9.0｜UCD-SNMP-MIB::ssCpuUser

系统占用时间比｜GET｜.1.3.6.1.4.1.2021.11.10.0｜UCD-SNMP-MIB::ssCpuSystem

闲置时间比｜GET｜.1.3.6.1.4.1.2021.11.11.0｜UCD-SNMP-MIB::ssCpuIdle

每个 Core 的用量｜WALK｜.1.3.6.1.2.1.25.3.3.1.2｜HOST-RESOURCES-MIB::hrProcessorLoad

内存

内存容量｜GET｜.1.3.6.1.4.1.2021.4.5.0｜UCD-SNMP-MIB::memTotalReal

内存消耗量｜GET｜.1.3.6.1.4.1.2021.4.6.0｜UCD-SNMP-MIB::memAvailReal

内存剩余量｜GET｜.1.3.6.1.4.1.2021.4.11.0｜UCD-SNMP-MIB::memTotalFree

虚拟内存容量｜GET｜.1.3.6.1.4.1.2021.4.3.0｜UCD-SNMP-MIB::memTotalSwap

虚拟内存剩余量｜GET｜.1.3.6.1.4.1.2021.4.4.0｜UCD-SNMP-MIB::memAvailSwap

储存设备

各磁盘容量｜WALK｜.1.3.6.1.4.1.2021.9.1.6.1｜UCD-SNMP-MIB::dskTotal

各磁盘消耗量｜WALK｜.1.3.6.1.4.1.2021.9.1.7.1｜UCD-SNMP-MIB::dskAvail

各磁盘消耗量百分比｜WALK｜.1.3.6.1.4.1.2021.9.1.9.1｜UCD-SNMP-MIB::dskPercent

网络环境

网络设备名称｜WALK｜.1.3.6.1.2.1.31.1.1.1.1｜IF-MIB::ifName

## 外部链接

- 中文SNMP协议讨论组
- Net-SNMP
- Net-SNMP on sourceforge.net
- SimpleWeb
- RFC1157: A Simple Network Management Protocol (SNMP)
- CISCO SNMP
- RFC3411: An Architecture for Describing Simple Network Management Protocol (SNMP) Management Frameworks
- RFC3584: Coexistence between Version 1, Version 2, and Version 3 of the Internet-standard Network Management Framework
- RFC3512: Configuring Networks and Devices with Simple Network Management Protocol (SNMP)
- OpenSNMP
- SNMP FAQ part 1
- SNMP FAQ part 2
- Cisco SNMP repository and documentation
- SNMP4J - Free Open Source SNMP for Java
- Snml-SNMP：Simple Network Management Language (简单网络管理语言)