Skip to main content

Chapter 4.1 - Firewall Architecture, Segmentation & Zero Trust

Module 4: Defense Engineering & Hardening This module shifts perspective entirely - from attacker to defender. Every technique in Module 3 has a structural countermeasure. This chapter covers the foundational controls.


Table of Contents

  1. Firewall Generations & Processing Models
  2. Stateful Inspection - Connection Tracking & State Tables
  3. Next-Generation Firewalls - Application Awareness & Deep Inspection
  4. iptables & nftables - Linux Packet Filtering in Depth
  5. Network Segmentation - Zones, DMZ Design & VLANs
  6. Micro-Segmentation & East-West Traffic Control
  7. Zero Trust Architecture - Principles, Components & Implementation
  8. Firewall Rule Auditing & Misconfiguration Detection
  9. Defensive Metrics & Validation
  10. MITRE ATT&CK Mapping & Control Coverage

1. Firewall Generations & Processing Models

Firewalls evolved from simple packet filters to application-aware inspection engines. Understanding what each generation can and cannot enforce is essential for designing layered defenses - no single generation handles all threat classes.

Evolution of Firewall Technology

GenerationCore MechanismVisibilityBlind Spots
Packet filter (L3/L4)ACL on IP/port/protocolHeader fields onlyAll payload; stateless = ACK scan bypass
Stateful inspectionConnection state trackingTCP session lifecycleApplication-layer content; encrypted payloads
Application-layer gateway (proxy)Full protocol proxyApplication commands (FTP, DNS)Non-proxied protocols; TLS without inspection
NGFWDPI + App-ID + User-ID + IPSApplication, user, contentEncrypted C2 without TLS inspection; zero-days
Cloud-native / SASEIdentity + context + cloud deliveryUser, device, app, behaviorDepends on agent deployment; blind on unmanaged devices

Packet Processing Pipeline

Understanding the order in which rules are evaluated prevents logical misconfigurations - a rule that can never be reached because a broader rule precedes it is a common audit finding:

Ingress interface


[Ingress ACL] ← Pre-routing filter (can block before routing decision)


[Routing decision] ← Determines egress interface


[Stateful tracking] ← Is this an established/related connection?

├── Established → fast path (skip deep inspection)

└── New → policy lookup


[Policy match] ← First matching rule wins (most firewalls)


[Action: allow/deny/inspect/log]


[Egress ACL]


Egress interface

First-match vs best-match: Most firewalls (iptables, Palo Alto, Cisco ASA) use first-match - rules are evaluated top-to-bottom and the first match terminates evaluation. A broad ALLOW rule above a specific DENY rule makes the DENY unreachable. This is the source of the vast majority of firewall misconfigurations found in audits.



2. Stateful Inspection - Connection Tracking & State Tables

Stateful firewalls track TCP/UDP/ICMP sessions in a connection tracking table (conntrack). Each entry records the 5-tuple, state, timeout, and expected next transitions. This allows the firewall to:

  • Permit return traffic for established outbound connections without explicit rules
  • Detect out-of-state packets (TCP ACK with no corresponding SYN = potential scan)
  • Enforce protocol behavior (FTP data channel, related ICMP errors)

Linux Connection Tracking

# View the connection tracking table
conntrack -L # List all tracked connections
conntrack -L --proto tcp # TCP only
conntrack -L --state ESTABLISHED # Only established sessions

# Real-time event monitoring (new connections, destroyed sessions)
conntrack -E # Event mode - watch in real time
conntrack -E -e NEW # Only new connection events
conntrack -E -e DESTROY # Only destroyed connections

# Example conntrack output:
# tcp 6 431999 ESTABLISHED src=10.0.1.5 dst=203.0.113.1 sport=54231 dport=443
# src=203.0.113.1 dst=10.0.1.5 sport=443 dport=54231
# [ASSURED] mark=0 use=1
# Fields: proto timeout state original_tuple reply_tuple flags

# Conntrack table statistics
conntrack -S # Per-CPU stats
# Watch for: insert_failed (table full), drop (hash collision)

# Set conntrack table size (for high-traffic environments)
sysctl net.netfilter.nf_conntrack_max # Current max
sysctl -w net.netfilter.nf_conntrack_max=1048576 # Set to 1M entries
echo "net.netfilter.nf_conntrack_max = 1048576" >> /etc/sysctl.conf

# Conntrack timeouts - reduce for DDoS/scan resilience
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=300 # 5 min (default: 5 days!)
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_syn_sent=10 # 10s SYN timeout
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=15 # TIME_WAIT

# Flush entire conntrack table (use with caution - drops all tracked sessions)
conntrack -F

TCP State Tracking and Bypass Techniques

# Stateful rule: only allow NEW and ESTABLISHED inbound, block invalid
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP # Drop invalid state
iptables -A INPUT -j DROP # Default deny

# Why INVALID matters:
# Packets with no corresponding conntrack entry and no SYN flag = INVALID
# This catches: ACK scans, out-of-window RSTs, fragmented packet attacks
# Without this rule, some port scanners bypass stateful inspection

# Detect conntrack table exhaustion attacks (SYN flood fills table)
watch -n 1 'conntrack -S | grep insert_failed'
# Rising insert_failed = table full = new connections dropped = effective DoS

3. Next-Generation Firewalls - Application Awareness & Deep Inspection

NGFWs operate at L7, identifying applications by content signatures rather than port numbers. This matters because attackers routinely run services on non-standard ports (SSH on 443, C2 over HTTP on 8080) or tunnel protocols inside allowed ones (DNS tunneling, HTTP tunneling over port 80).

Application Identification

NGFW App-ID engines work by:

  1. Protocol decoding - parse the application protocol to identify it definitively
  2. Pattern matching - match payload against application signatures
  3. Behavioral analysis - classify based on flow behavior (packet sizes, timing, direction ratios)
  4. Unknown application handling - classify by port if content is unrecognizable (risky fallback)

Palo Alto Networks - Policy Concepts

Palo Alto is the dominant enterprise NGFW. Its policy model organizes rules by Security Zone pairs rather than IP ranges alone:

# PAN-OS CLI - view security policy rules
show security policy-rule all

# Show application usage on a policy rule
show running security-policy

# Check application identification on live sessions
show session all filter application unknown # Sessions with unidentified app
show session all filter state active # All active sessions
show session id 12345 # Detail for specific session

# Application override - force classify traffic (use sparingly)
# Forces PAN to skip App-ID and classify by port only
# Useful for custom internal apps that App-ID can't identify

# Verify which applications are allowed through a rule
show security policy-rule "Allow-Internet" application

# Threat logs - blocked threats from IPS/AV
show log threat direction equal forward | match "critical\|high"

# Traffic logs with application detail
show log traffic application equal unknown start-time equal last-5-minutes

SSL/TLS Inspection Policy

# PAN-OS: verify SSL inspection is active
show running ssl-decrypt

# Key configuration points:
# - Forward Trust cert: corporate CA cert loaded on firewall, trusted by endpoints
# - Forward Untrust cert: different CA for sites with untrusted certs (users see warning)
# - Decryption profile: controls TLS version, cipher requirements, certificate validation
# - Exclusions: banking, healthcare, personal accounts (legal/privacy requirements)

# Check what's being excluded from decryption
show decryption exclude-cache

# Linux/open-source equivalent: Squid with ssl-bump
# Check which connections Squid is decrypting vs splicing:
tail -f /var/log/squid/access.log | grep "CONNECT\|TUNNEL"
# CONNECT = Squid intercepted and decrypted
# TUNNEL = Squid passed through without inspection (excluded)

4. iptables & nftables - Linux Packet Filtering in Depth

iptables - Tables, Chains & Rules

iptables organizes rules into tables (filter, nat, mangle, raw) and chains (INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING). For firewall purposes, the filter table is primary.

# View all rules with line numbers and packet/byte counters
iptables -L -n -v --line-numbers # filter table (default)
iptables -t nat -L -n -v --line-numbers # NAT table
iptables -t mangle -L -n -v # Mangle table

# Save and restore rules (persistent across reboots)
iptables-save > /etc/iptables/rules.v4 # Save current rules
iptables-restore < /etc/iptables/rules.v4 # Restore saved rules

# Production server hardening ruleset
# ============================================
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t mangle -F

# Default policies - deny everything, allow nothing
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT # Allow outbound (adjust per policy)

# Allow loopback (required for local services)
iptables -A INPUT -i lo -j ACCEPT

# Allow established/related return traffic
iptables -A INPUT -m conntrack \
--ctstate ESTABLISHED,RELATED -j ACCEPT

# Drop invalid state packets (ACK scans, out-of-state)
iptables -A INPUT -m conntrack \
--ctstate INVALID -j DROP

# Rate-limit new SSH connections (brute-force protection)
iptables -A INPUT -p tcp --dport 22 \
-m conntrack --ctstate NEW \
-m recent --set --name SSH_BRUTE # Track new SSH connection sources

iptables -A INPUT -p tcp --dport 22 \
-m conntrack --ctstate NEW \
-m recent --update --name SSH_BRUTE \
--seconds 60 \ # Within 60 seconds
--hitcount 4 \ # More than 4 attempts
-j DROP # Drop the connection

iptables -A INPUT -p tcp --dport 22 \
-m conntrack --ctstate NEW -j ACCEPT # Allow SSH if under threshold

# Allow HTTP/HTTPS for web server
iptables -A INPUT -p tcp \
--dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p tcp \
--dport 443 -m conntrack --ctstate NEW -j ACCEPT

# Allow ICMP ping (controlled - rate limited)
iptables -A INPUT -p icmp --icmp-type echo-request \
-m limit --limit 5/second \ # Max 5 pings/second
-j ACCEPT

# Log and drop everything else
iptables -A INPUT -m limit \
--limit 10/minute \ # Don't flood syslog
-j LOG --log-prefix "IPT_DROP: " --log-level 4
iptables -A INPUT -j DROP

nftables - Modern Replacement

nftables is the Linux kernel's successor to iptables, offering better performance, atomic rule updates, and a cleaner syntax. Most distributions now ship nftables by default:

# View current ruleset
nft list ruleset

# nftables equivalent of the iptables ruleset above:
cat > /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset

table inet filter {
# Connection tracking sets for rate limiting
set ssh_brute {
type ipv4_addr
flags dynamic, timeout
timeout 60s
}

chain input {
type filter hook input priority 0
policy drop # Default deny

iif lo accept # Allow loopback
ct state established,related accept # Allow return traffic
ct state invalid drop # Drop invalid state

# SSH rate limiting using nftables sets
tcp dport 22 ct state new \
add @ssh_brute { ip saddr limit rate over 4/minute } \
drop # Drop if > 4 new SSH/min from same IP

tcp dport 22 ct state new accept # Allow SSH under threshold

# Web traffic
tcp dport { 80, 443 } ct state new accept

# ICMP rate limit
ip protocol icmp icmp type echo-request \
limit rate 5/second accept

# Logging
limit rate 10/minute log prefix "NFT_DROP: " level warn
}

chain forward {
type filter hook forward priority 0
policy drop # Default deny forwarding
}

chain output {
type filter hook output priority 0
policy accept # Allow all outbound
}
}
EOF

# Apply ruleset
nft -f /etc/nftables.conf

# Atomic rule update (add rule without disrupting existing connections)
nft add rule inet filter input \
tcp dport 8080 ct state new accept

# List rules with handles (needed for deletion)
nft list chain inet filter input -a

# Delete a specific rule by handle
nft delete rule inet filter input handle 15

# Enable nftables service (persists across reboots)
systemctl enable nftables
systemctl start nftables

5. Network Segmentation - Zones, DMZ Design & VLANs

Security Zone Architecture

The core principle of segmentation: a compromised host in one zone must not automatically have access to hosts in another zone. Every lateral movement technique from Chapter 3.3 relies on flat network access - segmentation defeats it structurally.

Standard zone model:

ZoneHostsTrust LevelFirewall Policy
InternetEverything externalUntrustedDeny all inbound by default
DMZWeb servers, mail, DNS, VPNSemi-trustedAllow specific inbound from Internet; restricted outbound
InternalWorkstations, printersMedium trustAllow outbound to Internet via proxy; no direct Internet inbound
ServerInternal apps, databasesHigh trustStrict access from specific Internal subnets only
OT/ICSIndustrial controlCriticalAir-gap or near-air-gap; no Internet access
ManagementFirewalls, switches, servers (OOB)HighestAccessible only from jump host; MFA required

DMZ Design

# Example: three-interface firewall DMZ
# eth0 = Internet (untrusted)
# eth1 = DMZ (web servers: 192.168.10.0/24)
# eth2 = Internal LAN (10.0.0.0/24)

# Internet to DMZ: allow HTTP/HTTPS to web servers only
iptables -A FORWARD -i eth0 -o eth1 \
-p tcp --dport 443 \
-d 192.168.10.0/24 \
-m conntrack --ctstate NEW -j ACCEPT

iptables -A FORWARD -i eth0 -o eth1 \
-p tcp --dport 80 \
-d 192.168.10.0/24 \
-m conntrack --ctstate NEW -j ACCEPT

# Internet to Internal: deny ALL (no exceptions)
iptables -A FORWARD -i eth0 -o eth2 -j DROP

# DMZ to Internal: deny ALL (compromise of web server does not equal access to LAN)
iptables -A FORWARD -i eth1 -o eth2 -j DROP

# DMZ to Internet: allow only specific outbound (patch updates, API calls)
iptables -A FORWARD -i eth1 -o eth0 \
-p tcp --dport 443 \
-s 192.168.10.0/24 \
-m conntrack --ctstate NEW -j ACCEPT

# Internal to DMZ: allow HTTP/HTTPS to web servers (internal access)
iptables -A FORWARD -i eth2 -o eth1 \
-p tcp -m multiport --dports 80,443 \
-m conntrack --ctstate NEW -j ACCEPT

# Internal to Internet: allow via proxy only (transparent proxy on port 3128)
# Force all outbound web traffic through Squid
iptables -t nat -A PREROUTING -i eth2 \
-p tcp --dport 80 \
-j REDIRECT --to-port 3128 # Redirect HTTP to Squid transparent proxy

# Allow established return traffic in all directions
iptables -A FORWARD -m conntrack \
--ctstate ESTABLISHED,RELATED -j ACCEPT

# Log inter-zone violations
iptables -A FORWARD -j LOG \
--log-prefix "FW_FORWARD_DENY: " --log-level 4
iptables -A FORWARD -j DROP

VLAN Configuration for Segmentation

# Linux: create VLAN sub-interfaces (802.1Q tagging)
# Requires: modprobe 8021q

modprobe 8021q
echo "8021q" >> /etc/modules

# Create VLAN interfaces
ip link add link eth0 name eth0.10 type vlan id 10 # VLAN 10 = DMZ
ip link add link eth0 name eth0.20 type vlan id 20 # VLAN 20 = Internal
ip link add link eth0 name eth0.30 type vlan id 30 # VLAN 30 = Server

# Assign IPs
ip addr add 192.168.10.1/24 dev eth0.10
ip addr add 10.0.20.1/24 dev eth0.20
ip addr add 10.0.30.1/24 dev eth0.30

# Bring up interfaces
ip link set eth0.10 up
ip link set eth0.20 up
ip link set eth0.30 up

# Cisco IOS switch - VLAN configuration (for context)
# vlan 10
# name DMZ
# vlan 20
# name Internal
# interface GigabitEthernet0/1
# switchport mode trunk
# switchport trunk allowed vlan 10,20,30
# interface GigabitEthernet0/2
# switchport mode access
# switchport access vlan 10

# Verify VLAN separation - traffic on VLAN 10 should not reach VLAN 20
# without traversing the firewall/router
ping -I eth0.10 10.0.20.5 # Should fail if properly segmented

6. Micro-Segmentation & East-West Traffic Control

Traditional segmentation controls north-south traffic (between zones). Micro-segmentation controls east-west traffic (between hosts within the same zone) - the attack path exploited by lateral movement.

The Lateral Movement Problem

In a flat network (no micro-segmentation), a compromised workstation on the Internal VLAN can reach every other workstation - enabling worm propagation, pass-the-hash, and SMB relay across the entire segment. Micro-segmentation limits the blast radius.

Host-Based Firewall Enforcement

# Windows: enforce Windows Firewall via GPO
# Computer Configuration -> Windows Settings -> Security Settings ->
# Windows Defender Firewall with Advanced Security
# Block inbound SMB between workstations:

# PowerShell: block SMB inbound from non-server subnets
New-NetFirewallRule \
-DisplayName "Block Lateral SMB" \
-Direction Inbound \
-Protocol TCP \
-LocalPort 445 \
-RemoteAddress "10.0.0.0/24" \ # Block from workstation subnet to workstation
-Action Block \
-Profile Domain

# Allow SMB only from IT management subnet
New-NetFirewallRule \
-DisplayName "Allow SMB from IT" \
-Direction Inbound \
-Protocol TCP \
-LocalPort 445 \
-RemoteAddress "10.0.100.0/24" \ # IT management subnet only
-Action Allow \
-Profile Domain

# Linux: restrict lateral access between servers
# Allow only specific source IPs to reach a service
nft add rule inet filter input \
ip saddr != 10.0.30.0/24 \ # Not from Server subnet
tcp dport 5432 drop # Block PostgreSQL from non-server hosts

Software-Defined Perimeter with eBPF/Cilium

For Kubernetes and cloud-native environments, Cilium uses eBPF to enforce network policy at the kernel level with zero performance impact:

# Cilium NetworkPolicy - allow only specific pods to reach the database
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: db-access-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: postgres # Policy applies to postgres pods
ingress:
- fromEndpoints:
- matchLabels:
app: api-server # Only api-server pods can connect
toPorts:
- ports:
- port: "5432"
protocol: TCP
egress:
- toFQDNs: # Allow DNS resolution only
- matchPattern: "*.internal"
# Apply policy
kubectl apply -f db-access-policy.yaml

# Verify policy is enforced
cilium policy get
cilium endpoint list # Show per-pod policy status

# Test policy enforcement
kubectl exec -it test-pod -- nc -zv postgres-svc 5432
# Should succeed from api-server pod, fail from all others

7. Zero Trust Architecture - Principles, Components & Implementation

Zero Trust Principles

Zero Trust rejects the perimeter security model ("trusted inside, untrusted outside") because:

  • Lateral movement is trivial once perimeter is breached (demonstrated in Module 3)
  • Remote work, cloud, and BYOD have dissolved the perimeter
  • Insider threats bypass perimeter controls entirely

Core tenets (NIST SP 800-207):

  1. All resources are accessed over secure, authenticated channels - location (IP, VLAN, VPN-connected) is not an implicit trust signal
  2. Access is granted per-session and per-resource - no persistent broad access grants
  3. Access policy incorporates all available context - user identity, device health, location, time, request behavior
  4. The network is assumed hostile - east-west traffic is inspected, not trusted

Zero Trust Components

+--------------------------------------------------------------+
| Control Plane |
| +-------------------+ +------------------+ |
| | Policy Engine |<---| Identity Provider| (Okta, AAD) |
| | (Access Decision | | Device Trust | (Intune, MDM)|
| | Point) | | Threat Intel |(CrowdStrike) |
| +--------+----------+ +------------------+ |
| | Policy Decision |
+-----------+--------------------------------------------------+
|
+-----------v--------------------------------------------------+
| Data Plane |
| +------------------------------------------------------+ |
| | Policy Enforcement Point (PEP) | |
| | - Reverse proxy / API gateway | |
| | - Network access control | |
| | - Endpoint agent | |
| +------------------------------------------------------+ |
| ^ v |
| Subject Resource |
| (User + Device) (App / Data / Service) |
+--------------------------------------------------------------+

Implementing Zero Trust with nginx + mTLS

A practical starting point: replace implicit network trust with explicit mTLS authentication at the service layer:

# Generate CA and service certificates
# Step 1: Create CA
openssl genrsa -out ca.key 4096
openssl req -new -x509 \
-key ca.key \
-out ca.crt \
-days 3650 \
-subj "/CN=ZeroTrust-Internal-CA"

# Step 2: Generate server certificate for the protected service
openssl genrsa -out server.key 2048
openssl req -new -key server.key \
-out server.csr \
-subj "/CN=api.internal.corp"
openssl x509 -req \
-in server.csr \
-CA ca.crt -CAkey ca.key \
-CAcreateserial \
-out server.crt -days 365

# Step 3: Generate client certificate for each authorized service
openssl genrsa -out client-api.key 2048
openssl req -new -key client-api.key \
-out client-api.csr \
-subj "/CN=frontend-service/O=api-access"
openssl x509 -req \
-in client-api.csr \
-CA ca.crt -CAkey ca.key \
-CAcreateserial \
-out client-api.crt -days 365

# nginx config - require client certificate for access
# /etc/nginx/sites-available/protected-api
server {
listen 443 ssl;
server_name api.internal.corp;

ssl_certificate /etc/ssl/server.crt;
ssl_certificate_key /etc/ssl/server.key;
ssl_client_certificate /etc/ssl/ca.crt; # CA that signed client certs
ssl_verify_client on; # REQUIRE client cert
ssl_verify_depth 2;

ssl_protocols TLSv1.3; # TLS 1.3 only
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;

location / {
# Optionally: check specific CN or OU from client cert
if ($ssl_client_s_dn !~ "O=api-access") {
return 403; # Reject wrong certificate purpose
}
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Client-CN $ssl_client_s_dn_cn; # Pass identity downstream
}
}

Zero Trust with BeyondCorp / Google IAP Model

# Implement IAP-style access control with OAuth2 + device posture
# Using oauth2-proxy as the enforcement point:

docker run -d \
--name oauth2-proxy \
-p 4180:4180 \
quay.io/oauth2-proxy/oauth2-proxy:latest \
--provider=google \
--client-id=YOUR_OAUTH_CLIENT_ID \
--client-secret=YOUR_OAUTH_SECRET \
--cookie-secret=$(python3 -c 'import secrets; print(secrets.token_hex(16))') \
--email-domain=corp.com \ # Only allow @corp.com email addresses
--upstream=http://internal-app:8080 \
--redirect-url=https://app.corp.com/oauth2/callback \
--skip-provider-button=true # Auto-redirect to provider

# nginx: route all traffic through oauth2-proxy
location / {
auth_request /oauth2/auth; # Check authentication first
error_page 401 = /oauth2/sign_in; # Redirect to login if not authenticated

auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;

proxy_set_header X-Forwarded-User $user;
proxy_set_header X-Forwarded-Email $email;
proxy_pass http://internal-app:8080;
}

location /oauth2/ {
proxy_pass http://oauth2-proxy:4180;
proxy_set_header Host $host;
}

8. Firewall Rule Auditing & Misconfiguration Detection

Rule bloat is universal in long-lived firewalls - shadowed rules, overly permissive any/any rules, and stale rules for decommissioned systems accumulate over years.

# fwaudit - open-source firewall rule analysis
# Detects: shadowed rules, unreachable rules, any/any, missing logging

# Parse iptables rules and analyze
iptables-save > /tmp/current_rules.txt
fwaudit --iptables /tmp/current_rules.txt \
--report /tmp/audit_report.html

# Manual analysis: find any/any rules in iptables
iptables -L -n | grep -E "0\.0\.0\.0/0.*0\.0\.0\.0/0.*ACCEPT"
# Any rule accepting from anywhere to anywhere = immediate finding

# Find rules with no logging (accept rules without a matching log rule)
iptables -L -n -v | grep ACCEPT | \
awk '{print $8, $9, $10}' | sort -u # Show destinations of ACCEPT rules

# Find shadowed rules - a rule that can never be reached
# Example: ACCEPT any -> 10.0.0.0/8 (rule 3) is shadowed by ACCEPT any -> 0.0.0.0/0 (rule 1)
# Manual inspection required - iptables doesn't flag this automatically

# nmap-based rule validation - test from outside what should be blocked
# From the internet-facing interface, test that DMZ restrictions hold:
nmap -sS \
-p 22,3389,445,1433,3306 \ # High-risk ports that should be blocked
--open \
192.168.10.0/24 # DMZ subnet
# Any open results = firewall misconfiguration

# Test inter-zone controls from inside
# From Internal LAN, verify you cannot reach the database directly
nmap -sT -p 5432,3306,1433 \
10.0.30.0/24 \ # Server subnet
--source-ip 10.0.20.50 # From workstation IP

# Cisco ASA: check for any/any rules
show access-list | grep "permit ip any any"
show access-list | grep "permit tcp any any"

# Palo Alto: find overly permissive rules
show security policy-rule all | \
match "any.*any.*any.*allow"

9. Defensive Metrics & Validation

Measuring Segmentation Effectiveness

# Automated segmentation testing - Nmap sweep from each zone
# Should be run after any firewall rule change

# Create zone test script
cat > /usr/local/bin/segmentation_test.sh << 'EOF'
#!/bin/bash
# Run from each zone, redirect output to SIEM/log

ZONES=(
"10.0.20.0/24:Internal"
"192.168.10.0/24:DMZ"
"10.0.30.0/24:Server"
)

PROBE_PORTS="22,23,80,443,445,3389,1433,3306,5432"

for zone_entry in "${ZONES[@]}"; do
subnet=$(echo $zone_entry | cut -d: -f1)
name=$(echo $zone_entry | cut -d: -f2)
echo "=== Testing access TO $name ($subnet) ==="
nmap -sT -p $PROBE_PORTS --open $subnet \
-oG - 2>/dev/null | \
grep "open" | \
awk -v zone="$name" '{print zone, $2, $5}'
echo ""
done
EOF
chmod +x /usr/local/bin/segmentation_test.sh

# Key firewall metrics to track:
# - Connections per second (capacity planning)
# - Block rate (rising = scan/attack; falling = policy drift)
# - Top blocked source IPs (threat intel)
# - Rule hit counts (zero-hit rules = candidates for removal)
# - Connection table utilization (approaching max = DoS risk)

# iptables: show rule hit counts
iptables -L -n -v | awk '$1 > 0' # Show only rules with packet hits

# Reset counters after policy review
iptables -Z # Zero all packet/byte counters

# Export iptables metrics to Prometheus (node_exporter)
# node_exporter with --collector.iptables flag exposes rule hit counts
# Then visualize in Grafana

10. MITRE ATT&CK Mapping & Control Coverage

ATT&CK TechniqueIDFirewall/Segmentation ControlZero Trust Control
Lateral Movement: SMBT1021.002Block 445 east-west via micro-segDevice trust required per session
Lateral Movement: WMIT1021.006Block 135/dynamic RPC between workstationsEndpoint agent verifies request
C2: Standard Application LayerT1071NGFW App-ID blocks unknown appsEgress proxy with TLS inspection
Exfiltration: Data TransferT1041Egress filtering + DLPPer-session access tokens; data classification
Discovery: Network ScanningT1046Log/alert on cross-zone port scansEvery access requires authenticated request
Valid Accounts: DomainT1078Cannot block (valid credentials)Behavioral anomaly + device posture check
DCSync / RPCT1003.006Block MS-DRSR from non-DC IPsIdentity-aware PEP rejects non-DC
Exploit Public AppT1190WAF + NGFW IPSSASE inspects all traffic regardless of source
Initial Access: PhishingT1566Email gateway; no network blockMFA defeats credential phishing
Defense Evasion: Port KnockingT1205Stateful inspection detects sequenceMutual authentication (mTLS) makes knocking moot

End of Chapter 4.1 - Firewall Architecture, Segmentation & Zero Trust

Next: Chapter 4.2 - SIEM, SOAR & Detection Engineering