この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
aws-controltower-AuditAdministratorRole という Lambda 実行ロールが AWS Control Towerの 監査(Audit) アカウントには用意されています。 このロールを使って メンバーアカウントへアクセスできます(つまりクロスアカウントアクセス)。 主にセキュリティ周りの対応(修復) を行うためのものです。
- ※1: Assume Role 先のロール名は
aws-controltower-AdministratorExecutionRole
- ※2: 読み取り専用(ReadOnly)用の Lambda 実行ロールも準備されています
(
aws-controltower-AuditReadOnlyRole
)
今回は aws-controltower-AuditAdministratorRole
を使ってみます。
「メンバーアカウントへのアクセス基盤」作成として、最小限の実装を行ってみました。
作ったもの
メンバーアカウント先で sts:GetCallerIdentity を実行するだけ の 「何もしない (接続確認だけする) Lambda関数」 を作ります。
Lambda関数 基本設定
下図のような設定の Lambda関数です。 ランタイムとしては Python 3.8 を使っています。
実行ロールに aws-controltower-AuditAdministratorRole
を指定しています。
Lambda関数 コード
以下のようなコードを作成しています。
src/check_assume_role/app.py
import boto3
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def _sts_client(target_account_id):
logger.info('[START] _sts_client')
sts_connection = boto3.client('sts')
try:
# Assume Role
role_arn = "arn:aws:iam::%s:role/aws-controltower-AdministratorExecutionRole" % target_account_id
role_session_name = "CROSS_ACCOUNT_ACCESS_FROM_CTAUDIT"
logger.info("- RoleArn=%s" % role_arn)
logger.info("- RoleSessionName=%s" % role_session_name)
target = sts_connection.assume_role(
RoleArn=role_arn,
RoleSessionName=role_session_name,
)
except Exception as e:
logger.error(e)
exit()
else:
client = boto3.client(
'sts',
aws_access_key_id=target['Credentials']['AccessKeyId'],
aws_secret_access_key=target['Credentials']['SecretAccessKey'],
aws_session_token=target['Credentials']['SessionToken']
)
logger.info('[END] _sts_client')
return client
def check(sts_client):
logger.info('[START] check')
try:
resp = sts_client.get_caller_identity()
logger.info("- Account=%s" % resp['Account'])
logger.info("- Arn=%s" % resp['Arn'])
except Exception as e:
logger.error(e)
exit()
else:
logger.info('[END] check')
return {"status": "success"}
def lambda_handler(event, context):
logger.info('[START] lambda_handler')
# Get Client
sts_client = _sts_client(event['TargetAccountId'])
# Run remediation(check)
logger.info('# running check')
results = check(sts_client)
# End
logger.info('[END] lambda_handler')
return results
メンバーアカウントのアカウントIDを入力イベントに登録する想定です。
{ "TargetAccountId": "123456789012" }
のような入力イベントです。
(補足) SAMで作成
これらのリソース、設定を AWS SAM(Serverless Application Model) で展開しています。
template.yaml
は以下のとおりです。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: python3.8
Timeout: 600
Handler: app.lambda_handler
Architectures:
- arm64
Parameters:
Project:
Type: String
Default: "audit-remediation"
Resources:
CheckFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "${Project}-check-assume-role"
Role: !Sub "arn:aws:iam::${AWS::AccountId}:role/aws-controltower-AuditAdministratorRole"
CodeUri: src/check_assume_role
Outputs:
CheckFunction:
Description: "Check Function ARN"
Value: !GetAtt CheckFunction.Arn
確認
Lambda 関数の実行
以下のようなテストイベント { "TargetAccountId": "123456789012" }
を作成して、実行します。
成功しました。以下のような出力としています。
各種ログの確認
### CloudWatch Logs の確認 at 監査アカウント
/aws/lambda/${関数名}
ロググループに実行ログが保存されます。
### CloudTrail の確認 at 監査アカウント
メンバーアカウントへ Assume Role していることが CloudTrail イベントから確認できました。
### CloudTrail の確認 at メンバーアカウント
メンバーアカウント上で API実行(GetCallerIdentity) できていることを CloudTrail イベントから確認できました。
以下 イベントレコードの userIdentity
抜粋です。
おわりに
AWS Control Tower に用意されている aws-controltower-AuditAdministratorRole
を使ったクロスアカウントアクセスを試してみました。
EventBridge や Step Functions と組み合わせることで、 「セキュリティリスクのあるリソースの自動修復」など 日々のセキュリティ運用に活用できそうです。