「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート - ⑤全てのVPCでフローログを有効化する

# はじめに

AWSにはアカウントやリソースへの脅威検知に対応した、**AWS IAM Access Analyzer**, **AWS Security Hub**, **Amazon Detective**, **Amazon Inspector**, **Amazon GuardDuty**, **AWS CloudTrail**, **AWS Config** などのサービスが用意されています。

また、**AWS Security Hub** では、[**CIS AWS Foundations Standard**](https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-standards-cis.html) , [**Payment Card Industry Data Security Standard**](https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-standards-pcidss.html) , [**AWS Foundational Security Best Practices Standard**](https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-standards-fsbp.html) などのセキュリティ標準が公開されており、このガイドラインは、**AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定**を集めた**ベストプラクティス集**として活用できます。

本記事では、アカウントやリソースへの**脅威検知が可能なAWSサービスを有効化**するとともに、上記のセキュリティ標準に限りなく準拠することで、セキュアで堅牢なAWSアカウントを実現します。また、これらを**お手軽に実現できるCloudFormationテンプレートを公開**しています。

+ [**aws-cloudformation-templates/security - GitHub**](https://github.com/eijikominami/aws-cloudformation-templates/blob/master/security/)

このCloudFormationテンプレートの実行はこちらから。

[![cloudformation-launch-stack](https://raw.githubusercontent.com/eijikominami/aws-cloudformation-templates/master/images/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review?stackName=DefaultSecuritySettings&templateURL=https://eijikominami.s3-ap-northeast-1.amazonaws.com/aws-cloudformation-templates/security/template.yaml) 

![](https://raw.githubusercontent.com/eijikominami/aws-cloudformation-templates/master/images/architecture-default-security-settings.png)

# VPC フローログの有効化

[**VPC フローログ**](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/flow-logs.html)とは、**VPC 内のトラフィックに関する情報をキャプチャしたログ** のことで、`Amazon S3` もしくは ` Amazon CloudWatch Logs` にこれらのデータを保存することが可能です。**CIS AWS Foundations Benchmark** では、

+ 2.9 **すべての VPC で VPC フローログ記録が有効になっていることを確認します** 

という項目を規定しており、**VPC フローログを用いることで異常なトラフィック等を検出できる**ことを指摘しています。この規定に準拠するために、このCloudFormationテンプレートでは、以下の設定を行います。

1. 上記のポリシーに準拠しているか AWS Config を用いて **定期的にチェック** を行う
2. 非準拠であった場合には、`AWS Config` が `SSM Automation` を自動起動する
3. `SSM Automation` を用いて **VPCフローログ** を自動作成する

それぞれの設定について、順を追って説明します。

## 1. AWS Configの有効化

`AWS Config` を有効化する手順については、[過去の記事](https://qiita.com/eijikominami/items/53f3a1d83df31981ad86#aws-config) をご覧ください。

### サービスにリンクされたロールの作成

``AWS Config`` で使用する ``Service-Linked Role`` を作成します。この ``Service-Linked Role`` は、 **AWSリソースへの読み込み権限** と **S3への書き込み権限** を ``Config`` に、また、**IAMとSystemManagerへの書き込み権限** を ``Config Remediation`` にそれぞれ付与します。

```yaml
Resources:
  ServiceLinkedRoleForConfig:
    Type: AWS::IAM::ServiceLinkedRole
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
    Properties: 
      AWSServiceName: config.amazonaws.com
      Description: A service-linked role required for AWS Config to access your resources.
  ServiceLinkedRoleForConfigRemediation:
    Type: AWS::IAM::ServiceLinkedRole
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
    Properties: 
      AWSServiceName: remediation.config.amazonaws.com 
      Description: A service-linked role required for AWS Config Remediation to access your resources.
```

### AWS Configの有効化

``AWS Config`` の ``DeliveryChannel`` と ``ConfigurationRecorder`` を作成します。

```yaml
Resources:
  ConfigDeliveryChannel:
    Type: AWS::Config::DeliveryChannel
    Properties:
      Name: default
      S3BucketName: !Ref S3ForConfig
  ConfigConfigurationRecorder:
    Type: AWS::Config::ConfigurationRecorder
    Properties:
      Name: default
      RecordingGroup:
        AllSupported: true
        IncludeGlobalResourceTypes: true
      RoleARN: !Sub arn:aws:iam::DefaultSecuritySettings:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
```

### Amazon S3 バケットを作成

**設定情報 （履歴ファイルやスナップショット）** を保存するために使用する、``Amazon S3`` **バケット**と、それに紐づく**バケットポリシー**を作成します。

```yaml
Resources:
  S3ForConfig:
    Type: 'AWS::S3::Bucket'
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration: 
          - ServerSideEncryptionByDefault: 
              SSEAlgorithm: AES256
      BucketName: !Sub defaultsecuritysettings-config-${AWS::Region}-${AWS::AccountId}
      LifecycleConfiguration:
        Rules:
          - Id: ExpirationInDays
            ExpirationInDays: 60
            Status: Enabled
      PublicAccessBlockConfiguration: 
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
  S3BucketPolicyForConfig:
    Type: AWS::S3::BucketPolicy
    Properties: 
      Bucket: !Ref S3ForConfig
      PolicyDocument:
        Version: 2012-10-17
        Id: !Ref S3ForConfig
        Statement:
          - Effect: Allow
            Principal:
              Service: config.amazonaws.com
            Action:
              - 's3:GetBucketAcl'
              - 's3:ListBucket'
            Resource:
              - !GetAtt S3ForConfig.Arn
          - Effect: Allow
            Principal:
              Service: config.amazonaws.com
            Action:
              - 's3:PutObject'
            Resource:
              - !Join
                - ''
                - - !GetAtt S3ForConfig.Arn
                  - /AWSLogs/
                  - !Sub ${AWS::AccountId}
                  - /Config/*
            Condition:
              StringEquals:
                s3:x-amz-acl: bucket-owner-full-control
          - Effect: Deny
            Principal: '*'
            Action: 's3:*'
            Resource: 
              - !GetAtt S3ForConfig.Arn
              - !Join
                - ''
                - - !GetAtt S3ForConfig.Arn
                  - /*
            Condition:
              Bool: 
                aws:SecureTransport: false
```

## 2. AWS Configを用いた定期チェック

VPC フローログの存在チェックには、あらかじめ `AWS Config` に用意されている　`VPC_FLOW_LOGS_ENABLED ` マネージドルールを使用します。なお、この `Config Rule` を設定する前に `ConfigurationRecorder` を生成しておく必要があります。そこで、`DependsOn` 属性に `ConfigurationRecorder` リソースを設定しています。

```yaml
Resources:
  ConfigVpcFlowLogsEnabled:
    DependsOn:
      - ConfigConfigurationRecorder
    Type: 'AWS::Config::ConfigRule'
    Properties:
      ConfigRuleName: vpc-flow-logs-enabled
      Description: Amazon Virtual Private Cloud フローログが見つかり、Amazon VPC に対して有効になっているかどうかを確認します。
      Source:
        Owner: AWS
        SourceIdentifier: VPC_FLOW_LOGS_ENABLED 
```

## 3. SSM Automation を用いた自動修復

``Systems Manager Automation`` は、``AWS Config`` で **直接指定できる、現時点で唯一の自動修復手段** となっています。そこで、VPC フローログを作成する ``Systems Manager Automation`` **ドキュメント** を作成し、``AWS Config`` との紐付けを行います。

下の``Systems Manager Automation`` ドキュメントでは、

1. `CloudWatch` の `CreateLogGroup` を用いて **ロググループを作成**
2. `CloudWatch` の `PutRetentionPolicy` を用いて **ログの保存期間を指定** (= 今回は60日間）
3. `EC2` の `CreateFlowLogs` を用いて、 **VPC フローログを作成**

しています。

```yaml
Resources:
  SSMAutomationCreateFlowLogs:
    Type: 'AWS::SSM::Document'
    Properties: 
      Content:
        schemaVersion: "0.3"
        assumeRole: "{{ AutomationAssumeRole }}"
        description: Create VPC flow logs.
        mainSteps:
          - name: CreateLogGroup
            action: aws:executeAwsApi
            inputs:
              Service: logs
              Api: CreateLogGroup
              logGroupName: "/aws/vpc/{{ ResourceId }}"
          - name: PutRetentionPolicy
            action: aws:executeAwsApi
            inputs:
              Service: logs
              Api: PutRetentionPolicy
              logGroupName: "/aws/vpc/{{ ResourceId }}"
              retentionInDays: 60
          - name: CreateFlowLogs
            action: aws:executeAwsApi
            inputs:
              Service: ec2
              Api: CreateFlowLogs
              DeliverLogsPermissionArn: "{{ DeliverLogsPermissionArn }}"
              LogDestinationType: cloud-watch-logs
              LogGroupName: "/aws/vpc/{{ ResourceId }}"
              ResourceId.N: 
                - "{{ ResourceId }}"
              ResourceType: VPC
              TrafficType: ALL
        parameters:
          AutomationAssumeRole:
            type: String
            description: Automation Assume Role Arn
          DeliverLogsPermissionArn:
            type: String
            description: Deliver Logs Permission Arn
          ResourceId:
            type: String
            description: Resource ID
      DocumentType: Automation
```

## 4. AWS Config と SSM Automation の紐付け

上述の AWS API アクションを ``Systems Manager Automation`` から呼び出すことを可能とする **IAM Role** を作成します。

```yaml
Resources:
  IAMRoleForSSM:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: ssm.amazonaws.com
            Action: 'sts:AssumeRole'
      Description: A role required for SSM to access IAM.
      Policies:
        - PolicyName: !Sub 'DefaultSecuritySettings-AWSSystemManagerIAMRole-${AWS::Region}'
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:PutRetentionPolicy'
                  - 'ec2:CreateFlowLogs'
                Resource:
                  - '*'
      RoleName: !Sub 'DefaultSecuritySettings-SSM-${AWS::Region}'
```

また、これと同時に、`EC2` が `CloudWatch Logs` に対して **VPCフローログ** を発行することを許可する**IAM Role** も作成します。

```yaml
Resources:
  IAMRoleForVPCFlowLog:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: vpc-flow-logs.amazonaws.com
            Action: 'sts:AssumeRole'
      Description: A role required for VPC flow logs to access CloudWatch Logs.
      Policies:
        - PolicyName: !Sub 'DefaultSecuritySettings-AWSVPCFlowLogCloudWatchLogsPolicy-${AWS::Region}'
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                  - 'logs:DescribeLogGroups'
                  - 'logs:DescribeLogStreams'
                Resource: '*'
      RoleName: !Sub 'DefaultSecuritySettings-AWSVPCFlowLogRole-${AWS::Region}'
```

これらのIAM RoleのARNは、``AWS Config`` から ``Systems Manager Automation`` へ渡されるパラメータの1つとして規定されます。 ``AWS::Config::RemediationConfiguration`` は、**非準拠（NON_COMPLIANT）と判定された場合の自動修復方法を規定**し、``Config Rule`` と ``Systems Manager Automation`` との紐付けや、受け渡されるパラメータの規定を行います。自動修復を行う場合は、**AutomationAssumeRole, DeliverLogsPermissionArn, ResourceId** の各パラメータの入力が必須です。

```yaml
Resources:
  ConfigVpcFlowLogsEnabledRemediationConfiguration:
    Type: 'AWS::Config::RemediationConfiguration'
    Properties:
      Automatic: true
      ConfigRuleName: !Ref ConfigVpcFlowLogsEnabled
      MaximumAutomaticAttempts: 1
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - !GetAtt IAMRoleForSSM.Arn
        DeliverLogsPermissionArn:
          StaticValue:
            Values:
              - !GetAtt IAMRoleForVPCFlowLog.Arn
        ResourceId:
          ResourceValue:
            Value: RESOURCE_ID
      RetryAttemptSeconds: 30
      TargetId: !Ref SSMAutomationCreateFlowLogs
      TargetType: SSM_DOCUMENT
```

以上で、**全てのVPCでフローログを有効化** することができました。

# 関連リンク
1. [**サービスの有効化** - 「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート](https://qiita.com/eijikominami/items/53f3a1d83df31981ad86)
2. [**パスワードポリシーの自動修復** - 「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート](https://qiita.com/eijikominami/items/85acced082d0dc8d9901)
3. [**モニタリングと通知の設定** - 「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート](https://qiita.com/eijikominami/items/1887d19ce3bb33f716ba)
4. [**アクセスキーのローテーションと削除** - 「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート](https://qiita.com/eijikominami/items/eba16015e8e27e42fc36)
5. **全てのVPCでフローログを有効化する** - 「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート
6. [**SSHとRDPのアクセスを制限する** - 「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート](https://qiita.com/eijikominami/items/936912ee715079606e55)
7. [**デフォルトセキュリティグループを無効化する** - 「セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート](https://qiita.com/eijikominami/items/2fa109f00b5c63686c42)
8. [**S3バケットのサーバサイド暗号化** - セキュアで堅牢なAWSアカウント」を実現する CloudFormationテンプレート](https://qiita.com/eijikominami/items/581a8e0e424117322125)