Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deployment/build_packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
PACKAGES_DIR="${SCRIPT_PATH}/packages/"
LIBRARY="${SCRIPT_PATH}/../hammer/library"

LAMBDAS="ami-info logs-forwarder ddb-tables-backup sg-issues-identification s3-acl-issues-identification s3-policy-issues-identification iam-keyrotation-issues-identification iam-user-inactive-keys-identification cloudtrails-issues-identification ebs-unencrypted-volume-identification ebs-public-snapshots-identification rds-public-snapshots-identification sqs-public-policy-identification s3-unencrypted-bucket-issues-identification rds-unencrypted-instance-identification ami-public-access-issues-identification api"
LAMBDAS="ami-info logs-forwarder ddb-tables-backup sg-issues-identification s3-acl-issues-identification s3-policy-issues-identification iam-keyrotation-issues-identification iam-user-inactive-keys-identification cloudtrails-issues-identification ebs-unencrypted-volume-identification ebs-public-snapshots-identification rds-public-snapshots-identification sqs-public-policy-identification s3-unencrypted-bucket-issues-identification rds-unencrypted-instance-identification kms-keyrotation-issues-identification ami-public-access-issues-identification api"

pushd "${SCRIPT_PATH}" > /dev/null
pushd ../hammer/identification/lambdas > /dev/null
Expand Down
32 changes: 32 additions & 0 deletions deployment/cf-templates/ddb.json
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,38 @@
"TableName": {"Fn::Join" : ["", [ { "Ref": "ResourcesPrefix" }, "rds-unencrypted" ] ]}
}
},
"DynamoDBKMSKeyRotation": {
"Type": "AWS::DynamoDB::Table",
"DeletionPolicy": "Retain",
"DependsOn": ["DynamoDBCredentials"],
"Properties": {
"AttributeDefinitions": [
{
"AttributeName": "account_id",
"AttributeType": "S"
},
{
"AttributeName": "issue_id",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "account_id",
"KeyType": "HASH"
},
{
"AttributeName": "issue_id",
"KeyType": "RANGE"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": "10",
"WriteCapacityUnits": "2"
},
"TableName": {"Fn::Join" : ["", [ { "Ref": "ResourcesPrefix" }, "kms-key-rotation" ] ]}
}
},
"DynamoDBAMIPublicAccess": {
"Type": "AWS::DynamoDB::Table",
"DeletionPolicy": "Retain",
Expand Down
11 changes: 11 additions & 0 deletions deployment/cf-templates/identification-crossaccount-role.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@
],
"Resource": "*"
},
{
"Action": [
"kms:ListKeys",
"kms:GetKeyRotationStatus",
"kms:DescribeKey",
"kms:ListResourceTags"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "KmsIssues"
},
{
"Sid": "CloudTrailIssues",
"Effect": "Allow",
Expand Down
11 changes: 11 additions & 0 deletions deployment/cf-templates/identification-role.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@
],
"Resource": "*"
},
{
"Action": [
"kms:ListKeys",
"kms:GetKeyRotationStatus",
"kms:DescribeKey",
"kms:ListResourceTags"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "KmsIssues"
},
{
"Sid": "CloudTrailIssues",
"Effect": "Allow",
Expand Down
223 changes: 222 additions & 1 deletion deployment/cf-templates/identification.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"SourceIdentificationEBSVolumes",
"SourceIdentificationEBSSnapshots",
"SourceIdentificationRDSSnapshots",
"SourceIdentificationKMSKeyRotation",
"SourceIdentificationAMIPublicAccess"
]
},
Expand Down Expand Up @@ -90,6 +91,9 @@
"SourceIdentificationRDSSnapshots": {
"default": "Relative path to public RDS snapshots lambda sources"
},
"SourceIdentificationKMSKeyRotation": {
"default": "Relative path to KMS key rotation sources"
},
"SourceIdentificationAMIPublicAccess":{
"default": "Relative path to Public AMI sources"
}
Expand Down Expand Up @@ -169,6 +173,10 @@
"Type": "String",
"Default": "rds-public-snapshots-identification.zip"
},
"SourceIdentificationKMSKeyRotation": {
"Type": "String",
"Default": "kms-keyrotation-issues-identification.zip"
},
"SourceIdentificationAMIPublicAccess": {
"Type": "String",
"Default": "ami-public-access-issues-identification.zip"
Expand Down Expand Up @@ -229,6 +237,9 @@
"IdentificationMetricRDSSnapshotsError": {
"value": "RDSSnapshotsError"
},
"IdentificationMetricKMSKeyRotationError": {
"value": "KMSKeyRotationError"
},
"IdentificationMetricAMIPublicAccessError": {
"value": "AMIPublicAccessError"
},
Expand Down Expand Up @@ -295,6 +306,12 @@
"SNSTopicNameRDSSnapshots": {
"value": "describe-rds-public-snapshots-lambda"
},
"SNSDisplayNameKMSKeyRotation": {
"value": "describe-kms-key-rotation-sns"
},
"SNSTopicNameKMSKeyRotation": {
"value": "describe-kms-key-rotation-lambda"
},
"SNSDisplayNameAMIPublicAccess": {
"value": "describe-ami-public-access-sns"
},
Expand Down Expand Up @@ -379,6 +396,12 @@
"IdentifyRDSSnapshotsLambdaFunctionName": {
"value": "describe-rds-public-snapshots"
},
"InitiateKMSKeyRotationLambdaFunctionName": {
"value": "initiate-kms-key-rotation"
},
"IdentifyKMSKeyRotationLambdaFunctionName": {
"value": "describe-kms-key-rotation"
},
"InitiateAMIPublicAccessLambdaFunctionName": {
"value": "initiate-ami-public-access"
},
Expand Down Expand Up @@ -1860,6 +1883,105 @@
"LogGroupName" : { "Ref": "LogGroupLambdaEvaluateRDSEncryption" }
}
},
"LambdaInitiateKMSKeyRotationEvaluation": {
"Type": "AWS::Lambda::Function",
"DependsOn": ["SNSNotifyLambdaEvaluateKMSKeyRotation", "LogGroupLambdaInitiateKMSKeyRotationEvaluation"],
"Properties": {
"Code": {
"S3Bucket": { "Ref": "SourceS3Bucket" },
"S3Key": { "Ref": "SourceIdentificationKMSKeyRotation" }
},
"Environment": {
"Variables": {
"SNS_KMS_KEY_ROTATION_ARN": { "Ref": "SNSNotifyLambdaEvaluateKMSKeyRotation" }
}
},
"Description": "Lambda function for initiate to identify disabled KMS key rotation issues.",
"FunctionName": {"Fn::Join" : ["", [ { "Ref": "ResourcesPrefix" },
{ "Fn::FindInMap": ["NamingStandards", "InitiateKMSKeyRotationLambdaFunctionName", "value"] } ]
]},
"Handler": "initiate_to_desc_kms_key_rotation.lambda_handler",
"MemorySize": 128,
"Timeout": "300",
"Role": {"Fn::Join" : ["", [ "arn:aws:iam::",
{ "Ref": "AWS::AccountId" },
":role/",
{ "Ref": "ResourcesPrefix" },
{ "Ref": "IdentificationIAMRole" }
] ]},
"Runtime": "python3.6"
}
},
"LogGroupLambdaInitiateKMSKeyRotationEvaluation": {
"Type" : "AWS::Logs::LogGroup",
"Properties" : {
"LogGroupName": {"Fn::Join": ["", [ "/aws/lambda/",
{ "Ref": "ResourcesPrefix" },
{ "Fn::FindInMap": ["NamingStandards",
"InitiateKMSKeyRotationLambdaFunctionName",
"value"]
} ] ] },
"RetentionInDays": "7"
}
},
"SubscriptionFilterLambdaInitiateKMSKeyRotationEvaluation": {
"Type" : "AWS::Logs::SubscriptionFilter",
"DependsOn": ["LambdaLogsForwarder",
"PermissionToInvokeLambdaLogsForwarderCloudWatchLogs",
"LogGroupLambdaInitiateKMSKeyRotationEvaluation"],
"Properties" : {
"DestinationArn" : { "Fn::GetAtt" : [ "LambdaLogsForwarder", "Arn" ] },
"FilterPattern" : "[level != START && level != END && level != DEBUG, ...]",
"LogGroupName" : { "Ref": "LogGroupLambdaInitiateKMSKeyRotationEvaluation" }
}
},
"LambdaEvaluateKMSKeyRotation": {
"Type": "AWS::Lambda::Function",
"DependsOn": ["LogGroupLambdaEvaluateKMSKeyRotation"],
"Properties": {
"Code": {
"S3Bucket": { "Ref": "SourceS3Bucket" },
"S3Key": { "Ref": "SourceIdentificationKMSKeyRotation" }
},
"Description": "Lambda function to describe disabled KMS key rotation issues.",
"FunctionName": {"Fn::Join" : ["", [ { "Ref": "ResourcesPrefix" },
{ "Fn::FindInMap": ["NamingStandards", "IdentifyKMSKeyRotationLambdaFunctionName", "value"] } ]
]},
"Handler": "describe_kms_key_rotation.lambda_handler",
"MemorySize": 256,
"Timeout": "300",
"Role": {"Fn::Join" : ["", [ "arn:aws:iam::",
{ "Ref": "AWS::AccountId" },
":role/",
{ "Ref": "ResourcesPrefix" },
{ "Ref": "IdentificationIAMRole" }
] ]},
"Runtime": "python3.6"
}
},
"LogGroupLambdaEvaluateKMSKeyRotation": {
"Type" : "AWS::Logs::LogGroup",
"Properties" : {
"LogGroupName": {"Fn::Join": ["", [ "/aws/lambda/",
{ "Ref": "ResourcesPrefix" },
{ "Fn::FindInMap": ["NamingStandards",
"IdentifyKMSKeyRotationLambdaFunctionName",
"value"]
} ] ] },
"RetentionInDays": "7"
}
},
"SubscriptionFilterLambdaEvaluateKMSKeyRotation": {
"Type" : "AWS::Logs::SubscriptionFilter",
"DependsOn": ["LambdaLogsForwarder",
"PermissionToInvokeLambdaLogsForwarderCloudWatchLogs",
"LogGroupLambdaEvaluateKMSKeyRotation"],
"Properties" : {
"DestinationArn" : { "Fn::GetAtt" : [ "LambdaLogsForwarder", "Arn" ] },
"FilterPattern" : "[level != START && level != END && level != DEBUG, ...]",
"LogGroupName" : { "Ref": "LogGroupLambdaEvaluateKMSKeyRotation" }
}
},
"LambdaInitiateAMIPublicAccessEvaluation": {
"Type": "AWS::Lambda::Function",
"DependsOn": ["SNSNotifyLambdaEvaluateAMIPublicAccess", "LogGroupLambdaInitiateAMIPublicAccessEvaluation"],
Expand Down Expand Up @@ -1912,7 +2034,6 @@
"LogGroupName" : { "Ref": "LogGroupLambdaInitiateAMIPublicAccessEvaluation" }
}
},

"LambdaEvaluateAMIPublicAccess": {
"Type": "AWS::Lambda::Function",
"DependsOn": ["LogGroupLambdaEvaluateAMIPublicAccess"],
Expand Down Expand Up @@ -2124,6 +2245,22 @@
]
}
},
"EventInitiateEvaluationKMSKeyRotation": {
"Type": "AWS::Events::Rule",
"DependsOn": ["LambdaInitiateKMSKeyRotationEvaluation"],
"Properties": {
"Description": "Hammer ScheduledRule to initiate KMS key rotation evaluations",
"Name": {"Fn::Join" : ["", [{ "Ref": "ResourcesPrefix" }, "InitiateEvaluationKMSKeyRotation"] ] },
"ScheduleExpression": {"Fn::Join": ["", [ "cron(", "35 ", { "Ref": "IdentificationCheckRateExpression" }, ")" ] ]},
"State": "ENABLED",
"Targets": [
{
"Arn": { "Fn::GetAtt": ["LambdaInitiateKMSKeyRotationEvaluation", "Arn"] },
"Id": "LambdaInitiateKMSKeyRotationEvaluation"
}
]
}
},
"EventInitiateEvaluationAMIPublicAccess": {
"Type": "AWS::Events::Rule",
"DependsOn": ["LambdaInitiateAMIPublicAccessEvaluation"],
Expand Down Expand Up @@ -2282,6 +2419,16 @@
"SourceArn": { "Fn::GetAtt": ["EventInitiateEvaluationRDSEncryption", "Arn"] }
}
},
"PermissionToInvokeLambdaInitiateKMSKeyRotationEvaluationCloudWatchEvents": {
"Type": "AWS::Lambda::Permission",
"DependsOn": ["LambdaInitiateKMSKeyRotationEvaluation", "EventInitiateEvaluationKMSKeyRotation"],
"Properties": {
"FunctionName": { "Ref": "LambdaInitiateKMSKeyRotationEvaluation" },
"Action": "lambda:InvokeFunction",
"Principal": "events.amazonaws.com",
"SourceArn": { "Fn::GetAtt": ["EventInitiateEvaluationKMSKeyRotation", "Arn"] }
}
},
"PermissionToInvokeLambdaInitiateAMIPublicAccessEvaluationCloudWatchEvents": {
"Type": "AWS::Lambda::Permission",
"DependsOn": ["LambdaInitiateAMIPublicAccessEvaluation", "EventInitiateEvaluationAMIPublicAccess"],
Expand Down Expand Up @@ -2508,6 +2655,24 @@
}]
}
},
"SNSNotifyLambdaEvaluateKMSKeyRotation": {
"Type": "AWS::SNS::Topic",
"DependsOn": "LambdaEvaluateKMSKeyRotation",
"Properties": {
"DisplayName": {"Fn::Join" : ["", [ { "Ref": "ResourcesPrefix" },
{ "Fn::FindInMap": ["NamingStandards", "SNSDisplayNameKMSKeyRotation", "value"] } ]
]},
"TopicName": {"Fn::Join" : ["", [ { "Ref": "ResourcesPrefix" },
{ "Fn::FindInMap": ["NamingStandards", "SNSTopicNameKMSKeyRotation", "value"] } ]
]},
"Subscription": [{
"Endpoint": {
"Fn::GetAtt": ["LambdaEvaluateKMSKeyRotation", "Arn"]
},
"Protocol": "lambda"
}]
}
},
"SNSNotifyLambdaEvaluateAMIPublicAccess": {
"Type": "AWS::SNS::Topic",
"DependsOn": "LambdaEvaluateAMIPublicAccess",
Expand Down Expand Up @@ -2646,6 +2811,16 @@
"FunctionName": { "Fn::GetAtt": ["LambdaEvaluateRDSEncryption", "Arn"] }
}
},
"PermissionToInvokeLambdaEvaluateKMSKeyRotationSNS": {
"Type": "AWS::Lambda::Permission",
"DependsOn": ["SNSNotifyLambdaEvaluateKMSKeyRotation", "LambdaEvaluateKMSKeyRotation"],
"Properties": {
"Action": "lambda:InvokeFunction",
"Principal": "sns.amazonaws.com",
"SourceArn": { "Ref": "SNSNotifyLambdaEvaluateKMSKeyRotation" },
"FunctionName": { "Fn::GetAtt": ["LambdaEvaluateKMSKeyRotation", "Arn"] }
}
},
"PermissionToInvokeLambdaEvaluateAMIPublicAccessSNS": {
"Type": "AWS::Lambda::Permission",
"DependsOn": ["SNSNotifyLambdaEvaluateAMIPublicAccess", "LambdaEvaluateAMIPublicAccess"],
Expand Down Expand Up @@ -3258,6 +3433,52 @@
"TreatMissingData": "notBreaching"
}
},
"AlarmErrorsLambdaInitiateKMSKeyRotationEvaluation": {
"Type": "AWS::CloudWatch::Alarm",
"DependsOn": ["SNSIdentificationErrors", "LambdaInitiateKMSKeyRotationEvaluation"],
"Properties": {
"AlarmActions": [ { "Ref": "SNSIdentificationErrors" } ],
"OKActions": [ { "Ref": "SNSIdentificationErrors" } ],
"AlarmName": {"Fn::Join": ["/", [ { "Ref": "LambdaInitiateKMSKeyRotationEvaluation" }, "LambdaError" ] ]},
"EvaluationPeriods": 1,
"Namespace": "AWS/Lambda",
"MetricName": "Errors",
"Dimensions": [
{
"Name": "FunctionName",
"Value": { "Ref": "LambdaInitiateKMSKeyRotationEvaluation" }
}
],
"Period": 3600,
"Statistic": "Maximum",
"ComparisonOperator" : "GreaterThanThreshold",
"Threshold": 0,
"TreatMissingData": "notBreaching"
}
},
"AlarmErrorsLambdaKMSKeyRotationEvaluation": {
"Type": "AWS::CloudWatch::Alarm",
"DependsOn": ["SNSIdentificationErrors", "LambdaEvaluateKMSKeyRotation"],
"Properties": {
"AlarmActions": [ { "Ref": "SNSIdentificationErrors" } ],
"OKActions": [ { "Ref": "SNSIdentificationErrors" } ],
"AlarmName": {"Fn::Join": ["/", [ { "Ref": "LambdaEvaluateKMSKeyRotation" }, "LambdaError" ] ]},
"EvaluationPeriods": 1,
"Namespace": "AWS/Lambda",
"MetricName": "Errors",
"Dimensions": [
{
"Name": "FunctionName",
"Value": { "Ref": "LambdaEvaluateKMSKeyRotation" }
}
],
"Period": 3600,
"Statistic": "Maximum",
"ComparisonOperator" : "GreaterThanThreshold",
"Threshold": 0,
"TreatMissingData": "notBreaching"
}
},
"AlarmErrorsLambdaInitiateAMIPublicAccessEvaluation": {
"Type": "AWS::CloudWatch::Alarm",
"DependsOn": ["SNSIdentificationErrors", "LambdaInitiateAMIPublicAccessEvaluation"],
Expand Down
Loading