Ensure recommended metric-filters and alarms are implemented on Multi-region CloudTrail

3.1 to 3.13 Monitoring (AWS CIS Benchmark).

Description

Real-time monitoring of API calls can be achieved by directing CloudTrail Logs to CloudWatch Logs and establishing corresponding metric filters and alarms.

It is strongly recommended that a metric filter and alarm be established for detecting:

  • Unauthorized API calls (3.1)
  • Console logins that are not protected by multi-factor authentication (MFA) (3.2)
  • Root login attempts (3.3)
  • Changes made to Identity and Access Management (IAM) policies (3.4)
  • Changes to CloudTrail's configurations (3.5)
  • Failed console authentication attempts (3.6)
  • Customer-created CMKs which have changed state to disabled or scheduled deletion (3.7)
  • Changes to S3 buckets (3.8)
  • Changes to AWS Config configuration (3.9)
  • Changes made to Security Groups (Note: Security Groups are a stateful packet filter that controls ingress and egress traffic within a VPC.) (3.10)
  • Changes made to NACLs (3.11)
  • Changes to the network (3.12)
  • Changes to route tables (3.13)
  • Changes made to VPCs (Note: It is possible to have more than 1 VPC within an account. In addition, it is also possible to create a peer connection between 2 VPCs, which enables network traffic to route between VPCs) (3.14)

Set up the metric filter, alarm, SNS topic, and subscription via the AWS Management Console

Step 1.

a) Detect unauthorized API calls

Create a metric filter based on the filter pattern provided which checks for unauthorized API calls and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <unauthorized_api_calls_metric> --metric-transformations metricName= <unauthorized_api_calls_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.errorCode = "UnauthorizedOperation") || ($.errorCode = "AccessDenied") }'

b) Detect console logins that are not protected by multi-factor authentication (MFA)

Create a metric filter based on the filter pattern provided which checks for AWS Management Console sign-in without MFA and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <no_mfa_console_signin_metric> --metric-transformations metricName= <no_mfa_console_signin_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = "ConsoleLogin") && ($.additionalEventData.MFAUsed != "Yes") }'

c) Detect root login attempts

Create a metric filter based on the filter pattern provided which checks for "Root'' account usage and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <root_usage_metric> --metric-transformations metricName= <root_usage_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filterpattern '{ $.userIdentity.type = "Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != "AwsServiceEvent" }'

d) Detect changes made to Identity and Access Management (IAM) policies

Create a metric filter based on filter pattern provided which checks for IAM policy changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <iam_changes_metric> --metric-transformations metricName= <iam_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 -- filter-pattern '{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventNa me=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolic y)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=Del etePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersi on)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.event Name=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGr oupPolicy)||($.eventName=DetachGroupPolicy)}'

e) Detect changes to CloudTrail's configurations

Create a metric filter based on the filter pattern provided which checks for cloudtrail configuration changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <cloudtrail_cfg_changes_metric> --metric-transformations metricName= <cloudtrail_cfg_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }'

f) Detect failed console authentication attempts

Create a metric filter based on the filter pattern provided which checks for AWS management Console Login Failures and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <console_signin_failure_metric> --metric-transformations metricName= <console_signin_failure_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = ConsoleLogin) && ($.errorMessage = "Failed authentication") }'

g) Detect customer-created CMKs which have changed state to disabled or scheduled deletion

Create a metric filter based on the filter pattern provided which checks for disabled or scheduled for deletion CMK's and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <disable_or_delete_cmk_changes_metric> --metrictransformations metricName= <disable_or_delete_cmk_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{($.eventSource = kms.amazonaws.com) && (($.eventName=DisableKey)||($.eventName=ScheduleKeyDeletion)) }'

h) Detect changes to S3 buckets

Create a metric filter based on the filter pattern provided which checks for S3 bucket policy changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <s3_bucket_policy_changes_metric> --metric-transformations metricName= <s3_bucket_policy_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }'

i) Detect changes to AWS Config configuration

Create a metric filter based on the filter pattern provided which checks for AWS Configuration changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <aws_config_changes_metric> --metric-transformations metricName= <aws_config_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventSource = config.amazonaws.com) && (($.eventName=StopConfigurationRecorder)||($.eventName=DeleteDeliveryChannel) ||($.eventName=PutDeliveryChannel)||($.eventName=PutConfigurationRecorder)) }' Note: You can choose your own metricName and metricNamespace strings. Using the same metricNamespace for all Foundations Benchmark metrics will group them together.

j) Detect changes made to Security Groups

Create a metric filter based on the filter pattern provided which checks for security groups changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <security_group_changes_metric> --metric-transformations metricName= <security_group_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }'

k) Changes made to NACLs

Create a metric filter based on the filter pattern provided which checks for NACL changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <nacl_changes_metric> --metric-transformations metricName= <nacl_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 -- filter-pattern '{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }'

l) Changes to the network

Create a metric filter based on the filter pattern provided which checks for network gateways changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <network_gw_changes_metric> --metric-transformations metricName= <network_gw_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }'

m) Detect changes to route tables

Create a metric filter based on the filter pattern provided which checks for route table changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <route_table_changes_metric> --metric-transformations metricName= <route_table_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 --filter-pattern '{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }'

n) Detect changes made to VPCs

Create a metric filter based on filter pattern provided which checks for VPC changes and the <cloudtrail_log_group_name> taken from audit step 1. aws logs put-metric-filter --log-group-name <cloudtrail_log_group_name> -- filter-name <vpc_changes_metric> --metric-transformations metricName= <vpc_changes_metric> ,metricNamespace='CISBenchmark',metricValue=1 -- filter-pattern '{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }'

Note: You can choose your own metricName and metricNamespace strings.

Using the same metricNamespace for all Foundations Benchmark metrics will group them together.

Step 2. Create an SNS topic that the alarm will notify aws sns create-topic --name <sns_topic_name>

Note: You can execute this command once and then reuse the same topic for all monitoring alarms.

Step 3. Create an SNS subscription to the topic created in step 2 aws sns subscribe --topic-arn <sns_topic_arn> --protocol <protocol_for_sns> - -notification-endpoint <sns_subscription_endpoints>

Note: You can execute this command once and then reuse the SNS subscription for all monitoring alarms.

Step 4. Create an alarm that is associated with the CloudWatch Logs Metric Filter created in step 1 and an SNS topic created in step 2 aws cloudwatch put-metric-alarm --alarm-name -- metric-name --statistic Sum --period 300 --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --namespace 'CISBenchmark' --alarm-actions <sns_topic_arn>

Depending on the rule you chose in step 1, continue with that rule now, replacing and as per either:

a) Detect unauthorized API calls

= <unauthorized_api_calls_alarm>
= <unauthorized_api_calls_metric>

b) Console logins that are not protected by multi-factor authentication (MFA)

= <no_mfa_console_signin_alarm>
= <no_mfa_console_signin_metric>

c) Detect root login attempts

= <root_usage_alarm>
= <root_usage_metric>

d) Changes made to Identity and Access Management (IAM) policies

= <iam_changes_alarm>
= <iam_changes_metric>

e) Changes to CloudTrail's configurations

= <cloudtrail_cfg_changes_alarm>
= <cloudtrail_cfg_changes_metric>

f) Failed console authentication attempts

= <console_signin_failure_alarm>
= <console_signin_failure_metric>

g) Customer-created CMKs which have changed state to disabled or scheduled deletion

= <disable_or_delete_cmk_changes_alarm>
= <disable_or_delete_cmk_changes_metric>

h) Detect changes to S3 buckets

= <s3_bucket_policy_changes_alarm>
= <s3_bucket_policy_changes_metric>

i) Detect changes to AWS Config configuration

= <aws_config_changes_alarm>
= <aws_config_changes_metric>

j) Detect changes made to Security Groups

= <security_group_changes_alarm>
= <security_group_changes_metric>

k) Changes made to NACLs

= <nacl_changes_alarm>
= <nacl_changes_metric>

l) Changes to the network

= <network_gw_changes_alarm>
= <network_gw_changes_metric>

m) Detect changes to route tables

= <route_table_changes_alarm>
= <route_table_changes_metric>

n) Detect changes made to VPCs

= <vpc_changes_alarm>
= <vpc_changes_metric>