AWS Config(6)デフォルトセキュリティグループの無効化

デフォルトセキュリティグループ

CIS AWS Foundations Benchmark というセキュリティガイドラインが公開されており、このガイドラインは、AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定を集めたベストプラクティス集として活用できる。

この CIS AWS Foundations Benchmarkでは、デフォルトセキュリティグループについて、以下の設定とすることが奨励されている。

  • 4.3 IAM すべての VPC のデフォルトセキュリティグループがすべてのトラフィックを制限するようにします

この CIS AWS Foundations Benchmark準拠していないデフォルトセキュリティグループSSM Automation を用いて 自動修復 するために以下の設定を行う。

  1. 上記のポリシーに準拠しているか AWS Config を用いて定期的にチェックを行う
  2. 非準拠であった場合には、AWS ConfigSSM Automation自動起動する
  3. SSM Automation非準拠のデフォルトセキュリティグループの設定を自動修復する

1. AWS Configの有効化

AWS Configを有効化する手順については、こちら

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

デフォルトセキュリティグループ設定のチェックには、あらかじめAWS Configに用意されている vpc-default-security-group-closed マネージドルールを使用する。デフォルトセキュリティグループがこの条件を満たしていない場合、このリソースはルールに 非準拠(NON_COMPLIANT) であると判定される。

なお、この Config Rule を設定する前に ConfigurationRecorder を生成しておく必要がある。そこで、DependsOn 属性に ConfigurationRecorder リソースを設定している。

Resources:
  ConfigVpcDefaultSecurityGroupClosed:
    DependsOn:
      - ConfigConfigurationRecorder
    Type: 'AWS::Config::ConfigRule'
    Properties:
      ConfigRuleName: vpc-default-security-group-closed
      Description: いずれの Amazon Virtual Private Cloud (VPC) のデフォルトのセキュリティグループでもインバウンドとアウトバウンドのいずれのトラフィックも許可しないことを確認します。
      Source:
        Owner: AWS
        SourceIdentifier: VPC_DEFAULT_SECURITY_GROUP_CLOSED 

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

Systems Manager Automation は、AWS Config直接指定できる、現時点で唯一の自動修復手段 となっている。そこで、デフォルトのセキュリティグループを修復する Systems Manager Automation ドキュメント を作成し、AWS Config との紐付けを行う。

下のSystems Manager Automation ドキュメントは、EC2RevokeSecurityGroupIngress, RevokeSecurityGroupEgress, DescribeSecurityGroups を実行して、デフォルトセキュリティグループの設定を自動修復する。

Resources:
  SSMAutomationRevokeDefaultSecurityGroup:
    Type: 'AWS::SSM::Document'
    Properties: 
      Content:
        schemaVersion: "0.3"
        assumeRole: "{{ AutomationAssumeRole }}"
        description: Revoke Default Security Group.
        mainSteps:
          - name: DescribeSecurityGroups
            action: aws:executeAwsApi
            onFailure: Abort
            inputs:
              Service: ec2
              Api: DescribeSecurityGroups
              GroupIds: ["{{ GroupId }}"]
            outputs:
              - Name: IpPermissionsIngress
                Selector: $.SecurityGroups[0].IpPermissions
                Type: MapList
              - Name: IpPermissionsEgress
                Selector: $.SecurityGroups[0].IpPermissionsEgress
                Type: MapList
          - name: RevokeSecurityGroupIngress
            action: aws:executeAwsApi
            onFailure: Continue
            inputs:
              Service: ec2
              Api: RevokeSecurityGroupIngress
              GroupId: "{{ GroupId }}"
              IpPermissions: "{{ DescribeSecurityGroups.IpPermissionsIngress }}"
          - name: RevokeSecurityGroupEgress
            action: aws:executeAwsApi
            onFailure: Continue
            inputs:
              Service: ec2
              Api: RevokeSecurityGroupEgress
              GroupId: "{{ GroupId }}"
              IpPermissions: "{{ DescribeSecurityGroups.IpPermissionsEgress }}"
        parameters:
          AutomationAssumeRole:
            type: String
            description: Automation Assume Role Arn
          GroupId:
            type: String
            description: Group Id
      DocumentType: Automation

4. AWS Config と SSM Automation の紐付け

Systems Manager Automation ドキュメントは、上述の通り IAMRevokeSecurityGroupIngress などを実行する必要があるため、このAWS API アクションを Systems Manager Automation から呼び出すことを可能とする IAM Role を作成する。

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 '${PrefixOfLogicalName}-AWSSystemManagerIAMRole-${AWS::Region}'
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'ec2:RevokeSecurityGroupIngress'
                  - 'ec2:RevokeSecurityGroupEgress'
                  - 'ec2:DescribeSecurityGroups'
                Resource:
                  - '*'
      RoleName: !Sub '${AWS::StackName}-SSM-${AWS::Region}'

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

Resources:
  ConfigVpcDefaultSecurityGroupClosedRemediationConfiguration:
    Condition: CreateRemediationResources
    Type: 'AWS::Config::RemediationConfiguration'
    Properties:
      Automatic: true
      ConfigRuleName: !Ref ConfigVpcDefaultSecurityGroupClosed
      MaximumAutomaticAttempts: 1
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - !GetAtt IAMRoleForSSM.Arn
        GroupId:
          ResourceValue:
            Value: RESOURCE_ID
      RetryAttemptSeconds: 30
      TargetId: !Ref SSMAutomationRevokeDefaultSecurityGroup
      TargetType: SSM_DOCUMENT

以上で、デフォルトセキュリティグループからインバウンドおよびアウトバンドの許可ルールを削除することができた。

AWS Config(5)外部からのSSHおよびRDPアクセスを制限する

セキュリティグループの自動修復

CIS AWS Foundations Benchmark というセキュリティガイドラインが公開されており、このガイドラインは、AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定を集めたベストプラクティス集として活用できる。

この CIS AWS Foundations Benchmarkでは、EC2/VPCのセキュリティグループについて、以下の設定とすることが奨励されている。

  • 4.1 どのセキュリティグループでも 0.0.0.0/0 からポート 22 への入力を許可しないようにします
  • 4.2 どのセキュリティグループでも 0.0.0.0/0 からポート 3389 への入力を許可しないようにします

この CIS AWS Foundations Benchmark準拠していないセキュリティグループSSM Automation を用いて 自動修復 するために以下の設定を行う。

  1. 上記のポリシーに準拠しているか AWS Config を用いて定期的にチェックを行う
  2. 非準拠であった場合には、AWS ConfigSSM Automation自動起動する
  3. SSM Automation奨励されたセキュリティグループ設定となるように設定を自動修復する

1. AWS Configの有効化

AWS Configを有効化する手順については、こちら

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

セキュリティグループの設定のチェックには、あらかじめAWS Configに用意されている vpc-default-security-group-closed マネージドルールを使用する。セキュリティグループがこの条件を満たしていない場合、このリソースはルールに 非準拠(NON_COMPLIANT) であると判定される。

なお、この Config Rule を設定する前に ConfigurationRecorder を生成しておく必要がある。そこで、DependsOn 属性に ConfigurationRecorder リソースを設定している。

Resources:
  ConfigSVpcSgOpenOnlyToAuthorizedPorts:
    DependsOn:
      - ConfigConfigurationRecorder
    Type: 'AWS::Config::ConfigRule'
    Properties:
      ConfigRuleName: vpc-sg-open-only-to-authorized-ports
      Description: いずれかの 0.0.0.0/0 Amazon Virtual Private Cloud (Amazon VPC) を持つセキュリティグループで、特定のインバウンド TCP または UDP トラフィックのみが許可されるかどうかを確認します。
      InputParameters:
        authorizedTcpPorts: 1-21,23-3388,3390-65535
        authorizedUdpPorts: 1-21,23-3388,3390-65535
      Source:
        Owner: AWS
        SourceIdentifier: VPC_SG_OPEN_ONLY_TO_AUTHORIZED_PORTS 

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

Systems Manager Automation は、AWS Config直接指定できる、現時点で唯一の自動修復手段 となっている。そこで、セキュリティグループ を修復する Systems Manager Automation ドキュメントAWS Config との紐付けを行う。

修復には、あらかじめ用意されている AWS-DisablePublicAccessForSecurityGroup ドキュメントを使用する。このドキュメントは、すべての IP アドレスに対して開かれているデフォルトの SSH および RDP ポートを無効にする。

Resources:
  ConfigVpcSgOpenOnlyToAuthorizedPortsRemediationConfiguration:
    Condition: CreateRemediationResources
    Type: 'AWS::Config::RemediationConfiguration'
    Properties:
      # NOTE: AutomationAssumeRole, MaximumAutomaticAttempts and RetryAttemptSeconds are Required if Automatic is true.
      Automatic: true
      ConfigRuleName: !Ref ConfigSVpcSgOpenOnlyToAuthorizedPorts
      MaximumAutomaticAttempts: 1
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - !GetAtt IAMRoleForSSM.Arn
        GroupId:
          ResourceValue:
            Value: RESOURCE_ID
      RetryAttemptSeconds: 30
      TargetId: AWS-DisablePublicAccessForSecurityGroup
      TargetType: SSM_DOCUMENT

以上で、すべての IP アドレスに対して開かれているデフォルトの SSH および RDP ポートを無効にすることができた。

AWS Config(4)VPCフローログの自動生成

VPCフローログ

CIS AWS Foundations Benchmark というセキュリティガイドラインが公開されており、このガイドラインは、AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定を集めたベストプラクティス集として活用できる。

この CIS AWS Foundations Benchmarkでは、VPCフローログについて以下のように定められている。

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

この CIS AWS Foundations Benchmark準拠していないVPCが存在した場合SSM Automation を用いて VPCフローログを自動作成 するために以下の設定を行う。

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

1. AWS Configの有効化

AWS Configを有効化する手順については、こちら

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

VPCフローログの存在確認には、あらかじめAWS Configに用意されている vpc-flow-logs-enabled マネージドルールを使用する。VPCフローログが設定されていない場合、このVPCはルールに 非準拠(NON_COMPLIANT) であると判定される。

なお、この Config Rule を設定する前に ConfigurationRecorder を生成しておく必要がある。そこで、DependsOn 属性に ConfigurationRecorder リソースを設定している。

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 ドキュメントは、EC2CreateFlowLogs を実行して、IAM パスワードポリシーの設定を自動修復する。

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: cloudwatch
              Api: CreateLogGroup
              logGroupName: "/aws/vpc/{{ ResourceId }}"
          - name: PutRetentionPolicy
            action: aws:executeAwsApi
            inputs:
              Service: cloudwatch
              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
      Tags:
        - Key: !Ref TagKey
          Value: !Ref TagValue

4. AWS Config と SSM Automation の紐付け

Systems Manager Automation ドキュメントは、上述の通り EC2CreateFlowLogs などを実行する必要があるため、このAWS API アクションを Systems Manager Automation から呼び出すことを可能とする IAM Role を作成する。

また、VPCからCloudWatch Logsにフローログを書き込むことのできる権限を持つIAM Roleも別途作成しておく。

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 '${PrefixOfLogicalName}-AWSSystemManagerIAMRole-${AWS::Region}'
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:PutRetentionPolicy'
                  - 'ec2:CreateFlowLogs'
                Resource:
                  - '*'
      RoleName: !Sub '${AWS::StackName}-SSM-${AWS::Region}'
  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 '${AWS::StackName}-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 '${AWS::StackName}-AWSVPCFlowLogRole-${AWS::Region}'

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

Resources:
  ConfigVpcFlowLogsEnabledRemediationConfiguration:
    Condition: CreateRemediationResources
    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

以上で、CIS AWS Foundations Benchmark に準拠していないVPCに対して、VPCフローログを自動生成することができた。

AWS Config(3)アクセスキーの管理と自動削除

アクセスキーの適切な管理

CIS AWS Foundations Benchmark というセキュリティガイドラインが公開されており、このガイドラインは、AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定を集めたベストプラクティス集として活用できる。

この CIS AWS Foundations Benchmarkでは、アクセスキーの取り扱いについて以下のように定めている。

  • 1.3 90 日間以上使用されていない認証情報は無効にします
  • 1.4 アクセスキーは 90 日ごとに更新します

この CIS AWS Foundations Benchmark準拠していないアクセスキーCloudWatch EventsLambda を用いて 自動削除 するために以下の設定を行う。

  1. 上記のポリシーに準拠しているか AWS Config を用いて定期的にチェックを行う
  2. 非準拠であった場合には、CloudWatch EventsLambda自動起動する
  3. Lambda非準拠のアクセスキーを削除する

1. AWS Configの有効化

AWS Configを有効化する手順については、こちら

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

アクセスキーのチェックには、あらかじめAWS Configに用意されている access-keys-rotated マネージドルールを使用する。CIS AWS Foundations Benchmark で奨励されているアクセスキーの有効期限は、マネージドルール内の InputParameters で設定する。アクセスキーがこの条件を満たしていない場合、このリソースはルールに 非準拠(NON_COMPLIANT) であると判定される。

なお、この Config Rule を設定する前に ConfigurationRecorder を生成しておく必要がある。そこで、DependsOn 属性に ConfigurationRecorder リソースを設定している。

Resources:
  ConfigIamAccessKeysRotated:
    DependsOn:
      - ConfigConfigurationRecorder
    Type: 'AWS::Config::ConfigRule'
    Properties:
      ConfigRuleName: access-keys-rotated
      Description: アクティブなアクセスキーが、maxAccessKeyAge で指定された日数内にローテーションされるかどうかを確認します。
      InputParameters:
        maxAccessKeyAge: 90
      Source:
        Owner: AWS
        SourceIdentifier: ACCESS_KEYS_ROTATED

3. CloudWatch Events を用いた Lambda の自動実行

Configルールに 非準拠(NON_COMPLIANT)となった場合に、これを修復するLambdaを発火させるためのトリガとして、CloudWatch Events を設定する。

Resources:
  CloudWatchEventsForConfigIamAccessKeysRotated:
    Type: 'AWS::Events::Rule'
    Properties: 
      Description: CloudWatch Events about Config IAM Access Keys Rotated.
      EventPattern:
        source:
          - aws.config
        detail-type: 
          - Config Rules Compliance Change
        detail:
          messageType:
            - ComplianceChangeNotification
          newEvaluationResult:
            complianceType:
              - NON_COMPLIANT
      Name: AWS_Config
      State: ENABLED
      Targets:
        - Arn: !GetAtt LambdaDeleteExpiredAccessKeys.Arn
          Id: lambda

4. Lambda を用いた アクセスキー の削除

Lambdaが受け取るConfigから通知されたメッセージには、期限切れのアクセスキーを持つIAMユーザの情報が含まれる。そこでLambdaは、このユーザが持つアクセスキーのうち、有効期限を超過したアクセスキーのIDを探し当てDeleteAccessKey API を用いてこれを削除する。

また、AWS::Lambda::Permission リソースタイプを用いて、前述のCloudWatch Eventsが、このLambdaを実行可能とする権限を設定する。

Resources:
  LambdaDeleteExpiredAccessKeys:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        ZipFile: |
          import boto3
          import datetime
          import time
          import logging

          logger = logging.getLogger()
          logger.setLevel(logging.INFO)

          def lambda_handler(event, context):
              logger.info(str(event))
            
              if 'detail' in event:
                  detail = event['detail']
                  if 'configRuleName' in detail:
                      # access-keys-rotated
                      if detail['configRuleName'] == 'access-keys-rotated':
                          iam = boto3.client('iam')
                          users = iam.list_users()
                          for user in users['Users']:
                              if detail['resourceId'] == user['UserId']:
                                  access_keys = iam.list_access_keys(
                                      UserName=user['UserName']
                                      )
                                  for access_key in access_keys['AccessKeyMetadata']:
                                      create_date = access_key['CreateDate'].timestamp()
                                      now = time.time()
                                      if now - create_date > 60*60*24*90:
                                          response = iam.delete_access_key(
                                              UserName=user['UserName'],
                                              AccessKeyId=access_key['AccessKeyId']
                                          )
      Description: 有効期限が過ぎたアクセスキーを削除します
      FunctionName: deleteExpiredAccessKeys
      Handler: index.lambda_handler
      MemorySize: 128
      Role: !GetAtt IAMRoleForLambda.Arn
      Runtime: python3.7
      Tags:
        - Key: !Ref TagKey
          Value: !Ref TagValue
      Timeout: 3
      TracingConfig:
        Mode: Active
  LambdaDeleteExpiredAccessKeysPermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref LambdaDeleteExpiredAccessKeys
      Principal: events.amazonaws.com
      # DO NOT write 'SourceAccount' option.
      SourceArn: !GetAtt CloudWatchEventsForConfigIamAccessKeysRotated.Arn

以上で、CIS AWS Foundations Benchmark に非準拠のアクセスキーを削除することができた。

AWS Config(2)パスワードポリシーの自動修復

IAMパスワードポリシーの自動修復

CIS AWS Foundations Benchmark というセキュリティガイドラインが公開されており、このガイドラインは、AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定を集めたベストプラクティス集として活用できる。

この CIS AWS Foundations Benchmarkでは、IAMユーザ用のパスワードポリシーについて、以下の設定とすることが奨励されている。

  • 1.5 IAM パスワードポリシーには少なくとも 1 つの大文字が必要です
  • 1.6 IAM パスワードポリシーには少なくとも 1 つの小文字が必要です
  • 1.7 IAM パスワードポリシーには少なくとも 1 つの記号が必要です
  • 1.8 IAM パスワードポリシーには少なくとも 1 つの数字が必要です
  • 1.9 IAM パスワードポリシーは 14 文字以上の長さが必要です
  • 1.10 IAM パスワードポリシーはパスワードの再使用を禁止しています

この CIS AWS Foundations Benchmark準拠していないIAMパスワードポリシーSSM Automation を用いて 自動修復 するために以下の設定を行う。

  1. 上記のポリシーに準拠しているか AWS Config を用いて定期的にチェックを行う
  2. 非準拠であった場合には、AWS ConfigSSM Automation自動起動する
  3. SSM Automation正しいIAMパスワードポリシーとなるように設定を自動修復する

1. AWS Configの有効化

AWS Configを有効化する手順については、こちら

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

IAM パスワードポリシー設定のチェックには、あらかじめAWS Configに用意されている iam-password-policy マネージドルールを使用する。CIS AWS Foundations Benchmark で奨励されているパスワードポリシーの値は、マネージドルール内の InputParameters で設定する。IAM パスワードポリシーがこの条件を満たしていなかった場合、このリソースはルールに 非準拠(NON_COMPLIANT) であると判定される。

なお、この Config Rule を設定する前に ConfigurationRecorder を生成しておく必要がある。そこで、DependsOn 属性に ConfigurationRecorder リソースを設定している。

Resources:
  ConfigIamPasswordPolicy:
    DependsOn:
      - ConfigConfigurationRecorder
    Type: AWS::Config::ConfigRule
    Properties:
      ConfigRuleName: iam-password-policy
      Description: IAM ユーザーのアカウントパスワードポリシーが、指定した要件を満たしているかどうかを確認します。
      InputParameters:
        RequireUppercaseCharacters: true
        RequireLowercaseCharacters: true
        RequireSymbols: true
        RequireNumbers: true
        MinimumPasswordLength: 14
        PasswordReusePrevention: 24
      Source:
        Owner: AWS
        SourceIdentifier: IAM_PASSWORD_POLICY

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

Systems Manager Automation は、AWS Config直接指定できる、現時点で唯一の自動修復手段 となっている。そこで、IAM パスワードポリシー を修復する Systems Manager Automation ドキュメント を作成し、AWS Config との紐付けを行う。

下のSystems Manager Automation ドキュメントは、IAMUpdateAccountPasswordPolicy を実行して、IAM パスワードポリシーの設定を自動修復する。

Resources:
  SSMAutomationUpdateAccountPasswordPolicy:
    Type: AWS::SSM::Document
    Properties: 
      Content:
        schemaVersion: "0.3"
        assumeRole: "{{ AutomationAssumeRole }}"
        description: Update account password policy.
        mainSteps:
          - name: UpdateAccountPasswordPolicy
            action: aws:executeAwsApi
            inputs:
              Service: iam
              Api: UpdateAccountPasswordPolicy
              AllowUsersToChangePassword: true
              HardExpiry: false
              MinimumPasswordLength: 14
              PasswordReusePrevention: 24
              RequireLowercaseCharacters: true
              RequireNumbers: true
              RequireSymbols: true
              RequireUppercaseCharacters: true
        parameters:
          AutomationAssumeRole:
            type: String
            description: Automation Assume Role Arn
      DocumentType: Automation

4. AWS Config と SSM Automation の紐付け

Systems Manager Automation ドキュメントは、上述の通り IAMUpdateAccountPasswordPolicy を実行する必要があるため、このAWS API アクションを Systems Manager Automation から呼び出すことを可能とする IAM Role を作成する。

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:
                  - 'iam:UpdateAccountPasswordPolicy'
                Resource:
                  - '*'
      RoleName: !Sub 'DefaultSecuritySettings-SSM-${AWS::Region}'

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

Resources:
  ConfigIamPasswordPolicyRemediationConfiguration:
    Type: AWS::Config::RemediationConfiguration
    Properties:
      Automatic: true
      ConfigRuleName: !Ref ConfigIamPasswordPolicy
      MaximumAutomaticAttempts: 1
      Parameters:
        AutomationAssumeRole:
          StaticValue:
            Values:
              - !GetAtt IAMRoleForSSM.Arn
      RetryAttemptSeconds: 60
      TargetId: !Ref SSMAutomationUpdateAccountPasswordPolicy
      TargetType: SSM_DOCUMENT

以上で、CIS AWS Foundations Benchmark に準拠したIAM パスワードポリシーへと、自動で修復することができた。

Amazon GuardDuty(1)GuardDutyの概要

GuardDutyとは

Amazon GuardDuty は、VPC フローログAWS CloudTrail イベントログDNS ログ を分析して、悪意のある操作や不正な動作を継続的にモニタリングする脅威検出サービス。AWS 環境内の予期しない潜在的に未許可なアクティビティや悪意のあるアクティビティを識別して、AWS アカウントとワークロードを保護を行う。

検出結果

潜在的に悪意のある予期しないアクティビティを検出すると、GuardDuty によって結果が生成される。またこれらの結果は、GuardDuty のマネージメントコンソールから閲覧できるだけでなく、 CloudWatch Events を利用して表示することもできる。

検出した脅威は以下のタイプに分類される。

タイプ 重要度 内容
Backdoor:EC2/Spambot EC2 インスタンスが ポート 25 でリモートホストと通信 して通常と異なる動作を示す。
Backdoor:EC2/C&CActivity.B!DNS EC2 インスタンスは、既知のコマンド&コントロールサーバーに関連付けられるドメイン名をクエリ している。
Backdoor:EC2/DenialOfService.Tcp EC2 インスタンスが、TCP プロトコルを使用したサービス拒否 (DoS) 攻撃の実行に利用されている可能性がある。
Backdoor:EC2/DenialOfService.Udp EC2 インスタンスが、UDP プロトコルを使用したサービス拒否 (DoS) 攻撃の実行に利用されている可能性がある。
Backdoor:EC2/DenialOfService.Dns EC2 インスタンスが、DNS プロトコルを使用したサービス拒否 (DoS) 攻撃の実行に利用されている可能性がある。
Backdoor:EC2/DenialOfService.UdpOnTcpPorts EC2 インスタンスが、TCP ポートで UDP プロトコルを使用したサービス拒否 (DoS) 攻撃の実行に利用されている可能性がある。
Backdoor:EC2/DenialOfService.UnusualProtocol EC2 インスタンスが、異常なプロトコルを使用したサービス拒否 (DoS) 攻撃の実行に利用されている可能性がある。
Behavior:EC2/NetworkPortUnusual EC2 インスタンスが 通常と異なるポート でリモートホストと通信している。
Behavior:EC2/TrafficVolumeUnusual EC2 インスタンスがリモートホストに対して通常と異なる 大量のネットワークトラフィック を生成している。
CryptoCurrency:EC2/BitcoinTool.B!DNS EC2 インスタンスは、 暗号通貨 関連のアクティビティに関連付けられているドメイン名をクエリしている。
CryptoCurrency:EC2/BitcoinTool.B EC2 インスタンスは、 暗号通貨 関連のアクティビティに関連付けられている IP アドレスをクエリしている。
PenTest:IAMUser/KaliLinux API が Kali Linux EC2 インスタンスから呼び出されました。
PenTest:IAMUser/ParrotLinux API が Parrot Security Linux EC2 インスタンスから呼び出されました。
PenTest:IAMUser/PentooLinux API が Pentoo Linux EC2 インスタンスから呼び出されました。
Persistence:IAMUser/NetworkPermissions プリンシパルが、通常 AWS アカウントの セキュリティグループ、ルート、ACL のネットワークアクセス許可を変更 するために使用される API を呼び出した。
Persistence:IAMUser/ResourcePermissions プリンシパルが、通常 AWS アカウントのさまざまなリソースの セキュリティアクセスポリシーを変更 するために使用される API を呼び出した。
Persistence:IAMUser/UserPermissions プリンシパルが、通常 AWS アカウントの IAM ユーザー、グループ、ポリシーを追加、変更、削除 するために使用される API を呼び出した。
Policy:IAMUser/S3BlockPublicAccessDisabled バケットの Amazon S3 ブロック パブリックアクセスが無効 になった。
Policy:IAMUser/RootCredentialUsage API が ルート認証情報を使用 して呼び出された。
PrivilegeEscalation:IAMUser/AdministrativePermissions プリンシパルが 許容度の高いポリシーを割り当て ようとしている。
Recon:EC2/PortProbeUnprotectedPort EC2 インスタンスの 保護されていないポートを既知の悪意のあるホストが探している
Recon:EC2/PortProbeEMRUnprotectedPort EMR クラスタの 保護されていないポートを既知の悪意のあるホストが探している
Recon:IAMUser/TorIPCaller API が Tor 出口ノード の IP アドレスから呼び出された。
Recon:IAMUser/MaliciousIPCaller.Custom API が カスタム脅威リストにある IP アドレス から呼び出された。
Recon:IAMUser/MaliciousIPCaller API が既知の 悪意のある IP アドレス から呼び出された。
Recon:EC2/Portscan EC2 インスタンスがリモートホストに アウトバウンドポートスキャン を実行している。
Recon:IAMUser/NetworkPermissions プリンシパルが、通常 AWS アカウントの既存のセキュリティグループ、ACL、ルートの ネットワークアクセス許可を検出 するために使用される API を呼び出した。
Recon:IAMUser/ResourcePermissions プリンシパルが、通常 AWS アカウントのさまざまなリソースに関連付けられた アクセス権限を検出 するために使用される API を呼び出した。
ResourceConsumption:IAMUser/ComputeResources プリンシパルが、通常 EC2 インスタンスなどの コンピューティングリソースを起動 するために使用される API を呼び出した。
Stealth:IAMUser/S3ServerAccessLoggingDisabled バケットの Amazon S3 サーバーアクセスログ記録が無効 になった.
Stealth:IAMUser/PasswordPolicyChange アカウントの パスワードポリシーが弱化 された.
Stealth:IAMUser/CloudTrailLoggingDisabled AWS CloudTrail の証跡が無効化 されている。
Stealth:IAMUser/LoggingConfigurationModified プリンシパルが、通常 AWS アカウントの CloudTrail ログ記録の停止、既存ログの削除 、その他アクティビティの痕跡を消去するために使用される API を呼び出した。
Trojan:EC2/BlackholeTraffic EC2 インスタンスは、ブラックホール と呼ばれるリモートホストの IP アドレスに通信しようとしている。
Trojan:EC2/DropPoint EC2 インスタンスは、マルウェア によって収集された認証情報やその他の盗難されたデータによって認識されているリモートホストの IP アドレスに通信しようとしている。
Trojan:EC2/BlackholeTraffic!DNS EC2 インスタンスは、ブラックホール IP アドレスにリダイレクトされるドメイン名へのクエリを実行している。
Trojan:EC2/DriveBySourceTraffic!DNS EC2 インスタンスは、Drive By Download 攻撃 の既知のソースであるリモートホストのドメイン名をクエリしている。
Trojan:EC2/DropPoint!DNS EC2 インスタンスは、マルウェア によって収集された認証情報やその他の盗難されたデータによって認識されているリモートホストのドメイン名をクエリしている。
Trojan:EC2/DGADomainRequest.B EC2 インスタンスで、アルゴリズムを使用して生成されたドメイン がクエリされている。
Trojan:EC2/DGADomainRequest.C!DNS EC2 インスタンスで、アルゴリズムを使用して生成されたドメイン がクエリされています。このようなドメインは、一般的にマルウェアによって悪用されることが多く、EC2 インスタンスが侵害されている場合がある。
Trojan:EC2/DNSDataExfiltration EC2 インスタンスが DNS クエリを通じて データを密かに抽出 しようとしている。
Trojan:EC2/PhishingDomainRequest!DNS EC2 インスタンスは フィッシング攻撃 に関与するクエリ実行のドメインである。
UnauthorizedAccess:EC2/MetadataDNSRebind Amazon EC2 インスタンスが、インスタンスメタデータサービスに解決される DNS ルックアップ を実行している。
UnauthorizedAccess:IAMUser/TorIPCaller API が Tor 出口ノードの IP アドレスから呼び出された。
UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom API が カスタム脅威リスト にある IP アドレスから呼び出された。
UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B 世界中でコンソールに対する複数の正常なログインが確認 された。
UnauthorizedAccess:IAMUser/MaliciousIPCaller API が既知の悪意のある IP アドレス から呼び出された。
UnauthorizedAccess:EC2/TorIPCaller EC2 インスタンスが Tor 出口ノードからのインバウンド接続を受信している。
UnauthorizedAccess:EC2/MaliciousIPCaller.Custom EC2 インスタンスが カスタム脅威リスト内の IP アドレス とアウトバウンド通信している。
UnauthorizedAccess:EC2/SSHBruteForce EC2 インスタンスが SSH ブルートフォース攻撃 に関与している。
UnauthorizedAccess:EC2/RDPBruteForce EC2 インスタンスが RDP ブルートフォース攻撃 に関与している。
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration インスタンス起動ロールを通じて EC2 インスタンス専用に作成された 認証情報が外部 IP アドレスから使用されている
UnauthorizedAccess:IAMUser/ConsoleLogin AWS アカウントのプリンシパルによる 通常とは違うコンソールへのログイン が確認された。
UnauthorizedAccess:EC2/TorClient EC2 インスタンスは Tor Guard または Authority ノードに接続している。
UnauthorizedAccess:EC2/TorRelay EC2 インスタンスは、Tor リレーとして Tor ネットワークに接続中である。

Amazon GuardDuty のセットアップ

Amazon GuardDutyはCloudFormationに対応しているため、CloudFormation経由でGuardDutyをセットアップすることができる。

サービスロールの有効化

以下のサービスロールを有効化することで、EC2リストの読み込み権限GuardDuty に付与する。これは、悪意のあるアクティビティに関係する AWS 環境の EC2 インスタンスのメタデータを取得するためである。

Resources:
  ServiceLinkedRoleForGuardDuty:
    Type: AWS::IAM::ServiceLinkedRole
    DeletionPolicy: Retain
    Properties: 
      AWSServiceName: guardduty.amazonaws.com
      Description: A service-linked role required for Amazon GuardDuty to access your resources.

GuardDutyの有効化

GuardDuty を有効化する。有効化すると直ちにデータの取得と分析を開始する。 これらの処理は、通常のAWS CloudTrail、VPC フローログ、および DNS ログの保存とは独立している。

Resources:
  GuardDutyDetector:
    DependsOn:
      - ServiceLinkedRoleForGuardDuty
    Type: AWS::GuardDuty::Detector
    Properties:
      Enable: true

CloudFormation Launch Stack URL

以下のボタンから上のCloudFormationテンプレートを実行することが可能である。ソースコードは、aws-cloudformation-templates/security – GitHub にて公開。

作成されるAWSサービス CloudFormationテンプレート
セキュリティサービス全般 cloudformation-launch-stack
GuardDutyのみ cloudformation-launch-stack

AWS Config(1)Configの概要

AWS Configとは

AWS Configは、リソースごとの設定項目を生成し、履歴としてこれを保持するため、全ての変更を追跡することが可能で、AWSリソース間の関係と設定の履歴などを確認することができる。

  • リソースの設定が最適であるか
  • 現在のスナップショットの取得
  • リソース設定の取得
  • 設定履歴の取得
  • リソース間の関係の表示
  • 通知

これらの機能を用いて、リソースの管理監査とコンプライアンス設定変更の確認とトラブルシューティングセキュリティ分析などを行うことができる。

設定項目は、S3バケットに蓄積することが可能で、データはJSON形式で、S3に6時間ごとに送信される。また、リソースが変更されたタイミング等で、Amazon SNSを用いてEメール等で通知することも可能である。

AWS Configは、マルチアカウントマルチリージョンの データ集約 に対応しており、複数のアカウントやリージョンの設定、コンプライアンスデータを1つのアカウントに集約することができる。

https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2016-aws-cloudtrail-aws-config?ref=https://tech.blog.surbiton.jp/

AWS Configの概念

設定履歴と設定項目、スナップショット、レコーダ

設定履歴は、特定期間の特定リソースに関する設定項目のコレクションである。また、設定項目は、アカウント内のサポートされているAWSリソースの属性(メタデータ、関係、設定、関連イベントなど)を記録したものである。設定スナップショット は、設定項目のコレクションで、記録対象のリソースの全体像を示す。スナップショットは、S3 Bucketに配信が可能。

設定レコーダは、(標準設定では)Configがサポートしている全てのリソースの設定項目の評価と保存を行う。設定レコーダをオフにすると設定変更トリガによる評価は実行されない。一方で、定期実行トリガは引き続き指定した間隔で実行される

設定ストリーム

設定ストリームは、設定項目の自動更新リストで、リソースの作成や変更、削除が行われる度に、Amazon SNSを使用して通知を行うことができる。

ルール

AWS Configでは、望ましい設定をルールとして定めることができ、これに違反しているリソースに対しては、非準拠 のフラグを立てる。ルールは、事前に用意されたマネージドルールのほかに、ユーザが自ら作成したカスタムルールを適用することもできる。これらのルールは、リソースの設定変更時に評価されるのか、それとも定期的に評価されるのかを定義することができる。

AWS Configの仕組み

AWS Configは、サポートされているAWSリソースを検出し、リソースごとに設定項目を生成し、その記録を履歴として保持する。Configはリソースごとに、DescribeもしくはListのAPIコールによって、リソースの全ての変更を追跡する。Configルールを利用することで、定期的にこのルールに照らして、リソースの設定の評価を行うことができる。

また、この設定項目は、S3バケット もしくは Amazon SNS に配信することができる。SNSへ配信時のメッセージタイプは以下の通り。

メッセージタイプ 内容
ComplianceChangeNotification コンプライアンスタイプの変更時
ConfigRulesEvaluationStarted リソースの評価開始時
ConfigurationSnapshotDeliveryStarted スナップショット配信開始時
ConfigurationSnapshotDeliveryCompleted スナップショット配信完了時
ConfigurationSnapshotDeliveryFailed スナップショット配信失敗時
ConfigurationHistoryDeliveryCompleted 設定履歴配信完了時
ConfigurationItemChangeNotification リソース変更時
OversizedConfigurationItemChangeNotification SNSの最大サイズ超過時

AWS Configのセットアップ

AWS ConfigはCloudFormationに対応しているため、CloudFormation経由でConfigをセットアップすることができる。

サービスロールの有効化

以下のサービスロールを有効化することで、AWSリソースの読み込み権限 および S3への書き込み権限Config に、IAMとSystemManagerへの書き込み権限Config Remediation にそれぞれ付与する。

Resources:
  ServiceLinkedRoleForConfig:
    Type: AWS::IAM::ServiceLinkedRole
    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
    DeletionPolicy: Retain
    Properties: 
      AWSServiceName: remediation.config.amazonaws.com 
      Description: A service-linked role required for AWS Config Remediation to access your resources.

Configの有効化

DeliveryChannelConfigurationRecorder を作成する。

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

すでにAWS Configをセットアップ済みの状態で上記テンプレートを実行すると、 the maximum number of delivery channels エラーが発生する。その場合は既存の DeliveryChannel を削除した上で、上記テンプレートを再度実行する。

aws configservice delete-delivery-channel --delivery-channel-name default
aws configservice delete-configuration-recorder --configuration-recorder-name default

S3バケットの作成

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

Resources:
  S3ForConfig:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      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

CloudFormation Launch Stack URL

以下のボタンから上のCloudFormationテンプレートを実行することが可能である。ソースコードは、aws-cloudformation-templates/security – GitHub にて公開。

作成されるAWSサービス CloudFormationテンプレート
セキュリティサービス全般 cloudformation-launch-stack
Configのみ cloudformation-launch-stack

モニタリング

他のAWSサービスを利用して、AWS Configのリソースをモニタリングすることができる。例えば、Amazon SQSAmazon CloudWatch Eventsを利用することで、AWSリソースが作成、変更、削除された際に通知を受け取ることが可能となる。

AWS Security Hub(1)Security Hubの概要

Security Hubとは

Security Hubは、Amazon GuardDutyAmazon InspectorAmazon Macie などのAWSが提供するセキュリティ関連サービスや、AWSパートナーが提供するセキュリティ製品からの セキュリティ検出結果等を統合的に閲覧可能なサービス で、本サービスを利用することで、情報の収集や優先度の決定などのコストを低減できる。発見事項は、Security Hub内に90日保管 される。Security Hubは、リージョンサービスであり、使用するリージョン毎にサービスを有効化する必要 がある。一方で、 複数アカウントをサポート しており、全てのアカウントを統合して発見事項を表示することもできる。

また、Center for Internet Security (CIS) AWS Foundations Benchmark のスコア表示にも対応しており、業界標準のベストプラクティスをどの程度満たしているかについても確認することが可能となっている。なお、この機能を正常に実行するためには、AWS Configを有効化することが必要。ベストプラクティスを満たしていない場合は、Security Hubから修復方法を確認することができる。

Amazon CloudWatch Eventsとの統合がサポートされているため、検出結果を受信した際に実行するカスタムアクションを規定することもできる。

また、インサイトと呼ばれるグループ化された検出結果のコレクションが存在し、コレクションを用いることで、修復が必要な問題の特定ができる。カスタムインサイトを作成することも可能。

AWS Security Hub のセットアップ

一部機能のみではあるがCloudFormationに対応しているため、CloudFormation経由でSecurity Hubをセットアップすることができる。

サービスロールの有効化

以下のサービスロールを有効化することで、AWS CloudTrail, AWS Config, Amazon CloudWatch Logs および Amazon SNS から 情報を取得する権限 を Security Hub 付与する。また、AWS Config に対して 新たなConfigルールを設定する権限 も付与される。このルールは、CIS AWS Foundationsコンプライアンスチェックに使用される。これらを正常に動作させるためには、 AWS Configを有効化 しておく必要がある。

Resources:
  ServiceLinkedRoleForSecurityHub:
    Type: AWS::IAM::ServiceLinkedRole
    DeletionPolicy: Retain
    Properties: 
      AWSServiceName: securityhub.amazonaws.com
      Description: A service-linked role required for AWS Security Hub to access your resources.

Security Hubの有効化

Security Hubを有効化することで、CIS AWS Foundationsコンプライアンスチェックが自動で有効化される。

Resources:
  SecurityHub:
    DependsOn:
      - ServiceLinkedRoleForSecurityHub
    Type: AWS::SecurityHub::Hub

AWS Security Hubのセットアップテンプレート

AWS Security Hubを含むAWSのセキュリティサービスをまとめて有効化できるCloudFormationテンプレートを公開している。

作成されるAWSサービス CloudFormationテンプレート
セキュリティサービス全般 cloudformation-launch-stack
Security Hub のみ cloudformation-launch-stack

CIS AWS Foundationsコンプライアンスチェック

Security Hubは、AWS Configに新たなConfigルールを自動的に作成した上で、Center for Internet Security (CIS) AWS Foundations Benchmarkに適合しているかのチェックを行う。Security Hubは、AWS Security Finding と呼ばれるテンプレートに沿って検出結果を表示するために、結果毎にデータ変換等を行う必要がない。AWS Security Finding の構成については、下記を参照のこと。

なお、CIS AWS Foundationsは、同一リージョン内のリソースに対しての結果のみ有効であり、他のリージョンのリソースに対しての結果は FAILED が返却される。したがって、例えば複数のリージョンでCloudTrailが有効化されており、各リージョンで証跡用およびアクセスログ用のバケットが作成されている場合は、チェック 2.3 および 2.6は非準拠として表示される

チェックは、前回から12時間以内に再度実行 される。また、変更によってトリガーされるチェックに関しては、リソースに変更が変更された際に実行される。

AWSサービスとの統合

Security Hubは、Amazon GuardDutyAmazon InspectorAmazon Macie など、AWSが提供するセキュリティ関連サービスで生成されたセキュリティ検索結果を統合することができる。統合を行うためには、各AWSサービスを有効化する必要がある。

CloudWatchイベントによる自動化

CloudWatchイベントを使用して、Security Hubで検知した問題やリソースの変更に自動的に対応することが可能である。以下の通知を行うことが可能である。

  1. 全ての結果を自動的にCloudWatchイベントに送信
  2. カスタムアクションに関連づけられた結果をCloudWatchイベントに送信
  3. カスタムアクションを使用してインサイトの結果をCloudWatchイベントに送信

1.の場合は、CIS AWS Foundationsコンプライアンスチェックに準拠している状態でも非準拠の場合でも、全ての結果が CloudWatch Events に送信されてしまうので、そのうち 準拠から非準拠となった状態のイベントのみを受信して、Amazon SNS に送信する場合は、以下のような Amazon CloudWatch Events を作成する。

  CloudWatchEventsForSecurityHub:
    Type: AWS::Events::Rule
    Properties: 
      Description: CloudWatch Events about SecurityHub.
      EventPattern:
        source:
          - aws.securityhub
        detail-type: 
          - Security Hub Findings - Imported
        # Events fired when status has been changed from PASSED to ARCHIVED.
        detail:
          findings:
            Compliance:
              Status:
                - PASSED
            RecordState:
              - ARCHIVED
      Name: AWS_Security_Hub
      State: ENABLED
      Targets:
        - Arn: !Ref SnsTopicARN
          Id: CloudWatchEventsForSecurityHub

これは、結果のステータスが PASSED から FAILED に変化した場合、

  1. 既存の結果のステータスを PASSED から ARCHIVED に設定
  2. 結果のステータスが FAILE である新たな結果を生成

という挙動となるため、1.の挙動のみを検知することで実現している。

CloudFormation Launch Stack URL

以下のボタンから上のCloudFormationテンプレートを実行することが可能である。ソースコードは、aws-cloudformation-templates/security – GitHub にて公開。

作成されるAWSサービス CloudFormationテンプレート
セキュリティサービス全般 cloudformation-launch-stack
Security Hub のみ cloudformation-launch-stack

AWS Amplify Framework(3)Authenticationカテゴリ

Authenticationカテゴリ

Authenticationカテゴリは、認証(AuthN)と認可(AuthZ)の機能を提供する。AWS Cognito ユーザプール を介して、FacebookやGoogleなどのOpenIDプロバイダーの情報を含むユーザ情報を格納し、ユーザの認証を行う。また、AWS Cognito Federated Identitiesを介して、例えば、S3へのファイルアップロードできる権限を付与するなど、AWSリソースに対しての認可の機能も提供する。AWS CLIは、アクセス制御ポリシーの自動化と、GraphQLを用いたきめ細やかなアクセス制御機能を提供する。

シンプルな認証では、AWS Cognito ユーザプール を通してユーザの認証のみを行い、この認証に通れば、(ログイン)アプリが利用するAWSリソースと通信が可能となる。一方で、ユーザ別にコンテンツを出し分ける必要がある場合などには、そのユーザに関連するAWSリソースのみにアクセス権限を付与しなければならない。この場合は、AWS Cognito Federated Identitiesを通して、そのユーザに必要な権限のみを許可された、AWS Credentialがやりとりされる。

セットアップ

Amplifyプロジェクトのルートディレクトリでamplify add authコマンドを実行することで、ウィザードに従って自動セットアップを行うことができる。

設定内容の例はこちら。

設定項目 内容
リソース名 myproject
User Pool名 myproject
Sign-Inに使用する属性 Email
MFA 無効
ユーザ登録等にEメールを使用 有効
認証メールのタイトル MyProject から 認証コード をお送りします
認証メールの本文 あなたの認証コードは {####} です。
Sign-Up時に必須の属性 Email, Name
Tokenの有効期間 30日
アクセスできるユーザ属性の限定 なし
その他の機能 ホワイトリストによるEmailドメインのフィルタ
OAuthの使用 なし
Lambda Triggers Pre Sign-up
ホワイトリストに指定するドメイン surbiton.jp

上の内容を設定するために、以下のような対話式ウィザードによって必要事項を埋めていく。

$ amplify add auth

 Do you want to use the default authentication and security configuration? Manual configuration
 Select the authentication/authorization services that you want to use: User Sign-Up & Sign-In only (Best used with a cloud API only)
 Please provide a friendly name for your resource that will be used to label this category in the project: myproject
 Please provide a name for your user pool: myproject
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Email
 Multifactor authentication (MFA) user login options: OFF
 Email based user registration/forgot password: Enabled (Requires per-user email entry at registration)
 Please specify an email verification subject: MyProject から 認証コード をお送りします
 Please specify an email verification message: あなたの認証コードは {####} です。
 Do you want to override the default password policy for this User Pool? No
 Warning: you will not be able to edit these selections. 
 What attributes are required for signing up? Email, Name
 Specify the app's refresh token expiration period (in days): 30
 Do you want to specify the user attributes this app can read and write? No
 Do you want to enable any of the following capabilities? Email Domain Filtering (whitelist)
 Do you want to use an OAuth flow? No
 Do you want to configure Lambda Triggers for Cognito? Yes
 Which triggers do you want to enable for Cognito (Press <space> to select, <a> to toggle all, <i> to invert selection)Pre Sign-up
 What functionality do you want to use for Pre Sign-up (Press <space> to select, <a> to toggle all, <i> to invert selection)Sign-Up email filtering (whitelist)
 Enter a comma-delimited list of allowed email domains (example: 'mydomain.com, myotherdomain.com'). surbiton.jp
Succesfully added the Lambda function locally
 Press enter to continue 
Successfully added resource myproject locally

Lambdaトリガー

Amplify CLIを用いることで、ホワイトリスト内のユーザのみに新規登録を認める処理を加えるなど、AWS Cognito ユーザプール のトリガに対応したLambdaを設定することができる。

Vue Components

Authカテゴリに関連して使用できるVueのUI Componentsは以下の通り。

Components 内容
<amplify-authenticator></amplify-authenticator> 認証全般
<amplify-sign-in></amplify-sign-in> Sign-In
<amplify-confirm-sign-in></amplify-confirm-sign-in> Sign-Inの確認
<amplify-sign-up></amplify-sign-up> Sign-Up
<amplify-forgot-password></amplify-forgot-password> パスワード忘れ時
<amplify-sign-out></amplify-sign-out> Sign-Out
<amplify-set-mfa></amplify-set-mfa> MFAの設定

認証画面の例

認証カテゴリを組み込んだログイン画面の実装例は以下の通り。

<template> ブロック

認証コンポーネント の詳細は、Authentication Components を参照。

<template>
  <div id="authenticator">
    <div v-if="signInStatus === 'signedOut'">
      <!-- 認証全般のコンポーネント -->
      <amplify-authenticator v-bind:authConfig="authConfig"></amplify-authenticator>
    </div>
  </div>
</template>

<script> ブロック

currentauthenticateduserメソッド の詳細は、 Amplify JavaScript library – Auth Class を参照。

<script>
// aws-amplify ライブラリの Auth カテゴリをインポート
import { Auth } from 'aws-amplify'
// aws-amplify-vue ライブラリの AmplifyEventBus カテゴリをインポート (イベントの発行とリッスン)
import { AmplifyEventBus } from 'aws-amplify-vue'

export default {
  name: 'Authenticator',
  components: {},
  // Vue - Amplify Plugin - Authentication Components
  // https://aws-amplify.github.io/docs/js/vue#authentication-components
  data: function() {
    return {
      signInStatus: 'signedOut',
      authConfig: {
        // Eメールによるサインイン
        usernameAttributes: 'Email',
        signUpConfig: {
          // サインアップ時の項目を一旦全て非表示にする
          hideAllDefaults: true,
          // サインアップ時の項目
          signUpFields: [
            {
              label: 'Email',
              key: 'email',
              required: true,
              displayOrder: 1,
              type: 'string',
              signUpWith: true
            },
            {
              label: 'Name',
              key: 'name',
              required: true,
              displayOrder: 2,
              type: 'string'
            },
            {
              label: 'Password',
              key: 'password',
              required: true,
              displayOrder: 3,
              type: 'password'
            },
          ]
        }
      }
    }
  },
  async beforeCreate() {
    try {
      // Amplify JavaScript library - Auth Class
      // https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#currentauthenticateduser
      // ログインステータスの取得
      await Auth.currentAuthenticatedUser()
      this.signInStatus = 'signedIn'
    } catch (err) {
      this.signInStatus = 'signedOut'
    }
    // Vue - Amplify Plugin - AmplifyEventBus
    // authStateイベント のリッスン
    // https://aws-amplify.github.io/docs/js/vue#amplifyeventbus
    AmplifyEventBus.$on('authState', info => {
      switch (info) {
        case 'signedIn':
          this.signInStatus = 'signedIn'
          break
        default:
          this.signInStatus = 'signedOut'
          break
      }
    });
  }
}

<style> ブロック

<style>
  #authenticator {
    margin: auto;
    width: 460px;
  }
</style>

それ以外の画面に認証処理を追加する例

未認証のユーザにはページを表示させないように、ログイン後に表示される画面に認証処理を追加する例はこちら。

<script> ブロック

beforeCreate() でログイン状態を取得する。

<script>
export default { 
  name: 'UserTable', 
  // 使用するコンポーネント 
  components: {}, 
  // データ 
  data () { 
    // 必ず初期値が必要 
    return { 
      signInStatus: 'signedOut'
    } 
  },
  async beforeCreate() { 
    try { 
      // Amplify JavaScript library - Auth Class
      // https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#currentauthenticateduser
      // ログインステータスの取得
      await Auth.currentAuthenticatedUser() 
      this.signInStatus = 'signedIn' 
    } catch (err) { 
      this.signInStatus = 'signedOut' 
    } 
    AmplifyEventBus.$on('authState', info => { 
      switch (info) { 
        case 'signedIn': 
          this.signInStatus = 'signedIn' 
          break 
        default: 
          this.signInStatus = 'signedOut' 
          break 
      } 
    }); 
  }
}
</script>

ローカライズ

標準の認証コンポーネントは、全て英語でメッセージが表示される。これらを 日本語対応 するためには、Amplifyの I18n カテゴリを使用して、main.js に以下の内容を追記する必要がある。

// 多言語対応
let languageDict = {
  ja:{
      // タイトル
      'Sign in to your account' : 'サインイン',
      'Create a new account': 'アカウントの新規作成',
      'Reset your password': 'パスワードをリセット',
      'Confirm Sign Up': 'メールアドレスの認証',
      // 入力項目
      'Username' : '会社のメールアドレス',
      'Email' : '会社のメールアドレス',
      'Enter your Email' : 'メールアドレスを入力してください',
      'Name' : '名前',
      'Password' : 'パスワード',
      'Enter your password' : 'パスワードを入力してください',
      'Code': '認証コード',
      'New Password': '新しいパスワード',
      'Confirmation Code': '認証コード',
      // 注釈
      'Forget your password? ' : 'パスワードを忘れた場合は ',
      'No account? ' : 'アカウントの作成は ',
      'Have an account? ': 'サインインは ', 
      'Lost your code? ': 'メールアドレスに認証コードが届きませんか? ', 
      // ボタン
      'Back to Sign In': 'サインイン',
      'Resend Code': '認証コードを再送信する',
      'Reset password' : 'パスワードを再設定',
      'Sign in' : 'こちら',
      'Sign In' : 'サインイン',
      'Sign Out' : 'サインアウト',
      'Create account' : 'こちら',
      'Create Account' : 'アカウントを作成',
      'Send Code': '次へ進む',
      'Submit': '送信',
      'Confirm': '登録完了',
      // エラーコード
      'Username cannot be empty': 'メールアドレスを入力してください',
      'null failed with error Generate callenges lambda cannot be called..': 'パスワードを入力してください',
      'Incorrect username or password.': 'メールアドレス もしくは パスワードが正しくありません',
      'Username/client id combination not found.': 'メールアドレスが正しくありません',
      'Invalid verification code provided, please try again.': '認証コードが正しくありません',
      'Password reset required for the user': 'パスワードを再設定してください'
  }
}
AmplifyModules.I18n.putVocabularies(languageDict)

AWS Connect(1)AWS Connectの概要

AWS Connectとは

AWS Connectとはクラウド型コンタクトセンターで、Amazonのコンタクトセンターと同じ技術が使われている。グラフィカルインタフェースを用いることでコーディングすることなく、対応フローの設計、スタッフの管理などが簡単に実現できる。

インフラの管理が不要で手軽に規模を拡大縮小できる。また、Amazon Lexとの連携によって自動応答を実現したり、CRMソリューションと連携して顧客情報の管理を行うこともできる。また、アウトバンドコンタクトAPIを用いて、スケジュールした時刻にプログラムから電話を発信することも可能である。

サポートされているブラウザは、最新3バージョンChrome最新Firefox。東京リージョンに対応し日本語にも対応している。