1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ciscoルーターに特定のSyslogが発生したら事前設定されたアクションを実行したい

Last updated at Posted at 2020-07-17

ルーターやスイッチに特定のイベントが発生したら事前設定されたアクションを実行したい、というのはよくあるシチュエーションだと思う。Cisco IOS, IOS-XE, IOS-XRなどではEEM (Embedded Event Manager)を使って実現が可能で、ゲストシェルが有効な装置であればOn-BoxのPythonによるスクリプトを定義しておくこともできる。

ほとんどのケースではこのEEMを使った運用で充分に用をなすだろうけれど、より複雑な挙動を外部スクリプトで実現したい場合は…?
例えばBundle-Etherを構成している2ポートのうち1ポートがLinkdownした場合に即座に冗長系のポートの正常性確認がしたい場合はどうだろう…?

ということで、特定のsyslogをトリガーにFluentdを利用して外部サーバーのスクリプトを実行する仕組みを考えてみた。

構成

今回の構成はこんな感じ。

                   +--------------------------------+
                   |                                |
                   |   +---------+        server    |
+--------+ 514/udp |   |         |                  |
| client +------------->         |                  |
+--------+         |   |         |                  |
                   |   | rsyslog |                  |
+--------+ 514/udp |   |         |                  |
| client +------------->         |                  |
+--------+         |   |         |                  |
                   |   +----+----+                  |
                   |        |                       |
                   |        | 5514/tcp              |
                   |        |                       |
                   |   +----v-----+  +----------+   |
                   |   | fluentd  +-->  script  |   |
                   |   +----------+  +----------+   |
                   |                                |
                   +--------------------------------+

ルーターからのsyslogをRsyslogの514/udpポートで受けてFluentdの5514/tcpポートへ転送。fluentdのout_execモジュールでスクリプトを実行する。

syslogはFluentdで直接受信するよう設定してもよいが、すでにサーバーで稼働しているであろうrsyslogをそのまま利用する構成としてみた。

設定

まずはRsyslogの設定。/etc/rsyslog.d/50-forward.confファイルに以下を記述する。

$ModLoad imudp
$UDPServerRun 514

$ActionQueueType LinkedList # use asynchronous processing
$ActionQueueFileName srvrfwd # set file name, also enables disk mode
$ActionResumeRetryCount -1 # infinite retries on insert failure
$ActionQueueSaveOnShutdown on # save in-memory data if rsyslog shuts down

*.* @@127.0.0.1:5514;RSYSLOG_SyslogProtocol23Format

次にFluentdの安定配布版であるtd-agentの設定。/etc/td-agent/td-agent.confに以下を追記する。

<source>
  @type syslog
  @id syslog_in
  port 5514
  bind 0.0.0.0
  severity_key severity
  facility_key facility
  tag syslog
  <transport tcp>
  </transport>
  <parse>
    message_format rfc5424
  </parse>
</source>

<match syslog.**>
  @type rewrite_tag_filter
  <rule>
    key message
    pattern /%([A-Z0-9_]+-[0-9]+-[A-Z0-9_]+):/
    tag $1.${tag}
  </rule>
</match>

<match LINK-3-UPDOWN.syslog.**>
  @type exec
  command /path/to/script.py
  <buffer>
    @type file
    path /var/log/td-agent/buffer/LINK-3-UPDOWN.syslog
    retry_max_times 3
    flush_interval 1m
  </buffer>
  <format>
    @type json
  </format>
</match>

## 不要なsyslogはnullに捨てておく
<match *.syslog.**>
  @type null
</match>

ここでポイントは rewrite_tag_filter を使ってタグを細分化している点。Cisco装置のsyslogは公式ドキュメントに記載されているように一定のフォーマットで表示される。
例えばIOS-XEの場合はこんな感じ。

timestamp: %facility-severity-MNEMONIC:description

例:
00:00:47: %LINK-3-UPDOWN: Interface GigabitEthernet1/0/1, changed state to up

このrewrite_tag_filterによりログ種別のフォーマット沿ってtd-agent側でタグ付けをしてくれるようになる。
あとはこのタグにひっかけてexecでスクリプトを叩くという流れ。

上記のtd-agentの設定では、発生したLINK-3-UPDOWNログは/var/log/td-agent/buffer/LINK-3-UPDOWN.syslog/ディレクトリにJSON形式でバッファファイルとして蓄えられ、1分毎にそれを引数として/path/to/script.pyが実行される。

つまりtd-agentが起動するコマンドは以下の形式になる。/path/to/script.pyに実行権限を付与しておくのを忘れずに。

/path/to/script.py /var/log/td-agent/buffer/LINK-3-UPDONW.syslog/buffer.{random}.log

バッファファイルの中身は以下のようなフォーマットになっている。/path/to/script.pyでは引数で与えられたこのJSONを読んでmessageを解析し、任意のスクリプトを実行すればよい。

{"host":"router1.example.com","message":"00:00:47: %LINK-3-UPDOWN: Interface GigabitEthernet1/0/1, changed state to up","priority":"notice","facility":"local7","ident":"11165741","pid":"-","msgid":"-","extradata":"-"}
{"host":"router2.example.com","message":"00:00:47: %LINK-3-UPDOWN: Interface GigabitEthernet2/0/1, changed state to up","priority":"notice","facility":"local7","ident":"99618182","pid":"-","msgid":"-","extradata":"-"}

あとは/path/to/script.pyにお好きな処理を書けばよい。
面倒なのでここではスクリプトの書き方は省略する。Ansibleなんかに連携させれば良いんじゃないかな?

これで自由自在にSyslogトリガーに外部コマンドを叩けるようになる。Slack通知やJira連携とかもできそう。
楽しい:v:

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?