PrelertでNWの異常検知

PrelertはElastic社が買収した異常検知が出来る機械学習のソフトウェアです。今回はこれを利用して、Elasticsearchに保存したデーターからNWの異常検知を行いたいと思います。

Prelertについて

PrelertはElasticsearch内に保存したデーターを元に異常検知を簡単に行なえます。異常検知の設定はGUIをベースに行える用になっており、結果も。APIを備えているため連携しての動作も可能です。利用例としてセキュリティの機器のログから不正な動きを検知する例や、IT機器の不具合を検知する例が挙げられています。

今回の構成

今回はNWの異常検知をNW機器のデーターから行いたいので、SwitchからSNMPを利用してトラフィック量の値を取り出した後に、Elasticsearchに保存します。PreleartはElasticsearchに保存した情報を元に異常検知を行う事とします。

Prelertのインストール

PrelertはElasticsearchとKibanaがインストールされた基盤の上でインストールファイルを実行するとインストールされます。5.Xの基盤にインストールしてみましたが、Prelertをインストールすると、KibanaのUIは以前のバージョンの物に戻ってしまいました。PrelertのDashboardはKibanaのアプリとしてインストールされるため、KibanaからPrelertを開くと様々な設定が可能となります。

Fluentdの設定

今回はFluentdを使ってNW機器からSNMPでポートのステータスを取得します。Interfaceの全項目について、InとOutのOctetカウンターを取得します。Nameにインターフェス名、Valueにカウンターの値が入る用にします。

 @type snmp
 tag snmp.switch1
 nodes name,value
 host [SWITCH IP]
 community public
 mib ifInOctets, ifOutOctets
 method_type walk
 polling_time 60
 polling_type async_run


 @type elasticsearch
 host localhost
 port 9200
 index_name snmp
 type_name snmp
 logstash_format true
 logstash_prefix snmp

Elasticsearchの設定

Elasticsearchにはテンプレートを設定しておきます。nameの項目はNot Analyzedを指定しておきます。

curl -XPUT localhost:9200/_template/snmp -d '
{
    "template": “snmp*", 
      "mappings": {
      "_default_": {
      "properties" : {
      "@timestamp" : {
        "type" : "date",
        "format" : "dateOptionalTime"
      },
      "name" : {
      "type" : "string",
      "index" : "not_analyzed"
     }
    }
   } 
 }
}'

Prelertの設定

Prelert上で異常検知の設定を行います。今回はFluentdから1分毎にデーターが送られており、5分毎のバケットの中のMax値を見てPrelertで異常検知を行う設定を行います。まずは、GUIから設定を行いますのでKibana経由でPrelertの管理画面を開きます。JobsからCreate New Jobを選択します。データーソースで、Elaticsearchを入力後に入力データーの指定を行います。今回はLocalにあるElasticsearhのsnmpで始まる名前のIndexを対象としてます。

ws000001

Name欄にJobのIDを指定します。その後、Analysis ConfigurationでAdd Detectorを選択してDetectorを作成します。Detectorはどの項目で、どの条件で異常検知を行うか指定出来ます。今回はValueのMax値をnameで分けて異常検知します。指定後にAddを選択します。

ws000004

Detectorが作成されました。Influencersの所でnameにチェックを入れます。Influencerを指定しておくと、異常が起こったのはどのポートなのかを表示してくれます。設定が完了したら、Saveを選択します。

ws000005

Save後にScheduleの設定画面が出てくるため、Scheduleを指定します。No End timeを指定すると、データーを取り込み続けて、異常検知をしてくれます。

結果

作成したJobのグラフのアイコンを指定すると、Summaryをみる事が出来ます。すでにデーターが取得されていれば異常を自動で検知して表示してくれます。今回は急激なトラフィックの増大が検知出来るかを試して見るために、iperfを利用してサーバー間でトラフィックを急増させてみました。結果が以下になります。スイッチのサーバーが接続されているインターフェースのIn、上位のスイッチへのインターフェースのOut共に異常が検知されています。

ws000000

所管

異常検知を行う場合に必要なアルゴリズムの選択や、パラメーターの調整無しに簡単に異常検知が出来るのは便利です。とは言え、どのような値を取ってきてDetectorの設定はどうするかは試行錯誤が必要です。今回もmeanが良いのか、Maxで取ったほうが良いのか等の試行錯誤はしました。Prelertはセキュリティ等も含めて、アイデア次第で様々な応用ができそうです。今回の内容は最低限の設定となってますが、データーの取得や保存方法を工夫すればもっとわかりやすく表示出来ると考えています。

広告
PrelertでNWの異常検知

OpenStack上のNWトラフィックをKibanaで可視化する

Logの可視化として、FuluentdとElasticsearch/Kibanaの組み合わせが使われています。今回のこの組み合わせで、OpenStackのOVS上に流れるトラフィックを可視化します。NWトラフィックを可視化する場合にOpenStack環境の物理スイッチ側でトラフィックを取ることも出来ますが、仮想マシン間の通信がホスト内で完結されてしまうと、その部分のトラフィックの様子を見る事が出来ません。OpenStackの構造上、各ホスト上のbr-int上を流れるトラフィックを可視化出来れば仮想マシン間も含めたすべての通信を見ることが出来ると考えられます。

Netflow / sFlowについて

NetflowはCisco機器が備えているNW可視化の仕組みです。ポートミラーリングはトラフィクをコピーする仕組みですが、NetflowはIPアドレスやポート番号等の情報を抜き出して、指定のホストに対して情報を送信する仕組みです。sFlowはNetflowを一般化したものになります。Fluentd用にNetflowプラグインが開発されていますので、Netflowで出力すれば簡単にElasticsearch側にデーターを出力出来ます。しかしながらOVSはNetflowでの出力も備えていますが、サンプリングレートや出力先のインターフェースの指定を備えていないようです。今回br-intのトラフィックを取るためにインターフェース自体にIPは振られていないため、出力先インターフェースの指定が必要です。そのため今回はOVSからはsFlowで出力して、それをNetFlowに再変換してElasticsearchに入力します。

OVSの設定を行う

OVS上でのsFlowの設定方法は以下に詳しく述べられています。

http://openvswitch.org/support/config-cookbooks/sflow/

OpenStackのコンピュートノードや、コントローラーノード上で以下の設定を行いbr-int上に流れるトラフィックのsFlowのデーターを送付します。送信先はsFlow Toolが動作するホストになります。sFlow Toolが動作するホストは10.0.0.1の想定で設定しています。

ovs-vsctl — –id=@sflow create sflow agent=eth1 target=”10.0.0.1:6343″ header=128 sampling=64 polling=60 — set bridge br-int sflow=@sflow

sFlow Toolを使う

sFlow ToolはsFlowを可視化してくれたり、NetFlowへの変換行ってくれるツールです。基本的に以下のレポジトリからCloneして、makeすればバイナリを生成して利用出来ます。

https://github.com/sflow/sflowtool

以下のコマンドで起動しておけばsFlow ToolがsFlowのデーター受け取った後に、Netflowに変換して送信してくれます。以下はLocalのFluentdに送信する想定です。

sflowtool -p 6343 -c 127.0.0.1 -d 5140

FluentdのNetflow Pluginを使う

Fluentd用のNetflow Pluginは以下で開発されています。

https://github.com/repeatedly/fluent-plugin-netflow

FluentdのコマンドでこのNetflow Pluginをインストールします。

td-agent-gem install fluent-plugin-netflow

インストール後にFluentdのtd-agent.confで以下の設定を行えば変換されたNetflowのトラフィックを受け取る事が出来ます。受け取ったNetflowのトラフィックにはgeo.netflowのタグ付けをして次の処理を行います。

<source>
  type netflow
  tag geo.netflow
  port 5140
  versions [5]
</source>

IPアドレス情報からGeoLocationを生成する

sFlowで収集した情報にSourceやDestのIPアドレスを元に、GeoLocatoinのタグを付与してあげれば、Kibana上で通信の場所をプロット出来ます。今回はFluentdのIPアドレスからGeoLocationタグを生成出来る以下のプラグインを利用します。

https://github.com/y-ken/fluent-plugin-geoip

以下のコマンドでインストールします。Developer Tool等のインストールも必要になります。

# sudo yum group install "Development Tools"
# sudo yum install geoip-devel --enablerepo=epel
# td-agent-gem install fluent-plugin-geoip

以下の設定をtd-agent.confに追加するとGeo Locationへの変換を行ってくれます。今回の設定ではDestination IPを元にGeoタグを付与しています。

<match geo.netflow>
  type geoip
  geoip_lookup_key ipv4_dst_addr
  <record>
    geoip_pin ${latitude["ipv4_dst_addr"]},${longitude["ipv4_dst_addr"]}
  </record>
  remove_tag_prefix geo.
  tag es.${tag}
  skip_adding_null_record
</match>

Elasticsearchにデーターを送る

データーを送信し始める前にElasticsearch側が必要なデーターをGeo Tagとして認識出来るようにテンプレートを定義しておきます。

curl -XPUT localhost:9200/_template/flow -d '
{
  "template" : "flow-*",
  "mappings" : {
    "netflow" : {
      "properties" : {
        "@timestamp" : {
          "type" : "date",
          "format" : "dateOptionalTime"
        },
        "ipv4_src_addr" : {
          "type" : "string"
    },
        "geoip_pin" : {
          "type" : "geo_point"
        }
      }
   }
  }
}'

FluentdのElasticsearchプラグインをインストールします。

# td-agent-gem install fluent-plugin-elasticsearch

FluentdのElasticsearchプラグインでデーターを送付します。td-agnt.confの設定は以下の通りです。以下の例ではLocalのElasticsearchにデーターを送信しています。

<match es.netflow>
  type elasticsearch
  host 127.0.0.1
  port 9200
  type_name netflow
  logstash_format true
  logstash_prefix flow
</match>

Kibanaで可視化する

Elasticsearchで集めたデーターはKibanaを使って、以下のように可視化出来ます。

図1

まとめ

実運用で使うなら、sFlow toolを挟まずにFluentdかLog StashのsFlowプラグインを開発した方が良い気がします。

OpenStack上のNWトラフィックをKibanaで可視化する