Amazon Inspector と Lambda の連携を IaC 化
やりたいこと
この環境を見かけたので Lambda コード部分以外を IaC (AWS CloudFormation) で実装
謝辞
Lambda のコードについては言及してないです。
具体的な Cloud One の仕様の話になってしまうので今回このブログでは記載していないです。
成果物
今回は Amazon Inspector のパターンでの実装になっています。
その他にする場合、EventBridge ルールの箇所を GuardDuty や Security Hub にすることでほかのパターンもできると思います。
以下のテンプレートをデプロイすることで一発完成です。
詳細は後述します。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
EventBridgeRuleName:
Type: String
Default: inspector-finding
NotifySeverities:
Type: CommaDelimitedList
Default: HIGH, CRITICAL
Resources:
C1WSSetupLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
Path: /
C1WSSetupLambda:
Type: AWS::Lambda::Function
Properties:
Handler: index.lambda_handler
MemorySize: 128
Runtime: python3.9
Timeout: 60
Role: !GetAtt C1WSSetupLambdaRole.Arn
Layers:
- Fn::Join:
- ""
- - "arn:aws:lambda:"
- !Ref AWS::Region
- ":770693421928:layer:Klayers-p39-requests:10"
Code:
ZipFile: |
import json, os, requests
def lambda_handler(event, context):
instance_ids = event['resources']
cve_number = event['detail']['title']
# 実際に行う処理
EventBridgeRule:
Type: AWS::Events::Rule
Properties:
Name: !Ref EventBridgeRuleName
EventPattern:
source: ["aws.inspector2"]
detail-type: ["Inspector2 Finding"]
detail:
status: ["ACTIVE"]
severity: !Ref NotifySeverities
Targets:
- Arn: !GetAtt C1WSSetupLambda.Arn
Id: lambda
InspectorEvent:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt C1WSSetupLambda.Arn
Principal: events.amazonaws.com
SourceArn: !GetAtt EventBridgeRule.Arn
内容について
テンプレートの中身について軽くコメントします。
Parameters:
EventBridgeRuleName:
Type: String
Default: inspector-finding
NotifySeverities:
Type: CommaDelimitedList
Default: HIGH, CRITICAL
Lambda をキックする脆弱性の重要度を選択します
Amazon Inspector のスコアと重要度ラベルの関係
- INFORMATIONAL: 0
- LOW : 0.1 - 3.9
- MEDIUM: 4.0 - 6.9
- HIGH: 7.0 - 8.9
- CRITICAL: 9.0 - 10.0
C1WSSetupLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- Fn::Join:
- ""
- - "arn:"
- Ref: AWS::Partition
- ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
Path: /
C1WSSetupLambda:
Type: AWS::Lambda::Function
Properties:
Handler: index.lambda_handler
MemorySize: 128
Runtime: python3.9
Timeout: 60
Role: !GetAtt C1WSSetupLambdaRole.Arn
Layers:
- Fn::Join:
- ""
- - "arn:aws:lambda:"
- !Ref AWS::Region
- ":770693421928:layer:Klayers-p39-requests:10"
IAM ロールの作成、および Lambda の作成です。
Lambda レイヤーは以下の有志の方のをお借りしました。
EventBridgeRule:
Type: AWS::Events::Rule
Properties:
Name: !Ref EventBridgeRuleName
EventPattern:
source: ["aws.inspector2"]
detail-type: ["Inspector2 Finding"]
detail:
status: ["ACTIVE"]
severity: !Ref NotifySeverities
Targets:
- Arn: !GetAtt C1WSSetupLambda.Arn
Id: lambda
EventBridge の設定
ターゲットは作成した Lambda
起動ルールは Amazon Inspector の Finding
InspectorEvent:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt C1WSSetupLambda.Arn
Principal: events.amazonaws.com
SourceArn: !GetAtt EventBridgeRule.Arn
Lambda に対して EventBridge が実行することを許可する設定
はまった個所
EventBridge から Lambda を実行するときはリソースベースポリシーで許可が必要!(コンソール上からの設定を除く)
これを忘れてずっと待ってたけど一向に実行ログが出なかったため EventBridge 側のメトリクスを見たら大量のFailedInvocationsが出力されていたため検索。。。
EventBridgeではLambdaを実行させるときに別途権限の付与が必要とのこと
※Permissionがないと以下のようにLambdaコンソールに存在していない
Amazon Inspector (EventBridge) からもらう内容
eventの中に含まれています
{
"version": "0",
"id": "22ac7f76-c252-fa8f-98e3-f81d657c5574",
"detail-type": "Inspector2 Finding",
"source": "aws.inspector2",
"account": "xxx",
"time": "2023-02-25T04:12:24Z",
"region": "ap-northeast-1",
"resources": [
"i-xxx"
],
"detail": {
"awsAccountId": "xxx",
"description": "Windows Common Log File System Driver Elevation of Privilege Vulnerability",
"findingArn": "arn:aws:inspector2:ap-northeast-1:xxx:finding/70bdf77b670c4de97568f3c9db380e3f",
"firstObservedAt": "Feb 25, 2023, 4:12:24 AM",
"fixAvailable": "YES",
"inspectorScore": 7.8,
"inspectorScoreDetails": {
"adjustedCvss": {
"adjustments": [],
"cvssSource": "WINDOWS_SERVER_2016",
"score": 7.8,
"scoreSource": "WINDOWS_SERVER_2016",
"scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C",
"version": "3.1"
}
},
"lastObservedAt": "Feb 25, 2023, 4:12:24 AM",
"packageVulnerabilityDetails": {
"cvss": [
{
"baseScore": 7.8,
"scoringVector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C",
"source": "WINDOWS_SERVER_2016",
"version": "3.1"
}
],
"referenceUrls": [
"https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-23376",
"https://catalog.update.microsoft.com/v7/site/Search.aspx?q=KB5022838"
],
"relatedVulnerabilities": [],
"source": "WINDOWS_SERVER_2016",
"sourceUrl": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-23376",
"vendorCreatedAt": "Feb 14, 2023, 8:00:00 AM",
"vendorSeverity": "N/A",
"vulnerabilityId": "CVE-2023-23376"
},
"remediation": {
"recommendation": {
"text": "See References"
}
},
"resources": [
{
"details": {
"awsEc2Instance": {
"iamInstanceProfileArn": "arn:aws:iam::xxx:instance-profile/xxx",
"imageId": "ami-xxx",
"ipV4Addresses": [
"x.x.x.x",
"x.x.x.x" # パブリックIPアドレスもここに表示される
],
"ipV6Addresses": [],
"keyName": "xxx_pem",
"launchedAt": "Feb 25, 2023, 4:02:56 AM",
"platform": "WINDOWS_SERVER_2016",
"subnetId": "subnet-xxx",
"type": "t2.medium",
"vpcId": "vpc-xxx"
}
},
"id": "i-xxx",
"partition": "aws",
"region": "ap-northeast-1",
"tags": {
"Name": "xxx"
},
"type": "AWS_EC2_INSTANCE"
}
],
"severity": "HIGH",
"status": "ACTIVE",
"title": "CVE-2023-23376",
"type": "PACKAGE_VULNERABILITY",
"updatedAt": "Feb 25, 2023, 4:12:24 AM"
}
}
最後に
簡単にですが久しぶりに CloudFormation テンプレートを書くのも楽しいですね。
Discussion