はじめに
SNMPv3は、SNMPv1やSNMPv2cと異なり、ユーザー認証や通信内容の暗号化に対応しています。
ネットワーク監視のセキュリティを高められる一方、設定項目が増えるため、認証パスワードや暗号化パスワード、ユーザー名の不一致によって通信できなくなることがあります。
では、SNMPv3の設定を間違えた場合、実際のパケットはどのようになるのでしょうか。
今回はCisco C1812JとRaspberry Piを使用して、以下の4パターンを検証しました。
- 正しいSHA/AESパスワードで正常通信
- SHA認証パスワードを間違える
- AES暗号化パスワードを間違える
- 存在しないSNMPv3ユーザー名を指定する
Wiresharkでパケットを確認すると、同じSNMPv3の設定ミスでも、エラーの種類によって応答が異なることが分かりました。
さらに、Cisco IOSのSNMPカウンタも確認し、パケットキャプチャの結果と比較しました。
検証環境
使用機器
| 機器 | 役割 |
|---|---|
| Cisco C1812J | SNMPエージェント |
| Raspberry Pi | SNMPマネージャ |
| Net-SNMP | snmpgetコマンド |
| tcpdump | パケットキャプチャ |
| Wireshark | SNMPパケット解析 |
Cisco C1812JのIOSバージョンは、12.4(15)T8です。
ネットワーク構成
+---------------------------+
| Cisco C1812J |
| |
| 192.168.20.1 |
| SNMPエージェント |
+-------------+-------------+
|
| LANケーブル直結
|
+-------------+-------------+
| Raspberry Pi |
| |
| 192.168.20.2 |
| snmpget / tcpdump |
+---------------------------+
Raspberry PiからCisco C1812Jに対してSNMPv3のGetRequestを送信します。
通信にはUDP/161を使用します。
Cisco側のSNMPv3設定
今回のCisco C1812Jには、SNMPv3の3つのセキュリティレベルに対応するユーザーが設定されています。
show snmp user の結果から、以下を確認しました。
| ユーザー | 認証方式 | 暗号化方式 | セキュリティレベル |
|---|---|---|---|
| usernoauth | なし | なし | noAuthNoPriv |
| userauth | SHA | なし | authNoPriv |
| userpriv | SHA | AES128 | authPriv |
今回の検証では、認証と暗号化の両方を使用する userpriv を中心に使用します。
SNMPグループの設定は以下のとおりです。
snmp-server group V3AUTH v3 auth access 10
snmp-server group V3PRIV v3 priv access 10
snmp-server group V3NOAUTH v3 noauth access 10
各グループにはACL 10が適用されています。
Raspberry PiからのSNMP通信が許可されていることを前提として検証します。
SNMPv3のセキュリティレベル
SNMPv3では、次の3つのセキュリティレベルを使用できます。
| セキュリティレベル | 認証 | 暗号化 |
|---|---|---|
| noAuthNoPriv | なし | なし |
| authNoPriv | あり | なし |
| authPriv | あり | あり |
今回使用する authPriv では、SHAによる認証とAES128による暗号化を使用します。
なお、SNMPv3で使用する認証・暗号化パスワードは、コマンド履歴などに残る可能性があります。実運用ではパスワードの取り扱いに注意が必要です。
Raspberry Piでパケットキャプチャを開始
Wiresharkで通信を解析するため、Raspberry Pi側でtcpdumpを起動します。
sudo tcpdump -i eth0 -nn -s 0 -w snmpv3-auth-failure.pcap 'host 192.168.20.1 and udp port 161'
-s 0 はパケット全体を取得するための指定です。
キャプチャしたファイルをWiresharkで開き、次の表示フィルタを設定します。

snmp && ip.addr == 192.168.20.1
これでSNMP通信を中心に確認できます。
検証① 正しいSHA/AESパスワードで正常通信
まずは、SNMPv3の設定が正しい状態で通信できることを確認します。
Raspberry Piから以下のコマンドを実行しました。
snmpget -v3 -l authPriv -u userpriv -a SHA -A '正しい認証パスワード' -x AES -X '正しい暗号化パスワード' 192.168.20.1 1.3.6.1.2.1.1.3.0
取得対象のOIDは sysUpTime.0 です。
1.3.6.1.2.1.1.3.0
これはSNMPエージェントの管理機能が初期化されてからの経過時間を示すオブジェクトです。
検証結果
snmpget は正常に成功しました。

これにより、以下を確認できました。
- SNMPv3ユーザー
userprivが使用できる - SHA認証が正常に動作する
- AES128による暗号化通信が正常に動作する
- Raspberry PiからCiscoのOIDを取得できる
この正常通信を基準として、以降の異常系を比較します。
検証② SHA認証パスワードを間違える
次に、SHA認証パスワードだけを間違えて実行します。
ユーザー名とAES暗号化パスワードは変更しません。
snmpget -v3 -l authPriv -u userpriv -a SHA -A 'WrongAuthPass123' -x AES -X '正しい暗号化パスワード' -r 0 -t 2 192.168.20.1 1.3.6.1.2.1.1.3.0
-r 0 はNet-SNMPクライアントの再試行を無効化する指定です。
-t 2 は応答待ち時間を2秒に設定します。
snmpgetの結果
認証失敗のエラーが表示されました。

snmpget: Authentication failure (incorrect password, community or key)
Wiresharkの結果
Wiresharkでは4パケットを観測しました。

| No. | Info |
|---|---|
| 1 | get-request |
| 2 | report 1.3.6.1.6.3.15.1.1.4.0 |
| 3 | encryptedPDU: privKey Unknown |
| 4 | report 1.3.6.1.6.3.15.1.1.5.0 |
最初のGetRequestとReportは、SNMPv3のEngine ID探索に関連する通信と考えられます。
SNMPv3では、認証や暗号化に必要な情報として、相手のSNMP Engine IDを使用します。
このため、通信開始時にEngine IDを確認する処理が発生することがあります。
UnknownEngineIDsのReport
2番目のパケットでは、次のOIDが確認できました。
1.3.6.1.6.3.15.1.1.4.0
これは usmStatsUnknownEngineIDs です。
未知のEngine IDに関連するReportであり、Engine ID探索時にも観測されます。
したがって、このReportだけを見て認証失敗と判断することはできません。
WrongDigestsのReport
注目したいのは4番目のパケットです。
1.3.6.1.6.3.15.1.1.5.0
これは usmStatsWrongDigests です。
SNMPv3メッセージの認証ダイジェスト検証に失敗したことを示します。
今回はSHA認証パスワードを意図的に間違えているため、検証条件と一致しています。
Cisco側のカウンタ
Cisco C1812Jで show snmp を実行したところ、以下の値を確認できました。
1 Wrong MD5 or SHA Digests
Wiresharkで確認したWrongDigestsのReportと整合する結果です。
ただし、このカウンタは累積値のため、厳密に今回の試行による増分を確認するには実行前後の比較が必要です。
考察
今回の環境では、SHA認証パスワードが間違っている場合、Ciscoが認証ダイジェストの不一致を検出し、Report-PDUを返しました。
Raspberry Pi側のNet-SNMPも、その結果を認証失敗として表示しています。
検証③ AES暗号化パスワードを間違える
続いて、SHA認証パスワードは正しいまま、AES暗号化パスワードだけを間違えます。
snmpget -v3 -l authPriv -u userpriv -a SHA -A '正しい認証パスワード' -x AES -X 'WrongPrivPass123' -r 0 -t 2 192.168.20.1 1.3.6.1.2.1.1.3.0
snmpgetの結果
SHA認証パスワード不一致の場合とは異なり、今回はタイムアウトになりました。

Timeout: No Response from 192.168.20.1.
Wiresharkの結果
観測されたのは3パケットでした。

| No. | Info |
|---|---|
| 1 | get-request |
| 2 | report 1.3.6.1.6.3.15.1.1.4.0 |
| 3 | encryptedPDU: privKey Unknown |
Engine ID探索に関連するReportは確認できましたが、その後の暗号化された要求に対するResponseやReportは観測されませんでした。
privKey Unknownとは?
WiresharkのInfo欄には、以下の表示がありました。
encryptedPDU: privKey Unknown
この表示は、Wireshark側が暗号化されたPDUを復号するための鍵情報を持っていないことを示します。
この表示だけで、Cisco側のAES復号処理が失敗したと判断することはできません。
Cisco側のDecryption Errorsを確認
Ciscoで show snmp を実行すると、以下のカウンタが表示されました。
0 Decryption Errors
AES暗号化パスワードが間違っているにもかかわらず、復号エラーとして記録されていません。
そこで、同じコマンドをもう一度実行し、前後のカウンタを比較しました。
show snmpの差分

| カウンタ | 実行前 | 実行後 | 差分 |
|---|---|---|---|
| SNMP packets input | 53792 | 53794 | +2 |
| SNMP packets output | 53820 | 53821 | +1 |
| Unknown EngineIDs | 9 | 10 | +1 |
| Encoding errors | 1 | 2 | +1 |
| Decryption Errors | 0 | 0 | 0 |
SNMP入力パケット数は2増加しています。
これは、Engine ID探索の要求と、その後の暗号化された要求を受信したことと整合します。
また、SNMP出力パケット数とUnknown EngineIDsがそれぞれ1増加しており、Engine ID探索に対するReportの送信と整合しています。
ここで特に注目したいのは、Decryption Errorsは増加していない一方で、Encoding errorsが1増加しているという点です。
考察
今回のCisco IOS 12.4(15)T8では、AES暗号化パスワードを間違えた要求に対して、以下の動作が観測されました。
- Engine ID探索に対するReportは返る
- 暗号化された要求に対するResponseは返らない
- snmpgetはタイムアウトする
- Decryption Errorsカウンタは増加しない
- Encoding errorsカウンタが1増加する
この結果から、AES暗号化パスワード不一致の試行に伴い、Cisco側で何らかのエンコーディング関連のエラーが記録されたことが分かります。
一方、Decryption Errorsは増加していないため、今回の試行では、少なくともこのカウンタに計上される復号エラーは確認できませんでした。
考えられる要因の1つは、誤ったAES鍵によって復号されたデータをSNMP PDUとして解析できず、Encoding errorsに計上された可能性です。
ただし、これは今回の観測結果に基づく推測であり、Cisco IOS内部の具体的な処理までは確認できていません。
今回の検証で重要なのは、AES暗号化パスワードの不一致が、必ずしもDecryption Errorsカウンタの増加として現れるわけではなかったことです。
SNMPv3のトラブルシューティングでは、タイムアウトや特定のエラーカウンタだけで原因を判断せず、Wiresharkのパケットキャプチャと複数のSNMPカウンタを組み合わせて確認することが重要だと分かりました。
検証④ 存在しないSNMPv3ユーザー名を指定する
最後に、Ciscoに存在しないユーザー名を指定してみます。
今回は unknownuser を使用しました。
snmpget -v3 -l authPriv -u unknownuser -a SHA -A '正しい認証パスワード' -x AES -X '正しい暗号化パスワード' -r 0 -t 2 192.168.20.1 1.3.6.1.2.1.1.3.0
snmpgetの結果
ユーザー名が存在しないことを示すエラーが表示されました。

snmpget: Unknown user name
Wiresharkの結果
今回は4パケットを観測しました。

| No. | Info |
|---|---|
| 1 | get-request |
| 2 | report 1.3.6.1.6.3.15.1.1.4.0 |
| 3 | encryptedPDU: privKey Unknown |
| 4 | report 1.3.6.1.6.3.15.1.1.3.0 |
注目したいのは、4番目のReportです。
1.3.6.1.6.3.15.1.1.3.0
これは usmStatsUnknownUserNames です。
SNMPv3メッセージで指定されたユーザー名が、受信側のUSMユーザー情報に存在しないことを示します。
今回のCisco C1812Jでは、存在しないユーザー名を検出すると、UnknownUserNamesのReportを返しました。
Net-SNMPもこれを認識し、Unknown user name と表示しています。
SNMPv3のReport-PDUとは?
ここまでの検証では、SNMPv3のReport-PDUが複数回登場しました。
Report-PDUは、SNMPv3のメッセージ処理に関連する問題などを通知するために使用されます。
今回の検証で確認した代表的なUSM関連OIDをまとめます。



| OID | 名称 | 意味 |
|---|---|---|
| 1.3.6.1.6.3.15.1.1.3.0 | usmStatsUnknownUserNames | 未知のユーザー名 |
| 1.3.6.1.6.3.15.1.1.4.0 | usmStatsUnknownEngineIDs | 未知のEngine ID |
| 1.3.6.1.6.3.15.1.1.5.0 | usmStatsWrongDigests | 認証ダイジェスト不一致 |
| 1.3.6.1.6.3.15.1.1.6.0 | usmStatsDecryptionErrors | 復号エラー |
今回、実際のパケットで確認できたのはUnknownUserNames、UnknownEngineIDs、WrongDigestsの3種類です。
DecryptionErrorsのReportは観測されませんでした。
なお、Report-PDUの返送はエラーの種類、メッセージのreportableフラグ、SNMPエージェントの実装などに依存します。
すべてのSNMPv3エラーで必ずReportが返るわけではありません。
4パターンの検証結果を比較
今回の検証結果をまとめると、以下のようになりました。
| 検証条件 | Wiresharkの結果 | snmpgetの結果 |
|---|---|---|
| 正しいSHA/AESパスワード | 正常な応答通信 | 成功 |
| SHA認証パスワード不一致 | WrongDigests Report | Authentication failure |
| AES暗号化パスワード不一致 | 暗号化要求後に応答なし | Timeout |
| 存在しないユーザー名 | UnknownUserNames Report | Unknown user name |
特に注目したいのは、SHA認証パスワード不一致とAES暗号化パスワード不一致の違いです。
SHA認証パスワード不一致では、認証ダイジェストの不一致を示すReportが返りました。
一方、AES暗号化パスワード不一致では、暗号化された要求の後に応答が返らず、タイムアウトとなりました。
このように、同じSNMPv3の設定ミスでも、Wireshark上の見え方やNet-SNMPのエラー表示は異なります。
SNMPv3のトラブルシューティングで役立つポイント
SNMPv3で通信できない場合、単純に「タイムアウトした」という結果だけでは原因を判断できません。
今回の検証から、次のような確認方法が有効だと分かりました。
Report-PDUのOIDを確認する
WiresharkでReportが返っている場合、Variable Bindings内のOIDを確認します。
WrongDigestsであれば認証ダイジェストの不一致、UnknownUserNamesであればユーザー名の不一致が疑われます。
Engine ID探索とエラーを区別する
UnknownEngineIDsのReportは、SNMPv3のEngine ID探索時にも発生します。
したがって、UnknownEngineIDsが表示されたからといって、それだけで異常とは判断できません。
Cisco側のSNMPカウンタを確認する
Cisco IOSでは以下のコマンドでSNMPの統計情報を確認できます。
show snmp
認証失敗や復号エラーに関連するカウンタを確認できる場合があります。
ただし、カウンタは累積値なので、可能であれば検証前後の差分を比較することが重要です。
タイムアウトの原因を決めつけない
SNMPv3のタイムアウトは、通信経路やACLだけでなく、認証・暗号化に関する設定不一致でも発生する可能性があります。
パケットキャプチャと機器側の統計情報を組み合わせて判断することが重要です。
まとめ
今回はCisco C1812JとRaspberry Piを使用して、SNMPv3の正常通信と3種類の異常系を検証しました。
実際に確認できたポイントは以下のとおりです。
- 正しいSHA/AESパスワードではSNMPv3のGetRequestが正常に成功した。
- SHA認証パスワードを間違えると、WrongDigestsのReportが返った。
- AES暗号化パスワードを間違えると、暗号化された要求に対する応答がなく、タイムアウトした。
- AESパスワード不一致の再検証では、Encoding errorsが1増加した一方、Decryption Errorsは増加しなかった。
- 存在しないユーザー名を指定すると、UnknownUserNamesのReportが返った。
- Engine ID探索時にはUnknownEngineIDsのReportが発生することがあった。
今回の検証で特に印象的だったのは、SNMPv3のエラーはすべて同じ動作になるわけではないという点です。
認証パスワードの不一致ではReportから原因を確認できましたが、暗号化パスワードの不一致ではタイムアウトとなりました。
Wiresharkでパケットを確認し、さらにCisco側のカウンタを比較することで、SNMPv3のトラブルシューティングをより具体的に理解できました。
これまでSNMPv2cとSNMPv3のセキュリティ比較、GetNextとGetBulkの性能比較、TrapとInformの動作比較を行ってきました。
今回のSNMPv3異常系の検証をもって、SNMP実機検証シリーズはいったん完結です。
SNMPは監視の仕組みとして身近なプロトコルですが、実際にパケットをキャプチャすると、仕様書だけでは気づきにくい動作を確認できます。
今後SNMPのトラブルシューティングを行う際にも、今回の検証結果を活用していきたいと思います。
