OPNsenseXIII · Port Forwarding and NAT ReflectionInbound NAT
1:1 NAT as destination — exposing an internal server on a public IP
What you'll learn
- Configure 1:1 NAT to expose an internal server
- Write the firewall rule that permits traffic to the 1:1 address
- Distinguish 1:1 NAT from port forwarding for server exposure
- Recognise when 1:1 NAT is the right tool vs port forwarding
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
1:1 NAT maps a public IP to an internal host. For inbound exposure, the public IP is the destination the Internet sends traffic to; the internal host is the destination the firewall forwards traffic to. The mapping applies to every port and every protocol — the internal host appears to own the public IP for all purposes.
This lesson covers 1:1 NAT as the inbound exposure mechanism — when it is the right tool, how to configure it, and the firewall rules that complete the configuration.
When 1:1 NAT is the right inbound tool
Three situations favour 1:1 NAT over port forwarding:
- A server needs a stable public identity. A mail server with PTR records, an HTTPS server with a dedicated IP for TLS validation, a game server with a stable endpoint. 1:1 NAT gives the server a public IP that is exclusively its own.
- The server runs many services on many ports. Port forwarding requires one entry per port. 1:1 NAT covers all ports in one entry. The trade-off is that all ports are exposed to the firewall — the operator must restrict them with firewall rules.
- The server uses protocols that port forwarding cannot handle. Some legacy protocols embed addresses in the payload or use non-standard transports. 1:1 NAT rewrites without a port filter, which works for any IP-based protocol.
When the requirement is “expose exactly ports 80 and 443”, port forwarding is the cleaner tool. The default-deny blocks everything else; only the forwarded ports are reachable. 1:1 NAT would also expose ports 22, 25, 3389, and every other port on the host, requiring firewall rules to block each one.
Configuring 1:1 NAT
The configuration under Firewall → NAT → 1:1 → Add:
- Interface: WAN
- External IP: 198.51.100.10 (the public IP)
- Internal IP: 192.0.2.10 (the server)
- Destination: any
The external IP must be configured on the WAN interface as an
IP alias before the 1:1 NAT entry can use it. Under
Interfaces → WAN, add 198.51.100.10 as a virtual IP (also
called an IP alias). The 1:1 NAT entry references the alias.
The internal IP is the server’s address. It can be any IP reachable from the firewall’s routing table — typically a directly connected LAN address, but it can also be a routed remote subnet.
$ ifconfig igb1 | grep inet inet 198.51.100.1 netmask 0xffffffe0 broadcast 198.51.100.31
inet 198.51.100.10 netmask 0xffffffe8 broadcast 198.51.100.15Illustrative output
The generated PF rules
A 1:1 NAT entry generates two rules: an rdr rule and a nat rule.
rdr on igb1 inet proto any from any to 198.51.100.10 -> 192.0.2.10
nat on igb0 inet from 192.0.2.10 to any -> 198.51.100.10
The rdr rule rewrites inbound destinations from any source. The nat rule rewrites outbound sources from the internal server. Together, they make the internal server appear to own the public IP.
The rdr rule applies to all protocols (proto any). There is no
port filter. The firewall rules that follow the rdr determine
which protocols and ports are actually permitted.
The firewall rules for 1:1 NAT
The 1:1 NAT entry alone does not permit any traffic. The firewall rules determine what is allowed. For a typical web server exposed via 1:1 NAT:
- Interface: WAN
- Direction: in
- Protocol: TCP
- Source: any (or restricted)
- Destination: 198.51.100.10 (the public IP, not the internal)
- Destination port: 443
- Action: pass
The destination in the rule is the public IP. PF rewrites the destination to the internal IP before evaluating the filter, so the rule matches against the rewritten packet. The GUI presents the pre-DNAT destination for matching — the public IP.
A common mistake: writing the rule with destination = internal IP. The rule does not match because PF evaluates the filter against the rewritten packet, and the rewritten destination is the internal IP. Writing the rule with destination = public IP is correct because the GUI translates the public IP to the post-DNAT destination internally.
$ pfctl -s rules | grep '198.51.100.10' | head -5@101 pass in quick on igb1 inet proto tcp from any to 192.0.2.10 port = 443
@102 pass in quick on igb1 inet proto tcp from any to 192.0.2.10 port = 80
@103 pass in quick on igb1 inet proto icmp from any to 198.51.100.10 icmp-type echoreqIllustrative output
1:1 NAT vs port forwarding for the same use case
Consider the same requirement: expose a web server at 192.0.2.10 on port 443 via public IP 198.51.100.10.
Port forwarding approach:
rdr on igb1 inet proto tcp from any to 198.51.100.10 port = 443 -> 192.0.2.10 port 443
pass in quick on igb1 inet proto tcp from any to 192.0.2.10 port = 443
Only TCP/443 is forwarded. Other ports on 198.51.100.10 are not forwarded to any host. The firewall’s default deny blocks other traffic. Net result: 198.51.100.10:443 is exposed; everything else on 198.51.100.10 is blocked.
1:1 NAT approach:
rdr on igb1 inet proto any from any to 198.51.100.10 -> 192.0.2.10
nat on igb0 inet from 192.0.2.10 to any -> 198.51.100.10
pass in quick on igb1 inet proto tcp from any to 192.0.2.10 port = 443
All protocols, all ports are forwarded to 192.0.2.10. The firewall rules determine what is permitted. If only the TCP/443 rule is present, only TCP/443 to 192.0.2.10 is allowed; all other traffic to 198.51.100.10 is dropped by the implicit deny because no rule permits it.
The functional difference: with port forwarding, the operator writes one entry (the port forward) and the firewall rules are generated. With 1:1 NAT, the operator writes two configurations (1:1 NAT plus firewall rules) and must keep them in sync.
The configuration difference: port forwarding is more declarative — “expose this port to this internal host”. 1:1 NAT is more imperative — “this internal host owns this public IP; I will write rules for what is allowed”.
The internal host’s routing requirement
The internal host must route replies through the firewall. The 1:1 NAT entry translates the source of the internal host’s outbound traffic to the public IP, but the firewall only performs the translation on traffic that passes through it. If the internal host’s default gateway is not the firewall, the host’s outbound traffic does not reach the firewall, the translation is not performed, and the source IP remains the internal IP — which the remote service cannot reply to (the reply would go to the public IP, not the internal IP).
This is the same requirement as port forwarding: the internal host’s default gateway must be the firewall.
For a 1:1 NAT’d server, the default-gateway requirement is sometimes overlooked because the server is “just sitting on the LAN” and the operator does not think about the gateway. But the gateway matters: without it, outbound traffic from the server does not get translated, and the return traffic breaks.
A worked example
The requirement: a mail server at 192.0.2.20 has its own public IP 198.51.100.20. The server runs SMTP (25), submission (587), and IMAPS (993). PTR records point to 198.51.100.20, so the server’s outbound traffic must come from 198.51.100.20.
Step 1: configure the virtual IP. Under
Interfaces → WAN → Virtual IPs, add 198.51.100.20/24 as an
IP alias.
Step 2: create the 1:1 NAT entry. External IP 198.51.100.20, internal IP 192.0.2.20, destination any.
Step 3: create firewall rules on the WAN interface:
- TCP/25 to 198.51.100.20
- TCP/587 to 198.51.100.20
- TCP/993 to 198.51.100.20
- ICMP echo to 198.51.100.20
Step 4: set the mail server’s default gateway to the firewall’s LAN IP (192.0.2.1).
Step 5: verify. From an external host, dig -x 198.51.100.20
returns the PTR record pointing to the mail server’s hostname.
Send an SMTP connection; the server responds. Check
tcpdump -ni igb1 host 198.51.100.20 for the post-NAT traffic.
Summary
- 1:1 NAT maps a public IP to an internal host for all protocols and ports. Use it for servers that need a stable public identity or run many services.
- The public IP must be configured as a virtual IP on the WAN interface.
- The 1:1 NAT entry alone does not permit traffic. Firewall rules are required to allow specific protocols and ports.
- The internal host’s default gateway must be the firewall for outbound traffic to be translated.
- Port forwarding is preferred when only specific ports need exposure; 1:1 NAT is preferred when the server needs a public identity.
Knowledge check · 4 questions
Q1. A web server at 192.0.2.10 needs to be exposed on a dedicated public IP 198.51.100.10 for HTTPS (443) only. Which configuration is the right choice?
Q2. A 1:1 NAT entry requires the public IP to be configured as a virtual IP on the WAN interface before the entry can match inbound traffic.
Q3. Which of the following are required for 1:1 NAT to work end-to-end for inbound exposure? Select all that apply.
Q4. A 1:1 NAT entry binds 198.51.100.10 to 192.0.2.10. The internal host is reachable from the Internet on TCP/443 (verified by curl). Outbound traffic from the internal host to the Internet has source IP 192.0.2.10 (private). What is the most likely cause?
Passing score: 75%. Answers are checked in this browser.