snmptrapを利用したインターフェースごとのアイテム検知について

お世話になります。
snmpttを利用してネットワーク機器のtrap監視を行っており、snmptrapを利用してインターフェースごとに「linkDown」や「lacptimeout」を検知させたいと思っています。
現状の設定だと「linkDown」や「Lacp times out」というキーでアイテム項目を作成しておりtrapの中身を見ないとIF名がわからない状況のため、
ディスカバリルールを利用してアイテムを作り、フィルタにてポートを制限し、検知させる仕組みを実装したいと思っているのですが、
zabbixの正規表現で「GE1/0/1」と「GE1/0/10」など、IF名の一部を含む文字列の区別をつけるよい方法が思い浮かびません。
いい方法があればご教示いただけると幸いです。

※フィルタにてポートを制限する方法と、アイテムは一通り作成し個別トリガーの有効化・無効化で対応する方法の2通りを考えています。
 できればどちらも使えるルールやトリガーの作り方があると嬉しいです

■zabbixバージョン:3.0.8、4.0.8 ※設定条件が違う場合は3.0.8で合わせたいです

■trap例
【linkdown】※trapの中でIF名が最後に入るパターン
.1.3.6.1.6.3.1.1.5.3 Normal Status Events xxx.xxx.xxx.xxx(IP) - A linkDown trap signifies that the SNMPv2 entity, 10 up down GE1/0/1
【lacptimeout】※trapの中でIF名が途中に入るパターン(この例はjuniperのMIB)
.1.3.6.1.4.1.2636.3.53.1.2.1.1 Normal Status Events xxx.xxx.xxx.xxx(IP) - Lacp times out et-0/0/1 638 ae1 576 0x3f

■現状の設定
・アイテム名:trap linkDown
・アイテムキー:snmptrap["linkDown"]
・トリガー:snmptrap["linkDown"].nodata(30)}=0
→同一ホストで連続して異なるIFがdownするとすべてを検知できないことがネックになっています。
(トリガーにnodata(30)を設定しているため、最小30秒間は同ホスト同アイテムの検知だと都度アクションを起こさない)

■試して失敗した例
以下のURLのP.35の設定(ディスカバリルールをifDescrで作成しアイテムをIF名で拾い、トリガー条件としてlinkDownの文字列が含まれている場合障害判定を行う)
https://www.zabicom.com/zabbix/images/Zabbix%204.0%20Non-Certified%20Int...

→yyyy/mm/dd hh:mm:ss .1.3.6.1.6.3.1.1.5.3 Normal "Status Events" 10.248.0.53 - A linkDown trap signifies that the SNMPv2 entity, 22 up down GE1/0/18
 という1/0/18のIFのdownが出た際に、【GE1/0/1】snmptrapと【GE1/0/18】snmptrapの2つのアイテムにひっかかってしまう

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー yk_taiko の写真

インターフェース名が一番最後に出るのがわかっているのであれば、
トリガーで 関数を str ではなく regexp にして、一番最後に "$"(行末指定) を付けるのはどうでしょうか。

ユーザー ynw の写真

yk_taiko様

ご確認ありがとうございます!
>【linkdown】※trapの中でIF名が最後に入るパターン
>.1.3.6.1.6.3.1.1.5.3 Normal Status Events xxx.xxx.xxx.xxx(IP) - A linkDown trap signifies that the SNMPv2 entity, 10 up down GE1/0/1
に関してはそれでもできそうな気がしているのですが、できれば、文中にIF名が入る以下のパターンにも対応できないかと考えていました。
>【lacptimeout】※trapの中でIF名が途中に入るパターン(この例はjuniperのMIB)
>.1.3.6.1.4.1.2636.3.53.1.2.1.1 Normal Status Events xxx.xxx.xxx.xxx(IP) - Lacp times out et-0/0/1 638 ae1 576 0x3f

こちらの場合だと難しいかなと思っていたのですが、置き換えたらIF名だけうまく「$」の設定が反映されるような関数の仕組みになりますでしょうか…?

ユーザー yk_taiko の写真

真ん中に入るものは、インターフェースの後ろがスペースだったりしませんか。
それなら、インターフェースの後ろにスペースが入るように条件を入れてあげれば良いと思います。

「スペースいれたもの」と「$ 付きのもの」を or で繋げたら、一つのトリガーで表せますかね。

ユーザー ynw の写真

yk_taiko様

ありがとうございます。理解不足で申し訳ありません、確認させてください。

現在2つの方法を想定しています。
①アイテムを「linkDown」のキーで拾い、トリガーをIFで絞って検知する
②アイテムをIF名で作成し、トリガーを「linkDown」の文字列で検知する

最初に前提を申し上げておらず恐縮ですが、大量にスイッチがあるため、IFの管理はホスト1台ずつ中のトリガー条件式に記入するのではなく、
ホストマクロの値かディスカバリルールのフィルタに検知したい項目を入力したいと思っています。

最初におっしゃっていた「regexpでトリガーを作成する」というのは①の仕組みを利用するという理解をしています。
現状の設定どおりsnmptrap["linkDown"]でアイテムを作成し、
ホストマクロを作成して値に$を設定した項目を作成しておくことになると思うのですが、
そのホストマクロに「IF名+$」版と「IF名+空白」版を2つ作り、トリガー条件として&でつなぐようなイメージになりますでしょうか。
もしよろしければ具体的な条件式の例があれば併せてご教示いただけますと幸いです。

ユーザー yk_taiko の写真

ローレベルディスカバリ(LLD)を使った監視設定の流れは以下のようになるかと思います。
(やり方は一つじゃないですし要件によっても違うので、あくまで一例ですが...)

1) 監視対象のIFの情報をディスカバリ(SNMPエージェント?) で取得
→ <#インターフェースのマクロ> にインターフェース名が入る
※ 登録したいインターフェースのフィルタリングを機械的に実施したいならこの時点で実施

2) ②の案の場合はアイテムをIFごとに作成
例: snmptrap[({<#インターフェースのマクロ>} )|({<#インターフェースのマクロ>}&)]
※ ①の案の場合は事前に linkDown のアイテム登録は済みのはず

3) トリガー作成 ①の案の場合はインターフェース名 ②の案の場合は linkDown
①の例: {<ホスト名>:<アイテムキー>.regexp({<#インターフェースのマクロ>} )}=1 or {<ホスト名>:<アイテムキー>.regexp({<#インターフェースのマクロ>}$)}=1
②の例: {<ホスト名>:<アイテムキー>.regexp(linkDown)}=1
※ インターフェース毎に手動でトリガーを有効化・無効化するならこの時点で実施

ユーザー ynw の写真

yk_taiko様

ご回答ありがとうございます!
丁寧に解説いただきありがとうございます。ずっと悩んでいたので、本当に大変助かります。

いただいた上記の内容を参考に、以下のように2パターンを設定してみました。

①アイテムを「linkDown」等のキーで拾い、トリガーをIFで絞って検知する方法
・キー:snmptrap["linkDown"]
・ホストマクロ:{$IFNAME}=GE[0-9]+\/[0-9]+\/([0-9]($|\s)|[1-9][0-9]($|\s))
・トリガー名:trap linkDown if {$IFNAME}
・トリガー条件:{ホスト名:snmptrap["linkDown"].regexp({$IFNAME})}=1 and {ホスト名:snmptrap["linkDown"].nodata(30)}=0
※Lacp times outの場合は、アイテムをsnmptrap["Lacp times out"]等で設定し、同じホストマクロを使いトリガーを設定する。

②ディスカバリルールでIFのアイテムを作成する方法
・ディスカバリルールのSNMP OID:{#IFNAME},1.3.6.1.2.1.2.2.1.2
・ディスカバリルールのフィルタ:GE[0-9]+\/[0-9]+\/([0-9]($|\s)|[1-9][0-9]($|\s))
・アイテムのプロトタイプのキー:snmptrap[{#IFNAME}]
・トリガーのプロトタイプ:{ホスト名:snmptrap[{#IFNAME}].regexp(linkDown)}=1 and {ホスト名:snmptrap[{#IFNAME}].nodata(30)}=0
※Lacp times outの場合は、トリガーのプロトタイプに{ホスト名:snmptrap[{#IFNAME}].regexp(Lacp times out)}=1を設定する

①は出力を確認できたのですが、
(当然ではありますが)トリガー名にホストマクロが出てしまい、「trap linkDown if GE[0-9]+\/[0-9]+\/([0-9]($|\s)|[1-9][0-9]($|\s))」という名前のアラートになってしまいました。。
(trapの中身はGE1/0/9だったため、一部の文字列が一致した場合の区別を検証は出来ていません)
このケースだとトリガー名にIF名を出すことは難しいのかなと思っています…。

②の出力についてはまだ確認できていないため、引き続きご報告させていただきます。
(検証環境がなく、サービスイン済みの環境にて確認しているため時間がかかり申し訳ありません…)

また、コメントでいただきました、
>例: snmptrap[({<#インターフェースのマクロ>} )|({<#インターフェースのマクロ>}&)]
の「&」が解釈出来ず、上記のように設定してしまいました。
万が一認識に齟齬がありましたら改めてご指摘いただければ幸いです。

ユーザー ynw の写真

申し訳ありません、上記②のルールだとやはり「GE1/0/18」のlinkDownに「GE1/0/1」と「GE1/0/18」のトリガーが反応してしまいましたので、見直しました。
yk_taiko様のコメントの意図がとれていなかったと思いますので、以下のように変更いたしましたが、アイテム自体がディスカバリされなくなってしまいました。

・アイテムのプロトタイプのキー:snmptrap[{#IFNAME}$]

ディスカバリルールのフィルタの$を省き「GE[0-9]+\/[0-9]+\/([0-9]|[1-9][0-9])」にもしてみましたが、状況が変わりませんでした。
設定方法が誤っていればご指摘いただけると大変幸いです。

ユーザー yk_taiko の写真

アイテムのプロトタイプのキーの後ろに ($|\s) を付ける感じでどうでしょう。
snmptrap[{#IFNAME}($|\s)]

※前回の & は $ の誤記でした。失礼しました。

<11:51> 追記
ちなみに、ディスカバリのフィルタを結構厳密に掛けられているようですが、"1.3.6.1.2.1.2.2.1.2" の結果で似通っている内容をフィルタ掛けたい感じでしょうか。

ユーザー ynw の写真

yk_taiko様

ご確認ありがとうございます!
snmptrap[{#IFNAME}($|\s)]でアイテムのプロトタイプを設定してみましたが、やはりアイテムがディスカバリされなくなってしまうようです…。

>ちなみに、ディスカバリのフィルタを結構厳密に掛けられているようですが、"1.3.6.1.2.1.2.2.1.2" の結果で似通っている内容をフィルタ掛けたい感じでしょうか。
ご認識の通りです。
製品にもよるのですが、ifDescrの結果で内部的に作成されているような不要なインターフェースもたくさん取得できてしまうため、今は物理インターフェースに絞っている状態です。
今は検知テストのために物理の全インターフェースが合致するような記載にしていますが、ゆくゆくはこのフィルタに検知したいポートのみを記載していきたいと考えています。
(対向がスイッチに接続しているポートは検知、対向がサーバに接続しているポートは非検知、など)

私が考えられる方法は2つでしたが、もし全然違う方法で検知させることが出来るようであれば実践したいと思いますので、お知恵をお貸しいただけますと幸いです…。

ユーザー yk_taiko の写真

その設定を入れただけでディスカバリされないということですと、対象ホストの ディスカバリの設定やアイテムプロトタイプの設定にエラーは出てないでしょうか。

ユーザー ynw の写真

yk_taiko様
大変失礼いたしました。
フィルタの指定に一部誤りがあったようで、修正したところディスカバリされるようになりました。
申し訳ありません。

フィルタをもう少しシンプルに変更してみました。
GE[0-9]+\/[0-9]+\/[0-9]+$
こちらで様子を見て、またご報告させていただきます。

ユーザー ynw の写真

yk_taiko様

ご報告が遅くなり申し訳ありません。
こちらの設定でうまく動いているようですので、本件対応できそうです…!
トラフィックは全ポートで取得したいがlinkup/downは特定ポートで検知したい場合、
 ・ver3.0は違うディスカバリルールを設定
 ・ver4.0は同じディスカバリルール内でアイテムのプロトタイプの保存前処理に [正規表現] - [(検知したいポートの正規表現)] - [\1] を設定することで実装できる
かと思いましたが、うまくいかずにアイテムが作成されてしまいました。。
アイテム自体は作成されても、中身が保存されないだけなのかなとも思いますが、なかなかアラートを自由に出せない環境なので少し諦めようかと思います…。

ここまででも、サポートいただき本当にとても助かりました。ありがとうございます。

ユーザー ngc7293 の写真

どこにコメントを付けるか迷いましたが根っこに。

このあたりのところは悩みどころなのですが、snmpttはTRAP定義ファイルにしたがいsnmptt.logにTRAPメッセージを記録することを逆手にとって、MIBファイルから(改造版snmpttconvertmibにて)変換して作成したTRAP定義ファイルをさらに書き換えています。
※とあるTRAPで発生/復旧のTRAPを紐付けるのため、この方法にたどりつきました。。。

例えば IF-MIB::linkDown の場合だと変換直後は以下内容になります。

EVENT linkDown .1.3.6.1.6.3.1.1.5.3 "Status Events" Normal
FORMAT $aA $ar A linkDown trap signifies that the SNMP entity, acting in $*
SDESC
A linkDown trap signifies that the SNMP entity, acting in
~中略~
Variables:
1: ifIndex
2: ifAdminStatus
3: ifOperStatus
EDESC

これをMIBに記載されている変数名をタグとしてくっつける形にするため以下のように書き換えます。

EVENT linkDown .1.3.6.1.6.3.1.1.5.3 "ifLinkEvents" Normal
FORMAT $aA $ar ifIndex:"$1" ifAdminStatus:$2 ifOperStatus:$3
SDESC
A linkDown trap signifies that the SNMP entity, acting in
~中略~
Variables:
1: ifIndex
2: ifAdminStatus
3: ifOperStatus
EDESC

あとはトリガーに以下のような定義を入れています。

名前::Link Down {{ITEM.VALUE}.iregsub(ifIndex:(\S+) ,\1)}
発生::{AAA.str(ifLinkEvents)} = 1 and {AAA.iregexp(ifOperStatus:down)} = 1
復旧::{AAA.str(ifLinkEvents)} = 1 and {AAA.iregexp(ifOperStatus:up)} = 1
タグの値が一致したすべての障害
タグ名::ifIndex
タグ値::{{ITEM.VALUE}.iregsub(ifIndex:(\S+) ,\1)}
手動クローズ::許可

時間制限なし、かつ、タグで条件を復旧条件を絞った場合、OSそのもの再起動したときに復旧しなくなります。このため手動クローズを許可しておく必要があります。

lacpなども同様の編集を行なえば対応できます。(juniperのtrap監視実績がないので定義例はご勘弁を)

ユーザー ynw の写真

ngc7293様

ありがとうございます!
MIBの中身を修正するということで実装するとは考えつきませんでした。
ver4.0のタグと手動クローズを利用すればこちらでも可能だということですね。

勉強不足で申し訳ないのですが、

>FORMAT $aA $ar ifIndex:"$1" ifAdminStatus:$2 ifOperStatus:$3

こちらの中身を変更しているのはトリガー条件に使用するためということでしょうか?
メールで通知する際に{ITEM.VALUE1}を使ってtrapの中身を出力し確認していたのですが、
こちらを変更することではそこには影響がないという認識でよろしいでしょうか。

ユーザー ngc7293 の写真

トリガーに吸い込むための一例です。

ひっかけたい情報が ifIndex だけ、かつ、それ以外の出力も{ITEM.VALUE}として処理したいのであれば、

FORMAT$aA $ar ifIndex:"$1" arg:$*

などとしてやれば可能です。$*は引数全部の意味になります。
ただこの場合はifIndexがかぶってしまいますが、そこはお目こぼしを

ユーザー ynw の写真

ngc7293様

返信が遅くなり申し訳ありません。
ありがとうございます。とても参考になりました。
色んな機種が本番稼働しているため既存で利用している標準のMIBを変更するには検証が必要になりそうですが、実装方法の一例として大変勉強になりました。
ベンダー固有のMIBを利用している場合など、もし応用することがあれば検討していきたいと思います。
ご回答ありがとうございました。

ユーザー ngc7293 の写真

(返信し損なったため、こちらのコメントは上書きしました)