Tools: Implementing a Three-Zone DMZ With a Single Firewall: iptables Rules, Zone Isolation, and Traffic Flow Analysis
Network topology
Default zone policies
iptables implementation
Traffic flow verification
DNAT for public service exposure
Reverse proxy in the DMZ
CacheGuard zone architecture 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. The firewall's default posture for each zone crossing: After applying rules, verify each permitted and denied flow: To expose DMZ services to the internet via the gateway's public IP: A more secure architecture places a reverse proxy in the DMZ rather than the web server directly. The reverse proxy: 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 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/ Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to ? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse
[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]
[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]
[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]
# 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
# 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
# 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
# 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)
# 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)
# 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)
# 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
# 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
# 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
[Internet] → eth0 → [DMZ: Reverse Proxy + WAF] → eth2 → [Internal: App server]
[Internet] → eth0 → [DMZ: Reverse Proxy + WAF] → eth2 → [Internal: App server]
[Internet] → eth0 → [DMZ: Reverse Proxy + WAF] → eth2 → [Internal: App server] - Terminates TLS (holds the certificate private key)
- Applies WAF inspection (ModSecurity + OWASP CRS)
- Forwards clean requests to backend servers in the internal zone