Skip to main content
RunBook Academy

← All runbooks in OPNsense

low riskinformational~45 min

Runbook: Troubleshoot Port Forwarding

1 · Prerequisites

Confirm every item is in place before any state change.

  • OPNsense 25.x with a public WAN IP
  • Port-forward rule already configured and was previously working, or being newly added
  • Internal destination host reachable from OPNsense
  • External test source (mobile network, public VPS, or another ISP connection)

2 · Pre-checks

Read-only diagnostic commands. If any of these don't match expected output, stop and investigate further.

  • · Capture a fresh encrypted config backup before any change
  • · Confirm the WAN interface has a public IP and the ISP is not blocking the port (some residential ISPs block 25, 80, 443, 3389)
  • · Confirm the internal host is up and listening on the destination port (netstat -an | grep <port> or ss -lntp | grep <port>)
  • · Disable the OPNsense web GUI on a non-standard port if you are forwarding 443 to avoid the anti-lockout/management collision

3 · Procedure

Execute each step in order. Verify the expected output of a step before moving to the next.

  1. 1Open Firewall > NAT > Port Forward and confirm the rule exists: WAN interface, source any (or restricted), destination WAN address, destination port, redirect target IP, redirect target port, NAT reflection settings.
  2. 2Open Firewall > Rules > WAN and confirm the auto-generated rule that matches the port-forward is present and enabled; if missing, click Apply changes on the NAT page to regenerate it.
  3. 3From the external test source, attempt to connect: curl -v http://<wan_ip>:<port> or nc -vz <wan_ip> <port>. Note the result and capture the exact error.
  4. 4At the OPNsense shell, run pfctl -sn | grep <wan_ip> to see the NAT table and pfctl -sr | grep <port> to see the matching WAN rule.
  5. 5Open Firewall > Log Files > Live View, filter on the WAN interface and destination port; check whether packets from the external source are arriving and what action OPNsense is taking.
  6. 6If the Live View shows a block, click the rule and inspect whether the block is on the WAN interface or a floating rule; fix the block (see opnsense-rb-troubleshoot-blocked-traffic).
  7. 7If packets arrive and are forwarded but no response is seen from the internal host, run Diagnostics > Tables and inspect the firewall state table for the matching 5-tuple; missing state suggests the internal host is not responding.
  8. 8Test from OPNsense itself: from Diagnostics > Command Prompt, curl http://<internal_ip>:<port> directly to the destination. If this fails, the internal service is the problem, not the port-forward.
  9. 9If the issue is from an internal source trying to reach the public IP, enable NAT reflection: Firewall > NAT > Port Forward, edit the rule, set NAT reflection to Enable (NAT + proxy) (or Enable (Pure NAT) if upstream routers need it).
  10. 10Pure-NAT reflection has known limitations for protocols that embed source IPs (SIP, FTP, some games); document the trade-off and consider Split-DNS instead.
  11. 11Apply changes and re-test from the external and internal sources.

4 · Verification

Confirm the procedure actually fixed the problem.

  • nc -vz <wan_ip> <port> from the external test source completes the handshake
  • curl -v http://<wan_ip>:<port> returns the expected HTTP response
  • pfctl -ss | grep <port> shows established states between the external source and the internal destination
  • Internal source can reach the service via the public IP without hairpin warnings (if reflection is enabled)

5 · Rollback

If verification fails, undo the procedure in reverse order.

  • Disable the NAT rule on Firewall > NAT > Port Forward and apply; the associated WAN rule is removed automatically.
  • If reflection was added, revert the rule to its prior reflection setting and apply.
  • Restore the pre-change encrypted config backup if alias, alias URL table, or other related changes were made.
  • Notify the change owner that the port-forward is no longer functional.

6 · Escalation

When the runbook isn't enough, contact:

  • · Escalate to the ISP if the port is silently blocked at the carrier level; common for 25, 80, 443, 3389 on residential plans.
  • · Escalate to the destination host team if the host is up but not responding on the expected port; suspect host firewall (Windows Firewall, iptables, nftables, cloud security group).
  • · Escalate to security if the request is to expose a service that is not approved for public exposure.
  • · Escalate to the application vendor if the protocol is one known to break with reflection (SIP/VoIP, FTP active mode, IPsec NAT-T).

Purpose

This runbook diagnoses why an inbound port-forward from the public internet is not working on OPNsense. It covers the most common causes: a missing or disabled NAT rule, an auto-generated firewall rule that did not materialize, an ISP-blocked port, a destination host not listening, and the internal-vs-external hairpin case.

When to use this runbook

Use this runbook when an externally-hosted service (web, SSH, game server, mail relay, etc.) is not reachable via the public WAN IP, and you have reason to believe OPNsense’s port-forward is the most likely cause. If the service was working and stopped, also review the change record for recent ruleset or alias edits.

Pre-checks

  • Capture a fresh encrypted config backup before any change.
  • Confirm the WAN interface has a public IP (ifconfig <wan_if> at the shell) and the ISP is not blocking the destination port (residential ISPs commonly block 25, 80, 443, 3389).
  • Confirm the internal host is up and listening on the destination port: from Diagnostics > Command Prompt, run netstat -an | grep <port> on a Windows host via RDP or ss -lntp | grep <port> over SSH on Linux.
  • If forwarding 443, move the OPNsense web GUI to a non-standard port first to avoid the management collision and the anti-lockout rule.

Procedure

  1. Confirm the NAT rule. Open Firewall > NAT > Port Forward. The rule should be: Interface WAN, Source any (or restricted alias), Destination WAN address, Destination port the public port, Redirect target IP the internal host, Redirect target port the internal port. Make a note of any NAT reflection setting.
  2. Confirm the auto-generated WAN rule. Open Firewall > Rules > WAN and confirm a matching pass rule exists for the same destination port. If it is missing, click Apply changes on the NAT page; OPNsense regenerates the auto-rule on apply.
  3. Test from the external source. From a phone on cellular data, a public VPS, or any other ISP, run nc -vz <wan_ip> <port> or curl -v http://<wan_ip>:<port>. Capture the exact error and time it.
  4. Inspect the NAT and rule tables at the shell. Open Diagnostics > Command Prompt and run:
    • pfctl -sn | grep <wan_ip> — the NAT rules
    • pfctl -sr | grep <port> — the firewall rules matching the port
    • pfctl -ss | grep <port> — the live state table
  5. Watch Live View. Open Firewall > Log Files > Live View, filter on the WAN interface and destination port, and re-trigger from the external source. Note whether packets are arriving and what action OPNsense takes (block/pass/redirect).
  6. If Live View shows a block. Note the matching rule. If the block is on the WAN interface or a floating rule with any/any, see opnsense-rb-troubleshoot-blocked-traffic for the diagnostic path.
  7. If packets arrive but no state is created. The internal host is not responding. Confirm directly: from OPNsense, curl http://<internal_ip>:<port>. If this fails, the issue is host-side firewall, the service not running, or wrong port.
  8. If the issue is from an internal source. That is the hairpin/NAT reflection case. Edit the NAT rule on Firewall > NAT > Port Forward, set NAT reflection to Enable (NAT + proxy) (preferred) or Enable (Pure NAT) if the proxy mode interferes with the protocol. Apply and re-test from inside.
  9. Consider Split-DNS instead of reflection. Reflection is brittle for protocols that embed source IPs (SIP, active FTP, some games, IPsec). For most internal-to-public access, prefer DNS host overrides that resolve the public hostname to the internal IP.
  10. Re-test and confirm. From the external source, repeat the connection test. From an internal source, repeat the same test if reflection was the requested behavior. Both should succeed.

Verification

  • nc -vz <wan_ip> <port> from the external test source completes the handshake.
  • curl -v http://<wan_ip>:<port> returns the expected HTTP response (or the expected protocol response for non-HTTP services).
  • pfctl -ss | grep <port> shows established states between the external source and the internal destination.
  • Internal source can reach the service via the public IP without hairpin warnings (if reflection is enabled).

Rollback

  • Disable the NAT rule on Firewall > NAT > Port Forward and apply; the associated WAN rule is removed automatically.
  • If reflection was added, revert the rule to its prior reflection setting and apply.
  • Restore the pre-change encrypted config backup if alias, alias URL table, or other related changes were made.
  • Notify the change owner that the port-forward is no longer functional.

Escalation

  • Escalate to the ISP if the port is silently blocked at the carrier level. Common for 25, 80, 443, and 3389 on residential plans; many ISPs will unblock on request for business plans.
  • Escalate to the destination host team if the host is up but not responding on the expected port; suspect the host firewall (Windows Firewall, iptables, nftables, cloud security group).
  • Escalate to security if the request is to expose a service that is not approved for public exposure in the change record.
  • Escalate to the application vendor if the protocol is one known to break with reflection (SIP/VoIP, FTP active mode, IPsec NAT-T).

References

  1. OPNsense documentation — NAT
  2. OPNsense documentation — Port forward
  3. OPNsense documentation — NAT reflection / hairpin