DEV Community

ZeroTrust Architect
ZeroTrust Architect

Posted on • Originally published at cacheguard.com

Implementing a Three-Zone DMZ With a Single Firewall: iptables Rules, Zone Isolation, and Traffic Flow Analysis

A DMZ is implemented by placing internet-facing servers in a network zone that is accessible from the internet but isolated from the internal LAN. A single firewall with three network interfaces is sufficient for most SME deployments. Here is the technical implementation.

DMZ Network

Network topology

[Internet]
    |
   eth0 (WAN: 203.0.113.1)
    |
[Firewall/Gateway]
    |           |
   eth1        eth2
(DMZ:        (Internal LAN:
192.168.10.0/24)  192.168.1.0/24)
    |
[Web server: 192.168.10.5]
[Email server: 192.168.10.6]
Enter fullscreen mode Exit fullscreen mode

Default zone policies

The firewall's default posture for each zone crossing:

From → To Default policy Rationale
Internet → DMZ Deny (explicit permits only) Only specific published services allowed
Internet → Internal Deny all No direct external access to internal LAN
DMZ → Internal Deny all Compromised DMZ server cannot reach internal
Internal → DMZ Permit Internal hosts manage DMZ servers
Internal → Internet Permit Outbound internal traffic allowed
DMZ → Internet Permit (restricted) DMZ servers can reach external resources

iptables implementation

# Flush existing rules
iptables -F FORWARD
iptables -P FORWARD DROP   # Default deny all zone crossings

# === INTERNET → DMZ ===
# Allow inbound HTTPS to web server
iptables -A FORWARD -i eth0 -o eth1 -d 192.168.10.5 -p tcp --dport 443 -j ACCEPT
# Allow inbound SMTP to email server
iptables -A FORWARD -i eth0 -o eth1 -d 192.168.10.6 -p tcp --dport 25 -j ACCEPT
# Allow established/related return traffic
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# === INTERNET → INTERNAL ===
# Default DROP already covers this (no explicit permit)

# === DMZ → INTERNAL ===
# Default DROP covers this.
# Explicit permit: web server to internal database only
iptables -A FORWARD -i eth1 -s 192.168.10.5 -o eth2 \
  -d 192.168.1.20 -p tcp --dport 5432 -j ACCEPT
iptables -A FORWARD -i eth2 -s 192.168.1.20 -o eth1 \
  -d 192.168.10.5 -m state --state ESTABLISHED,RELATED -j ACCEPT

# === INTERNAL → DMZ ===
# Allow internal management access to all DMZ servers
iptables -A FORWARD -i eth2 -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth2 -m state --state ESTABLISHED,RELATED -j ACCEPT

# === INTERNAL → INTERNET ===
iptables -A FORWARD -i eth2 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth2 -m state --state ESTABLISHED,RELATED -j ACCEPT

# === DMZ → INTERNET ===
# DMZ servers can reach the internet for updates, API calls
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

# === NAT ===
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Enter fullscreen mode Exit fullscreen mode

Traffic flow verification

After applying rules, verify each permitted and denied flow:

# Should succeed: internal host reaching DMZ web server
curl -k https://192.168.10.5  # from 192.168.1.x host

# Should succeed: internet reaching DMZ web server (test with external tool)
curl -k https://203.0.113.1   # after DNAT rule (see below)

# Should fail: DMZ server reaching internal LAN (not the database)
# From 192.168.10.5:
ping 192.168.1.1    # Expected: no response (FORWARD DROP)
Enter fullscreen mode Exit fullscreen mode

DNAT for public service exposure

To expose DMZ services to the internet via the gateway's public IP:

# DNAT: inbound HTTPS on public IP → DMZ web server
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 \
  -j DNAT --to-destination 192.168.10.5:443
Enter fullscreen mode Exit fullscreen mode

Reverse proxy in the DMZ

A more secure architecture places a reverse proxy in the DMZ rather than the web server directly. The reverse proxy:

  • Terminates TLS (holds the certificate private key)
  • Applies WAF inspection (ModSecurity + OWASP CRS)
  • Forwards clean requests to backend servers in the internal zone
[Internet] → eth0 → [DMZ: Reverse Proxy + WAF] → eth2 → [Internal: App server]
Enter fullscreen mode Exit fullscreen mode

The app server is never directly reachable from the internet. Only the reverse proxy is in the DMZ. WAF inspection happens before any request reaches the application.

CacheGuard zone architecture

CacheGuard implements this via its native zone model: external zone (eth0), internal/web zone (eth1) with optional rweb VLAN for web servers, and auxiliary zone (eth2) for general DMZ services. Zone policies are configured through the web interface without writing iptables rules directly.

https://www.cacheguard.com/what-is-a-dmz-network/


Originally published on the CacheGuard Blog. CacheGuard is free and open source — GitHub.

Top comments (0)