スクリプトのお勉強 技術

Python3でsnmptrapの受送信をしてみる

投稿日:

はじめに

私はなんちゃってプログラマですが、なぜかいまどきsnmptrapの受信プログラムを作ることになりました。

なんだかなと思いますが、、まぁブログネタにいいかなと思い、手元でもやってみることにしました。

snmptrapとは

Bingいわく「SNMPトラップとは、ネットワーク上の機器(SNMPエージェント)が異常や
状態変化を検知した際に、管理用コンピュータ(SNMPマネージャ)に向けて自動的に送信する通知のことです」

だそうです。

基本は簡単なデータですが、それが意外に真っ当に動作させるのは面倒でして。。

まずは動作させてみます。

環境

  • Windows 10
  • WSL2
  • pysnmp (4.4.12)
  • pyans1 (0.4.8)

注意点

現状、pyasn1のバージョンが0.5.0の場合、0.4.8でないと動作しません。ダウングレードさせたら動作しました。

こういう事があるからOSSは怖い。。

受信側(snmprecv.py)

全体はここに置きました。

起動方法

ポートが162番なので、rootで起動させる必要があります。

$ python3 -m venv ./venv
$ source venv/bin/activate
$ pip install poetry
$ poetry install
$ sudo ./exec.sh

プログラム自体は簡単です。以下は中心部分です。

snmpEngine = engine.SnmpEngine()

# for receive logging
snmpEngine.observer.registerObserver(
    requestObserver,
    'rfc3412.receiveMessage:request',
    'rfc3412.returnResponsePdu'
)

# port: 162 receive
config.addTransport(
    snmpEngine,
    udp.domainName,
    udp.UdpTransport().openServerMode((bindIF, 162))
)

# SNMP v1 my-area is security name
config.addV1System(snmpEngine, 'my-area', 'public')

ntfrcv.NotificationReceiver(snmpEngine, cbFun)

# not return
snmpEngine.transportDispatcher.jobStarted(1)

try:
    snmpEngine.transportDispatcher.runDispatcher()
except Exception as e:
    logger.exception(e)
    snmpEngine.observer.unregisterObserver()
    snmpEngine.transportDispatcher.closeDispatcher()

見たまんまなのですが、いまいち謎なのが”my-area”です。config.addV1System()は呼び出さないと何も処理しなくなります。

security nameとして”my-area”を指定するようですが、送信側は気にしなくても、この設定で受信するようです。

送信側(snmpsend.py)

起動は以下で行います。

$ python3 ./snmpsend.py

プログラムの説明は割愛します。

受信ログ(app.log)

送信データを受信したときのログは以下になります。

INFO : 2023-10-21T13:01:54.985775+0900 : Execution point: rfc3412.receiveMessage:request* transportDomain: 1.3.6.1.6.1.1* transportAddress: 172.22.123.3@50652* securityModel: 2* securityName: my-area* securityLevel: 1* contextEngineId: 0x80004fb8054445534b544f502d3642515645354422f5ff40* contextName: * PDU: SNMPv2TrapPDU:
 request-id=15081672
 error-status=noError
 error-index=0
 variable-bindings=VarBindList:
  VarBind:
   name=1.3.6.1.2.1.1.3.0
   =_BindValue:
    value=ObjectSyntax:
     application-wide=ApplicationSyntax:
      timeticks-value=0



  VarBind:
   name=1.3.6.1.6.3.1.1.4.1.0
   =_BindValue:
    value=ObjectSyntax:
     simple=SimpleSyntax:
      objectID-value=1.3.6.1.6.3.1.1.5.2



  VarBind:
   name=1.3.6.1.2.1.1.1.0
   =_BindValue:
    value=ObjectSyntax:
     simple=SimpleSyntax:
      string-value=my system




: 8949
INFO : 2023-10-21T13:01:54.986406+0900 : Notify from ContextId "0x80004fb8054445534b544f502d3642515645354422f5ff40", ContextName "": 8949
INFO : 2023-10-21T13:01:54.986834+0900 : 1.3.6.1.2.1.1.3.0 = 0: 8949
INFO : 2023-10-21T13:01:54.987125+0900 : 1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.2: 8949
INFO : 2023-10-21T13:01:54.987395+0900 : 1.3.6.1.2.1.1.1.0 = my system: 8949

終わりに

比較的あっさり実装できました。

一応GPT-4にも質問したのですが、結局pySNMPのサンプルそのままになりました。
使えない、、GPT-4。。

参考

https://pysnmp.readthedocs.io/en/latest/examples/v3arch/asyncore/manager/ntfrcv/advanced-topics.html

-スクリプトのお勉強, 技術

執筆者:

関連記事

Pythonからsvnしてみる

SVN: レガシーシステムの一つ。。 私の関わってるシステムでは、いまだにsvnレポジトリがあります。pythonで処理する必要性が生じましたが、そういえばどう処理していいもんか、完全に忘れました。 …

FastAPIでAPIを作ってみる(その1)

勉強として、FastAPIを使用して、実際にAPIを作成し、起動しようと思います。目標としては、本番運用用の設定まで行いたいと思います。 FastAPIとは FastAPIとは、Pythonによる、W …

Djangoのurls.pyにはまった。。

けっこうハマった。。 Django 2.2.4の話。以下のエラーを修正するのに、とっても時間がかかった。 django.urls.exceptions.NoReverseMatch: Reverse …

@nifty auひかり タイプVからタイプGに変えてみた

家のインターネットはいままで、光回線ではありましたが、昔のVSDLのままでした。auひかりでいう、マンション タイプVというやつです。 それを近年、リモートワークが増えていることや、半導体需要がなんと …

Webフレームワーク「Django 3.2」を使ってみる

LTSリリースなので、現状でアップデートしてないDjangoプロジェクトをDjango 3.2にしていこうかと思いました。例として、自分のDjango 2.0のプロジェクトをDjango 3.2にしま …

google オプトアウト Click here to opt-out.