CIDR表記でIPアドレスを検索する方法

# はじめに
Kibanaにおいて、IPアドレスをCIDR表記を用いて検索する方法を書きます。

# 利用環境
| product | version |
|---------|---------|
| Kibana | 6.5.4 |
| Elasticsearch | 6.5.4 |
| Winlogbeat | 6.5.4 |
| Sysmon | 8.04 |

# 前提
Sysmonによって出力された[Sysmon EventID 3][01]のNetwork connectionログを利用します。
Windowsイベントログとして出力されたSysmonログをWinlogbeatでElasticsearchに取り込み、KibanaでCIDR表記の検索をします。

# Kibanaとは
Elasticsearchを開発しオープンソースとして提供しているElastic社のBIツールになります。
Elasticsearchに格納されているデータをWebブラウザで検索したり、グラフで可視化したりするためのツールです。

**【参考URL】**
・[Kibanaとは][05]

# datatypeをipに設定する
Elasticsearchは事前にスキーマ定義が必要ないスキーマレスアーキテクチャになります。
スキーマを定義せずにLogstashやBeatsでログを取り込むと多くのフィールドは`文字列データ(textやkeyword)`として取り込まれます。

今回検索に利用するフィールドは`event_data.DestinationIp`となります。
値としてIPv4やIPv6が入りますが、WinlogbeatのIndex Templateでは`datatype`が`string(keyword)`として取り込まれCIDR表記で検索できません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211371/d3fb1350-e485-8456-277d-77804869d484.png)

```ruby:event_data.DestinationIpのdatatype(2018/12/29分)
GET /winlogbeat-6.5.4-2018.12.29/_mapping/doc/field/event_data.DestinationIp

{
  "winlogbeat-6.5.4-2018.12.29" : {
    "mappings" : {
      "doc" : {
        "event_data.DestinationIp" : {
          "full_name" : "event_data.DestinationIp",
          "mapping" : {
            "DestinationIp" : {
              "type" : "keyword"      ←ここの値
            }
          }
        }
      }
    }
  }
}
```

`event_data.DestinationIp`フィールドのIPアドレス件数を集計した表グラフにおいて
`"172.217.0.0/16"`と検索しても`No results found`となってしまいます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211371/f155c8ff-2d3b-e989-a84a-64baad6977c4.png)

一度取り込んだデータの`datatype`は変更出来ないようです。
Index Templateを更新して新たに取り込むデータにおいて、`datatype`が`ip`となるようにします。

```ruby:IndexTemplate
PUT _template/winlogbeat-6.5.4
{
  "index_patterns" : [
    "winlogbeat-6.5.4-*"
  ],
  "settings" : {
    "index" : {
      "mapping" : {
        "total_fields" : {
          "limit" : "10000"
        }
      },
      "refresh_interval" : "5s",
      "number_of_routing_shards" : "30",
      "number_of_shards" : "1"
    }
  },
  "mappings" : {
    "doc" : {
      "_meta" : {
        "version" : "6.5.4"
      },
      "date_detection" : false,

　　　(中略・・・)

        "event_data" : {
          "type" : "object",
          "properties" : {            ←追記(179行目)
            "DestinationIp" : {       ←追記(180行目)
              "type" : "ip"           ←追記(181行目)　
            }
          }
        },
```

# CIDR表記で検索する
2019年01月13日(月)のログを新しいIndex Templateを利用して取り込みます。
新たに生成されたIndexである`winlogbeat-6.5.4-2019.01.13`において、`datatype`が`ip`となっていることを確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211371/88b9e652-7706-c911-035b-d82329c95b02.png)

```ruby:event_data.DestinationIpのdatatype(2019/01/13分)
GET /winlogbeat-6.5.4-2019.01.13/_mapping/doc/field/event_data.DestinationIp
{
  "winlogbeat-6.5.4-2019.01.13" : {
    "mappings" : {
      "doc" : {
        "event_data.DestinationIp" : {
          "full_name" : "event_data.DestinationIp",
          "mapping" : {
            "DestinationIp" : {
              "type" : "ip"      ←ここの値
            }
          }
        }
      }
    }
  }
}
```

対象期間を2019/01/13に変更します。
今度は`"172.217.0.0/16"`と検索すると該当するIPアドレスのみが表示されるようになりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211371/95a069ea-4f5f-6fa0-7af4-c92a3b69214c.png)

検索バー下にある`Add a filter`ではOR条件の検索はできませんが、`"172.217.0.0/16" OR "13.107.0.0/16"`と検索すれば複数のセグメントを対象にログ検索することも可能です。
意外と便利ですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211371/372d6a5a-7a12-b4f9-101f-878354ff1a37.png)

# まとめ
いかがでしたでしょうか。
アクセスログやセキュリティログの分析において、送信元や宛先のIPアドレスをレンジで検索したいことは多分にあると思います。
ネットワークエンジニアであれば、CIDR表記でセグメント単位で絞り込むケースもあると思いますので、是非活用してみてはいかがでしょうか。

不明な点、誤植などありましたら、コメントをお願いします！！

# 参考
・[Field datatypes][02]
・[IP datatype][03]
・[Index Template][04]

[01]: https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=90003 "Sysmon EventID 3"
[02]: https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html "Field datatypes"
[03]: https://www.elastic.co/guide/en/elasticsearch/reference/current/ip.html "IP datatype"
[04]: https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates.html "Index Template"
[05]: https://www.elastic.co/jp/products/kibana "Kibana"