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 パスワードポリシーへと、自動で修復することができた。