アクセスキーの適切な管理
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
に非準拠のアクセスキーを削除することができた。