スクリプトのお勉強 技術

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

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

執筆者:

関連記事

Nuxt.js – CRUDアプリケーションのフォーム/一覧を作成する

前回で作ったAPIのフロントエンドアプリケーションを作ろうと思います。 どういうアプリ? サンプルとして作ったAPIが住所録的だったので、住所録を作りました。 以下の機能があります。 登録(確認付き) …

Go言語でtarアーカイブコマンド作成

今所属している会社で1バイナリでとりあえず済ませる簡単ツールはgo言語で書くことが多いようです。 私はそれほどgo言語が好きというわけでもありませんが、勉強がてら、ディレクトリからtarアーカイブする …

PyWebIOでform 入力+ REST API呼び出しを作ってみる

仕事柄、簡単なWebアプリを作りたいと思うことはよくあり、その場合はその場で直せるスクリプトで書きたいとよく思うものです。 すごーく簡単なフォームを非常に簡単に使いたいので、まずは簡単に作れるフレーム …

Githubからお告げ

Githubからお告げが来た お告げってのは大げさですが。 Github にpackage-lock.jsonを置いておくと、Githubが脆弱性検査をして、メールを知らせてくれます。 js-yaml …

Python3/ある日付から日付までの月/日/時間ごとの時刻を算出する

小ネタです。 要するに、時刻A と 時刻B を指定したときの、各時間間隔での時刻取得したかったです。 当初はdateutilを使う方法でなく、自前で実装しようと思ったのですが、面倒なことに気づきました …

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