🐷
特定 CloudTrail イベント発生時 Lambda を実行
ゴール / やりたいこと
CloudTrail で 特定イベントがあった場合に Lambda を実行する
※今回は作成/更新されたポリシー内でリソース * に対してアクションが Allow とされているかのチェック
アーキテクチャ図
詳細
監視している CloudTrail で CloudWatch Logs へのログ保存を有効にする
CloudWatch Logs で Lambda をターゲットとしたサブスクリプションフィルターを作成する
ターゲットにする Lambda を指定して Filter 設定をする
※Log format は CloudTrail にして Filter 対象はイベント名がCreatePolicyまたはPutRolePolicy
Lambda コード詳細
import base64, json
def lambda_handler(event, context):
print(event)
# CloudWatchLogsからのデータはbase64エンコードされているのでデコード
decoded_data = base64.b64decode(event['awslogs']['data'])
# バイナリに圧縮されているため展開
json_data = json.loads(gzip.decompress(decoded_data))
# CloudWatch Logsに複合&解凍したログを出力
print("--- Base Log ---")
BaseLog = json_data["logEvents"][0]["message"]
print(BaseLog)
CustomLog = json.loads(BaseLog)
print("--- Customize Log ---")
User = CustomLog["userIdentity"]["arn"]
PolicyName = CustomLog["requestParameters"]["policyName"]
print("User: " + User)
print("Policy Name: " + PolicyName)
eventname = CustomLog["eventName"]
Username = User.split("/")[2]
print(Username)
URLorigin = "https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/policies/"
URLPOLICY = CustomLog["responseElements"]["policy"]["arn"]
doc = json.loads(CustomLog["requestParameters"]["policyDocument"])
Document = str(doc["Statement"])
for i in range(len(doc["Statement"])):
Resource = doc["Statement"][i]["Resource"]
Effect = doc["Statement"][i]["Effect"]
print(i)
print("Policy Document: " + Document)
print("Resource Parameter: " + Resource)
if "*" == Resource and "Allow" == Effect:
print(PolicyName)
print(eventname)
post_msg = "イベント名: "+ eventname + "\r \nポリシー名: "+ PolicyName + "\r \nユーザー名:" + Username + "\r \n注意: フルアクセス権限のままのポリシーがあります"+"\r \n please see the URL : " + URLorigin + URLPOLICY
title = "フルアクセスイベント検知"
seeURL = "plese see the URL : " + URLorigin+URLPOLICY
CloudWatch Logs から送られるイベントの内容
送られる実データ
{
"awslogs": {
"data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwWQRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpLwivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQDQiMdxRQEAAA=="
}
}
["awslogs"]["data"] を base64 ででコードしたもの
{
"messageType": "DATA_MESSAGE",
"owner": "xxx",
"logGroup": "aws-cloudtrail-logs-xxx",
"logStream": "xxx_CloudTrail_ap-northeast-1_3",
"subscriptionFilters": [
"test" # サブスクリプションフィルター名
],
"logEvents": [
{
"id": "37408450509333532446236020242338017431792257269505589323",
"timestamp": 1677452936048,
"message": "~~~" # 以下 CloudTrail のログが含まれる
}
]
}
CloudTrail のログ
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "xxx",
"arn": "arn:aws:sts::xxx:assumed-role/xxx/xxx",
"accountId": "xxx",
"accessKeyId": "xxx",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "xxx",
"arn": "arn:aws:iam::xxx:role/xxx",
"accountId": "xxx",
"userName": "xxx"
},
"webIdFederationData": {},
"attributes": {
"creationDate": "2023-02-26T04:46:10Z",
"mfaAuthenticated": "false"
}
}
},
"eventTime": "2023-02-26T06:26:27Z",
"eventSource": "iam.amazonaws.com",
"eventName": "CreatePolicy",
"awsRegion": "us-east-1",
"sourceIPAddress": "x.x.x.x",
"userAgent": "AWS Internal",
"requestParameters": {
"policyName": "test",
"policyDocument": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"VisualEditor0\",\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:*\",\n \"Resource\": \"*\"\n }\n ]\n}",
"tags": [
{
"key": "xxx",
"value": "xxx"
}
]
},
"responseElements": {
"policy": {
"policyName": "test",
"policyId": "xxx",
"arn": "arn:aws:iam::xxx:policy/test",
"path": "/",
"defaultVersionId": "v1",
"attachmentCount": 0,
"permissionsBoundaryUsageCount": 0,
"isAttachable": true,
"createDate": "Feb 26, 2023 6:26:27 AM",
"updateDate": "Feb 26, 2023 6:26:27 AM",
"tags": [
{
"key": "xxx",
"value": "xxx"
}
]
}
},
"requestID": "4aa1660e-f5c4-45b0-9e6f-2c62869e9013",
"eventID": "9b2ea1bc-28e8-4e24-9371-eede765a5df0",
"readOnly": false,
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "333053306512",
"eventCategory": "Management",
"sessionCredentialFromConsole": "true"
}
Logs Insights
CloudWatch Logs に対して簡単な Filter でクエリできて整形して表示してくれる
めちゃくちゃ便利だった
Discussion