Egress Filtering With a Cloud Firewall
Securing outbound network traffic from cloud workloads is a critical component of any robust cloud security posture. While ingress filtering protects…
Securing outbound network traffic from cloud workloads is a critical component of any robust cloud security posture. While ingress filtering protects against external threats, egress filtering prevents unauthorized data exfiltration, limits the impact of compromised systems, and enforces compliance. This article details how to implement comprehensive egress filtering strategies using native cloud firewall services in Azure, AWS, and GCP.
The core principle involves routing all egress traffic from Virtual Networks (VNets) or Virtual Private Clouds (VPCs) through a centralized cloud-managed firewall. This allows for granular, FQDN-based (Fully Qualified Domain Name) allow-listing, ensuring that applications can only communicate with approved external services and blocking all other outbound connections by default. This "deny-all, permit-by-exception" approach significantly reduces the attack surface and provides invaluable telemetry through denied traffic logs.
Centralized Egress Architecture
To effectively enforce egress policies, all outbound traffic from spoke VNets/VPCs must traverse a dedicated firewall instance, typically deployed in a hub VNet/VPC. This centralization simplifies management and ensures policy consistency across the environment.
Azure: Azure Firewall Hub-and-Spoke
In Azure, the recommended architecture for centralized egress filtering is a hub-and-spoke model. Spoke VNets peer with a hub VNet where Azure Firewall is deployed.
- Hub VNet: Contains the Azure Firewall subnet (
AzureFirewallSubnet, minimum /26) and potentially a Gateway Subnet for VPN/ExpressRoute. - Spoke VNets: Host application workloads.
- VNet Peering: Connects spokes to the hub. Ensure "Allow Gateway Transit" is enabled on the hub side peering if spokes need to use a VPN/ExpressRoute gateway in the hub, and "Use Remote Gateways" on the spoke side.
- User-Defined Routes (UDRs): Crucial for redirecting traffic. For each spoke VNet, a UDR must be applied to all subnets from which egress traffic originates. This UDR specifies a default route (
0.0.0.0/0) with the Azure Firewall's private IP address as the next hop.
Azure Firewall is a stateful, managed firewall service that supports FQDN-based rules, network rules (IP/port), and application rules (Layer 7, HTTP/S, SQL, etc.).
AWS: Transit Gateway with AWS Network Firewall
AWS leverages Transit Gateway (TGW) for scalable hub-and-spoke connectivity. AWS Network Firewall is then deployed in a "security VPC" attached to the TGW.
- Transit Gateway: Acts as a central router for VPCs and on-premises networks.
- Security VPC: A dedicated VPC where AWS Network Firewall endpoints are deployed in each Availability Zone. These endpoints are essentially ENIs (Elastic Network Interfaces) with private IPs.
- Spoke VPCs: Workload VPCs.
- Routing:
- Spoke VPC route tables direct
0.0.0.0/0traffic to the TGW. - TGW route tables (one per spoke attachment, or shared) direct traffic destined for the internet to the security VPC attachment.
- Security VPC route tables (for subnets where TGW attaches) direct
0.0.0.0/0traffic to the AWS Network Firewall endpoint ENI. - AWS Network Firewall policy processes the traffic.
- Traffic returning from the Firewall is routed to an Internet Gateway (IGW) or NAT Gateway within the security VPC.
- Spoke VPC route tables direct
AWS Network Firewall is a highly scalable, managed service offering stateful inspection, intrusion prevention, and web filtering, including FQDN filtering.
GCP: Cloud Next-Generation Firewall (Cloud NGFW) with Shared VPC or Network Connectivity Center
GCP offers Cloud NGFW, a managed service integrated with VPC Firewall policies. For centralized egress, Shared VPC is a common pattern, or the newer Network Connectivity Center for larger deployments.
- Shared VPC Host Project: Contains the host network where the Cloud NGFW policies are defined and applied.
- Service Projects: Contain the application workloads, attached to the Shared VPC host network.
- Cloud NGFW Policy: A global resource that can apply policies across multiple VPC networks (in Shared VPC, this means all service projects using that host network). Policies contain hierarchical firewall policy rules.
- Default Route: Egress traffic from instances in service projects (or any VPC subnet) will naturally follow the default route to the internet via the VPC's Internet Gateway, but the Cloud NGFW policy will intercept and evaluate it.
- Network Connectivity Center (NCC): For more complex hub-and-spoke scenarios, NCC allows centralizing network services like Cloud NGFW. Routes would point to the NCC hub, which then directs traffic to a dedicated security VPC for inspection before forwarding to the internet.
GCP Cloud NGFW provides advanced L7 capabilities, threat intelligence, and FQDN filtering, applied at the network edge.
Implementing FQDN-Based Egress Rules
The cornerstone of secure egress is allowing only specific FQDNs that applications legitimately require. This is often an iterative process.
Initial Discovery Phase
Start with a deny-all rule and monitor logs. This is usually not feasible for production environments. A more practical approach for existing applications is a discovery phase:
- Deploy the firewall with a more permissive "monitor" policy initially (e.g., allow all on specific ports, then log everything).
- Deploy your application and run through all its use cases, including updates, package installations, and API calls.
- Analyze the firewall logs to identify all FQDNs and IP addresses the application attempts to reach.
- Compile an allow-list based on these logs.
- Gradually restrict the policy to allow-list only these identified FQDNs.
Remember that many services resolve to multiple IP addresses (CDNs, load balancers) which can change. FQDN rules are crucial here.
Example: Azure Firewall Application Rule for Package Managers
Allowing access to common package managers and update services is a frequent requirement.
# Azure CLI - Create an Azure Firewall application rule collection
az network firewall application-rule collection create \
--firewall-name myAzureFirewall \
--resource-group myResourceGroup \
--name "AppUpdateRules" \
--priority 100 \
--action Allow \
--collection-name "PackageManagers" \
--rule-name "UbuntuUpdates" \
--source-addresses "*" \
--protocols Http=80 Https=443 \
--fqdn-tags "UbuntuServer" # Azure Firewall FQDN Tags simplify management
# Example for Python PyPI
az network firewall application-rule collection rule add \
--firewall-name myAzureFirewall \
--resource-group myResourceGroup \
--collection-name "PackageManagers" \
--name "PyPI" \
--source-addresses "*" \
--protocols Https=443 \
--fqdns "pypi.org" "files.pythonhosted.org"
Azure Firewall supports FQDN Tags (e.g., WindowsUpdate, UbuntuServer) which dynamically update to include all necessary FQDNs for those services, significantly reducing manual management.
Example: AWS Network Firewall Rule Group (Domain List)
AWS Network Firewall uses "rule groups" that can contain stateful rules, including domain lists.
# AWS CLI - Create a stateful domain list rule group
# First, create a file containing the domains
cat << EOF > domains.txt
pypi.org
files.pythonhosted.org
packages.cloud.google.com
security.ubuntu.com
EOF
aws network-firewall create-rule-group \
--rule-group-name "EgressAllowList" \
--type STATEFUL \
--capacity 100 \
--rule-group '
{
"RulesSource": {
"RulesSourceContent": "pass tcp any any -> $HOME_NET 80,443 (msg:\"Allowlist domains\"; flow:established,related; ip:proto 6; sid:1000001; rev:1; content:\"GET\"; http_method; pcre:\"/\";)"
},
"StatelessRulesAndCustomActions": {},
"StatefulRuleOptions": { "RuleOrder": "STRICT_ORDER" }
}' \
--description "Egress FQDN Allow List for common services" \
--tags Key=Environment,Value=Production
# Note: Domain Lists in AWS Network Firewall are created separately and then referenced.
# The actual domain list is uploaded to S3 and referenced in a Suricata-compatible rule.
# A simpler approach is using Suricata rules with 'tls.sni' or 'http.host' keywords.
# Example Suricata rule for FQDNs
# This rule would be part of a Suricata-compatible rule group definition.
# alert tls any any -> any any (msg:"Allow PyPI"; tls.sni; content:"pypi.org"; sid:1000002; rev:1;)
# alert tcp any any -> any [80,443] (msg:"Allow Google Cloud Packages"; http.host; content:"packages.cloud.google.com"; sid:1000003; rev:1;)
AWS Network Firewall's Suricata compatibility allows for powerful, regex-based FQDN matching, including wildcards.
Example: GCP Cloud NGFW FQDN Object and Policy Rule
GCP Cloud NGFW uses FQDN objects and hierarchical firewall policies.
# GCP gcloud CLI - Create an FQDN object
gcloud network-security firewall-endpoint-associations create my-firewall-assoc \
--project=my-host-project \
--location=global \
--network=my-shared-vpc-host-network
# Create an FQDN object (note: this is often done via Security Policies not standalone FQDN objects directly via gcloud for Cloud NGFW.
# Instead, FQDNs are directly specified in L7 rules.)
# GCP gcloud CLI - Example of a Cloud NGFW L7 Policy Rule
# This example assumes a hierarchical firewall policy is already created and associated.
# Rules are added to the policy.
gcloud compute network-firewall-policies rules create 1000 \
--firewall-policy=my-org-firewall-policy \
--action=allow \
--description="Allow outbound to PyPI" \
--direction=EGRESS \
--enable-logging \
--target-resources=projects/my-service-project-id/global/networks/my-shared-vpc-host-network \
--src-ip-ranges=0.0.0.0/0 \
--destination-fqdns="pypi.org,files.pythonhosted.org" \
--ports=443 \
--protocol=tcp \
--priority=1000
GCP's approach is highly integrated with its resource hierarchy and supports granular policy application.
Logging and Monitoring Denied Traffic
Logging denied egress traffic is paramount. These logs provide invaluable insights into:
- Misconfigurations: Applications failing due to missing FQDNs in the allow-list.
- Lateral Movement Attempts: Compromised systems attempting to "call home" or exfiltrate data.
- Shadow IT: Unsanctioned applications attempting to connect to external services.
All cloud firewalls integrate with their respective logging services:
- Azure Firewall: Logs sent to Azure Monitor (Log Analytics Workspace) or Storage Accounts. Use Kusto queries for analysis.
- AWS Network Firewall: Logs sent to Amazon S3 or Amazon CloudWatch Logs. Integrate with Athena or other SIEM tools.
- GCP Cloud NGFW: Logs sent to Cloud Logging. Use Log Explorer and export to BigQuery or Splunk.
Configure alerts for suspicious patterns in denied logs, such as repeated attempts to reach known malicious domains or unusual volumes of denied traffic from a specific workload.
Trade-offs and Considerations
| Feature | Description | Consideration |
|---|---|---|
| Cost | Managed firewall services incur costs based on deployment, data processed, and throughput. | Factor into budget; high traffic can significantly increase costs. |
| Performance/Latency | Introducing an intermediate hop (firewall) can add latency. | Minimal for most applications, but critical low-latency apps might need careful testing. Throughput scales well with managed services. |
| Complexity | Setting up routing, policies, and logging requires careful planning. | Requires a good understanding of networking and cloud-specific firewall features. |
| Management Overhead | Updating FQDN allow-lists as application requirements change. | Automate policy updates where possible (e.g., CI/CD pipelines). Use FQDN tags/groups provided by the firewall. |
| SNI Inspection | For HTTPS traffic, FQDN filtering often relies on Server Name Indication (SNI) for hostname identification. | If applications don't use SNI (rare for modern HTTPS), or if traffic is truly encrypted end-to-end without SNI exposure, L7 FQDN filtering may not work. You might need Layer 4 IP-based rules or TLS inspection (with its own complexities). |
Common Pitfalls
- Incomplete FQDN Lists: Often, initial lists miss internal service calls, authentication endpoints, or less frequent update/telemetry destinations. This leads to application failures. Thorough discovery is key.
- Ignoring IP-based Egress: While FQDNs are preferred, some services (especially legacy or those without proper DNS resolution) might require IP-based rules. Balance between strict FQDN and necessary IP exemptions.
- Asymmetric Routing: Ensure traffic paths are consistent. If return traffic doesn't pass through the firewall, stateful inspection will fail, and connections will drop. This is particularly relevant with complex TGW or peering setups.
- Overly Broad Source/Destination IP Ranges: Don't use
0.0.0.0/0as a source if you can limit it to specific subnets. Similarly, avoidanyfor destination IPs unless absolutely necessary. - Forgetting About Internal DNS Resolution: Ensure your cloud DNS (e.g., Azure DNS Private Zones, AWS Route 53 Private Hosted Zones, GCP Cloud DNS) is correctly configured for internal services. Egress firewalls only handle traffic leaving the VNet/VPC.
- Not Logging Denials: A firewall without logging is a blind security control. Always enable and actively monitor denial logs.