Skip to main content
RunBook Academy

OPNsenseXV · DMZ ArchitectureDMZ services and isolation

Triple-homed firewall — WAN, DMZ, LAN interfaces and the routing decisions

Advanced⏱ ~16 minifconfigpfctlroutetcpdump

What you'll learn

  • Configure the three interfaces of a triple-homed firewall
  • Trace a packet through the firewall between any two of the three interfaces
  • Apply the rule sets that govern each interface
  • Recognise the production traps of three-interface operation

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14

Not yet marked complete on this device.

The triple-homed firewall has three interfaces: WAN, DMZ, and LAN. Each interface has its own IP, its own rule set, and its own role in the routing decisions the firewall makes. The discipline of operating three interfaces is that each interface’s ruleset must be reasoned about independently, the routing table must be consistent across all three, and the default-deny posture must be applied on every interface.

This lesson covers how the triple-homed firewall routes between interfaces, the rule sets that govern each interface, and the production traps that come from operating three interfaces on one firewall.

The three interfaces

A triple-homed firewall has:

  • WAN interface (igb0). Connects to the Internet. The IP is the firewall’s public IP (or behind an ISP gateway with NAT). Inbound traffic from the Internet arrives here.
  • DMZ interface (igb2). Connects to the DMZ switch. The IP is the gateway for the DMZ subnet. Public-facing services live on this subnet.
  • LAN interface (igb1). Connects to the LAN switch. The IP is the gateway for the LAN subnet. Internal users, servers, and infrastructure live on this subnet.

The three interfaces each have a different subnet, a different IP, and a different role. The firewall is the routing point for every inter-interface packet.

Read-only / Safethree interfaces
$ ifconfig igb0 igb1 igb2 2>/dev/null | grep -E '^[a-z]|inet [0-9]'
igb0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
      inet 198.51.100.1 netmask 0xffffffe0 broadcast 198.51.100.31
igb1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
      inet 192.0.2.1 netmask 0xffffff00 broadcast 192.0.2.255
igb2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
      inet 203.0.113.1 netmask 0xffffff00 broadcast 203.0.113.255

Illustrative output

The three interfaces are up and have distinct subnets. The operator can route between them.

The routing table

The routing table for a triple-homed firewall has three connected routes plus a default route:

Read-only / Safetriple-homed routing table
$ netstat -rn | grep -v '::' | head -10
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default            198.51.100.2       UGS     igb0
127.0.0.1          link#4             UH      lo0
192.0.2.0/24       link#6             UC    igb1
198.51.100.0/27    link#5             UC    igb0
203.0.113.0/24     link#7             UC    igb2

Illustrative output

The four routes (three connected, one default) cover every destination. The firewall can reach every IP on every subnet it is attached to, and every Internet destination via the default route.

Packet flow: Internet to DMZ

A packet from the Internet destined for the public web server in the DMZ:

Internet client 203.0.113.50:54321 → WAN IP 198.51.100.1:443 → DMZ web server 203.0.113.10:443
  1. Packet arrives on igb0 (WAN). Source IP = Internet client, destination IP = firewall WAN IP.
  2. PF evaluates rules on igb0. The auto-generated rule from the port-forward permits TCP from any to any on port 443.
  3. NAT redirection. PF rewrites the destination from firewall WAN IP to DMZ web server IP. The destination port is preserved (443 → 443).
  4. State created. PF creates state tracking both the original and the rewritten addresses.
  5. Routing decision. The kernel consults the routing table. The rewritten destination IP 203.0.113.10 matches the connected route on igb2.
  6. PF evaluates rules on igb2 (DMZ). For state-matched traffic, this evaluation is skipped. For new flows on the DMZ interface, the rules apply.
  7. Packet exits on igb2. The frame is delivered to the DMZ web server.

The return traffic follows the same path in reverse: web server → firewall DMZ interface → state match → NAT reverse → WAN interface → Internet.

Packet flow: LAN to DMZ

A packet from a LAN host (e.g. an operator) to a DMZ server for administrative purposes:

LAN host 192.0.2.50:54321 → firewall LAN IP 192.0.2.1 → DMZ server 203.0.113.10:22
  1. Packet arrives on igb1 (LAN). Source IP = LAN host, destination IP = DMZ server IP.
  2. PF evaluates rules on igb1. A specific rule permits the operator’s host to reach the DMZ server on TCP 22 (SSH). State is created.
  3. Routing decision. The kernel consults the routing table. The destination 203.0.113.10 matches the connected route on igb2.
  4. Packet exits on igb2. The frame is delivered to the DMZ server.

The source IP is preserved (the LAN host’s IP), and the destination IP is the DMZ server. No NAT is applied because the traffic is between two RFC 1918 subnets.

Packet flow: DMZ to LAN (denied)

A packet from a compromised DMZ host trying to reach a LAN host:

DMZ host 203.0.113.50:54321 → firewall DMZ IP 203.0.113.1 → LAN host 192.0.2.50:22
  1. Packet arrives on igb2 (DMZ). Source IP = DMZ host, destination IP = LAN host.
  2. PF evaluates rules on igb2. The default deny on the DMZ interface blocks the packet. No state is created.
  3. PF logs the dropped packet. With logging enabled, the firewall log shows the drop.
  4. No routing decision. The packet is dropped before the kernel makes a routing decision.

The default deny on the DMZ interface is the foundation of the segregation. Without it, the compromised DMZ host can reach the LAN.

The rule sets per interface

WAN interface rules

The WAN interface sees inbound traffic from the Internet. The rules:

OrderActionSourceDestinationPortDescription
1passanyDMZ web server80, 443Public HTTP/HTTPS
2passanyDMZ mail server25, 587Public SMTP
3passanyDMZ DNS server53Public DNS
4blockanyRFC 1918anyBlock bogons (RFC 1918 from Internet)
5blockanyanyanyDefault deny

Rules 1-3 are auto-generated from port-forwards. Rule 4 blocks traffic destined to RFC 1918 addresses (which should never appear as destinations on the WAN interface — the Internet does not route to private IPs). Rule 5 is the default deny.

DMZ interface rules

The DMZ interface sees traffic from DMZ hosts. The rules:

OrderActionSourceDestinationPortDescription
1passDMZ serversfirewall DMZ IP53DMZ hosts using firewall DNS
2passmonitoring agentDMZ serversvariousMonitoring scrapes
3passDMZ serversany80, 443Outbound for updates, OCSP
4blockDMZ subnetLAN subnetsanyDMZ cannot reach LAN
5blockanyanyanyDefault deny

Rules 1-3 permit the specific flows the DMZ needs. Rule 4 explicitly blocks DMZ-to-LAN traffic (defense in depth on top of the default deny). Rule 5 is the catch-all.

LAN interface rules

The LAN interface sees traffic from LAN hosts. The rules:

OrderActionSourceDestinationPortDescription
1passLAN subnetfirewall LAN IP80, 443LAN hosts using firewall GUI (if exposed on LAN)
2passLAN subnetfirewall LAN IP22LAN hosts using firewall SSH (if exposed on LAN)
3passLAN subnetDMZ jump hosts22Operators reaching bastion
4passLAN subnetanyanyOutbound Internet (default LAN rule)
5blockanyanyanyDefault deny

Rules 1-2 permit LAN access to the firewall itself (if exposed). Rule 3 permits operators to reach the bastion. Rule 4 is the default LAN rule. Rule 5 is the default deny.

Production patterns

Three patterns cover most triple-homed deployments.

Pattern 1: Single firewall, three physical NICs

The simplest pattern: three physical NICs, one for each interface. Production deployments often have a fourth NIC for a dedicated management VLAN.

igb0 — WAN (public IP from ISP)
igb1 — LAN (internal subnet)
igb2 — DMZ (public-facing services)
igb3 — Management (operator access)

This is the standard pattern for small and medium estates.

Pattern 2: Single firewall, trunk for LAN-side

The LAN-side uses a trunk NIC for both LAN and management. The DMZ is on a separate physical NIC.

igb0 — WAN
igb1 — Trunk for LAN + management VLANs
igb2 — DMZ

The DMZ is on a separate physical NIC because the DMZ should not share a Layer 2 segment with anything else. The trunk carries LAN-side VLANs (users, servers, management, IoT, etc.).

Pattern 3: HA pair with triple-homing on both nodes

A high-availability pair has triple-homing on both nodes. The WAN, DMZ, and LAN are all CARP-redundant.

node1.igb0 + node2.igb0 = CARP WAN VIP
node1.igb1 + node2.igb1 = CARP LAN VIP
node1.igb2 + node2.igb2 = CARP DMZ VIP

The HA pair is covered in Parts XXVI-XXIX. The triple-homing pattern is the same; the addition is CARP for IP redundancy and pfsync for state replication.

Read-only / Saferules per interface
$ pfctl -s rules | awk '/^@/ {print $0}' | awk '{for(i=1;i<=NF;i++) if($i~/^on$/) print $(i+1)}' | sort | uniq -c | sort -rn
  12 igb1
 8 igb2
 6 igb0

Illustrative output

The three interfaces have different rule counts because each has different needs. The asymmetry is the right outcome.

The three-interface traps

Three traps recur in triple-homed deployments.

Trap 1: Forgetting the DMZ interface rule set

The operator writes the WAN and LAN rule sets carefully, but the DMZ interface has no rules. The default deny blocks all DMZ-to-anything traffic, including legitimate flows. The operator adds “permit any to any” on the DMZ to “fix” the issue, undoing the segregation.

The fix: write the DMZ rule set from scratch, based on what the DMZ actually needs. DNS, NTP, updates, monitoring. No permits to the LAN.

Trap 2: NAT on the wrong interface

The operator configures outbound NAT for the LAN-to-Internet flow (which is correct) and accidentally applies it to inter-interface traffic. The DMZ-to-LAN traffic gets source-rewritten, breaking the LAN’s ability to identify the DMZ host in logs.

The fix: outbound NAT applies to traffic leaving the WAN interface. Inter-VLAN and inter-interface traffic (LAN ↔ DMZ) does not get outbound NAT unless explicitly configured.

Trap 3: Bogons on the WAN

The operator forgets to block RFC 1918 sources on the WAN interface. An attacker can send packets with RFC 1918 source IPs to the firewall, hoping the firewall logs them or processes them. The firewall should drop these packets at the WAN interface.

The fix: a block rule on the WAN for RFC 1918 sources, plus a similar rule for other bogons (the multicast ranges, the reserved ranges). OPNsense has a built-in “bogons” alias that can be used.

Summary

  • A triple-homed firewall has three interfaces (WAN, DMZ, LAN) each with its own IP, subnet, and rule set.
  • The routing table has three connected routes plus a default route. The kernel routes between interfaces based on the destination IP.
  • Every interface needs its own rule set. The default deny is at the bottom of every rule set.
  • Three production traps: forgetting the DMZ rule set, applying outbound NAT to inter-interface traffic, and not blocking bogons on the WAN.

Knowledge check · 4 questions

  1. Q1. A triple-homed firewall has interfaces igb0 (WAN), igb1 (LAN), igb2 (DMZ). A packet from a LAN host arrives on igb1 with destination 203.0.113.10 (DMZ server). The routing table shows 203.0.113.0/24 via igb2. The DMZ rule set has no explicit rules. What happens?

  2. Q2. A DMZ interface with no explicit rules allows all traffic by default.

  3. Q3. Which of the following are valid patterns for a triple-homed firewall? Select all that apply.

  4. Q4. A triple-homed firewall has a default LAN rule permitting LAN subnet to any. A packet from a DMZ host arrives on igb2 destined for a LAN host. The DMZ rules have no explicit rule permitting or blocking the traffic. What happens?

Passing score: 75%. Answers are checked in this browser.