アクセスキーの適切な管理
CIS AWS Foundations Benchmark というセキュリティガイドラインが公開されており、このガイドラインは、AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定を集めたベストプラクティス集として活用できる。
この CIS AWS Foundations Benchmark
では、アクセスキーの取り扱いについて以下のように定めている。
- 1.3 90 日間以上使用されていない認証情報は無効にします
- 1.4 アクセスキーは 90 日ごとに更新します
この CIS AWS Foundations Benchmark
に 準拠していないアクセスキー を CloudWatch Events
と Lambda
を用いて 自動削除 するために以下の設定を行う。
- 上記のポリシーに準拠しているか
AWS Config
を用いて定期的にチェックを行う - 非準拠であった場合には、
CloudWatch Events
がLambda
を自動起動する 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
に非準拠のアクセスキーを削除することができた。