1

Message processing model 3 returned error: Unknown security name単一のデバイスに対して get/getNext コマンドを実行中にエラーが発生しました。私は2秒ごとにデバイスを叩いています。パフォーマンスを向上させるために、別のテーブルを取得したい場合。スレッドを作成し、アプリケーションから各スレッドに並列にアクセスします。シングルスレッドモードでデバイスにアクセスすると、すべてのリクエストが正常に機能します。ただし、マルチスレッドモードで実行すると、断続的に上記のエラーが発生します(10回のリクエストで2回失敗します)。これがスタックトレースです。

2014-06-11 11:26:10,371 [http-8080-6] INFO  com.kp.SnmpV3Connection - User Target: Security level is: 3Security Name is: user7
2014-06-11 11:26:10,371 [http-8080-3] INFO  com.kp.SnmpV3Connection - User Target: Security level is: 3Security Name is: user7
2014-06-11 11:26:10,373 [http-8080-6] DEBUG org.snmp4j.security.UsmUserTable - Adding user user7 = UsmUser[secName=user7,authProtocol=1.3.6.1.6.3.10.1.1.3,authPassphrase=kp-pass,privProtocol=1.3.6.1.6.3.10.1.2.4,privPassphrase=kp-pass,localizationEngineID=null]
2014-06-11 11:26:10,373 [http-8080-6] DEBUG org.snmp4j.security.UsmUserTable - Adding user user7 = UsmUser[secName=user7,authProtocol=1.3.6.1.6.3.10.1.1.3,authPassphrase=kp-pass,privProtocol=1.3.6.1.6.3.10.1.2.4,privPassphrase=kp-pass,localizationEngineID=null]
2014-06-11 11:26:10,374 [http-8080-6] DEBUG org.snmp4j.security.USM - Security name not found for engineID=, securityName=75:73:65:72:37
2014-06-11 11:26:10,374 [http-8080-6] DEBUG org.snmp4j.security.USM - Security name not found for engineID=, securityName=75:73:65:72:37
2014-06-11 11:26:10,376 [http-8080-6] ERROR org.snmp4j.util.TableUtils - org.snmp4j.MessageException: Message processing model 3 returned error: Unknown security name
2014-06-11 11:26:10,376 [http-8080-6] ERROR org.snmp4j.util.TableUtils - org.snmp4j.MessageException: Message processing model 3 returned error: Unknown security name

ここで与えられたリンクに従って、私は以下のセキュリティモデルを使用しています:

USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(
                    MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);

もう 1 つのオプション noAuthNopriv はオプションではありません。authpriv で実行する必要があります。誰かが私を正しい方向に向けることができますか?

snmp セッションまたは engineId に問題があると思います。

**********************編集**********************

数週間の調査の後、USM オブジェクトを作成する方法を最終的に見つけました。

USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);

すべてのリクエストに対してこのオブジェクトを作成し、securitymodel に追加すると、UserTable と usertime テーブルが再作成されました。USM をシングルトンにすることで問題を修正し、USM テーブルの再作成を防止しました。しかし、私は新しい問題を抱えてしまいました.今はエラーが発生しています.

2014-06-24 07:11:19,671 [DefaultUDPTransportMapping_10.110.113.75/0] DEBUG org.snmp4j.mp.MPv3 - SNMPv3 header decoded: msgId=1263968764, msgMaxSize=65535, msgFlags=03, secModel=3
2014-06-24 07:11:19,671 [DefaultUDPTransportMapping_10.110.113.75/0] DEBUG org.snmp4j.security.USM - getUser(engineID=80:00:05:49:04:4d:49:4d:49:43, securityName=user10)
2014-06-24 07:11:19,671 [DefaultUDPTransportMapping_10.110.113.75/0] DEBUG org.snmp4j.security.UsmTimeTable - CheckTime: received message outside time window (non authoritative)
2014-06-24 07:11:19,671 [DefaultUDPTransportMapping_10.110.113.75/0] DEBUG org.snmp4j.security.USM - RFC3414 ?3.2.7.a Not in time window; engineID='80:00:05:49:04:4d:49:4d:49:43', engineBoots=5, engineTime=58766
2014-06-24 07:11:19,671 [DefaultUDPTransportMapping_10.110.113.75/0] WARN  org.snmp4j.MessageDispatcherImpl - statusInfo=1.3.6.1.6.3.15.1.1.2.0 = 0, status=1411

もう少し調査した結果、snmp4j がそれ自身のエンジン時間と UserTimeTable のデバイス エンジン時間の両方を更新していないことがわかりました。


この問題に加えて、さらにいくつかのクエリがあります。

  1. USM をシングルトンにすると、USM テーブルはアプリケーションごとに寿命を迎えます。このテーブルをクリアするにはどうすればよいですか (数万のデバイスがあり、最終的にメモリ不足になる可能性があります)。どのような基準でこのユーザーをクリアできますか?

  2. SNMP4J で engineboot と enginetimes を明示的に要求するにはどうすればよいですか?

  3. ユーザー名とセキュリティ名が同じで、認証フレーズとプライバシー フレーズが異なり、(場合によっては同じ engineId) である場合、SNMP4J がデバイスを区別する方法 よろしくお願いします。

4

2 に答える 2

0

@Karthik Prasadの回答を補強するために、snmp4j v2.8.6の時点でクラスがないことに注意しくださいUSMFactory。したがって、ソリューションは次のようになります。

public class SnmpDeviceProxy {    // one of your application classes
 
  public static final USM USM;
  static {
    // extract USM into a singleton to avoid multiple userTable instances creation that causes 'UnknownSecurityName'
    USM = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
    SecurityModels.getInstance().addSecurityModel(USM);
  }

問題の詳細

USM をシングルトンにする前に、呼び出すたびにSecurityModels.getInstance().addSecurityModel(USM)新しいモデルを実際に追加するのではなく、同じモデルを何度も何度も書き直しaddSecurityModelます。

  public SecurityModels addSecurityModel(SecurityModel model) {
    securityModels.put(new Integer32(model.getID()), model);
    return this;
  }

、つまりmodel.getId()、定数から値を取得するメソッドからキーを取得して、モデルをマップに配置します。

  public int getID() {
    return SECURITY_MODEL_USM;
  }

がっかりするように次のように宣言されています。

  public static final int SECURITY_MODEL_USM = 3;

つまり、どの USM インスタンスを追加しようとしても、常にsecurityModelsキーでマップに保存されます3userTableまた、保存されるたびに、各 USM インスタンスの子オブジェクト (フィールド) であるため、以前の状態が失われます。その結果、USM インスタンスを作成した直後に呼び出すと、が空または不完全なaddSecurityModel期間が開きます。userTableこの期間中にスレッドがテーブルにクエリを実行すると、Unknown security name. しかし、USM をシングルトンにして一度だけ保存すると、以前の値を失うことなくモデル マップを更新できます。

于 2022-02-16T05:34:15.400 に答える