VPCフローログを使ってみた+Node.jsでログのパーサー作った

VPCフローログを使ってみたメモ。
また、Lambdaなどで使えるようにNode.jsで使えるログパーサーも作ったのでメモ

# 参考

+ [VPC フローログ](https://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/flow-logs.html)

# 事前準備

+ EC2を起動する
+ EC2にはssh(ポート22)のINBOUNDを許可したセキュリティグループを設定

# VPCフローログとは

+ VPC、サブネットもしくはEC2の特定のネットワークインターフェースでの通信ログをCloudWatchLogsに出力することができる機能
+ キャプチャできるのは「許可されたトラフィック」、「拒否されたトラフィック」、「全てのトラフィック」の3種類
+ 拒否されたトラフィックというのはセキュリティグループもしくはネットワークACLによってアクセスが拒否されたトラフィック
+ パケットの中身についてはキャプチャできない(TCPプロトコルのACKやSYNの何が有効になったのかなど） 
+ 転送されたパケット数やパケットのバイト数はキャプチャできる
 

# フローログ用のIAMロールを作成する

フローログの結果はCloudWatchLogsに出力されます。
ということでCloudWatchLogsへ出力するIAMロールを設定する必要があるので作成します。

+ マネージメントコンソールからIAMを選択する
+ Roles->Create New Role
+ RoleNameに任意の名前を設定「VPCFlowLogRole」
+ AWS Service RolesでEC2を選択
+ Attach Policyで「CloudWatchLogsFullAccess」を選択

作成後、作成したロールにTrust Relationshipを設定します。

+ マネージメントコンソールからIAMを選択する
+ Roles->VPFlowFlogRoleを選択
+ Trust Relationshipsタブを選択し、Edit Trust Relationshipを選択
+ 以下のJSONをコピペして、Update Trust Policyを選択

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "vpc-flow-logs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
} 
```

# フローログを有効化してみる

今回はEC2に設定された特定のNICのログを取得する方法でやってみます。

+ マネージメントコンソールからEC2を選択
+ Network Interfacesから検査対象にしたいEC2のネットワークインターフェースを選択する
+ Flow Logsタブを選択し「Create Flow Log」ボタンを選択する

以下を選択します。

+ Filter->All(RejectもAcceptも全てキャプチャ)
+ IAMRole->VPCFlowLogRole
+ DestinationLogGroup->/var/log/vpcflowlog


これでEC2の特定のネットワークインターフェースに対するフローログができました。
簡単ですね。

# VPCフローログを見てみる

とりあえずsshログインして、少し待ちます。
数分時間が経つと取得できました。

![Screen Shot 2016-04-07 at 2.23.21 PM.png](https://qiita-image-store.s3.amazonaws.com/0/20193/ce6d57e4-f196-923d-a1ef-9221e6a12f9a.png "Screen Shot 2016-04-07 at 2.23.21 PM.png")

上記よりわかる事。

+ NTP(ポート123)の通信を行っている。セキュリティグループでINBOUNDの許可はしていないがOUTBOUNDは全て許可しているためEC2が送信元の通信トラフィックは可能であるため。(セキュリティグループはステートフルである)
+ SSH(ポート22)でログインをしたのでそのトラフィックが記録されている
+ 8080や3389ポートによるアクセスがされているが、セキュリティグループで許可していないので拒否(reject)した事が記録されている
+ TCPの3ウェイハンドシェイクや切断、ACKによる通信確認のトラフィックは取得されていないように見える

# Node.jsでログのパーサーを作ってみた

LambdaからElasticSearchなどに流す時に使えるようにログのパーサーを作ってnpmにあげてます。コードはGithubに置いてます。

+ [toshihirock/node-vpc-flow-log-parser](https://github.com/toshihirock/node-vpc-flow-log-parser)
+ [vpc-flow-log-parser](https://www.npmjs.com/package/vpc-flow-log-parser)

ELBアクセスログのLmabda->ElasticSearchは以前記事でまとめたので同じようにやればできるかと思います。

[Lambda+Elasticsearch(Amazon Elasticsearch Service)でELBのログをサーバーレスでKibanaで可視化する](http://qiita.com/toshihirock/items/e530f3cb6dcf545601c9)

インストールは以下でできます。

```bash
$npm install vpc-flow-log-parser
```

特徴としては以下です。

+ それぞれの値をName:value形式にパースする
+ プロトコル番号が出力されるので「protocol_name: 'TCP'」というように文字列でも出力。プロトコル番号はこちらを参照 [Protocol Numbers](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)
+ キャプチャウィンドウの開始時間、終了時間がUnix時間で返却されるのでYYYY-MM-DD HH:mm:ssフォーマットのUTCで「start_utc」及び「end_utc」として出力

言葉だと分かりにくいので実際に使ってみたものを確認下さい。

```bash
$node
> var parse = require('./index');
undefined
> parse('2 11111 eni-901258d8 133.130.120.204 172.31.23.15 123 123 17 3 228 1460005175 1460005449 ACCEPT OK')
{ version: '2',
  account_id: '11111',
  interface_id: 'eni-901258d8',
  srcaddr: '133.130.120.204',
  dstaddr: '172.31.23.15',
  srcport: '123',
  dstport: '123',
  protocol: '17',
  packets: '3',
  byte: '228',
  start: '1460005175',
  end: '1460005449',
  action: 'ACCEPT',
  log_status: 'OK',
  protocol_name: 'UDP',
  start_utc: '2016-04-07 04:59:35',
  end_utc: '2016-04-07 05:04:09' }
>
```

良かったら使ってみてください。