Skip to main content

VPC has Network Firewall Enabled

Overview

This check verifies that your VPCs have AWS Network Firewall deployed. Network Firewall provides deep packet inspection and centralized traffic filtering for your VPC, helping you monitor and control network traffic at scale.

Risk

Without a Network Firewall, traffic flowing through your VPC bypasses deep inspection and centralized policy enforcement. This gap can enable:

  • Data exfiltration - Sensitive data leaving your network undetected
  • Command-and-control attacks - Malware communicating with external servers
  • Lateral movement - Attackers moving between resources within your VPC
  • Malware delivery - Malicious content entering your network

Unmonitored network traffic reduces your visibility into potential threats and weakens your security posture.

Remediation Steps

Prerequisites

  • AWS Console access with permissions to create Network Firewall resources
  • A VPC with at least one subnet dedicated to the firewall endpoint
  • Basic understanding of your network traffic patterns
Required IAM permissions

Your IAM user or role needs these permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"network-firewall:CreateFirewall",
"network-firewall:CreateFirewallPolicy",
"network-firewall:CreateRuleGroup",
"network-firewall:DescribeFirewall",
"network-firewall:UpdateLoggingConfiguration",
"ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"logs:CreateLogGroup",
"logs:PutResourcePolicy"
],
"Resource": "*"
}
]
}

AWS Console Method

  1. Open the Network Firewall console

  2. Configure basic settings

    • Enter a Firewall name (e.g., my-vpc-firewall)
    • Select the VPC you want to protect
    • Under Subnet mappings, select at least one subnet for the firewall endpoint
      • Tip: Use a dedicated "firewall subnet" in each Availability Zone you want to protect
  3. Create or select a firewall policy

    • Choose Create and associate an empty firewall policy for a new deployment
    • Or select an existing policy if you have one configured
    • Give your policy a descriptive name (e.g., my-vpc-firewall-policy)
  4. Review and create

    • Review your settings
    • Click Create firewall
    • Wait for the firewall status to show Ready (this may take a few minutes)
  5. Configure firewall rules (important!)

    • After the firewall is created, navigate to Firewall policies
    • Select your policy and add rule groups to define what traffic to allow or block
    • At minimum, configure stateless default actions (e.g., forward to stateful engine)
  6. Update route tables

    • Update your VPC route tables to direct traffic through the firewall endpoints
    • The firewall endpoint IDs are shown in the firewall details under Firewall endpoints
AWS CLI (optional)

Step 1: Create a firewall policy

First, create a basic firewall policy that forwards all traffic to the stateful inspection engine:

aws network-firewall create-firewall-policy \
--firewall-policy-name my-vpc-firewall-policy \
--firewall-policy '{
"StatelessDefaultActions": ["aws:forward_to_sfe"],
"StatelessFragmentDefaultActions": ["aws:forward_to_sfe"]
}' \
--region us-east-1

Save the FirewallPolicyArn from the output.

Step 2: Create the firewall

aws network-firewall create-firewall \
--firewall-name my-vpc-firewall \
--firewall-policy-arn <policy-arn-from-step-1> \
--vpc-id <your-vpc-id> \
--subnet-mappings "SubnetId=<your-firewall-subnet-id>" \
--region us-east-1

Replace:

  • <policy-arn-from-step-1> with the ARN from Step 1
  • <your-vpc-id> with your VPC ID (e.g., vpc-0abc123def456)
  • <your-firewall-subnet-id> with your dedicated firewall subnet ID
aws network-firewall update-logging-configuration \
--firewall-name my-vpc-firewall \
--logging-configuration '{
"LogDestinationConfigs": [
{
"LogType": "ALERT",
"LogDestinationType": "CloudWatchLogs",
"LogDestination": {
"logGroup": "/aws/network-firewall/my-vpc-firewall"
}
},
{
"LogType": "FLOW",
"LogDestinationType": "CloudWatchLogs",
"LogDestination": {
"logGroup": "/aws/network-firewall/my-vpc-firewall"
}
}
]
}' \
--region us-east-1

Note: Create the CloudWatch log group first if it does not exist.

CloudFormation (optional)

This template creates a Network Firewall with a basic policy, rule groups, and CloudWatch logging:

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Network Firewall deployment for VPC protection

Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: The VPC ID where the Network Firewall will be deployed

FirewallSubnetId:
Type: AWS::EC2::Subnet::Id
Description: The subnet ID for the Network Firewall endpoint

FirewallName:
Type: String
Default: my-network-firewall
Description: Name for the Network Firewall

Resources:
# Stateless Rule Group - Forward all traffic to stateful engine
StatelessRuleGroup:
Type: AWS::NetworkFirewall::RuleGroup
Properties:
RuleGroupName: !Sub "${FirewallName}-stateless-rules"
Type: STATELESS
Capacity: 100
RuleGroup:
RulesSource:
StatelessRulesAndCustomActions:
StatelessRules:
- RuleDefinition:
MatchAttributes:
Sources:
- AddressDefinition: "0.0.0.0/0"
Destinations:
- AddressDefinition: "0.0.0.0/0"
Actions:
- "aws:forward_to_sfe"
Priority: 1

# Stateful Rule Group - Domain filtering example
StatefulRuleGroup:
Type: AWS::NetworkFirewall::RuleGroup
Properties:
RuleGroupName: !Sub "${FirewallName}-stateful-rules"
Type: STATEFUL
Capacity: 100
RuleGroup:
RulesSource:
RulesSourceList:
TargetTypes:
- HTTP_HOST
- TLS_SNI
Targets:
- ".amazonaws.com"
- ".aws.amazon.com"
GeneratedRulesType: ALLOWLIST

# Firewall Policy
FirewallPolicy:
Type: AWS::NetworkFirewall::FirewallPolicy
Properties:
FirewallPolicyName: !Sub "${FirewallName}-policy"
FirewallPolicy:
StatelessDefaultActions:
- "aws:forward_to_sfe"
StatelessFragmentDefaultActions:
- "aws:forward_to_sfe"
StatelessRuleGroupReferences:
- ResourceArn: !GetAtt StatelessRuleGroup.RuleGroupArn
Priority: 1
StatefulRuleGroupReferences:
- ResourceArn: !GetAtt StatefulRuleGroup.RuleGroupArn

# Network Firewall
NetworkFirewall:
Type: AWS::NetworkFirewall::Firewall
Properties:
FirewallName: !Ref FirewallName
FirewallPolicyArn: !Ref FirewallPolicy
VpcId: !Ref VpcId
SubnetMappings:
- SubnetId: !Ref FirewallSubnetId
DeleteProtection: true
SubnetChangeProtection: true

# CloudWatch Log Group for Firewall Logs
FirewallLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/aws/network-firewall/${FirewallName}"
RetentionInDays: 30

# Logging Configuration
FirewallLogging:
Type: AWS::NetworkFirewall::LoggingConfiguration
Properties:
FirewallArn: !Ref NetworkFirewall
LoggingConfiguration:
LogDestinationConfigs:
- LogType: ALERT
LogDestinationType: CloudWatchLogs
LogDestination:
logGroup: !Ref FirewallLogGroup
- LogType: FLOW
LogDestinationType: CloudWatchLogs
LogDestination:
logGroup: !Ref FirewallLogGroup

Outputs:
FirewallArn:
Description: ARN of the Network Firewall
Value: !Ref NetworkFirewall

FirewallPolicyArn:
Description: ARN of the Firewall Policy
Value: !Ref FirewallPolicy

FirewallEndpointIds:
Description: Firewall endpoint IDs (use these in route tables)
Value: !Select [0, !GetAtt NetworkFirewall.EndpointIds]

Deploy the template:

aws cloudformation create-stack \
--stack-name network-firewall-stack \
--template-body file://template.yaml \
--parameters \
ParameterKey=VpcId,ParameterValue=<your-vpc-id> \
ParameterKey=FirewallSubnetId,ParameterValue=<your-subnet-id> \
ParameterKey=FirewallName,ParameterValue=my-network-firewall \
--region us-east-1
Terraform (optional)
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "vpc_id" {
description = "The VPC ID where the Network Firewall will be deployed"
type = string
}

variable "firewall_subnet_id" {
description = "The subnet ID for the Network Firewall endpoint"
type = string
}

variable "firewall_name" {
description = "Name for the Network Firewall"
type = string
default = "my-network-firewall"
}

# Stateless Rule Group
resource "aws_networkfirewall_rule_group" "stateless" {
capacity = 100
name = "${var.firewall_name}-stateless-rules"
type = "STATELESS"

rule_group {
rules_source {
stateless_rules_and_custom_actions {
stateless_rule {
priority = 1
rule_definition {
actions = ["aws:forward_to_sfe"]
match_attributes {
source {
address_definition = "0.0.0.0/0"
}
destination {
address_definition = "0.0.0.0/0"
}
}
}
}
}
}
}
}

# Stateful Rule Group - Domain filtering
resource "aws_networkfirewall_rule_group" "stateful" {
capacity = 100
name = "${var.firewall_name}-stateful-rules"
type = "STATEFUL"

rule_group {
rules_source {
rules_source_list {
generated_rules_type = "ALLOWLIST"
target_types = ["HTTP_HOST", "TLS_SNI"]
targets = [".amazonaws.com", ".aws.amazon.com"]
}
}
}
}

# Firewall Policy
resource "aws_networkfirewall_firewall_policy" "main" {
name = "${var.firewall_name}-policy"

firewall_policy {
stateless_default_actions = ["aws:forward_to_sfe"]
stateless_fragment_default_actions = ["aws:forward_to_sfe"]

stateless_rule_group_reference {
priority = 1
resource_arn = aws_networkfirewall_rule_group.stateless.arn
}

stateful_rule_group_reference {
resource_arn = aws_networkfirewall_rule_group.stateful.arn
}
}
}

# Network Firewall
resource "aws_networkfirewall_firewall" "main" {
name = var.firewall_name
firewall_policy_arn = aws_networkfirewall_firewall_policy.main.arn
vpc_id = var.vpc_id

subnet_mapping {
subnet_id = var.firewall_subnet_id
}

delete_protection = true
subnet_change_protection = true
}

# CloudWatch Log Group
resource "aws_cloudwatch_log_group" "firewall" {
name = "/aws/network-firewall/${var.firewall_name}"
retention_in_days = 30
}

# Logging Configuration
resource "aws_networkfirewall_logging_configuration" "main" {
firewall_arn = aws_networkfirewall_firewall.main.arn

logging_configuration {
log_destination_config {
log_destination = {
logGroup = aws_cloudwatch_log_group.firewall.name
}
log_destination_type = "CloudWatchLogs"
log_type = "ALERT"
}

log_destination_config {
log_destination = {
logGroup = aws_cloudwatch_log_group.firewall.name
}
log_destination_type = "CloudWatchLogs"
log_type = "FLOW"
}
}
}

output "firewall_arn" {
description = "ARN of the Network Firewall"
value = aws_networkfirewall_firewall.main.arn
}

output "firewall_policy_arn" {
description = "ARN of the Firewall Policy"
value = aws_networkfirewall_firewall_policy.main.arn
}

output "firewall_endpoint_ids" {
description = "Firewall endpoint IDs (use these in route tables)"
value = aws_networkfirewall_firewall.main.firewall_status[0].sync_states[*].attachment[0].endpoint_id
}

Deploy with Terraform:

terraform init
terraform plan -var="vpc_id=<your-vpc-id>" -var="firewall_subnet_id=<your-subnet-id>"
terraform apply -var="vpc_id=<your-vpc-id>" -var="firewall_subnet_id=<your-subnet-id>"

Verification

After deploying the Network Firewall, verify it is working:

  1. Check firewall status in the console

  2. Re-run the Prowler check

    prowler aws --check networkfirewall_in_all_vpc -r us-east-1
CLI verification commands

List all firewalls:

aws network-firewall list-firewalls --region us-east-1

Get firewall details:

aws network-firewall describe-firewall \
--firewall-name my-vpc-firewall \
--region us-east-1

Check firewall status:

aws network-firewall describe-firewall \
--firewall-name my-vpc-firewall \
--query 'FirewallStatus.Status' \
--output text \
--region us-east-1

Expected output: READY

Verify logging is configured:

aws network-firewall describe-logging-configuration \
--firewall-name my-vpc-firewall \
--region us-east-1

Additional Resources

Notes

  • Cost considerations: AWS Network Firewall charges based on firewall endpoint hours and data processed. Review the pricing page before deployment.

  • Subnet requirements: Deploy firewall endpoints in dedicated subnets (one per Availability Zone). Do not place other resources in firewall subnets.

  • Route table updates required: After creating the firewall, you must update your VPC route tables to direct traffic through the firewall endpoints. Without proper routing, the firewall will not inspect traffic.

  • High availability: For production workloads, deploy firewall endpoints in multiple Availability Zones to ensure redundancy.

  • Centralized vs. distributed: You can either deploy a firewall in each VPC or use a centralized "inspection VPC" with AWS Transit Gateway for hub-and-spoke architectures.

  • Default-deny posture: Start with a permissive policy during initial deployment to avoid blocking legitimate traffic, then gradually tighten rules based on observed traffic patterns.

  • Logging is essential: Always enable logging to CloudWatch Logs or S3 to monitor firewall activity and troubleshoot connectivity issues.