【简单网络管理协议】
简单网络管理协议（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的例子展示了设备的基本信息：
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
Copyright (c) 1986-2003 by cisco Systems, Inc.
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 使用状况
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 存取 ====
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
)
=== 经常监视的数据 ===
处理器、记忆体、储存设备、网路环境为最常被监视的项目，这些项目的细节资讯如下表：