######################## # TO BE DISABLED # # These alerts have been recreated in Splunk, where they return far more useful information. # These alerts only say, "Something happened" and don't explain what/where/how, so they're # mostly useless. # # I plan to disable them completely once I gain confidence in the splunk alerts locals { alarm_namespace = "cis" } # Notification via Splunk Alert: "CIS 3.1 - Unauthorized API Calls" resource "aws_cloudwatch_log_metric_filter" "unauthorized_api_calls" { name = "UnauthorizedAPICalls" pattern = "{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }" log_group_name = var.log_group_name metric_transformation { name = "UnauthorizedAPICalls" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "unauthorized_api_calls" { alarm_name = "UnauthorizedAPICalls" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.unauthorized_api_calls.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "50" alarm_description = "Monitoring unauthorized API calls will help reveal application errors and may reduce time to detect malicious activity." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] depends_on = [ module.cloudtrail-logging ] } # This doesn't match the CIS exactly, because we do our MFA through okta instead of through AWS, so MFA is false for our # logins. Instead, we make sure they come in via okta and to the correct account. # # Okta handles our MFA, so MFA is always set to false for our logins. Lets just make sure they use the correct account(s). # # Notification via Splunk Alert: "CIS 3.2 - Management Console sign-in without MFA" resource "aws_cloudwatch_log_metric_filter" "no_mfa_console_signin" { name = "NoMFAConsoleSignin" pattern = "{ ($.eventName = \"ConsoleLogin\") && ($.additionalEventData.MFAUsed != \"Yes\") && ( ($.additionalEventData.SamlProviderArn NOT EXISTS) || (($.additionalEventData.SamlProviderArn != \"arn:aws-us-gov:iam::701290387780:saml-provider/OKTA\") && ($.additionalEventData.SamlProviderArn != \"arn:aws:iam::471284459109:saml-provider/OKTA\"))) }" log_group_name = var.log_group_name metric_transformation { name = "NoMFAConsoleSignin" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "no_mfa_console_signin" { alarm_name = "NoMFAConsoleSignin" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.no_mfa_console_signin.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring for single-factor console logins will increase visibility into accounts that are not protected by MFA." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.3 - Root Account Usage" resource "aws_cloudwatch_log_metric_filter" "root_usage" { name = "RootUsage" pattern = "{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }" log_group_name = var.log_group_name metric_transformation { name = "RootUsage" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "root_usage" { alarm_name = "RootUsage" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.root_usage.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring for root account logins will provide visibility into the use of a fully privileged account and an opportunity to reduce the use of it." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.4 - IAM policy changes" resource "aws_cloudwatch_log_metric_filter" "iam_changes" { name = "IAMChanges" pattern = "{($.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)}" log_group_name = var.log_group_name metric_transformation { name = "IAMChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "iam_changes" { alarm_name = "IAMChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.iam_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to IAM policies will help ensure authentication and authorization controls remain intact." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.5 - CloudTrail configuration changes" resource "aws_cloudwatch_log_metric_filter" "cloudtrail_cfg_changes" { name = "CloudTrailCfgChanges" pattern = "{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }" log_group_name = var.log_group_name metric_transformation { name = "CloudTrailCfgChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "cloudtrail_cfg_changes" { alarm_name = "CloudTrailCfgChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.cloudtrail_cfg_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to CloudTrail's configuration will help ensure sustained visibility to activities performed in the AWS account." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.6 - Console Signin Failures" resource "aws_cloudwatch_log_metric_filter" "console_signin_failures" { name = "ConsoleSigninFailures" pattern = "{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }" log_group_name = var.log_group_name metric_transformation { name = "ConsoleSigninFailures" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "console_signin_failures" { alarm_name = "ConsoleSigninFailures" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.console_signin_failures.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.7 - Disable or Delete CMK" resource "aws_cloudwatch_log_metric_filter" "disable_or_delete_cmk" { name = "DisableOrDeleteCMK" pattern = "{ ($.eventSource = kms.amazonaws.com) && (($.eventName = DisableKey) || ($.eventName = ScheduleKeyDeletion)) }" log_group_name = var.log_group_name metric_transformation { name = "DisableOrDeleteCMK" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "disable_or_delete_cmk" { alarm_name = "DisableOrDeleteCMK" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.disable_or_delete_cmk.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring failed console logins may decrease lead time to detect an attempt to brute force a credential, which may provide an indicator, such as source IP, that can be used in other event correlation." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.8 - S3 Bucket Policy Change" resource "aws_cloudwatch_log_metric_filter" "s3_bucket_policy_changes" { name = "S3BucketPolicyChanges" pattern = "{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }" log_group_name = var.log_group_name metric_transformation { name = "S3BucketPolicyChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "s3_bucket_policy_changes" { alarm_name = "S3BucketPolicyChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.s3_bucket_policy_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to S3 bucket policies may reduce time to detect and correct permissive policies on sensitive S3 buckets." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.9 - AWS Config Service Changes" resource "aws_cloudwatch_log_metric_filter" "aws_config_changes" { name = "AWSConfigChanges" pattern = "{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel)||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }" log_group_name = var.log_group_name metric_transformation { name = "AWSConfigChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "aws_config_changes" { alarm_name = "AWSConfigChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.aws_config_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to AWS Config configuration will help ensure sustained visibility of configuration items within the AWS account." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.10 - Security Group Changes" resource "aws_cloudwatch_log_metric_filter" "security_group_changes" { name = "SecurityGroupChanges" pattern = "{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup)}" log_group_name = var.log_group_name metric_transformation { name = "SecurityGroupChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "security_group_changes" { alarm_name = "SecurityGroupChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.security_group_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to security group will help ensure that resources and services are not unintentionally exposed." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.11 - Network ACL Changes" resource "aws_cloudwatch_log_metric_filter" "nacl_changes" { name = "NACLChanges" pattern = "{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }" log_group_name = var.log_group_name metric_transformation { name = "NACLChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "nacl_changes" { alarm_name = "NACLChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.nacl_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to NACLs will help ensure that AWS resources and services are not unintentionally exposed." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.12 - Network Gateway Changes" resource "aws_cloudwatch_log_metric_filter" "network_gw_changes" { name = "NetworkGWChanges" pattern = "{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }" log_group_name = var.log_group_name metric_transformation { name = "NetworkGWChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "network_gw_changes" { alarm_name = "NetworkGWChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.network_gw_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to network gateways will help ensure that all ingress/egress traffic traverses the VPC border via a controlled path." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.13 - Route Table Changes" resource "aws_cloudwatch_log_metric_filter" "route_table_changes" { name = "RouteTableChanges" pattern = "{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }" log_group_name = var.log_group_name metric_transformation { name = "RouteTableChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "route_table_changes" { alarm_name = "RouteTableChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.route_table_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to route tables will help ensure that all VPC traffic flows through an expected path." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] } # Notification via Splunk Alert: "CIS 3.14 - VPC Changes" resource "aws_cloudwatch_log_metric_filter" "vpc_changes" { name = "VPCChanges" pattern = "{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }" log_group_name = var.log_group_name metric_transformation { name = "VPCChanges" namespace = local.alarm_namespace value = "1" default_value = 0 } depends_on = [ module.cloudtrail-logging ] } resource "aws_cloudwatch_metric_alarm" "vpc_changes" { alarm_name = "VPCChanges" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.vpc_changes.id namespace = local.alarm_namespace period = "300" statistic = "Sum" threshold = "1" alarm_description = "Monitoring changes to VPC will help ensure that all VPC traffic flows through an expected path." alarm_actions = ["arn:${var.aws_partition}:sns:${var.aws_region}:${local.c2_account}:account-alerts"] insufficient_data_actions = [] }