NAT, Firewall, Security Group #

When designing and securing virtual networks in the cloud, we can’t rely on just a single gateway. Reliable cloud network security applies the Defense in Depth model (Layered Defense) using a combination of security components working at different levels: NAT Gateway, Security Groups, and Network Access Control Lists (NACL). Each of these components serves a different purpose — from providing secure one-way outbound internet access for private servers, to filtering incoming data packets at the subnet level and the virtual machine instance level. Understanding how stateful versus stateless filtering works, and how to optimally configure these components, is the key to building a robust and functional network defense fortress in the cloud.

NAT Gateway: One-Way Outbound Internet Access #

Resources isolated inside a private subnet have no public IP address, so they can’t be reached by anyone from the public internet. However, in daily application operations, those private servers often need outbound internet access — for example, downloading OS security patch updates, installing code library dependencies, or calling external third-party API endpoints (like a payment gateway).

That’s where the NAT (Network Address Translation) Gateway comes in. The NAT Gateway sits in the Public Subnet and acts as a one-way outbound bridge:

flowchart TD
    App["App Server (Private Subnet - IP: 10.0.10.5)"]
    NAT["NAT Gateway (Public Subnet - Public IP: 54.123.45.1)"]
    Internet["Public Internet (Target: 8.8.8.8)"]
    
    App -->|"1. Send Request to 8.8.8.8"| NAT
    NAT -->|"2. SNAT: Replace Source IP 10.0.10.5 -> 54.123.45.1"| Internet
    Internet -->|"3. Return Answer to 54.123.45.1"| NAT
    NAT -->|"4. Translate back & forward to 10.0.10.5"| App

Source NAT (SNAT) Mechanism: #

  1. Connection Initiation: The App Server sends an outbound HTTP request to the internet. This data packet has a sender IP (Source IP) of the instance’s private IP (10.0.10.5).
  2. Address Translation: The packet passes through the NAT Gateway. The NAT Gateway records this connection in its mapping table, replaces the private Source IP with the NAT Gateway’s own static public IP (54.123.45.1), then sends it to the internet.
  3. Return Response: The internet sends the response packet back to the NAT Gateway’s public IP.
  4. Redistribution: The NAT Gateway reads its mapping table to match the connection port, translates the destination address back to the instance’s private IP (10.0.10.5), and forwards it safely to the App Server.

From the public internet’s perspective, data traffic appears to come only from the NAT Gateway’s single public IP. The internet never knows our private server’s IP exists behind the scenes, and the outside internet cannot initiate new connections toward our private servers.

The NAT Gateway is a managed service with automatic scaling (auto-scaling). It’s designed to handle thousands of concurrent connections and automatically scales its bandwidth capacity up to 45 Gbps (on AWS) without requiring configuration or manual intervention from us.

NAT Gateway Cost Optimization Strategies: #

Although very useful, the NAT Gateway is one of the higher-cost operational components in the cloud. We’re charged a per-hour rental fee per NAT Gateway instance, plus a per-GB Data Processing Fee for traffic passing through it.

To save costs, we can apply the following strategies:

  • Deploy VPC Endpoints: Use free VPC Gateway Endpoints to access internal cloud provider services (like AWS S3 or DynamoDB) so that data traffic doesn’t need to exit through the NAT Gateway.
  • NAT Instance as an Alternative: For non-production environments (Dev/Test), we can replace the managed NAT Gateway with a NAT Instance (a small EC2 virtual machine configured as a NAT router using Linux iptables scripts). This is far cheaper although it requires manual maintenance and lacks built-in auto-scaling.

Security Group: Virtual Firewall at the Instance Level #

Security Groups (SGs) act as the first-level virtual firewall granularly controlling inbound and outbound data traffic for our compute resources. SGs attach directly at the virtual network interface (Elastic Network Interface/ENI) level of Virtual Machines, databases, or Load Balancers.

Key Security Group Characteristics: #

  • Stateful: SGs maintain a connection state table. If we allow a request inbound on a specific port, that request’s return response is automatically allowed outbound without needing to register it in the outbound rules. This minimizes misconfiguration errors and simplifies administration.
  • Allow-Only: We can only write rules that allow (Allow). There’s no option to explicitly write blocking (Deny) rules. All data traffic not registered in SG rules is automatically dropped by default.
  • Security Group Chaining: We can designate another Security Group as a rule’s Source or Destination, replacing static IP CIDR blocks.
// ANTI-PATTERN: Writing static IP addresses for auto-scaling resources
  Inbound Rule: Allow TCP Port 8080 from Source: 10.0.1.45/32 (Load Balancer IP)
  
  Problems:
  ✗ The Load Balancer IP can change at any time during scaling.
  ✗ Every time Load Balancer instances increase, we must manually edit this IP rule.

// CORRECT: Use Security Group Chaining (SG Reference)
  Inbound Rule: Allow TCP Port 8080 from Source: sg-load-balancer-id
  
  Benefits:
  ✓ All new auto-scaled VMs using the Load Balancer SG are automatically allowed.
  ✓ No manual IP maintenance during machine replacement.

Network ACL (NACL): Firewall at the Subnet Level #

Network Access Control Lists (NACLs) are an additional security layer acting as a protective firewall at the subnet boundary. Every data packet wanting to enter or leave a subnet must pass NACL inspection first before touching the Security Group level.

Key NACL Characteristics: #

  • Stateless: NACLs don’t remember connection status. Inbound and outbound rules are evaluated separately and independently. If we allow inbound traffic on port 80, we must create an outbound rule allowing the ephemeral port response so communication doesn’t break.
  • Supports Allow & Deny Rules: Unlike Security Groups, NACLs support explicitly writing blocking (Deny) rules. This is very useful for blocking specific IP ranges detected doing port scanning or DDoS attacks.
  • Sequential Evaluation (Numbered Rules): NACL rules are evaluated in order from the smallest rule number to the largest. Evaluation stops immediately upon finding the first matching rule (first match).
Example NACL Inbound Rule Evaluation Order:
  Rule #100: Deny  TCP Port 22 from Source: 198.51.100.45/32 (Attacker IP)
  Rule #200: Allow TCP Port 22 from Source: 0.0.0.0/0 (Entire internet)
  
  Result: SSH requests from IP 198.51.100.45 match Rule 100 and are blocked (Deny).
  SSH requests from other IPs skip Rule 100 (no match), continue to Rule 200, and are allowed.

Ephemeral Port Challenges on Stateless NACLs: #

Because NACLs are stateless, we must understand the concept of Ephemeral Ports. When our application server (e.g., in a private subnet) initiates an outbound connection to a database on port 5432, the application server’s OS opens a random short-lived port in the 1024 - 65535 range (OS-dependent) to receive the database’s return response.

If we don’t open the 1024-65535 port range in our private subnet NACL inbound rules, the database’s response packets are blocked by the NACL, causing connection timeouts even though our Security Group is configured correctly.


Network Security Extensions: Web Application Firewall (WAF) & IDS/IPS #

Although Security Groups and NACLs are strong enough to filter traffic by IP addresses and network ports (Layers 3 and 4), both aren’t smart enough to inspect data packet content (Layer 7).

To protect our web applications from advanced cyber attacks, we need additional protection layers:

1. Web Application Firewall (WAF) #

WAFs work at the application level (Layer 7) to deeply inspect HTTP/HTTPS payloads. WAFs sit in front of Application Load Balancers (ALBs) or CDNs (CloudFront/Cloudflare).

  • Function: Can detect and block web application attacks like SQL Injection, Cross-Site Scripting (XSS), session parameter manipulation, and bad bot activity. WAFs analyze string patterns inside request URLs and HTTP bodies.

2. Intrusion Detection & Prevention System (IDS/IPS) #

To detect network threats invisible to regular firewalls (like malware, ransomware, or traffic anomalies), large companies deploy IDS/IPS inside their VPC.

  • VPC Traffic Mirroring: A feature duplicating data packets from VM network interfaces asynchronously without disrupting original throughput performance, then sending copies to custom IDS servers for attack pattern analysis.
flowchart TD
    Trafik["Public Internet"] --> WAF["1. Web Application Firewall (Layer 7 - Payload Check)"]
    WAF --> ALB["2. Load Balancer (Routing)"]
    ALB --> NACL["3. Network ACL (Subnet Boundary - Stateless)"]
    NACL --> SG["4. Security Group (Instance Boundary - Stateful)"]
    SG --> VM["5. Virtual Machine Instance"]

The table below compares the three security filtering tools in depth:

Comparison CriteriaSecurity GroupNetwork ACL (NACL)Web Application Firewall (WAF)
OSI LayerLayers 3 & 4 (Network/Transport).Layers 3 & 4 (Network/Transport).Layer 7 (Application).
Filtering BasisIP Addresses, Network Ports, Protocols.IP Addresses, Network Ports, Protocols.HTTP Payload Content, Headers, Cookies, Patterns.
Inspection AbilityCan’t see data/payload content.Can’t see data/payload content.Can decrypt SSL & inspect data payloads.
Protection FitRestricting SSH/Database port access.Blocking attacker subnet IPs (DDoS).Preventing SQL Injection, XSS, Bad User Agents.

Code Example: Implementing NAT Gateway & Layered Security via Terraform #

Here’s an example Terraform declaration for deploying a NAT Gateway with an Elastic IP in the Public Subnet, plus configuring a custom Network ACL for private subnets that explicitly blocks attacker IPs:

# ✓ CORRECT: Use Terraform to deploy a NAT Gateway and configure custom NACLs securely

# 1. Allocate an Elastic IP for the NAT Gateway
resource "aws_eip" "nat_eip" {
  domain = "vpc"
  tags = {
    Name = "production-nat-eip"
  }
}

# 2. Deploy the NAT Gateway in Public Subnet 1
resource "aws_nat_gateway" "nat_gw" {
  allocation_id = aws_eip.nat_eip.id
  subnet_id     = aws_subnet.public_az1.id # Must be placed in a public subnet

  tags = {
    Name = "production-nat-gateway"
  }
}

# 3. Custom Network ACL for the Private Subnet (Application Subnet)
resource "aws_network_acl" "private_nacl" {
  vpc_id     = aws_vpc.main.id
  subnet_ids = [aws_subnet.private_az1.id, aws_subnet.private_az2.id]

  # --- INBOUND RULES ---

  # ✓ CORRECT: Block specific attacker IPs at the smallest rule number (Deny Rule)
  ingress {
    protocol   = "tcp"
    rule_no    = 50
    action     = "deny"
    cidr_block = "198.51.100.45/32" # Blocked attacker IP
    from_port  = 0
    to_port    = 65535
  }

  # Allow inbound traffic from the internal VPC
  ingress {
    protocol   = "-1"
    rule_no    = 100
    action     = "allow"
    cidr_block = "10.0.0.0/16"
    from_port  = 0
    to_port    = 0
  }

  # ✓ CORRECT: Open inbound Ephemeral Ports to receive return responses from the internet (outbound call responses)
  ingress {
    protocol   = "tcp"
    rule_no    = 110
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 1024
    to_port    = 65535
  }

  # --- OUTBOUND RULES ---

  # Allow outbound traffic to the local VPC
  egress {
    protocol   = "-1"
    rule_no    = 100
    action     = "allow"
    cidr_block = "10.0.0.0/16"
    from_port  = 0
    to_port    = 0
  }

  # Allow outbound traffic to the internet (via NAT Gateway for OS patching)
  egress {
    protocol   = "tcp"
    rule_no    = 110
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 80
    to_port    = 80
  }

  egress {
    protocol   = "tcp"
    rule_no    = 120
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 443
    to_port    = 443
  }

  tags = {
    Name = "private-subnet-nacl"
  }
}

Summary #

  • NAT Gateways guarantee one-way outbound internet access for private subnets — private servers can call the outside internet, but the outside internet is totally blocked from initiating inbound connections.
  • Optimize NAT Gateway costs by leveraging free VPC Endpoint services for internal traffic like S3/DynamoDB.
  • Security Groups are stateful instance-level firewalls — responses from allowed connections pass automatically without separate outbound rule configuration.
  • Use Security Group Chaining to reference other SGs as connection sources, supporting instant auto-scaling flexibility.
  • Network ACLs (NACLs) are stateless subnet-level firewalls — requiring us to configure outbound and inbound rules separately, including opening ephemeral ports 1024-65535.
  • Use a WAF (Web Application Firewall) at Layer 7 to protect web apps from SQL injection and HTTP payload exploits.
  • Use the smallest rule number in NACLs to set explicit Deny rules blocking attacker IP addresses before packets reach application servers.

← Previous: Public vs Private Network   Next: Load Balancing →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact