【AWS】VPCフローログを使ってみた

#はじめに
今回、AWSサービスの1つであるVPCフローログというサービスを触る機会があった。
どうやらググっても情報量はさほどなさげなため、簡単にまとめてみることにした。
#VPCフローログとは
>VPC フローログは、VPC のネットワークインターフェイスとの間で行き来する IP トラフィックに関する情報をキャプチャできるようにする機能です。
>フローログのデータは、Amazon CloudWatch Logs を使用して保存されます。
>フローログを作成すると、そのデータを Amazon CloudWatch Logs で表示し、取得できます。

参照元：AWSドキュメントVPCフローログより
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/flow-logs.html#flow-log-records

ここで大事なのは以下となります。
・**VPCフローログはENIを行き来するトラフィックに関する情報をキャプチャする。**
・**VPCフローログはAmazon Cloud Watch LogsにENIごとに保存される。**
・**VPCフローログの取得は、ENI単位、サブネット範囲、VPC範囲で行える。**
つまりサブネット範囲・VPC範囲でログの取得を行った場合、範囲内のすべてのENIが対象となります。
#使ってみる
例えば次のような単純な構成でサブネット範囲でログを取得してみます。
まず前提として、ELBはデフォルトで冗長構成となっていますが、ログをZoneC側に流さないようにZoneAのみで稼動させています。
果たしてどうなるでしょうか。
![image](https://qiita-image-store.s3.amazonaws.com/0/88739/4d352ba9-29a6-003f-4072-1f7d9211094b.png)

今回はサブネット範囲(172.31.16.0/20)でログを取得するため、記録されるENIはzoneAにあるELB一枚、EC2一枚の計2つ分のログが記録されると思っていました。
**しかし、どうやらデフォルトで冗長化されているELB(zoneAに一枚,zoneCに一枚)を片系稼動させると片系側でもう一枚ENIが投入され、結局二枚(zoneAに二枚)になるようです。**

![image](https://qiita-image-store.s3.amazonaws.com/0/88739/7474e29a-ecd8-3bd0-ea9d-1bf839804a30.png)

というわけで、ENI3枚分(ELB二枚、EC2一枚)のログが生まれてしまいました。
![image](https://qiita-image-store.s3.amazonaws.com/0/88739/a8c8cf19-b7a4-97b1-30f9-74ec9a4afd15.png)
まずは一旦中味をのぞいてみるとします。
#どんな感じでログが取れるのか
前提としてSGの設定は、マイIPのみ許可しています。
・ELBのログ
![image](https://qiita-image-store.s3.amazonaws.com/0/88739/4b48a1cc-ebfb-1770-ab3d-4e3a300cdd7d.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/88739/a0e8e0cb-c00a-3008-46a9-9252f053196c.png)

EC2のログ
![image](https://qiita-image-store.s3.amazonaws.com/0/88739/9d0a6735-7cc1-d7c4-a61a-f6f195dbabb0.png)

**？？？「FlowLogsは人間が見るログじゃねぇからな」**
ほんとそれ。可読性が低いですね・・・。
ちなみに見方としては上記ドキュメントにも記載されていますが、以下となります。

|フィールド|
|----|
|VPCフローログバージョン|現行は2らしいです。|
|AWSアカウントID|
|ENIのID|
|送信元IP|
|送信先IP|
|送信元ポート|
|送信先ポート|
|プロトコル番号|
|キャプチャ開始(unix時間)|
|キャプチャ終了(unix時間)|
|アクション(ACCEPT,REJECT)|
|ログは記録されたか(OK,NODATA,SKIPDATA)|

実際ログを取ってみると、意外と見知らぬIPからの通信がきており、SGが仕事していることが分かります。
黒塗りの部分は私がEC2にSSH接続をした場面が記録されています。
さて、ご覧の通りここで大事なのは以下となります。
・**XFFは記録されず、直前に通ったENIがある場合、ENIのプライベートIPが記録される。（EC2のログ）**
・**ELBのヘルスチェックのログが多数記録されてしまう。（ELBのログ、EC2のログ）**
・**ELBを経由してEC2にやってくる通信は、全てが直前であるELBのENIプライベートIPとして記録される。（EC2のログ）**
#実際に使えるのか
さて、ざっくり分かったような分からんような感じですが、大切なのは実際に使えるか否かです。
この機能の使い方としていったいどういった使い方が相応しいのか・・・。
今回は前述の構成でELB上の通信のみをキャプチャすることにフォーカスして考えます。
#ELBを通過する通信のみをキャプチャしてみる
こういった場合には以下の画像のように、対象ELB専用にサブネットを作成します。
その上で、対象サブネット(172.31.32.0/20)に対してVPCフローログを有効化します。
![image](https://qiita-image-store.s3.amazonaws.com/0/88739/a800ac5a-9d2a-d059-daba-c5361eb78aed.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/88739/1c451f6c-078c-ca1e-209d-d75d22148320.png)
こうすることでいい感じにELBの二枚分のENIのログを取得することができました。
#まとめ
なんか色々残念な感じの記事になってしまいましたが、一旦ここでまとめようと思います。
○**ログの可読性が低いため、万が一のため有効化するくらいが現実的か。**
○**EC2オンリーの環境の場合、意外とそのまま使えるかもしれない。**
○**以下の画像のようにログを複数クリックしてイベントを見ると自動で連結してくれるため結構便利。**
![image](https://qiita-image-store.s3.amazonaws.com/0/88739/1f49eaad-5282-a89e-d590-62cc0b5f7759.png)
○**XFFは出ない。**
○**ヘルスチェックの通信が記録されないようにしないとELBのログとして見るのは厳しい。**
○**以下のようにAWS CLIなど経由でログを取得し、整形すればアクセスログとして使えるかもしれない。**

```
[ec2-user@ip-172-31-31-219 ~]$ aws logs get-log-events --log-group-name VPC-Flow-Logs --log-stream-name eni-6d018c25-all | grep -v [{/}] | grep -v "timestamp" | grep -v "ingestionTime" | grep -v 172.31.31.219
            "message": "2 xxxxxxxxxxxx eni-6d018c25 222.186.34.155 172.31.34.40 77 8089 6 1 40 1457611633 1457611693 REJECT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 187.17.111.99 172.31.34.40 80 37882 6 1 44 1457611693 1457611753 REJECT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 172.31.34.40 192.88.99.255 0 0 41 10 1240 1457611693 1457612293 ACCEPT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 58.218.205.83 172.31.34.40 43272 8080 6 1 40 1457611817 1457611873 REJECT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 117.27.251.96 172.31.34.40 15459 3306 6 1 40 1457612113 1457612173 REJECT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 58.218.204.225 172.31.34.40 43861 3128 6 1 40 1457612175 1457612233 REJECT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 64.125.239.200 172.31.34.40 45298 80 6 1 40 1457612233 1457612293 REJECT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 64.125.239.166 172.31.34.40 33160 22 6 1 40 1457612233 1457612293 REJECT OK"
            "message": "2 xxxxxxxxxxxx eni-6d018c25 103.37.45.94 172.31.34.40 6000 1433 6 1 40 1457612233 1457612293 REJECT OK"

```

#結論
そのまま使うのは結構きつい。
ELBアクセスログを使おう（提案）