はじめに
SNMP(Simple Network Management Protocol)は、ルータやスイッチなどのネットワーク機器を監視・管理するためのプロトコルです。
SNMPには複数のバージョンがあり、SNMPv2cとSNMPv3では、主に認証方式やセキュリティ機能が異なります。
特にSNMPv3では、SNMPv2cで使用されていたコミュニティ文字列に代わり、ユーザー名と認証鍵を使用したメッセージ認証や、通信データの暗号化が利用できます。
今回はCisco C1812JとRaspberry Piを使用し、SNMPv2cとSNMPv3で同じ情報を取得して、Wiresharkでパケットの違いを確認してみました。
今回の検証目的
- SNMPv2cのコミュニティ文字列が平文で送信されることを確認する
- SNMPv3の認証方式と暗号化機能を確認する
- WiresharkでSNMPv2cとSNMPv3のパケット構造を比較する
- SNMPv3のエンジンID探索や暗号化PDUの動作を理解する
検証環境
使用機器
| 機器 | 用途 |
|---|---|
| Cisco C1812J | SNMPエージェント |
| Raspberry Pi | SNMPマネージャ |
| Wireshark | パケット解析 |
| Net-SNMP | SNMPコマンド実行 |
| tcpdump | パケットキャプチャ |
Cisco IOSのバージョン
Cisco IOS Software, C181X Software
Version 12.4(15)T8
System image file is
"flash:c181x-advipservicesk9-mz.124-15.T8.bin"
Cisco 1812-J (MPC8500)
ネットワーク構成
+---------------------+
| Cisco C1812J |
| |
| 192.168.20.1 |
| SNMP Agent |
+----------+----------+
|
| LANケーブル
|
+----------+----------+
| Raspberry Pi |
| |
| SNMP Manager |
| tcpdump |
+---------------------+
C1812JとRaspberry PiをLANケーブルで直接接続しています。
※ Raspberry PiのIPアドレスは環境に応じて設定します。
SNMPv2cとSNMPv3の違い
まず、それぞれの特徴を整理します。
| 項目 | SNMPv2c | SNMPv3 |
|---|---|---|
| 認証方式 | コミュニティ文字列 | ユーザー名と認証鍵 |
| メッセージ認証 | なし | 対応 |
| データ暗号化 | なし | 対応 |
| GetRequest | 対応 | 対応 |
| GetBulkRequest | 対応 | 対応 |
| InformRequest | 対応 | 対応 |
SNMPv2cでは、コミュニティ文字列が平文で送信されます。
一方、SNMPv3ではUSM(User-based Security Model)を使用し、認証と暗号化を組み合わせることができます。
SNMPv3には、以下の3種類のセキュリティレベルがあります。
| セキュリティレベル | 認証 | 暗号化 |
|---|---|---|
| noAuthNoPriv | なし | なし |
| authNoPriv | あり | なし |
| authPriv | あり | あり |
今回は主にSNMPv2cとSNMPv3のauthPrivを比較します。
C1812JでSNMPv3の対応アルゴリズムを確認
まず、C1812Jで使用可能なSNMPv3の認証アルゴリズムを確認しました。
RT1(config)#snmp-server user TESTUSER TESTGROUP v3 auth ?
md5 Use HMAC MD5 algorithm for authentication
sha Use HMAC SHA algorithm for authentication
MD5とSHAに対応していることが確認できました。
続いて、暗号化アルゴリズムを確認します。
RT1(config)#snmp-server user TESTUSER TESTGROUP v3 auth sha AuthPass1234 priv ?
3des Use 168 bit 3DES algorithm for encryption
aes Use AES algorithm for encryption
des Use 56 bit DES algorithm for encryption
DES、3DES、AESが利用可能であることが確認できました。
今回の検証では、認証にSHA-1、暗号化にAESを使用します。
※ IOS 12.4のSHAはSHA-1を指します。現在の新規システムでは、より新しい認証アルゴリズムに対応した機器を使用することが望まれます。
SNMPv2cの設定と検証
Cisco側の設定例
configure terminal
snmp-server community Public01 RO
end
Public01を読み取り専用のコミュニティ文字列として設定します。
※ 検証専用の例です。実運用では送信元IPアドレスをACLで制限する必要があります。
Raspberry PiからSNMPで情報取得
今回はsysName.0を取得します。
OIDは以下のとおりです。
1.3.6.1.2.1.1.5.0
Raspberry Piで実行するコマンドは以下です。
snmpget -v2c -c Public01 192.168.20.1 1.3.6.1.2.1.1.5.0
このコマンドで、SNMPv2cを使用してC1812Jのホスト名を取得します。
Wiresharkでパケットを確認
WiresharkでSNMPパケットを確認したところ、以下の情報が表示されました。
Simple Network Management Protocol
version: v2c (1)
community: Public01

ここで注目したいのが、community: Public01という部分です。
SNMPv2cでは、コミュニティ文字列が暗号化されずに送信されていることが分かります。
つまり、ネットワーク上でSNMPパケットをキャプチャできる環境では、コミュニティ文字列を確認できてしまいます。
SNMPv2cではコミュニティ文字列を使用してアクセス制御を行いますが、通信内容の機密性は確保されません。
SNMPv3の設定と検証
続いてSNMPv3を検証します。
今回は認証と暗号化を有効にしたauthPrivを使用します。
Cisco側の設定例
configure terminal
snmp-server group V3PRIV v3 priv
snmp-server user userpriv V3PRIV v3 auth sha AuthPass1234 priv aes 128 PrivPass1234
end
設定した内容は以下です。
| 項目 | 設定値 |
|---|---|
| SNMPバージョン | v3 |
| ユーザー名 | userpriv |
| セキュリティレベル | authPriv |
| 認証アルゴリズム | SHA-1 |
| 暗号化アルゴリズム | AES-128 |
パスワードは検証用のサンプルです。
Raspberry PiからSNMPv3で情報取得
以下のコマンドを実行しました。
snmpget -v3 -l authPriv -u userpriv -a SHA -A AuthPass1234 -x AES -X PrivPass1234 192.168.20.1 1.3.6.1.2.1.1.5.0
実行結果:
iso.3.6.1.2.1.1.5.0 = STRING: "RT1.cisco.com"
正常にホスト名を取得できました。
これにより、SNMPv3のSHA認証とAES暗号化を使用した情報取得が成功したことが分かります。
WiresharkでSNMPv3のパケットを確認
続いて、SNMPv3の通信をWiresharkで確認しました。
最初に確認したパケットは、以下の内容でした。
Simple Network Management Protocol
msgVersion: snmpv3 (3)
msgGlobalData
msgAuthoritativeEngineID: <MISSING>
msgAuthoritativeEngineBoots: 0
msgAuthoritativeEngineTime: 0
msgUserName: <MISSING>
msgAuthenticationParameters: <MISSING>
msgPrivacyParameters: <MISSING>
msgData: plaintext (0)

SNMPv3を使用しているにもかかわらず、plaintextと表示されています。
なぜでしょうか。
SNMPv3では最初から暗号化されるわけではない
SNMPv3では、通信開始時に相手のSNMPエンジンIDなどを確認する処理が行われる場合があります。
この処理はSNMPエンジンID探索(Engine ID Discovery)と呼ばれます。
認証・暗号化に必要な情報を取得するため、探索パケットは認証なし・暗号化なしで送信されることがあります。
そのため、authPrivを使用していても、すべてのパケットが暗号化されるわけではありません。
msgFlagsを確認する
WiresharkでmsgFlagsを確認すると、以下のように表示されました。
msgFlags: 04
.... .1.. = Reportable: Set
.... ..0. = Encrypted: Not set
.... ...0 = Authenticated: Not set
msgSecurityModel: USM (3)

msgFlags: 04は、Reportableビットだけが有効になっていることを示します。
| フラグ | 値 | 意味 |
|---|---|---|
| Reportable | 1 | Reportを要求可能 |
| Encrypted | 0 | 暗号化なし |
| Authenticated | 0 | 認証なし |
このパケットでは、認証も暗号化も行われていません。
ただし、これはSNMPv3のauthPriv設定が無効という意味ではありません。
エンジンID探索など、通信確立に必要な処理である可能性があります。
SNMPv3の暗号化されたPDUを確認
続いて、Wiresharkで別のSNMPv3パケットを確認したところ、以下の表示が確認できました。
encryptedPDU: privKey Unknown

これは、Wiresharkが暗号化されたPDUを検出したものの、復号に必要な鍵を保持していないことを示します。
SNMPv3のauthPrivでは、SNMPメッセージのPDU部分が暗号化されます。
SNMPv2cでは平文で確認できるOIDや取得値も、SNMPv3のauthPrivでは復号しない限り確認できません。
なお、SNMPv3でもユーザー名など一部のヘッダー情報は暗号化されません。
msgFlagsと暗号化の関係
SNMPv3では、フラグによって認証・暗号化の状態を確認できます。
| msgFlags | 認証 | 暗号化 | Reportable |
|---|---|---|---|
| 00 | なし | なし | なし |
| 04 | なし | なし | あり |
| 01 | あり | なし | なし |
| 05 | あり | なし | あり |
| 03 | あり | あり | なし |
| 07 | あり | あり | あり |
03または07であれば、認証と暗号化の両方が有効です。
encryptedPDUのフラグを確認すると07でした。

SNMPv3のReportパケットについて
キャプチャ中には、以下のパケットも確認できました。
report 1.3.6.1.6.3.15.1.1.4.0
このOIDは、usmStatsUnknownEngineIDsを表します。
SNMPv3では、通信相手のSNMPエンジンIDを知らない状態でリクエストを送信すると、エージェントからReportが返される場合があります。
このReportを利用して、マネージャは通信相手のエンジンIDを学習できます。
その後、必要な情報を用いて正式なSNMPv3リクエストを送信します。
したがって、今回のようにReportが表示されたからといって、必ずしも通信エラーというわけではありません。
実際、今回の検証ではSNMPv3による情報取得が成功しています。
SNMPv2cとSNMPv3の検証結果
今回の検証結果をまとめます。
| 検証項目 | SNMPv2c | SNMPv3 authPriv |
|---|---|---|
| 情報取得 | 成功 | 成功 |
| 識別情報 | コミュニティ文字列 | ユーザー名 |
| 認証方式 | コミュニティ文字列によるアクセス制御 | SHA-1によるメッセージ認証 |
| 暗号化 | なし | AES |
| PDUの可視性 | 平文 | 暗号化 |
今回の実機検証によって、SNMPv2cとSNMPv3では、情報を取得するという基本的な機能は同じでも、セキュリティ面で大きな違いがあることが確認できました。
まとめ
今回、Cisco C1812JとRaspberry Piを使用して、SNMPv2cとSNMPv3の通信を比較しました。
SNMPv2cでは、コミュニティ文字列が平文で送信されることをWiresharkで確認できました。
一方、SNMPv3ではユーザー名と認証鍵による認証に加え、AESによるPDUの暗号化を利用できることが分かりました。
また、SNMPv3では通信開始時にエンジンID探索が行われることがあり、authPrivを使用していても暗号化されていないパケットが存在することも確認できました。
今回の検証を通じて、SNMPv3は単純にSNMPv2cのコミュニティ文字列をユーザー名に置き換えたものではなく、メッセージ認証と暗号化によってセキュリティを強化したプロトコルであることを理解できました。
続編:GetNextとGetBulkの通信効率を比較
SNMPのセキュリティ面に続いて、GetNextRequestとGetBulkRequestの違いも実機で検証しました。
同じMIB情報を取得したところ、GetBulkではリクエスト数が約89.9%削減され、平均実行時間も約77.4%短縮されました。

