スクリプトのお勉強 技術

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での勘違い(if A:)

勘違い 小ネタです。 Pythonでは、以下のように書くことができます。 a = [] if a: print(“not empty!”) else: print(“empty!”) 結果は以下になり …

めっちゃ冷や汗。。(^^;;)

めっちゃ冷や汗が出たので、書いておこう。。 $ ls [‘ [‘という名のファイルを無意識に作ったらしい。もちろん意図的ではない。 なんとなく、消そうとして、、、 $ rm -rf “[\ …

seaborn + Pandas + Python によるグラフ描画(その2: グラフ描画編)

前回の続き 前回の続きです。 折れ線グラフ まずは折れ線グラフを描画したいと思います。 描画するのは以下です。 運用商品(4つ)日経平均 以下で起動します。引数(dataset-2017-201908 …

gradleのcommandLineでリダイレクト

gradleというビルドツールがあります。なぜかRPMを作成するのに使ってます。Ansibleも使ってるんですがね。。 それはともかく、ここの通りなのですが、例えばls -lRの出力を、プロジェクトデ …

Python3 – django-webtest

忙しいので断片だけ。。 DjangoでWebブラウザからアクセスする感じでテストする、やり方の一つです。以前にやったように、 Seleniumからやってもいいのすが、そこまでじゃない場合の単体テスト方 …

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