GrafanaによるNetFlow v9トラフィック分析

ルーターからエクスポートされるNetFlow version 9レコードを収集してトラフィック状況を視覚化、分析するシステムを構築してみました。

#完成品イメージ
GrafanaによるNetFlowトラフィック可視化ダッシュボード

![grafana_dashboard2.png](https://qiita-image-store.s3.amazonaws.com/0/134927/78ea4ce3-418b-7c17-0a16-ddc4208c577e.png)

#目的
[NetFlow v9に対応したフリーの可視化ソフトウェア](http://www.cisco.com/c/en/us/products/ios-nx-os-software/ios-netflow/networking_solutions_products_genericcontent0900aecd805ff72b.html)が少なく、商用ソフトウエアは高価なため、気軽に可視化できるしくみを作れないかと思っていたところ、[NetOpsCoding #3](https://atnd.org/events/78025)勉強会で、日本マイクロソフトの北島さんの「Monitoring Intelligence」というプログラム紹介されていたツールを応用すれば作れそうかなと思いトライしてみました。

#構築
## NetFlowエクスポーター(ルーター)の準備、構築
Cisco ASR1001を使ってみました。

- Cisco ASR 1001
 - IOS XE Software, Version 03.16.03.S

Cisco AVC(Application Visibility and Control)という機能で、トラフィックをアプリケーション識別させるフィールドをNetFlow v9テンプレートに載せてみました。

設定はこんな感じです。
![cisco_netflow_config.png](https://qiita-image-store.s3.amazonaws.com/0/134927/3519df6f-10ab-d00b-78ac-0b908d56b4f8.png)


フローレコード情報とテンプレート出力を確認。

```
#show flow monitor monitor-avc-monitoring cache format table 

IPV4 SRC ADDR    IPV4 DST ADDR    APP NAME                          trns src port  trns dst port  intf input            intf output                bytes        pkts    time first     time last  ip prot
===============  ===============  ================================  =============  =============  ====================  ====================  ==========  ==========  ============  ============  =======
X.X.X.X          X.X.X.X          layer7 twitter                            52441            443  Gi0/0/1               Gi0/0/0                     4898          37  11:43:44.132  11:43:51.553        6
X.X.X.X          X.X.X.X          layer7 facebook                             443          52321  Gi0/0/0               Gi0/0/1                   112313         130  11:43:27.969  11:43:52.749        6
X.X.X.X          X.X.X.X          layer7 skype                              51200            443  Gi0/0/1               Gi0/0/0                      793           3  11:43:27.383  11:43:31.048        6
X.X.X.X          X.X.X.X          layer7 ssl                                  443          51467  Gi0/0/0               Gi0/0/1                    15644          12  11:43:33.639  11:43:33.789        6
X.X.X.X          X.X.X.X          port telnet                                  23          52400  Gi0/0/0               Gi0/0/1                     8269          11  11:43:36.925  11:43:55.947        6
X.X.X.X          X.X.X.X          layer7 google-services                      443          52469  Gi0/0/0               Gi0/0/1                      712           9  11:43:49.134  11:43:49.351        6
```

```
#show flow exporter exporter-avc-monitoring templates
Flow Exporter exporter-avc-monitoring:
Client: Flow Monitor monitor-avc-monitoring
Exporter Format: NetFlow Version 9
Template ID    : 274
Source ID      : 256
Record Size    : 41
Template layout
_____________________________________________________________________
|                 Field                   |  Type | Offset |  Size  |
---------------------------------------------------------------------
| ipv4 source address                     |     8 |     0  |     4  |
| ipv4 destination address                |    12 |     4  |     4  |
| ip protocol                             |     4 |     8  |     1  |
| transport source-port                   |     7 |     9  |     2  |
| transport destination-port              |    11 |    11  |     2  |
| interface input snmp                    |    10 |    13  |     4  |
| application id                          |    95 |    17  |     4  |
| interface output snmp                   |    14 |    21  |     4  |
| counter bytes                           |     1 |    25  |     4  |
| counter packets                         |     2 |    29  |     4  |
| timestamp sys-uptime first              |    22 |    33  |     4  |
| timestamp sys-uptime last               |    21 |    37  |     4  |
---------------------------------------------------------------------
```


## NetFlowコレクター(可視化ツール)の準備、構築
DockerHub上のイメージを使ってFluentdとInfluxDB、Grafanaを準備します。

使用したOS, ツールは以下です。

- Ubuntu 16.04.1 LTS
- Docker 1.10.3
- Docker Image
 - fluent/fluentd 0.12.28 (latest)
 - influxdb 0.13.0 (latest)
 - grafana/grafana 3.1.1 (latest)
- Fluentd Plugin
 - fluent-plugin-influxdb (0.2.8)
 - fluent-plugin-netflow (0.2.4)

### Ubuntu/Dockerの準備
Dockerをインストールします。Ubuntu atp docker.ioパッケージをインストールします。

```
$ sudo apt install docker.io
```

### Fluentdの準備
ルーターからのNetFlowデータを受信してInfluxDBに保存するFluentdをインストールします。
fluent-plugin-influxdb, fluent-plugin-netflow両方のプラグインに対応したDocker Imageがなかったため、fluent projectのFluentd Docker Image (fluent/fluentd)をcloneしてカスタマイズしてbuildしました。

```
$ git clone https://github.com/fluent/fluentd-docker-image.git
$ cd fluentd-docker-image/
```

```Dockerfile. 
$ diff -uw Dockerfile.orig Dockerfile
--- Dockerfile.orig     2016-08-25 11:03:39.264019589 +0900
+++ Dockerfile  2016-08-25 11:02:59.523127344 +0900
@@ -14,6 +14,8 @@
     echo 'gem: --no-document' >> /etc/gemrc && \
     gem install oj && \
     gem install fluentd -v 0.12.28 && \
+    gem install fluent-plugin-influxdb && \
+    gem install fluent-plugin-netflow && \
     apk del build-base ruby-dev && \
     rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /usr/lib/ruby/gems/*/cache/*.gem
```

```fluent.conf
<source>
  type netflow
  tag netflow
  bind 172.17.0.3
  port 9996
</source>
<match netflow>
  type influxdb
  host influxdb
  port 8086
  dbname netflow9
  time_precision s
  tag_keys ["app_id", "first_switched", "last_switched", "flowset_id", "host", "input_snmp", "output_snmp", "ipv4_src_addr", "ipv4_dst_addr", "l4_src_port", "l4_dst_port", "protocol", "version", "ip_dscp", "ip_frag_offset", "ip_frag_flags", "icmp_ipv4_type", "icmp_ipv4_code", "tcp_ack_num", "tcp_header_len", "tcp_flags" ]
</match>
<match **>
 type stdout
</match>
```

```
$ cd ..
$ sudo docker build -t fluentd-netflow:fluentd fluentd-docker-image
```

### InfluxDBの準備
```
$ sudo docker pull influxdb
```

### Grafanaの準備
```
$ sudo docker pull grafana/grafana
```

### Dockerイメージの起動
InfluxDBの起動、InfluxDBのセットアップ、Fluentd, Grafana起動の順におこないます。

```
$ sudo docker run -d --name=influxdb -p 8083:8083 -p 8086:8086 -v $HOME/influxdb:/var/lib/influxdb influxdb

$ influx
> create database netflow9
> create retention policy netflow on netflow9 duration 8w replication 1 default

$ sudo docker run -d --name=fluentd --link influxdb:influxdb -p 24224:24224 -p 9996:9996/udp -v $HOME/fluentd/:/var/lib/fluentd fluentd-netflow:fluentd

$ sudo docker run -d --name=grafana --link influxdb:influxdb -p 3000:3000 -v $HOME/grafana/:/var/lib/grafana grafana/grafana
```


### データの確認
以下の様なコマンドでレコードが出力されたらNetFlowレコードのDB書き込みが成功しています。

```
$ influx
> use netflow9
> select * from netflow where time > now() - 3m
```

### Grafanaのセットアップ
Grafanaのセットアップは[「GrafanaとInfluxDBでネットワークリソースの視覚化」]
(http://qiita.com/kooshin/items/a770c6df33fe2ffb2d0b#%E6%BA%96%E5%82%99)の記事が参考になります。
GrafanaのGraph設定のMetrics項目に設定する内容は以下を参考にしてください。

```
インターフェースから入ってくるトラフィック
SELECT sum("in_bytes") *8/30.0 FROM "netflow" WHERE "input_snmp" = '1' AND  $timeFilter GROUP BY time(30s) fill(0)

インターフェースから入ってくるTCPトラフィック
SELECT sum("in_bytes") *8/30.0 FROM "netflow" WHERE "input_snmp" = '1' AND "protocol" = '6' AND  $timeFilter GROUP BY time(30s) fill(0)

インターフェースから入ってくるトラフィックのうちCisco AVCでTwitterと識別されるトラフィック
SELECT sum("in_bytes") *8/30.0 FROM "netflow" WHERE "input_snmp" = '1' AND "app_id" = '218104325' AND $timeFilter GROUP BY time(30s) fill(0)
```

# 完成
色々と試してみてください。
コメントなど歓迎します。

# 参考資料
- [Freeware NetFlow Software - Cisco IOS NetFlow](http://www.cisco.com/c/en/us/products/ios-nx-os-software/ios-netflow/networking_solutions_products_genericcontent0900aecd805ff72b.html)

- [NetOpsCoding #3](https://atnd.org/events/78025)

- [GrafanaとInfluxDBでネットワークリソースの視覚化]
(http://qiita.com/kooshin/items/a770c6df33fe2ffb2d0b#%E6%BA%96%E5%82%99)

- [ELKによる構築記事 - Step-by-Step Setup of ELK for NetFlow Analytics]
(http://blogs.cisco.com/security/step-by-step-setup-of-elk-for-netflow-analytics)