OPNsense Forum

English Forums => Virtual private networks => Topic started by: mlenje on August 12, 2026, 09:23:06 PM

Title: PSA: WireGuard gateway monitoring silently fails on IP mismatch
Post by: mlenje on August 12, 2026, 09:23:06 PM
If you're using a WireGuard client interface as a monitored gateway (for gateway groups, failover, or just health alerting) and your gateway status looks suspiciously *always healthy* — even during a real tunnel outage — check this first. It cost me a long debugging session, and the actual cause turned out to be a simple, easy-to-make configuration mismatch, not a bug.

## The trap

There are **two separate "Gateway" fields**, in two different places, that look related but aren't automatically kept in sync:

1. **VPN > WireGuard > Instances → your instance → "Gateway"** — a field on the WireGuard instance itself.
2. **System > Gateways > Configuration → your gateway object → "IP Address"** — the address you set when creating a monitored gateway for this interface, typically with Far Gateway checked and an arbitrary placeholder IP (since a WireGuard tunnel has no real on-link next-hop).

Nothing in the UI tells you these two need to be the **same address**. If you pick your own arbitrary placeholder for #2 without checking what's already in #1, you end up with two different "gateway" IPs for the same interface — and only the one from #1 actually gets a working route.

## The symptom

- `dpinger_status()` reports the gateway as healthy (`status => none`, `loss => 0.0%`) even when the tunnel is genuinely down.
- Packet capture on the tunnel interface shows *nothing* — your monitor traffic is silently falling through to your WAN default route instead of the tunnel (confirmed via `tcpdump` + checking source-NAT'd traffic on the WAN interface).
- The kernel routing table never gets a route for your Monitor IP via the tunnel, no matter how many times you reload services or reboot.
- No error appears in the general system log — the actual failure is logged in `/var/log/wireguard/latest.log`, not `/var/log/system/latest.log`, and reads something like:
  ```
  route: message indicates error: Invalid argument
  add host <monitor-ip>: gateway <your-placeholder-ip> fib 0: Invalid argument
  ```

## The fix

Check VPN > WireGuard > Instances → your instance → "Gateway" field. Whatever address is there, use **that exact address** as the "IP Address" in your System > Gateways configuration for this interface — don't invent your own placeholder.

In my case, the instance's Gateway field was `10.2.0.3`; I'd used `10.2.0.1` for the System Gateway object. Changing the System Gateway to `10.2.0.3` fixed it completely — no manual static routes needed, confirmed via packet capture that monitor traffic now genuinely traverses the tunnel, and `dpinger_status()` correctly reports real loss/downtime.

## Why this happens (briefly, for the curious)

OPNsense's interface-route-building logic (`system_interface_route()` in `system.inc`) checks whether *any* host route already exists on the device with a link-level gateway before attempting to add its own — but doesn't check whether that existing route is for the specific address it needs. WireGuard's own instance logic already creates a correct route for its own Gateway field; if your System Gateway uses a different address, that unrelated route satisfies the "something already exists" check and the actual route you need is silently never created.

Not a bug, technically — just a very easy trap to fall into, and one the UI doesn't warn you about. Worth checking if your WireGuard gateway monitoring has ever felt "too quiet."

**Update:** if you've fixed the Gateway-field mismatch described above and your gateway *still* seems to never detect a real outage, check one more thing before assuming something's still wrong: dpinger's advanced parameters need to be adjusted too, not just the IP Address.

When I built a second site, I matched the System Gateway's IP Address to the WireGuard instance's Gateway field correctly from the start — no leak, route table looked right — but disabling the peer still didn't flip the status to down within any reasonable time. Turned out the advanced settings on System > Gateways > Configuration (Probe Interval, Time Period, Loss Interval, Data Length, Packet Loss/Latency thresholds, and the **Failover States** checkbox) were left at looser defaults than my known-working gateway. With those loose enough, dpinger just hadn't gathered enough samples yet to trip the alarm — it looked exactly like the routing bug above, but was a completely separate, simpler issue.

**Fix:** when setting up a new WireGuard gateway for monitoring, adjust the *entire* advanced parameter set, not just IP Address / Far Gateway / Monitor IP. In my case, the values that worked for my setup were:

- Failover States: **checked**
- Latency Low/High Threshold: 200 / 500
- Packet Loss Low/High Threshold: 20 / 50
- Probe Interval: 2
- Time Period: *(left blank — uses default)*
- Loss Interval: 4
- Data Length: *(left blank — uses default)*

Notably, leaving Time Period and Data Length **blank** (rather than setting an explicit value) was part of what worked — an explicit value there was one of the things that made detection sluggish on the misconfigured gateway.

TL;DR: "gateway always shows healthy" has (at least) two independent causes — a routing mismatch (see above) and a detection-sensitivity mismatch (this). Worth ruling out both.
Title: Re: PSA: WireGuard gateway monitoring silently fails on IP mismatch
Post by: Lucid1010 on August 13, 2026, 08:06:09 AM
Q: What value should I enter for the monitor IP in the System Gateway settings?

I am using Mullvad, and according to their documentation, I should enter their DNS address (10.64.0.1).

However, since I have set up multiple selective routings (3 or more), I can only use 10.64.0.1 as the monitor IP for a single gateway due to a duplicate IP error.
Title: Re: PSA: WireGuard gateway monitoring silently fails on IP mismatch
Post by: mlenje on August 13, 2026, 08:20:41 AM
The Monitor IP doesn't need to be your VPN provider's internal DNS address specifically — it just needs to be *some* real host that actually responds to ICMP when routed through that particular tunnel. Mullvad's docs suggesting `10.64.0.1` is just a convenient, known-working example, not a requirement.

Since OPNsense won't let you reuse the same Monitor IP across multiple gateways, the simplest fix is to give each tunnel a different public target — for example:

- Gateway 1: `9.9.9.9` (Quad9)
- Gateway 2: `1.1.1.1` (Cloudflare)
- Gateway 3: `8.8.8.8` (Google)
- Gateway 4: `1.0.0.1` (Cloudflare secondary)

Any of these will work as long as it genuinely answers ping through that specific tunnel — don't just assume it does, confirm it (see below).

One thing worth double-checking based on some fairly extensive troubleshooting I went through recently with a similar multi-gateway WireGuard setup on ProtonVPN: **make sure it's actually the Monitor IP field throwing the duplicate error, and not the Gateway "IP Address" field** (the Far Gateway placeholder). Those are two separate fields on the same System Gateway config screen, and both need to be unique per gateway too — the placeholder "IP Address" also can't be reused across multiple WireGuard gateways on this same box. If you're getting a duplicate error on that field instead of (or in addition to) Monitor IP, you'll need a distinct placeholder value per tunnel as well (e.g. `10.64.1.1`, `10.64.2.1`, `10.64.3.1`, etc. — arbitrary, unused, just needs to be unique).

Also, whichever Monitor IP you land on per gateway, actually verify it before trusting it — this bit me hard on a recent project. Confirm with a packet capture that the ping genuinely traverses the tunnel interface (not silently falling through to WAN):

```
tcpdump -ni <tunnel-interface> icmp
```
while pinging the monitor IP sourced from that tunnel's local address in another window. If nothing shows up on the tunnel interface, the monitor IP isn't actually testing what you think it's testing — regardless of what the dashboard says.

Hope this helps.

I also recommend using Claude as you set it up to help answer questions and troubleshoot.