CloudWatch Alarm for Network Gateway Changes
Overview
This check verifies that you have a CloudWatch alarm configured to detect changes to network gateways in your AWS account. It monitors CloudTrail events for actions like creating, deleting, attaching, or detaching Internet Gateways and Customer Gateways.
Network gateways control how your private networks connect to the internet and other networks. Monitoring changes to these critical components helps you detect unauthorized modifications quickly.
Risk
Without monitoring, gateway changes can go unnoticed. This creates serious security risks:
- Data exfiltration: An attacker could attach an Internet Gateway to expose private resources
- Network disruption: Deleting or detaching gateways can break connectivity and cause outages
- Bypassing controls: Changes might circumvent network inspection or firewall rules
This check is classified as Medium severity and impacts both confidentiality and availability.
Remediation Steps
Prerequisites
You need:
- AWS Console access with permissions to create CloudWatch alarms and metric filters
- CloudTrail logs already flowing to a CloudWatch Logs log group
How to verify CloudTrail is sending logs to CloudWatch
- Go to CloudTrail in the AWS Console
- Click Trails in the left menu
- Select your trail
- Look for CloudWatch Logs section - it should show a log group name
- If not configured, you'll need to set this up first (see AWS documentation)
AWS Console Method
Step 1: Open CloudWatch Logs
- Sign in to the AWS Console
- Go to CloudWatch (search for it in the top search bar)
- In the left menu, expand Logs and click Log groups
- Find and click on your CloudTrail log group (often named similar to
CloudTrail/DefaultLogGrouporaws-cloudtrail-logs-*)
Step 2: Create a Metric Filter
- Click the Metric filters tab
- Click Create metric filter
- In the Filter pattern field, paste this pattern:
{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }
- Click Next
- Enter these values:
- Filter name:
NetworkGatewayChanges - Metric namespace:
CloudTrailMetrics - Metric name:
NetworkGatewayEventCount - Metric value:
1
- Filter name:
- Click Next, then Create metric filter
Step 3: Create an Alarm
- After creating the filter, find it in the list and click Create alarm (in the Actions column)
- Configure the alarm:
- Statistic: Sum
- Period: 5 minutes
- Threshold type: Static
- Whenever NetworkGatewayEventCount is...: Greater/Equal than 1
- Click Next
- Under Notification, select or create an SNS topic to receive alerts
- Click Next
- Enter an alarm name:
NetworkGatewayChangesAlarm - Click Next, review, and click Create alarm
AWS CLI (optional)
Step 1: Create the metric filter
Replace <your-cloudtrail-log-group> with your actual CloudTrail log group name.
aws logs put-metric-filter \
--region us-east-1 \
--log-group-name "<your-cloudtrail-log-group>" \
--filter-name "NetworkGatewayChanges" \
--filter-pattern '{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }' \
--metric-transformations \
metricName=NetworkGatewayEventCount,metricNamespace=CloudTrailMetrics,metricValue=1
Step 2: Create the CloudWatch alarm
Replace <your-sns-topic-arn> with your SNS topic ARN for notifications.
aws cloudwatch put-metric-alarm \
--region us-east-1 \
--alarm-name "NetworkGatewayChangesAlarm" \
--alarm-description "Alarm for network gateway changes detected via CloudTrail" \
--metric-name "NetworkGatewayEventCount" \
--namespace "CloudTrailMetrics" \
--statistic Sum \
--period 300 \
--threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--evaluation-periods 1 \
--alarm-actions "<your-sns-topic-arn>" \
--treat-missing-data notBreaching
CloudFormation (optional)
Save this template and deploy it via the CloudFormation console or CLI.
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudWatch alarm for network gateway changes
Parameters:
CloudTrailLogGroupName:
Type: String
Description: Name of the CloudTrail log group
Default: CloudTrail/DefaultLogGroup
AlarmNotificationTopicArn:
Type: String
Description: SNS topic ARN for alarm notifications
Resources:
NetworkGatewayChangesMetricFilter:
Type: AWS::Logs::MetricFilter
Properties:
LogGroupName: !Ref CloudTrailLogGroupName
FilterName: NetworkGatewayChanges
FilterPattern: >-
{ ($.eventName = CreateCustomerGateway) ||
($.eventName = DeleteCustomerGateway) ||
($.eventName = AttachInternetGateway) ||
($.eventName = CreateInternetGateway) ||
($.eventName = DeleteInternetGateway) ||
($.eventName = DetachInternetGateway) }
MetricTransformations:
- MetricName: NetworkGatewayEventCount
MetricNamespace: CloudTrailMetrics
MetricValue: '1'
NetworkGatewayChangesAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: NetworkGatewayChangesAlarm
AlarmDescription: Alerts when network gateway changes are detected
MetricName: NetworkGatewayEventCount
Namespace: CloudTrailMetrics
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 1
ComparisonOperator: GreaterThanOrEqualToThreshold
AlarmActions:
- !Ref AlarmNotificationTopicArn
TreatMissingData: notBreaching
Outputs:
AlarmArn:
Description: ARN of the network gateway changes alarm
Value: !GetAtt NetworkGatewayChangesAlarm.Arn
Deploy with CLI:
aws cloudformation deploy \
--region us-east-1 \
--template-file network-gateway-alarm.yaml \
--stack-name network-gateway-monitoring \
--parameter-overrides \
CloudTrailLogGroupName="<your-cloudtrail-log-group>" \
AlarmNotificationTopicArn="<your-sns-topic-arn>"
Terraform (optional)
variable "cloudtrail_log_group_name" {
description = "Name of the CloudTrail log group"
type = string
}
variable "alarm_sns_topic_arn" {
description = "SNS topic ARN for alarm notifications"
type = string
}
resource "aws_cloudwatch_log_metric_filter" "network_gateway_changes" {
name = "NetworkGatewayChanges"
pattern = "{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }"
log_group_name = var.cloudtrail_log_group_name
metric_transformation {
name = "NetworkGatewayEventCount"
namespace = "CloudTrailMetrics"
value = "1"
}
}
resource "aws_cloudwatch_metric_alarm" "network_gateway_changes" {
alarm_name = "NetworkGatewayChangesAlarm"
alarm_description = "Alerts when network gateway changes are detected"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = 1
metric_name = "NetworkGatewayEventCount"
namespace = "CloudTrailMetrics"
period = 300
statistic = "Sum"
threshold = 1
treat_missing_data = "notBreaching"
alarm_actions = [var.alarm_sns_topic_arn]
}
Deploy:
terraform init
terraform plan -var="cloudtrail_log_group_name=<your-log-group>" -var="alarm_sns_topic_arn=<your-sns-arn>"
terraform apply -var="cloudtrail_log_group_name=<your-log-group>" -var="alarm_sns_topic_arn=<your-sns-arn>"
Verification
After completing the remediation:
- Go to CloudWatch > Alarms > All alarms
- Find
NetworkGatewayChangesAlarmin the list - Verify the alarm state shows OK (not INSUFFICIENT_DATA after some time has passed)
- Go to CloudWatch > Logs > Log groups > your CloudTrail log group
- Click the Metric filters tab and confirm
NetworkGatewayChangesexists
CLI verification commands
Check the metric filter exists:
aws logs describe-metric-filters \
--region us-east-1 \
--log-group-name "<your-cloudtrail-log-group>" \
--filter-name-prefix "NetworkGatewayChanges"
Check the alarm exists:
aws cloudwatch describe-alarms \
--region us-east-1 \
--alarm-names "NetworkGatewayChangesAlarm"
Re-run the Prowler check:
prowler aws --check cloudwatch_changes_to_network_gateways_alarm_configured --region us-east-1
Additional Resources
- Creating CloudWatch Alarms for CloudTrail Events
- AWS Security Hub CloudWatch Controls (CloudWatch.12)
- CIS Amazon Web Services Foundations Benchmark
- Filter and Pattern Syntax for CloudWatch Logs
Notes
-
CloudTrail prerequisite: This check requires CloudTrail logs to be sent to CloudWatch Logs. If you haven't configured this, the metric filter will have no data to process.
-
Multi-region considerations: CloudTrail can be configured as a multi-region trail. Ensure your trail covers all regions where network gateway changes might occur.
-
SNS topic required: The alarm needs an SNS topic with subscribers (email, SMS, or other endpoints) to actually notify you. Creating the alarm without an SNS topic means no one gets alerted.
-
Initial alarm state: New alarms start in
INSUFFICIENT_DATAstate. This is normal and will change toOKonce CloudWatch has collected enough data points. -
Related checks: Consider also implementing alarms for VPC changes, security group changes, and NACL changes for comprehensive network monitoring.