Multi-WAN failover tutorials promise resilience but deliver flaky fallback, broken DNS, and dead sessions when a link flaps. Sticky connections, proper monitoring triggers, and DNS that works from any link fix it. Here’s the shortest correct path from two connections to a truly resilient setup.

Prerequisites and Assumptions

You need an OPNsense installation with at least two WAN interfaces that already have gateway addresses and are capable of passing traffic. Basic LAN configuration is assumed—clients receive DHCP, and you have a working default‑allow rule. Before starting, verify:

  • Both WAN interfaces are up and you can ping each gateway from the firewall (Interfaces > Diagnostics > Ping).
  • Each WAN has a manually defined gateway under System > Gateways > All; the interface column matches the WAN assignment.
  • The system default gateway is currently set to something sensible (we’ll override it for LAN traffic).
  • You know the monitor IP for each WAN—a stable, public target reachable only through that interface. Use the ISP’s next‑hop if reachable, or an anycast DNS like 8.8.8.8 or 1.1.1.1—never the gateway IP itself (see DNS section).

Gateway Groups Done Right

The Tier and Trigger Level Trap

Gateway groups are ordered by tiers, not a priority dropdown. A lower tier number is preferred. The default trigger level “Member Down” means dpinger removes a gateway only when the monitored IP stops responding entirely—useless when a WAN turns unreliable but the interface stays up. Packet loss and high latency can cripple traffic long before the link truly drops.

The behaviour you actually want:

Setting What it does Recommended value
Tier Failover order; lower = higher priority. Gateways in the same tier share load Tier 1 for primary, Tier 2 for backup
Trigger Condition that removes a gateway from the group Packet Loss or High Latency, not just Member Down
Packets Lost (%) Threshold for packet loss trigger 20–30% (depends on link quality)
RTT (ms) Threshold for high latency trigger 500 ms

With “Member Down” alone, dpinger keeps a gateway in the group while it’s dropping 80% of packets. Checking “Packet Loss” or “High Latency” removes the gateway as soon as the monitor detects degraded performance. Set the thresholds under System > Gateways > edit each gateway > Advanced; a 3000ms probe interval with 500ms latency trigger and 20% loss works for most.

Gateway Group Creation

  1. Go to System > Gateways > Group.
  2. Click Add.
  3. Enter a Group Name (e.g. FailoverWAN).
  4. Under Gateway Priority: - First entry: select your primary WAN gateway, set Tier 1. - Click the + to add another row. - Second entry: select your secondary WAN gateway, set Tier 2.
  5. Leave Virtual IP empty unless you need a CARP address.
  6. Under Trigger Level, check Packet Loss and High Latency (uncheck Member Down if necessary—you want the performance checks).
  7. Save and Apply changes.

You are done when: Both gateways appear in the group table, and System > Gateways > All shows dpinger runtime information with green “Online” status for each monitor IP you’ve set (you’ll set those in the DNS section).

Sticky Connections: The Missing Piece

Without sticky connections, the state table sees a policy‑based routing change when a gateway flaps and remaps existing sessions to the new default WAN. That immediately kills any ongoing TCP connection—your SSH session, video call, or file transfer—because reply traffic suddenly comes from a different source IP.

Enable sticky connections globally:

  • Go to Firewall > Settings > Advanced, find Sticky connections (under Multi‑WAN). Set it to “Use sticky connections” and set the Source tracking timeout to 60–300 seconds. Save.

This tells the state table that connections created via a gateway group must keep using the same gateway for the lifetime of the state entry, even after a failback or flap. Now make your LAN firewall rule reference the gateway group, not a single gateway. The gateway group object automatically attaches sticky behaviour to every connection that matches the rule.

You are done when: The Firewall > Settings > Advanced page shows sticky connections enabled, and your LAN outbound rule (created next) uses the gateway group, not the default gateway.

DNS That Doesn’t Break When a WAN Drops

System DNS and Gateway Monitoring

dpinger monitors gateways by pinging the Monitor IP defined per gateway. If that IP is the WAN gateway address and the link goes down, dpinger can’t reach it—that’s fine. However, if the firewall’s own DNS servers (System > Settings > General) are resolvers reachable only via a single WAN, the firewall itself may lose DNS when that WAN fails. That can break dpinger if it needs to resolve its monitor IP, cause NTP failures, or block future configuration changes.

Set monitoring IPs per gateway:

  1. System > Gateways > All, edit each WAN gateway.
  2. In the Monitor IP field, put an IP reachable only via that WAN. Use the ISP’s DNS server, or a public IP like 8.8.8.8, 1.1.1.1, 9.9.9.9. Do not use the same monitor IP for both WANs; dpinger requires per‑interface binding.
  3. Under Advanced, set thresholds if needed.

For the firewall’s own DNS, go to System > Settings > General. Under DNS servers:

  • Remove any ISP‑provided servers that sit behind a single WAN.
  • Add two anycast addresses (e.g., 1.1.1.1 and 9.9.9.9).
  • Set Use gateway to “none” for all, so OPNsense routes to them via the current default route. If you prefer to force them out a specific interface, choose that gateway—but leave at least one server reachable via the backup WAN.

Unbound Outgoing Interfaces

Unbound must send queries out all WANs, not just the one it was bound to at startup. Otherwise, during a WAN failure, clients get SERVFAIL because Unbound keeps trying the dead interface.

  • Services > Unbound DNS > General.
  • Under Outgoing Network Interfaces, select all active WAN interfaces (and LAN if you want Unbound to listen on local networks; this is the listening list, not forwarding).
  • Network Interfaces should include LAN and loopback for queries, but the outgoing interfaces determine which source addresses Unbound binds to.
  • Set DNS Query Forwarding only if you have upstream forwarders. If you’re using root hints (default), Unbound queries root servers from whichever interface the routing table picks—that works as long as the default route changes on failover. Better: set the gateway group as the system default gateway (System > Gateways > Single, leave it set to “Auto-detect” or the gateway group) to ensure all locally originated traffic also fails over.

You are done when: A client can resolve www.opnsense.org with either WAN online, and a query from the firewall itself (drill @127.0.0.1 on the console) succeeds regardless of which link is up.

Firewall Rules That Actually Route Traffic

Create a LAN pass rule that uses the gateway group as its gateway—do not rely on the default gateway.

  1. Firewall > Rules > LAN.
  2. Click Add (plus icon) to insert a rule near the top.
  3. Action: Pass.
  4. Interface: LAN.
  5. Protocol: any.
  6. Source: LAN net (or a specific alias if you want to restrict).
  7. Destination: any.
  8. Gateway: select your FailoverWAN gateway group from the dropdown. Do not leave as “default.”
  9. Reply‑to: leave blank; OPNsense fills it in automatically when the gateway field references a group.
  10. Description: Outbound WAN failover.
  11. Save and Apply changes.
  12. Move this rule above any catch‑all pass rule that uses the default gateway. If you have an “allow all” rule without a gateway specified, edit it and set the gateway to the group as well, or disable it.

The reply‑to mechanism ensures that return traffic for a connection that entered via a specific WAN also leaves via that same WAN, which is critical for multi‑WAN symmetry.

You are done when: A traceroute (traceroute -n 1.1.1.1) from a LAN client shows the primary WAN gateway as the first hop. After disabling the primary interface (Interfaces > Overview, click the disable icon), the traceroute shows the secondary WAN gateway.

Testing Without Losing Your Mind

Controlled Failover

  1. Open a persistent SSH session from a LAN client to an external host.
  2. Start a continuous ping from the same client to 8.8.8.8 (or watch traceroute).
  3. On OPNsense, go to Interfaces > [primary WAN], click Disable. Or physically unplug the cable.
  4. Watch System > Gateways > Log; dpinger should show the primary gateway go down within a few seconds.
  5. The SSH session must stay alive—no disconnection, no freeze beyond a transient pause. The ping may drop one or two packets, then resume via the backup.
  6. Re‑enable the interface; dpinger detects the gateway is back, and new sessions use the primary again. The existing SSH session continues on the backup until it closes (sticky timeout expires or you kill it).

DNS Validation

While the primary WAN is still down:

  • From the LAN client, run dig +short www.opnsense.org. It must return an IP.
  • Check Unbound logs (Services > Unbound DNS > Log File) for lines showing the outgoing query interface; you’ll see it using the backup WAN’s IP address.
  • From the firewall console (SSH), run drill @127.0.0.1 opnsense.org; it must resolve.

You are done when: With either WAN offline, web browsing, DNS, and long‑lived TCP connections work. Failback re‑routes new flows to the primary without breaking sessions established during the outage.

Conclusion

Multi‑WAN failover falls apart when you treat it as just a gateway group. The pieces that make it solid are dpinger performance triggers, sticky connections for state table sanity, DNS that keeps working from the firewall and from Unbound, and a LAN rule that explicitly binds traffic to the group. Test with real disconnections and check that sessions survive. Once that’s in place, you can pull a cable and nobody notices.