VPCFlowLogsにCloudWatchLogsのAlarmを設定する（コンソール編）

# はじめに
EC2等から想定外の場所へのデータ流出を検出するため、VPC内のトラフィックにアラームを設定する環境を、コンソールから構築する方法を調べました。
備忘録として記事にしました。


# 目的
機密情報を扱う環境として、「決められた場所以外へのデータ送信（以下、不正トラフィック）を検出できる環境」の構築を目的としました。
悪意ある内部ユーザが、個人情報等を他のサーバにコピーしたらすぐにメール通知が飛ぶ、という環境がゴールのイメージです。

## GuardDutyではダメ？
GuardDutyは、AWS環境やAWSアカウントに対する攻撃を検知するもので、内部ユーザの悪意ある行動を検知することはできないようです。

## これだけでは不十分
これは外部へのデータ流出を検出するだけであり、流出自体を防止するわけではないです。他のセキュリティ対策と併用する必要があります。

- アウトバウンドの制限
    - 制限すると、外部のパッケージ等をインストールするのが難しくなるため、要注意。
- セキュリティ教育



# やったこと
コンソールから以下のことを行いました。

1. 送信先ロググループの作成
1. VPCから、フローログの設定
    1. 今回はデフォルトのVPCを使いました
    1. 作成時に、ロググループ送信用のIAMロールも作成できます。
1. CloudWatchLogsから、メトリクスの作成
1. アラームの作成
    1. 作成時に、SNSトピックも作成できます。


# 構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/e3c439b2-dcdc-bfb5-187b-bfe623c9a8f9.png)


# 実際の手順
## 送信先ロググループの作成
[CloudWatch]-[ロググループ]から、[ロググループを作成]をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/9d355813-dfd5-09f1-0623-dba08e78b841.png)


- ロググループ名
    - AWSが自動で作るロググループは`/aws/サービス名`や`/aws-サービス名/機能名`などで始まっています。
    - これらと自作のロググループがわからなくならないよう、`/test/機能名`や`/Custom/機能名`等の名前にしておくと良いかと思います。
- 保存期間
    - お好みで

[作成]で、ロググループが作成されます。

## VPCに、フローログの設定
[VPC]から対象のVPCを選択し、下部の[フローログ]タブから、"フローログの作成"をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/29b49536-48d7-c840-4393-48bbfaeb9f8b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/e04966c7-ee83-9a74-7952-ae79055b2161.png)

- "名前"、"フィルタ"、"最大集約間隔"はお好み。
- "送信先"は"CloudWatch Logs に送信"とし、先ほど作成したロググループを選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/e7934ea3-ae51-da5a-ce16-498dcf21fc8f.png)

- IAMロールは右下の"アクセス許可を設定"から作り、選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/bd46d297-4277-b7c2-5ef0-e7cb8b77a26a.png)

- "ログレコード形式"は、"AWSのデフォルト形式"では少ないので、"カスタム形式"を選んで、[Select all]をクリックしました。
    - その後、"形式のプレビュー"の[コピー]をクリックし、フィールドの名前を保存しておきます。
        - 後々、メトリクスのフィルタを作成するときに使います。

```
${account-id} ${action} ${az-id} ${bytes} ${dstaddr} ${dstport} ${end} ${flow-direction} ${instance-id} ${interface-id} ${log-status} ${packets} ${pkt-dst-aws-service} ${pkt-dstaddr} ${pkt-src-aws-service} ${pkt-srcaddr} ${protocol} ${region} ${srcaddr} ${srcport} ${start} ${sublocation-id} ${sublocation-type} ${subnet-id} ${tcp-flags} ${traffic-path} ${type} ${version} ${vpc-id}
```

[フローログを作成]で完了します。

## CloudWatchLogsから、メトリクスの作成
[CloudWatch]-[ロググループ]-[（作成したロググループ）]-[アクション]-[メトリクスフィルターを作成]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/fdc195b1-cc0d-ea7a-57fc-dd923223bbde.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/6ccd0193-8cb3-9172-2bfc-180e9c7e52e7.png)

- フィルターパターンを作成
    - [公式](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html)に構文の説明があります。
        - VPCFlowLogsはスペース区切りなので、"スペース区切りログイベントから値を取得するメトリクスフィルターの使用"以降が参考になります。
    - 先程コピーした、ログレコード形式のフィールド名群を、パターン構文用に編集します。
        - パターン構文のフィールド名にハイフン(-)は使えなかったため、アンダースコア(_)にしました。
        - 今回は「特定のIP以外の送信先に対して、100KBを超えるサイズの送信」としました。

```
# パターン構文用
[account_id, action, az_id, bytes, dstaddr, dstport, end, flow_direction, instance_id, interface_id, log_status, packets, pkt_dst_aws_service, pkt_dstaddr, pkt_src_aws_service, pkt_srcaddr, protocol, region, srcaddr, srcport, start, sublocation_id, sublocation_type, subnet_id, tcp_flags, traffic_path, type, version, vpc_id]

# パターン構文「特定のIP以外の送信先に対して、100KBを超えるサイズの送信」。後ろは省略可能
[account_id, action, az_id, bytes > 100000, dstaddr!=123.123.123.123 && dstaddr!=210.210.210.210 , dstport, end, flow_direction = egress, ...]
```
- パターンをテスト
    - 既にログが出力されている場合は、ここでテストできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/a72494e7-c840-25c1-6c0c-e657ac598b20.png)

- フィルター名
    - 任意で。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/3df9ba13-c9d5-a293-2536-8295dce31a9d.png)

- メトリクス名前空間
    - [AWSサービスが発行する名前空間](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/aws-services-cloudwatch-metrics.html)は、`AWS/サービス名`となっています。
        - 混じらないように、`Test/Flowlogs`としました。
- メトリクス名
    - 任意で。
- メトリクス値
    - 今回は1回でも発生したら検知するため 1。
- デフォルト値
    - 発生していない場合の時の値。今回は 0。
- ディメンジョン
    - デフォルト値を設定していると、指定できません。

[Next]-[メトリクスフィルターを作成]で完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/5dbb4c9a-c3d8-8799-b257-d4a42abf595a.png)

## アラームの作成
先程作成したメトリクスフィルターの、右上のチェックを付けて[アラームを作成]をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/81046909-baa6-515b-4719-a7e66940d886.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/276f421a-6b4b-2801-8e97-c62ceea204ed.png)

- メトリクス名
    - 先のメトリクスが自動でセットされます。
- 統計
    - 今回は"合計"。
- 期間
    - 今回は"5分"。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/48789aec-66cc-c988-72f0-0edefc5b289b.png)

- しきい値の種類
    - 静的
- TestIllegalTraffic が次の時..
- ... よりも
    - 合わせて　1以上　としました。
- アラームを実行するデータポイント
    - 1/1
- 欠落データの処理
    - "欠落データを適正（しきい値を超えていない）として処理"。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/641300a7-a093-1cb1-470b-7cb6e2e7b80b.png)

- アラーム状態トリガー
    - アラーム状態
- SNS トピックの選択
    - 作っていない場合、ここで作れます。
    - 今回は作りますので、"新しいトピックの作成"。
- 新規トピックの作成中...
    - 任意で。
- 通知を受け取る E メールエンドポイント …
    - 何かしら必須です。
    - [トピックの作成]で作成されます。
        - 設定したアドレス宛に確認メールが届きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/9ce645c3-8118-e7fd-0142-9c3242d37817.png)

- アラーム名
    - 任意で。
- アラームの説明
    - アラームのメールに記載されます。わかりやすい説明をしておくとよいと思います。

[次へ]-[アラームの作成]で完了。

# 作成したアラームが動くかチェック
作った構成が機能するか確かめます。

- デフォルトVPC内にEC2インスタンスを作成
    - EC2 Instance Connectを利用したいので、[インバウンドに使用されるIPのレンジを許可したセキュリティグループ](https://qiita.com/hayao_k/items/7b44ed1cd11651272985)を作成しました。
    - S3への出力をアラーム対象とするため、S3フルアクセスのロールをアタッチしました。
    - アラームが飛ぶと、CloudWatch上ではこうなります。
        - 指定したメールアドレスにも、アラームの通知が来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/4543443f-c652-e7d0-180e-b06c937d4603.png)

S3はよく使うのでフィルターから除外したい場合、[S3のIPアドレス](https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-find-ip-address-ranges/)を調べて、パターン構文に反映させてください。

# 片づけ
- アラームの削除
    - [CloudWatch]-[すべてのアラーム]から、作成したアラームをチェックし、[アクション]-[削除]。
- SNSの削除
    - [Amazon SNS]-[トピック]-[（作成したトピック）]をクリックして、"サブスクリプション"から対象のアドレスを選択し、削除。
    - その後、対象のトピックを削除。
- メトリクスフィルターの削除
    - 対象のメトリクスフィルターの右上にチェックをして、削除。
- メトリクスの削除は・・・
    - [手動では削除できず、](https://dev.classmethod.jp/articles/tsnote-support-cloudwatch-delete-metrics-launch-001/)新しくデータが発行されなければ自動で削除されるようです。
- フローログの削除
    - 対象のVPCを選択し、[フローログ]タブから選択、[アクション]-[フローログを削除]。
- IAMロールの削除
    - [IAM]-[ロール]から、フローログ用に作成したIAMロールを選択し、削除。
- ロググループの削除
    - [CloudWatch]-[ロググループ]から、作成したロググループを選択し、[アクション]-[ロググループの削除]。


# まとめ
「VPCの不正トラフィックを検出」というテーマで環境を構築する方法をまとめました。
~~次はCloudFormationを用いて作る方法を記事にしたいと思います。~~
[CloudFormationで書いた記事はこちらになります。](https://qiita.com/a_b_/items/e7d0d60d356355dcf5b5)