【VPC Flow Logs】マルチアカウントの VPCフローログ を 1つのS3バケットへ集約する

2020.05.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

VPCフローログ(VPC Flow Logs) は VPC内で行き来する IPトラフィックをキャプチャする機能です。 IPトラフィックの分析に役立ちます。

フローログデータは Amazon CloudWatch Logsまたは Amazon S3 に発行 できます。

CloudWatch Logs へ発行した場合は、 CloudWatch Logs Insights を使ってロググループに対して クエリを実行、結果を確認できます。 リアルタイムのログの可視化・アラートに役立ちます。

S3(バケット)へ発行した場合は、 Amazon Athena(ほか分析ツール) など使って ログを調査できます。 IPトラフィックのデータを蓄積、後に分析したい場合はこちらが役立ちます。

本ブログでは、マルチアカウント環境において 複数のVPCフローログを 1つのS3バケットへ集約 してみます。

S3バケットの作成

集約してフローログを格納するための S3バケットを作成します。 フローログは貯まり続けるので、ライフサイクルルール(XX日で失効) を入れることをおすすめします。

S3バケットに以下のようなバケットポリシーを入れます。
バケットに対する s3:PutObjects3:GetBucketAcl を許可するポリシーです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": [
                "arn:aws:s3:::(バケット名)/AWSLogs/(AWSアカウントID#A)/*",
                "arn:aws:s3:::(バケット名)/AWSLogs/(AWSアカウントID#B)/*",
                "arn:aws:s3:::(バケット名)/AWSLogs/(AWSアカウントID#C)/*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::(バケット名)"
        }
    ]
}

VPC Flow Logs の有効化

CloudFormationテンプレートを準備して作成します。

以下のようなテンプレートを作成してそれぞれのアカウントに展開します。 AWS::EC2::FlowLog リソースを作成するテンプレートです。 (参考: AWS::EC2::FlowLog | AWSドキュメント)

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  BucketName:
    Type: String
    Default: xxx
  FlowLogsFilter:
    Type: String
    Default: ALL
    AllowedValues: [ ALL, ACCEPT, REJECT ]
Resources:
  FlowLogs:
    Type: AWS::EC2::FlowLog
    Properties: 
      LogDestinationType: s3
      LogDestination: !Sub "arn:aws:s3:::${BucketName}"
      ResourceType: VPC
      ResourceId: !ImportValue Vpc
      TrafficType: !Ref FlowLogsFilter

パラメータ、リソース(FlowLogs) の内容は以下のとおりです。

  • パラメータ
    • BucketName: 先程作成した S3バケット名
    • FlowLogsFilter: 保存するIPトラフィックの種類(すべて/許可/拒否)
  • FlowLogsプロパティ
    • LogDestinationType: 送信先を S3とします
    • LogDestination: 送信先を指定します(S3バケット ARN)
    • ResourceType: リソースの種類(VPC)
    • ResourceId: 対象のVPC ID。 (上記テンプレートは別CFnスタックの Vpc アウトプットを参照するものにしています)
    • TrafficType: 保存するIPトラフィックの種類

確認

S3バケットを見てみます。

作成した S3バケットの AWSLogs/ に各アカウントIDのフォルダがあります。

各アカウントID毎に以下のようにフローログが保存されます。

適宜、これらログを Athena(ほか分析ツール)など使って調査しましょう。 (参考: VPCフローログをAmazon Athenaで分析する | Developers.IO)

おわりに

マルチアカウントのVPCフローログを、1バケットに集約してみました。

マルチアカウント統制に便利な Organizations の直接の連携機能として VPC Flow Logs の一括設定機能は今のところありません。

ですが CloudFormation StackSets との連携 で 組織単位で簡単にCFnテンプレートを展開できるので、 それを活用してマルチアカウントで一括 VPC Flow Logs 設定を検討すると良いかもしれません。

(参考: 【Organizations】組織単位で CloudFormation StackSetsを簡単にデプロイしてみる | Developers.IO)

少しでもどなたかのお役に立てば幸いです。

補足: S3バケットのCFnテンプレート

今回の構築で使った S3バケットの CFnテンプレートも以下記します。 適宜、バケットポリシーに記載しているアカウントID含んだARNを修正してください。

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  BucketName:
    Type: String
    Default: xxx
  BucketExpirationInDays:
    Type: Number
    Default: 90

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Ref BucketName
      # S3デフォルトの暗号化
      BucketEncryption:
        ServerSideEncryptionConfiguration: 
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      # XX日失効のライフサイクルルール
      LifecycleConfiguration:
        Rules:
          - Id: ExpirationRule
            Status: Enabled
            ExpirationInDays: !Ref BucketExpirationInDays
      # ブロックパブリックアクセスを全てONに
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties: 
      Bucket: !Ref BucketName
      PolicyDocument:
        # BucketPolicy
        Version: '2012-10-17'
        Statement:
        - Sid: AWSLogDeliveryWrite
          Effect: Allow
          Principal:
            Service: delivery.logs.amazonaws.com
          Action: s3:PutObject
          Resource:
            - !Sub "arn:aws:s3:::${BucketName}/AWSLogs/(アカウントID#A)/*"
            - !Sub "arn:aws:s3:::${BucketName}/AWSLogs/(アカウントID#B)/*"
            - !Sub "arn:aws:s3:::${BucketName}/AWSLogs/(アカウントID#C)/*"
          Condition:
            StringEquals:
              s3:x-amz-acl: bucket-owner-full-control
        - Sid: AWSLogDeliveryAclCheck
          Effect: Allow
          Principal:
            Service: delivery.logs.amazonaws.com
          Action: s3:GetBucketAcl
          Resource: !Sub "arn:aws:s3:::${BucketName}"

参考