PacketbeatのFlow情報をSankey Diagramで可視化する（Kibana6.2+ Vega Visualization）

# はじめに
Kibana 6.2.0で追加されたVega VisualizationでネットワークのSankey Diagramを表示している人がちょこちょこ観測されます。
（↓こういうやつですね。）

![Screenshot-2018-6-26 Kibana(6).png](https://qiita-image-store.s3.amazonaws.com/0/264679/874af469-6490-4cad-bce0-26a462b74f7b.png)

もちろん、Kibanaのプラグインとして[GitHub - chenryn/kbn_sankey_vis: Sankey diagram for Kibana visualize.](https://github.com/chenryn/kbn_sankey_vis)もあったりしますが、Vegaでも可視化してみたいですよね？
おそらく現時点で試されてる方の元ネタとなるのはElastic公式ブログの[「Sankey Visualization with Vega in Kibana 6.2 | Elastic」](https://www.elastic.co/blog/sankey-visualization-with-vega-in-kibana)で紹介されている可視化例を参考にしているものと思われます。

本記事では、リンク先で紹介されているVega JSONをちょこっとだけ加工して、PacketbeatのFlow情報をSankey Diagramで可視化してみたいと思います。


# 環境準備
## 目指す環境の状態
Packetbeatが起動されており、Elasticsearchにフロー情報が常時投入され続けている状態であること。
また、Kibanaが起動しており、Elasticsearchと接続された状態であること。
その状態の環境が既にあれば、本章は読み飛ばしてください。

## 前提条件
Linux系OSで以下のツールが使える状態であること。

- git
- Docker Engine 1.13.0+
- docker-compose

## 準備手順
Elastic公式の全部入りdocker-composeを実行します。

```bash
git clone https://github.com/elastic/stack-docker.git
cd stack-docker
TAG=6.2.3 docker-compose up
```
実行後、しばらく待つと、Elasticsearch（localhost:9200）、Kibana（localhost:5601）に接続できるようになります。
なお、バージョンとして6.2.3を指定している理由は後述します。

なお、この時ホストLinuxのkernelバージョンが古いと以下のメッセージが出現するかもしれません。

```terminal
ERROR: for auditbeat  Cannot start service auditbeat: linux spec capabilities: Unknown capability to add: "CAP_AUDIT_READ"
```

この場合は、以下のように、思い切って`docker-compose.yml`からAuditbeat関連の記述（`auditbeat`配下と`setup_auditbeat`配下）を削除します。今回はあくまでPacketbeatだけ動けばよいので。

```diff
-  auditbeat:
-    image: docker.elastic.co/beats/auditbeat:${TAG}
-    container_name: auditbeat
-    cap_add: ['AUDIT_CONTROL', 'AUDIT_READ']
-    # Auditbeat must run in the main process namespace.
-    pid: host
-    networks: ['stack']
-    depends_on: ['elasticsearch']

-  setup_auditbeat:
-    image: docker.elastic.co/beats/auditbeat:${TAG}
-    container_name: setup_auditbeat
-    volumes: ['./scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro']
-    # The script may have CR/LF line endings if using Docker for Windows, so
-    # remove them so that they won't confuse Bash.
-    command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s auditbeat']
-    networks: ['stack']
-    depends_on: ['kibana']
```

また、Virtualboxなど、直接ホストLinuxに接続できない環境の場合は、`elasticsearch`と`kibana`のポート設定を以下のように変更します。

```diff
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${TAG}
    container_name: elasticsearch
    environment: ['http.host=0.0.0.0', 'transport.host=127.0.0.1']
-   ports: ['127.0.0.1:9200:9200']
+   ports: ['9200:9200']
    networks: ['stack']

  kibana:
    image: docker.elastic.co/kibana/kibana:${TAG}
    container_name: kibana
-   ports: ['127.0.0.1:5601:5601']
+   ports: ['5601:5601']
    networks: ['stack']
    depends_on: ['elasticsearch']
```

これでポートフォワーディング越しでもブラウザで接続できるようになります。

# Kibana Visualization作成
localhost:5601にアクセスし、Kibanaにアクセスします。

visualize作成の前に、`Management => Advanced Settings`の中の`state:storeInSessionStorage`を`true`に変更します。

![Screenshot-2018-6-26 Kibana(5).png](https://qiita-image-store.s3.amazonaws.com/0/264679/da5f9328-3e27-356c-d8ba-3d18e00d561f.png)

これをしておかないと、今回のVega Visualizationを実行しようとした時に以下のエラーが起きるかもしれません。
（URL長すぎますよ、な内容）

![Screenshot-2018-6-26 Kibana(2).png](https://qiita-image-store.s3.amazonaws.com/0/264679/461315b5-b8b7-e092-87c0-b44f2d80c52e.png)

事前設定が完了したら、Visualizeメニューを選択。作成する新規visualizeの種類はVegaとします。

![Screenshot-2018-6-26 Kibana(1).png](https://qiita-image-store.s3.amazonaws.com/0/264679/a2c7b22f-4bda-eee9-c1e8-fa79b939a413.png)

すると、上記のようにVega Visualization作成画面が現れます。
左側がVegaで可視化するJSONの設定を記述する箇所で、右側が可視化結果です。
通常のVisualization作成画面と役割分担は同じですが、設定はVegaが理解できるJSON形式で記述する必要があります。

次に、JSON部分に[「Sankey Visualization with Vega in Kibana 6.2 | Elastic」](https://www.elastic.co/blog/sankey-visualization-with-vega-in-kibana)の`Vega code`の項で張られているソースコードをコピペします。

その後、以下の部分を書き換えます。

```diff
{
  $schema: https://vega.github.io/schema/vega/v3.0.json
  data: [
    {
      // query ES based on the currently selected time range and filter string
      name: rawData
      url: {
        %context%: true
        %timefield%: @timestamp
-       index: logstash-*
+       index: packetbeat-*
        body: {
          size: 0
          aggs: {
            table: {
              composite: {
                size: 10000
                sources: [
                  {
                    stk1: {
-                     terms: {field: "geo.src"}
+                     terms: {field: "source.ip"}
                    }
                  }
                  {
                    stk2: {
-                     terms: {field: "geo.dest"}
+                     terms: {field: "dest"}
                    }
...
```

そして、再生ボタンを押します。

![Screenshot-2018-6-26 Kibana(6).png](https://qiita-image-store.s3.amazonaws.com/0/264679/2ec1a1ca-e75f-f2ba-e441-e109d3874876.png)

見事、Flow情報をSankey Diagramで可視化できました！
（もしかすると、Flow情報の種類数によっては`size`などの設定値をカスタマイズする必要があるかもしれません。）

表示されている線や`Source`および`Destination`の上にある四角形にマウスを乗せると関連する場所のみがフォーカスされます。
例えば`10.0.2.2`の上にマウスカーソルを載せると以下のような表示になります。

![Screenshot-2018-6-26 Kibana.png](https://qiita-image-store.s3.amazonaws.com/0/264679/3d991faa-2f62-2221-99df-47404e99030a.png)

また、`Source`および`Destination`の上に表示されているそれぞれの四角形をクリックすると、その`Source`および`Destination`に関連した情報のみを可視化することができます。
例えば、`Source`である`10.0.2.2`の左隣の四角形をクリックすると以下のような表示となります。

![Screenshot-2018-6-26 Kibana(7).png](https://qiita-image-store.s3.amazonaws.com/0/264679/08c1f686-22b6-e1d4-4b94-c63cd97f112a.png)

`Source`が`10.0.2.2`であるFlow情報のみが可視化されました。
画面上部の`Show All`を選択すると、全ての情報が表示されていた画面に戻ります。

# その他注意事項
今回はElastic Stackのバージョンとして6.2.3を指定していました。
理由としては、6.2.4および6.3.0ではこのVisualizationは一部不完全な状態で表示されるためです。（有体にいえばバグっています。）
今回のVisualizationを6.3.0で表示した結果は以下となります。

![Screenshot-2018-6-26 Kibana(4).png](https://qiita-image-store.s3.amazonaws.com/0/264679/64f04d25-6167-5f82-dc8b-3f37d5908bf1.png)

`Destination`の上に表示されるはずの四角形が一部欠けているのが分かるでしょうか。
実際、この区域には何も描画されておらず、マウスを乗せたところで強調表示もされませんし、クリックしても関連情報のみが表示されることはありません。

[Vega visualizations that worked in 6.2.1-6.2.3 don't work correctly in 6.2.4 and 6.3.0 · Issue #20183 · elastic/kibana · GitHub](https://github.com/elastic/kibana/issues/20183)で報告されているため、今後改善は見込まれると思いますが、現時点でVegaによるSankey Diagramを使いたい方はElastic Stack 6.2.0～6.2.3の範囲で使った方が良さそうです。（イカした表示でお気に入りですが、まだまだExperimentalですね…！）