Chapter 23: Network Segmentation — Containing the Blast Radius

"The network is not a castle with thick walls. It is a submarine with watertight compartments. When one compartment floods, the others must hold." — NIST Special Publication 800-125B

Picture a corporate network map — not a neat topology diagram but a tangled web of connections. Now trace a red line from a compromised printer on the guest WiFi all the way to the production database server. If a printer on the guest WiFi can reach the production database, you are looking at a flat network. Every device can talk to every other device. The printer, the security cameras, the developer laptops, the payment processing servers — all on the same subnet with no barriers between them.

That is how most networks start. Everything on 10.0.0.0/8, one big happy family. And when an attacker compromises any single device — even the cheapest IoT sensor — they have a direct path to the crown jewels. This chapter shows you how to fix that.


Why Flat Networks Are Dangerous

A flat network is one where all devices share a single broadcast domain with no internal filtering or segmentation. Every device can communicate directly with every other device at Layer 2, and there are no firewalls or ACLs between them.

graph LR
    subgraph "Flat Network — 10.0.0.0/16"
        GW[Guest WiFi<br/>10.0.1.5] --- SW[Core Switch]
        DL[Developer Laptop<br/>10.0.1.20] --- SW
        PS[Payment Server<br/>10.0.1.50] --- SW
        DB[Production Database<br/>10.0.1.100] --- SW
        CAM[Security Camera<br/>10.0.1.200] --- SW
        PRINTER[Network Printer<br/>10.0.1.201] --- SW
    end

    ATTACKER[Attacker] -->|Compromises| GW
    GW -.->|"Direct path<br/>no barriers"| DB

    style DB fill:#ff6b6b,stroke:#c0392b,color:#fff
    style GW fill:#ff6b6b,stroke:#c0392b,color:#fff

Lateral Movement — How Attackers Exploit Flat Networks

Once inside a flat network, an attacker moves laterally — hopping from one compromised system to another — using a well-practiced playbook:

flowchart TD
    A[Initial Compromise<br/>Guest WiFi device] --> B[Network Discovery<br/>nmap -sn 10.0.0.0/16]
    B --> C[Service Enumeration<br/>nmap -sV open hosts]
    C --> D{Find credentials?}
    D -->|SSH keys in ~/.ssh| E[Pivot to servers via SSH]
    D -->|Passwords in .env files| F[Access databases directly]
    D -->|NTLM hashes in memory| G[Pass-the-hash attack]
    D -->|No credentials found| H[Exploit vulnerable services<br/>Unpatched SMB, Redis, etc.]

    E --> I[Credential Harvesting<br/>on new host]
    F --> J[Data Exfiltration]
    G --> I
    H --> I

    I --> K{More targets?}
    K -->|Yes| C
    K -->|Found crown jewels| J

    style A fill:#f39c12,stroke:#e67e22,color:#fff
    style J fill:#ff6b6b,stroke:#c0392b,color:#fff

Common lateral movement techniques:

# What an attacker does after compromising one host in a flat network

# 1. Discover the network topology
ip addr show                  # What network am I on?
ip route show                 # What networks can I reach?
arp -a                        # What hosts are nearby?
cat /etc/resolv.conf          # What DNS server? (often reveals AD domain)

# 2. Scan for other hosts and services
nmap -sn 10.0.0.0/16         # Ping sweep — find live hosts
nmap -sV -p 22,80,443,445,3306,5432,6379,8080,8443,27017 10.0.0.0/16
# Finds: SSH, HTTP, SMB, MySQL, PostgreSQL, Redis, web apps, MongoDB

# 3. Harvest credentials from the compromised host
find / -name "*.env" -o -name "credentials*" -o -name "*.pem" \
  -o -name "*.key" -o -name "wp-config.php" 2>/dev/null
cat ~/.ssh/known_hosts        # Where has this host SSH'd to before?
cat ~/.bash_history           # Previous commands (often contain passwords)
strings /proc/*/environ 2>/dev/null | grep -i password  # Process env vars
cat /etc/shadow               # If we have root — password hashes

# 4. Pivot to discovered services
ssh -i stolen_key admin@10.0.1.100
mysql -h 10.0.1.50 -u root -p'found_password'
redis-cli -h 10.0.1.60       # Redis often has no authentication
curl http://10.0.1.70:8500/v1/kv/?recurse  # Consul KV store — secrets!

# 5. Living off the land (Windows)
# These use legitimate admin tools — hard to detect
psexec.exe \\10.0.1.100 cmd.exe
wmic /node:10.0.1.100 process call create "cmd.exe"
Enter-PSSession -ComputerName 10.0.1.100

Segmentation is about limiting how far an attacker can move once inside. You cannot prevent all breaches. But you can contain them. If the guest WiFi is on a separate segment with no route to the database, compromising a guest device gives the attacker access to... the internet. Which they already had.


VLANs: The Foundation of Segmentation

Virtual LANs (VLANs) divide a physical network into multiple logical broadcast domains at Layer 2. Devices on different VLANs cannot communicate directly — traffic between VLANs must pass through a router or Layer 3 switch, which can apply access control lists (ACLs).

graph TD
    subgraph "Layer 3 Switch / Router"
        R[Inter-VLAN Routing<br/>with ACLs]
    end

    subgraph "VLAN 10 — Guest WiFi"
        G1[Guest Device 1]
        G2[Guest Device 2]
    end

    subgraph "VLAN 20 — Corporate Users"
        C1[Employee Laptop 1]
        C2[Employee Laptop 2]
    end

    subgraph "VLAN 30 — Application Servers"
        A1[Web Server]
        A2[API Server]
    end

    subgraph "VLAN 40 — Database Servers"
        D1[PostgreSQL Primary]
        D2[PostgreSQL Replica]
    end

    R --- G1 & G2
    R --- C1 & C2
    R --- A1 & A2
    R --- D1 & D2

    R -->|"ACL: VLAN 10 → VLAN 30: DENY ALL"| BLOCK1[Blocked]
    R -->|"ACL: VLAN 10 → VLAN 40: DENY ALL"| BLOCK2[Blocked]
    R -->|"ACL: VLAN 20 → VLAN 30: ALLOW 443 only"| ALLOW1[Allowed]
    R -->|"ACL: VLAN 30 → VLAN 40: ALLOW 5432 only"| ALLOW2[Allowed]

    style BLOCK1 fill:#ff6b6b,stroke:#c0392b,color:#fff
    style BLOCK2 fill:#ff6b6b,stroke:#c0392b,color:#fff
    style ALLOW1 fill:#2ecc71,stroke:#27ae60,color:#fff
    style ALLOW2 fill:#2ecc71,stroke:#27ae60,color:#fff

VLAN Configuration

Cisco IOS:

! Create VLANs
vlan 10
  name Guest-WiFi
vlan 20
  name Corporate-Users
vlan 30
  name Application-Servers
vlan 40
  name Database-Servers

! Assign access port to a VLAN (single VLAN, untagged)
interface GigabitEthernet0/1
  switchport mode access
  switchport access vlan 30
  spanning-tree portfast

! Trunk port (carries multiple VLANs, tagged with 802.1Q)
interface GigabitEthernet0/24
  switchport mode trunk
  switchport trunk allowed vlan 10,20,30,40
  switchport trunk native vlan 999    ! Unused VLAN as native — security

! Inter-VLAN routing with ACL
ip access-list extended BLOCK-GUEST-TO-SERVERS
  deny   ip 10.10.0.0 0.0.255.255 10.30.0.0 0.0.255.255
  deny   ip 10.10.0.0 0.0.255.255 10.40.0.0 0.0.255.255
  permit ip any any

interface Vlan10
  ip address 10.10.0.1 255.255.0.0
  ip access-group BLOCK-GUEST-TO-SERVERS in

VLAN Hopping Attacks

VLANs provide Layer 2 isolation, but they can be subverted through **VLAN hopping** attacks:

**1. Switch Spoofing:**
An attacker's device negotiates a trunk link with the switch using DTP (Dynamic Trunking Protocol). Once trunked, the attacker can send and receive frames on any VLAN.

**Defense:**

! Disable DTP on all access ports interface range GigabitEthernet0/1-20 switchport mode access switchport nonegotiate


**2. Double Tagging:**
The attacker sends a frame with two 802.1Q tags. The first tag matches the native VLAN and is stripped by the first switch. The second tag is the target VLAN — the frame is then forwarded to the target VLAN by the second switch.

**Defense:**

! Use a dedicated, unused VLAN as the native VLAN switchport trunk native vlan 999 ! Tag native VLAN traffic explicitly vlan dot1q tag native


**3. ARP Spoofing within a VLAN:**
Devices on the same VLAN can ARP spoof each other, enabling man-in-the-middle attacks within the VLAN.

**Defense:** Enable Dynamic ARP Inspection (DAI) and DHCP snooping:

ip dhcp snooping ip dhcp snooping vlan 10,20,30,40 ip arp inspection vlan 10,20,30,40


DMZ Architecture

A Demilitarized Zone (DMZ) is a network segment that sits between the public internet and the internal network. It hosts services that must be publicly accessible while keeping the internal network unreachable from outside.

graph TD
    INTERNET[Internet] --> EXT_FW

    subgraph EXT_FW["External Firewall"]
        EF["ALLOW: 80, 443 to DMZ only<br/>DENY: all to internal<br/>DENY: all other inbound"]
    end

    EXT_FW --> DMZ

    subgraph DMZ["DMZ Segment"]
        WEB[Web Server<br/>Reverse Proxy]
        MAIL[Mail Gateway<br/>Spam Filter]
        DNS[External DNS]
    end

    DMZ --> INT_FW

    subgraph INT_FW["Internal Firewall<br/>(Different vendor from external)"]
        IF["ALLOW: DMZ web → internal app:8080<br/>DENY: DMZ → all other internal<br/>DENY: DMZ-initiated connections<br/>(except whitelisted)"]
    end

    INT_FW --> INTERNAL

    subgraph INTERNAL["Internal Network"]
        APP[App Servers]
        DBS[Database Servers]
        AD[Active Directory]
    end

    style EXT_FW fill:#e74c3c,stroke:#c0392b,color:#fff
    style INT_FW fill:#e74c3c,stroke:#c0392b,color:#fff

DMZ Design Principles

  1. Two firewalls from different vendors: If one vendor's firewall has a zero-day vulnerability, the other may not. This prevents a single exploit from piercing both boundaries. Use, for example, Palo Alto externally and Fortinet internally.

  2. Minimal DMZ services: Only services that must be publicly accessible go in the DMZ. Internal applications, databases, Active Directory — never in the DMZ.

  3. DMZ cannot initiate connections inward: The internal firewall blocks DMZ-to-internal connections except for specific, required ports and destinations. If the web server is compromised, it cannot scan or attack internal systems.

  4. No direct internet-to-internal path: The two-firewall design ensures there is no single device that, if compromised, bridges the internet to the internal network.

  5. Separate management plane: Admin access to DMZ hosts uses a dedicated management VLAN, not the DMZ network or public internet.

Modern cloud architectures implement the DMZ concept using public and private subnets:

**AWS VPC:**

Internet Gateway → Public Subnet (ALB, NAT Gateway, Bastion) ← DMZ equivalent → Private Subnet (App Servers) ← Internal tier → Isolated Subnet (RDS, ElastiCache) ← Data tier


- **Public subnet:** Route to Internet Gateway. Hosts load balancers and bastion hosts.
- **Private subnet:** No direct internet route. Outbound through NAT Gateway. Hosts application servers.
- **Isolated subnet:** No internet route at all (not even NAT). Hosts databases.

Security Groups and Network ACLs serve the same purpose as DMZ firewalls — controlling traffic flow between tiers. The key difference: in cloud, these are software-defined and can be version-controlled, audited, and deployed via Infrastructure as Code (Terraform, CloudFormation).

East-West vs. North-South Traffic

This distinction is fundamental to understanding modern segmentation needs.

graph TD
    INTERNET[Internet / External Clients]

    INTERNET -->|"North-South Traffic<br/>(client ↔ data center)<br/>Inspected by perimeter firewall"| DC

    subgraph DC["Data Center / Cloud"]
        SVC_A[Service A<br/>User API]
        SVC_B[Service B<br/>Orders]
        SVC_C[Service C<br/>Payments]
        SVC_D[Service D<br/>Notifications]

        SVC_A <-->|"East-West Traffic<br/>(service ↔ service)<br/>80% of all DC traffic<br/>Often UNINSPECTED"| SVC_B
        SVC_B <-->|"East-West"| SVC_C
        SVC_A <-->|"East-West"| SVC_D
        SVC_C <-->|"East-West"| SVC_D
    end

    style INTERNET fill:#3498db,stroke:#2980b9,color:#fff

Traditional firewalls sit at the perimeter — they inspect north-south traffic beautifully. But once an attacker is inside, they move east-west between services. Gartner estimated in 2023 that east-west traffic accounts for over 80% of data center traffic. If you only secure the perimeter, you are protecting 20% of your traffic flows and leaving 80% unmonitored.

So you need firewalls between internal services too. That is micro-segmentation, and it is the modern approach. But first, consider the breach that made the entire industry rethink segmentation.


The Target Breach: A Segmentation Failure Case Study

In November 2013, attackers stole credit card data from 40 million customers and personal information from 70 million customers of Target Corporation. The breach cost Target over $200 million, and both the CEO and CIO resigned. This breach is the textbook example of segmentation failure.

**The attack chain:**

```mermaid
flowchart TD
    A["1. Phishing email to Fazio Mechanical<br/>(HVAC vendor)"] --> B["2. Fazio credentials stolen<br/>(Remote access to Target network)"]
    B --> C["3. Lateral movement:<br/>Vendor portal → POS network<br/>(No segmentation between zones)"]
    C --> D["4. RAM-scraping malware deployed<br/>on POS terminals across 1,797 stores"]
    D --> E["5. Card data captured from memory<br/>during swipe and decrypt"]
    E --> F["6. Data staged on internal server<br/>then exfiltrated via FTP"]
    F --> G["7. 40M credit cards + 70M personal records stolen"]

    style A fill:#f39c12,stroke:#e67e22,color:#fff
    style G fill:#ff6b6b,stroke:#c0392b,color:#fff

What proper segmentation would have prevented:

  1. HVAC vendor on isolated VLAN: The vendor portal should have been on a separate network segment with NO route to the POS network. The HVAC vendor needed access to billing and project management systems — not point-of-sale terminals.

  2. POS network with restricted outbound: POS terminals should only connect to the payment processor's IP addresses on specific ports. No FTP, no general internet access, no connections to internal staging servers.

  3. Internal firewall between zones: Even if the attacker reached the corporate network, firewall rules should have blocked any path from the vendor zone to the POS zone.

  4. Outbound filtering: The exfiltration happened via FTP from the POS network to external servers. Egress filtering would have blocked this immediately.

The irony: Target had a $1.6 million security monitoring system from FireEye that actually detected the malware and generated alerts. But the alerts were not acted upon. Segmentation would have made the attack architecturally impossible — no amount of alert fatigue could override a missing network route.


---

## Micro-Segmentation

Micro-segmentation extends the concept from network-level (VLANs between subnets) to workload-level (policies between individual services, containers, or even processes).

```mermaid
graph TD
    subgraph "Traditional Segmentation (VLAN-based)"
        subgraph "App VLAN"
            TA[Service A]
            TB[Service B]
            TC[Service C]
        end
        subgraph "DB VLAN"
            TX[Database X]
            TY[Database Y]
        end
        TA --> TX
        TA --> TY
        TB --> TX
        TB --> TY
        TC --> TX
        TC --> TY
    end

    subgraph "Micro-Segmentation (Workload-level)"
        subgraph "Same Network"
            MA[Service A]
            MB[Service B]
            MC[Service C]
            MX[Database X]
            MY[Database Y]
        end
        MA -->|"Policy: ALLOW 5432"| MX
        MC -->|"Policy: ALLOW 5432"| MY
        MB -.->|"Policy: DENY ALL to databases"| MX
        MB -.->|"Policy: DENY ALL to databases"| MY
        MA -.->|"Policy: DENY"| MY
        MC -.->|"Policy: DENY"| MX
    end

    style TB fill:#2ecc71,stroke:#27ae60,color:#fff
    style MB fill:#ff6b6b,stroke:#c0392b,color:#fff

In traditional segmentation, all services in the App VLAN can reach all databases in the DB VLAN. In micro-segmentation, each service has specific policies — Service A can only reach Database X, Service C can only reach Database Y, and Service B cannot reach any database at all.

AWS Security Groups — Micro-Segmentation in Cloud

# Create security groups that reference each other (not IP-based)

# ALB security group — accepts traffic from internet
aws ec2 create-security-group \
  --group-name alb-sg \
  --description "Load balancer — public HTTPS" \
  --vpc-id vpc-abc123

aws ec2 authorize-security-group-ingress \
  --group-id sg-alb456 \
  --protocol tcp --port 443 \
  --cidr 0.0.0.0/0

# API service security group — accepts traffic ONLY from ALB
aws ec2 create-security-group \
  --group-name api-sg \
  --description "API service — HTTPS from ALB only"

aws ec2 authorize-security-group-ingress \
  --group-id sg-api789 \
  --protocol tcp --port 8080 \
  --source-group sg-alb456    # Reference ALB SG, not IP range

# Database security group — accepts traffic ONLY from API service
aws ec2 create-security-group \
  --group-name database-sg \
  --description "Database — PostgreSQL from API only"

aws ec2 authorize-security-group-ingress \
  --group-id sg-db012 \
  --protocol tcp --port 5432 \
  --source-group sg-api789    # Reference API SG, not IP range

# Cache security group — accepts traffic ONLY from API service
aws ec2 authorize-security-group-ingress \
  --group-id sg-cache345 \
  --protocol tcp --port 6379 \
  --source-group sg-api789

The key advantage of security group references (vs. IP-based rules): when instances scale up or down, the rules automatically apply to new instances that join the security group. No IP addresses to manage.

Kubernetes Network Policies

# Default deny ALL ingress in the namespace
# This is the "default DROP" equivalent for Kubernetes
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-ingress
  namespace: production
spec:
  podSelector: {}     # Applies to ALL pods in namespace
  policyTypes:
    - Ingress
  # No ingress rules = deny all ingress

---
# Allow API pods to receive traffic from ingress controller only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-service
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress-nginx
        - podSelector:
            matchLabels:
              app: nginx-ingress-controller
      ports:
        - protocol: TCP
          port: 8080

---
# Allow ONLY the API pods to reach the database on port 5432
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-to-database
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: api-service
      ports:
        - protocol: TCP
          port: 5432

---
# Default deny ALL egress — then whitelist
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-egress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Egress
  # No egress rules = deny all egress

---
# Allow API pods to reach database and DNS only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-egress-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-service
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: database
      ports:
        - protocol: TCP
          port: 5432
    - to: []                    # Allow DNS resolution
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

The Kubernetes default-deny policy follows the same principle as setting a firewall default to DROP. Start with deny all, then create explicit allow rules for each required communication path. If a service does not have a policy allowing traffic to it, nothing can reach it.

Important: Kubernetes NetworkPolicies require a CNI plugin that supports them. Calico, Cilium, and Weave all support NetworkPolicies. The default kubenet CNI does NOT — policies will be accepted by the API server but never enforced. Verify your CNI supports policies before relying on them.

Map your service communication patterns before implementing micro-segmentation:

~~~bash
# Kubernetes — use Cilium Hubble to see actual traffic flows
hubble observe --namespace production --type l7

# Or capture SYN packets to see new connections being established
sudo tcpdump -i any -nn \
  'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0' \
  -w /tmp/syn-packets.pcap
# This captures ONLY SYN packets (new connections)
# Analyze to see which services talk to which

# View current connections on a server
ss -tunapl | grep ESTAB | awk '{print $5, "->", $6}'

# AWS — enable VPC Flow Logs for traffic analysis
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-id vpc-abc123 \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name vpc-flow-logs

# Query flow logs to find communication patterns
# (AWS Athena or CloudWatch Logs Insights)
# fields @timestamp, srcAddr, dstAddr, dstPort, action
# | filter action = "ACCEPT"
# | stats count(*) as connections by srcAddr, dstAddr, dstPort
# | sort connections desc
# | limit 50
~~~

PCI DSS Cardholder Data Environment (CDE) Segmentation

For organizations processing credit card payments, PCI DSS requires the cardholder data environment to be isolated from the rest of the network. Proper segmentation is not optional — it is a compliance requirement, and it dramatically reduces the scope of PCI audits.

graph TD
    subgraph "Out of PCI Scope"
        CORP[General Corporate Network<br/>Email, HR, Marketing, Dev]
    end

    CORP -->|"Firewall<br/>(Strict rules, logged,<br/>reviewed quarterly)"| FW_PCI

    subgraph "PCI Scope (CDE)"
        FW_PCI[PCI Boundary Firewall]

        subgraph "Cardholder Data Environment"
            POS[POS Terminals]
            PAY[Payment Processing Servers]
            CARD_DB[Card Data Database<br/>(Encrypted at rest)]
            HSM[HSMs<br/>(Encryption keys)]
            TOK[Tokenization Service]
        end
    end

    POS -->|"Port 443 only"| PAY
    PAY --> CARD_DB
    PAY --> HSM
    PAY --> TOK
    TOK -->|"Returns token,<br/>not card number"| CORP

    style FW_PCI fill:#e74c3c,stroke:#c0392b,color:#fff

PCI DSS segmentation requirements (v4.0):

  • Requirement 1.3: Network connections between the CDE and other networks must be restricted — only traffic that is necessary for business purposes
  • Requirement 1.4: Inbound traffic to the CDE must be restricted to only necessary communications
  • Requirement 11.3.4: Penetration testing must verify that segmentation controls are operational and effective
  • Segmentation testing frequency: At least every 6 months for service providers, annually for merchants

Benefits of CDE segmentation:

  • Only systems in the CDE are subject to PCI audit — dramatically reducing scope
  • Audit costs drop from "entire organization" to "just the CDE"
  • Security controls can be concentrated on the CDE
  • Breach impact is limited to the isolated segment

The Target breach would have been impossible if the POS network was properly segmented as a CDE. The HVAC vendor would have had no route to the payment systems. The POS terminals would have had no route to the internet for data exfiltration. Segmentation is not just a best practice — for PCI compliance, it is a requirement with teeth.


Cloud Network Architecture

How does all this translate to cloud environments? The concepts are identical — isolate workloads, restrict communication, default deny. The implementation uses cloud-native primitives instead of physical switches and firewalls.

AWS Multi-VPC Architecture

graph TD
    subgraph "Production VPC (10.1.0.0/16)"
        subgraph "Public Subnet (10.1.1.0/24)"
            ALB_P[Application Load Balancer]
            NAT_P[NAT Gateway]
        end
        subgraph "Private Subnet (10.1.2.0/24)"
            EC2_P[App Servers]
        end
        subgraph "Data Subnet (10.1.3.0/24)"
            RDS_P[RDS PostgreSQL]
            REDIS_P[ElastiCache Redis]
        end
    end

    subgraph "Development VPC (10.2.0.0/16)"
        subgraph "Public Subnet (10.2.1.0/24)"
            ALB_D[ALB]
        end
        subgraph "Private Subnet (10.2.2.0/24)"
            EC2_D[App Servers]
        end
        subgraph "Data Subnet (10.2.3.0/24)"
            RDS_D[RDS]
        end
    end

    subgraph "Shared Services VPC (10.0.0.0/16)"
        AD[Active Directory]
        SIEM[SIEM / Logging]
        CICD[CI/CD Pipeline]
        BASTION[Bastion Host]
    end

    TGW[Transit Gateway<br/>"Controlled routing between VPCs"]

    ALB_P --> EC2_P
    EC2_P --> RDS_P
    EC2_P --> REDIS_P

    ALB_D --> EC2_D
    EC2_D --> RDS_D

    EC2_P --- TGW
    EC2_D --- TGW
    AD --- TGW
    SIEM --- TGW

    TGW -->|"Route table:<br/>Prod ↔ Shared: ALLOW<br/>Dev ↔ Shared: ALLOW<br/>Prod ↔ Dev: DENY"| ROUTING[Routing Rules]

    style TGW fill:#3498db,stroke:#2980b9,color:#fff
AWS provides multiple segmentation mechanisms at different layers:

| Mechanism | OSI Layer | Scope | Stateful? | Best For |
|-----------|-----------|-------|-----------|----------|
| Security Groups | L4 | Instance/ENI | Yes (return traffic auto-allowed) | Per-workload micro-segmentation |
| Network ACLs | L4 | Subnet | No (must allow return traffic explicitly) | Subnet-level broad rules |
| VPC Peering | L3 | VPC-to-VPC | N/A (routing) | Point-to-point VPC connectivity |
| Transit Gateway | L3 | Multi-VPC routing | N/A (routing) | Hub-and-spoke multi-VPC architecture |
| PrivateLink | L4 | Service endpoint | N/A | Expose a service to other VPCs without routing |
| AWS Firewall Manager | L3-7 | Organization-wide | Yes | Centralized policy management |

**Best practice:** Use Security Groups as your primary micro-segmentation tool (reference other SGs by ID, not by IP). Use Network ACLs as a secondary "safety net" with broad deny rules. Use separate VPCs for different environments (prod, staging, dev) with Transit Gateway for controlled interconnection. Use PrivateLink to expose internal services without full VPC peering.

IoT Segmentation

IoT devices are particularly dangerous because they:

  • Run outdated, unpatched firmware
  • Have weak or default credentials (often hardcoded)
  • Cannot run endpoint protection agents
  • Often use insecure protocols (Telnet, unencrypted HTTP)
  • Are rarely monitored
graph TD
    subgraph "IoT VLAN (VLAN 50) — 10.50.0.0/24"
        CAM[Security Cameras]
        HVAC[HVAC Controllers]
        SENSOR[Building Sensors]
        PRINTER[Network Printers]
    end

    subgraph "IoT Management VLAN (VLAN 51)"
        MGMT[IoT Management Server<br/>Firmware updates, monitoring]
    end

    subgraph "Corporate Network"
        CORP_NET[Corporate Systems]
    end

    CAM -->|"ALLOW: Port 8443 only"| MGMT
    HVAC -->|"ALLOW: Port 8443 only"| MGMT
    SENSOR -->|"ALLOW: Port 8443 only"| MGMT
    PRINTER -->|"ALLOW: Port 9100 only<br/>from print server"| MGMT

    CAM -.->|"DENY ALL"| CORP_NET
    CAM -.->|"DENY ALL"| INTERNET[Internet]
    CAM -.->|"DENY: Port isolation<br/>Cannot reach other IoT"| SENSOR

    style CAM fill:#f39c12,stroke:#e67e22,color:#fff
    style HVAC fill:#f39c12,stroke:#e67e22,color:#fff

If a camera is compromised:

  • No route to corporate network — cannot access email, databases, AD
  • No route to internet — cannot exfiltrate data or reach C2 servers
  • Cannot scan or attack other IoT devices (port isolation)
  • Can only reach the management server, which is hardened and monitored

Segmentation Verification and Testing

Segmentation you don't test is segmentation you don't have. Configuration drift, emergency changes, and "temporary" exceptions erode segmentation continuously.

The Segmentation Test Matrix

Build a matrix of expected allow/deny rules between every zone pair and verify it regularly:

From \ ToDMZApp TierDB TierInternetGuest WiFi
Internet80,443 onlyDENYDENYN/AN/A
DMZN/A8080 onlyDENYDENYDENY
App TierDENYN/A5432 only443 (ext APIs)DENY
DB TierDENYDENYN/ADENYDENY
Guest WiFiDENYDENYDENY80,443 onlyN/A
# Automated segmentation verification script
#!/bin/bash
# segmentation-test.sh — Run from each network zone

TESTS=(
    "DMZ_TO_DB:10.30.0.1:5432:DENY"
    "DMZ_TO_APP:10.20.0.1:8080:ALLOW"
    "APP_TO_DB:10.40.0.1:5432:ALLOW"
    "APP_TO_DB_SSH:10.40.0.1:22:DENY"
    "GUEST_TO_APP:10.20.0.1:8080:DENY"
    "GUEST_TO_INTERNET:8.8.8.8:443:ALLOW"
)

for test in "${TESTS[@]}"; do
    IFS=':' read -r name host port expected <<< "$test"
    result=$(timeout 3 bash -c "echo >/dev/tcp/$host/$port" 2>&1 && echo "OPEN" || echo "CLOSED")

    if [[ "$expected" == "DENY" && "$result" == "CLOSED" ]]; then
        echo "[PASS] $name — $host:$port is blocked (expected)"
    elif [[ "$expected" == "ALLOW" && "$result" == "OPEN" ]]; then
        echo "[PASS] $name — $host:$port is open (expected)"
    else
        echo "[FAIL] $name — $host:$port is $result (expected $expected)"
    fi
done

# Verify cloud security groups
aws ec2 describe-security-groups --group-ids sg-api123 \
  --query 'SecurityGroups[*].IpPermissions[*].{
    Port:FromPort, Source:UserIdGroupPairs[0].GroupId,
    CIDR:IpRanges[0].CidrIp
  }' --output table

Common Segmentation Mistakes

Here are the mistakes that organizations make repeatedly.

1. Segmenting the network but not management access. SSH and RDP bypass all segmentation if a single admin account can reach every zone. Use jump boxes/bastion hosts with session recording. Require separate credentials per zone.

2. Allowing "temporary" exceptions that become permanent. A developer needs access from dev to the production database "just for this migration." Six months later, the rule is still there. Use time-limited firewall rules with automatic expiration. If your firewall does not support TTLs on rules, track exceptions in a ticket system with mandatory review dates.

3. Over-permissive rules between tiers. Allowing all ports between the app tier and database tier defeats the purpose. Allow ONLY the specific database port (5432 for PostgreSQL, 3306 for MySQL, 6379 for Redis). Not "all TCP." Not even "all TCP above 1024."

4. Not segmenting outbound traffic (egress filtering). If a compromised server can make arbitrary outbound connections, it can reach C2 servers, exfiltrate data, and download tools. Restrict outbound to only required destinations. If an app server only needs to reach api.stripe.com and smtp.sendgrid.net, those should be the only allowed outbound destinations.

5. Forgetting about DNS. DNS (port 53) is typically allowed everywhere — it is the most commonly used covert channel. Attackers use DNS tunneling to exfiltrate data and communicate with C2 servers through DNS queries. Force all DNS through internal resolvers and monitor for anomalous patterns (high query volume, long subdomain names, TXT record queries to unusual domains).

6. Not testing segmentation regularly. Network changes, new services, firewall rule updates, and configuration drift erode segmentation over time. Automated testing monthly, manual verification quarterly, penetration testing annually.


What You've Learned

This chapter covered network segmentation as the fundamental architectural control for containing breaches and limiting lateral movement:

  • Flat networks allow any compromised device to reach any other device. Lateral movement in a flat network is trivial — the attacker scans, finds credentials, pivots, and repeats until reaching the target.

  • VLANs provide Layer 2 isolation and are the foundation of segmentation. They have limitations including VLAN hopping (switch spoofing, double tagging) and lack of application awareness. Harden trunk ports and disable DTP.

  • DMZ architecture isolates public-facing services from internal systems using dual firewalls (ideally from different vendors). The internal firewall prevents DMZ-initiated connections to the internal network.

  • East-west traffic (service-to-service within the data center) represents 80%+ of traffic and is where lateral movement happens. Traditional perimeter security only addresses the 20% of north-south traffic.

  • Micro-segmentation applies policies at the individual workload level using cloud security groups, Kubernetes NetworkPolicies, or host-based firewalls. Default deny, then explicitly allow only required communication paths.

  • The Target breach demonstrated that insufficient segmentation between an HVAC vendor network and the POS network enabled a $200 million+ data breach that proper segmentation would have prevented architecturally — the attack path simply would not have existed.

  • PCI DSS CDE segmentation is a compliance requirement that reduces audit scope and concentrates security controls on payment-processing systems.

  • Cloud segmentation uses VPCs, security groups, network ACLs, and Transit Gateway to achieve the same isolation patterns as physical network segmentation — with the added benefit of infrastructure-as-code management.

  • Test your segmentation. Build a test matrix of expected allow/deny rules between every zone pair and verify it regularly. Segmentation you don't test is segmentation you don't have.

Segmentation is not about preventing the initial breach — it is about making sure a breach in one area does not mean a breach everywhere. You assume breach. Then you design your network so that a compromised IoT camera cannot reach the customer database, a phished employee cannot access the payment system, and a vendor with remote access cannot see anything beyond their designated portal. The submarine compartments hold even when one floods.