add cloudtrail-alarms module

ctalarms-whitelist
lalanza808 4 years ago
parent 6dc0deb490
commit 70a5102387

@ -0,0 +1,40 @@
# Cloudtrail Alarms
Hooks into an existing Cloudtrail and Cloudwatch Logs deployment enabled so that we can setup Log metric filters to look for certain patterns.
We are able to tail Cloudtrail events and alarm on certain log messages as they occur. The full list can be seen in [main.tf](./main.tf)
These alarms are necessary to be in compliance with CIS Benchmarks, a very popular framework for securing AWS environments.
## Usage
```
module "cloudtrail" {
source = "github.com/lalanza808/tf-modules.git/security/cloudtrail"
force_destroy_bucket = true
}
module "sns_topic" {
source = "github.com/lalanza808/tf-modules.git/monitoring/sns-email-topic"
sns_emails = ["user@email.com"]
}
module "cloudtrail-alarms" {
source = "github.com/lalanza808/tf-modules.git/monitoring/cloudtrail-alarms"
log_group_name = module.cloudtrail.log_group_name
sns_topic_arn = module.sns_topic.topic_arn
account_name = "Sandbox"
}
```
## Inputs
* `log_group_name` - Cloudwatch Logs group containing Cloudtrail event data
* `sns_topic_arn` - The SNS topic ARN to publish event messages to based upon alarm conditions
* `account_name` - Name of the AWS account for labeling purposes
See the full list of inputs here: [variables.tf](./variables.tf)
## Outputs
None - [output.tf](./output.tf)

@ -0,0 +1,97 @@
data "aws_caller_identity" "current" {}
locals {
account_id = data.aws_caller_identity.current.account_id
alert_for = "CloudTrailBreach"
metric_namespace = "CISBenchmarks"
metric_value = "1"
metric_name = [
"CIS-3.1-AuthorizationFailureCount",
"CIS-3.8-S3BucketActivityEventCount",
"CIS-3.10-SecurityGroupEventCount",
"CIS-3.11-NetworkAclEventCount",
"CIS-3.12-NetworkGatewayEventCount",
"CIS-3.14-VpcEventCount",
"EC2InstanceEventCount",
"EC2LargeInstanceEventCount",
"CIS-3.5-CloudTrailEventCount",
"CIS-3.6-ConsoleSignInFailureCount", # See link to this name down below
"CIS-3.4-IAMPolicyEventCount",
"CIS-3.2-ConsoleSignInWithoutMfaCount",
"CIS-3.3-RootAccountUsageCount",
"KMSKeyPendingDeletionErrorCount",
"CIS-3.9-AWSConfigChangeCount",
"CIS-3.13-RouteTableChangesCount",
"CIS-3.7-ScheduledDeletionCustomerKMSKey"
]
filter_pattern = [
"{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }",
"{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }",
"{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }",
"{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }",
"{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }",
"{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }",
"{ ($.eventName = RunInstances) || ($.eventName = RebootInstances) || ($.eventName = StartInstances) || ($.eventName = StopInstances) || ($.eventName = TerminateInstances) }",
"{ ($.eventName = RunInstances) && (($.requestParameters.instanceType = *.8xlarge) || ($.requestParameters.instanceType = *.4xlarge) || ($.requestParameters.instanceType = *.16xlarge) || ($.requestParameters.instanceType = *.10xlarge) || ($.requestParameters.instanceType = *.12xlarge) || ($.requestParameters.instanceType = *.24xlarge)) }",
"{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }",
"{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }",
"{ ($.eventName = DeleteGroupPolicy) || ($.eventName = DeleteRolePolicy) ||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}",
"{ $.eventName = ConsoleLogin && $.userIdentity.sessionContext.attributes.mfaAuthenticated = false && $.responseElements.ConsoleLogin = Success }",
"{ $.userIdentity.type = Root && $.userIdentity.invokedBy NOT EXISTS && $.eventType != AwsServiceEvent }",
"{ $.eventSource = kms* && $.errorMessage = \"* is pending deletion.\"}",
"{ $.eventSource = config.amazonaws.com && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel) ||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }",
"{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }",
"{ ($.eventSource=kms.amazonaws.com) && (($.eventName=DisableKey) || ($.eventName=ScheduleKeyDeletion)) }"
]
alarm_description = [
"Alarms when an unauthorized API call is made.",
"Alarms when an API call is made to S3 to put or delete a Bucket, Bucket Policy or Bucket ACL.",
"Alarms when an API call is made to create, update or delete a Security Group.",
"Alarms when an API call is made to create, update or delete a Network ACL.",
"Alarms when an API call is made to create, update or delete a Customer or Internet Gateway.",
"Alarms when an API call is made to create, update or delete a VPC, VPC peering connection or VPC connection to classic.",
"Alarms when an API call is made to create, terminate, start, stop or reboot an EC2 instance.",
"Alarms when an API call is made to create, terminate, start, stop or reboot a 4x-large or greater EC2 instance.",
"Alarms when an API call is made to create, update or delete a .cloudtrail. trail, or to start or stop logging to a trail.",
"Alarms when an unauthenticated API call is made to sign into the console.",
"Alarms when an API call is made to change an IAM policy.",
"Alarms when a user logs into the console without MFA.",
"Alarms when a root account usage is detected.",
"Alarms when a customer created KMS key is pending deletion.",
"Alarms when AWS Config changes.",
"Alarms when route table changes are detected.",
"Alarms when a customer managed KMS key is deleted or scheduled for deletion"
]
}
resource "aws_cloudwatch_log_metric_filter" "default" {
count = length(local.filter_pattern)
name = "${local.metric_name[count.index]}-filter"
pattern = local.filter_pattern[count.index]
log_group_name = var.log_group_name
metric_transformation {
name = local.metric_name[count.index]
namespace = local.metric_namespace
value = local.metric_value
}
}
resource "aws_cloudwatch_metric_alarm" "default" {
count = length(local.filter_pattern)
alarm_name = "${local.metric_name[count.index]}-alarm"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "1"
metric_name = local.metric_name[count.index]
namespace = local.metric_namespace
period = "300" // 5 min
statistic = "Sum"
treat_missing_data = "notBreaching"
threshold = local.metric_name[count.index] == "CIS-3.6-ConsoleSignInFailureCount" ? var.login_failures : 1
alarm_description = "AWS Account \"${var.account_name}\" (${local.account_id}) - ${local.alarm_description[count.index]}"
alarm_actions = [var.sns_topic_arn]
tags = var.tags
}

@ -0,0 +1,19 @@
variable "log_group_name" {
description = "Name of the Cloudwatch Logs group where Cloudtrail logs are flowing - used with Cloudwatch Alarms"
default = ""
}
variable "sns_topic_arn" {
description = "ARN of an SNS topic to notify when alarms are breached - used with Cloudwatch Alarms"
default = ""
}
variable "tags" {
default = {}
type = map
description = "Optional set of tags to apply to the infrastructure"
}
variable "account_name" {
description = "Name of the AWS account so that monitors report correct labels"
}
variable "login_failures" {
default = 3
}
Loading…
Cancel
Save