Feature

A Dead Tunnel Is the Outage Nothing Reports

When a WireGuard tunnel stops handshaking, everything behind it goes quiet - and quiet is exactly what a healthy site looks like from the outside. Fivenines watches every peer by handshake age and every Tailscale node by key expiry, from the agent you already installed.

Built for teams monitoring production infrastructure

Start free trial

No credit card · 2-minute setup

WireGuard peers Tailscale key expiry No idle-peer pages

VPN tunnels

wg0/paris-site handshake 18s
wg0/lyon-site handshake 41s
wg0/HIgo9xNz… handshake 1m
wg0/berlin-site silent 14m
Tailscale key: 46 days
4 peers active
1 silent
Key: 46 days
  • The Failure That Hides Itself

    A site behind a dead tunnel does not alert. Its servers stop reporting, its checks go quiet, and every dashboard reads the same as a site that is simply idle. Handshake age is the one signal that tells those two apart.

  • No Pages for Idle Peers

    WireGuard only handshakes when there is traffic, so an idle peer with an old handshake is healthy by design. The alert watches peers with persistent-keepalive configured, because only those have a cadence to measure against.

  • Your Keys Stay on the Box

    Private and preshared keys are never transmitted and have no column to be stored in. Even public keys are never displayed: peers show up under the alias from your wg-quick config, or a short fingerprint if it has none.

Deep dive

Why a Tunnel Needs Its Own Alert

Every other outage announces itself. A server falls over and stops sending metrics; a website goes down and a probe fails. A tunnel is different: when it dies, the machines behind it are still running perfectly and still trying to report. What breaks is the path their reports travel on, so the symptom is an absence rather than an error, and an absence is what a quiet weekend looks like too.

For an MSP that is the worst possible failure mode, because the blast radius is a whole client site rather than one host. Everything behind the tunnel goes dark at once, and nothing in the tool that is supposed to be watching it says anything is wrong.

So the tunnel gets watched as its own thing. The agent reads wg show on the host that terminates the tunnel and reports, per peer, how long ago it last completed a handshake. A peer with keepalive that has stopped handshaking has stopped carrying traffic - that is the signal, and it arrives seconds after it happens rather than whenever someone notices the client has been quiet.

What Each Collector Reports

WireGuard peers

One row per peer per interface: time since the last handshake, bytes received and sent, the current endpoint, the allowed IPs, and whether persistent-keepalive is set. Peers are identified by their public key, so renaming one in wg0.conf keeps its history and its open incident instead of minting a new peer.

WireGuard interfaces

How many peers each interface has and how many are currently active, where active means a handshake inside the last 3 minutes - one full rekey window plus margin. A zero-peer interface reports an honest zero rather than disappearing from the chart.

Tailscale node state

The daemon's backend state as Tailscale itself reports it, plus the node's own name. Stopped and NeedsLogin are real readings, not collection failures, so the moment a node leaves the tailnet you have a value that says so rather than a gap you have to interpret.

Tailscale key expiry

Days remaining on the node key, so you can be warned before it expires rather than after. A node with key expiry disabled in the admin console reports nothing here at all, which is the honest answer - not a countdown that would never end.

Tailnet rollups

How many peers the node can see and how many of those are online. Deliberately a rollup and not a row per peer: every node sees every other node, so per-peer data would cost hosts times tailnet-peers to describe the same small set of devices.

The host underneath

All of it sits beside the CPU, memory, disk and network figures for the same machine, so a saturated link and a flapping tunnel are on one timeline instead of in two products.

Deep dive

The Idle-Peer Problem, and Why It Is Not a Tuning Problem

WireGuard is silent by design. It does not keep a session open or send heartbeats of its own; it handshakes when there is data to send, and rekeys roughly every two minutes while traffic flows. Stop the traffic and the handshakes stop too, which means a peer that has been idle since Friday has a handshake age of three days and is in perfect health.

Alerting on handshake age alone therefore pages you for peers that are fine, and no threshold fixes it: any cutoff long enough to spare a genuinely idle peer is far too long to catch a dead one. It is a false positive by construction rather than a number that needs tuning.

The way out is to watch only the peers that have a guaranteed cadence. A peer with PersistentKeepalive set sends a packet every few seconds whether or not it has anything to say, so its handshake age genuinely does track its health - and that is the normal configuration for a site-to-site tunnel anyway, because at least one end usually sits behind NAT and needs keepalive to hold the mapping open. The alert watches those peers by default and leaves the rest alone.

The tradeoff is stated rather than hidden: a peer without keepalive is not watched by default, so set PersistentKeepalive = 25 on the NAT side of each tunnel you want covered. If your tunnels carry constant traffic you can flip the alert to watch every peer instead, and accept that idle ones will fire.

From Install to First Alert

1

Step 1

Install the agent

One command, about two minutes, on the host that terminates the tunnel. If you already monitor that server, skip this - the VPN collectors ride the agent you have.

2

Step 2

Turn the collectors on

Two toggles in the instance settings. WireGuard needs the agent to be able to run wg show, which its packaged unit grants; Tailscale needs nothing at all. Neither takes any configuration, because both commands are fixed and the peer names come from your own wg-quick config.

3

Step 3

Watch it, then alert on it

Peers appear on the instance page straight away, stalest first, and all 9 metrics can go on a custom dashboard. Add the VPN Tunnel Down template from the workflow gallery for WireGuard, and a metric threshold on Tailscale key-expiry days for the node keys.

Deep dive

Alerting on Tunnels

One alert ships as a one-click workflow template: VPN Tunnel Down. It fires per peer, so a hub with thirty tunnels opens one incident for the tunnel that broke rather than one for the host, and each closes on its own when that peer handshakes again. The default threshold is 5 minutes, which is also the floor the form will accept - a rekey fires on the first packet after two minutes and the scrape adds up to another minute, so a healthy keepalive tunnel can legitimately show an age near three minutes and a tighter cutoff would flap.

If wg itself stops working - the binary goes missing, the capability is dropped - the agent keeps reporting everything else, and a naive implementation would see no stale peers and close every open incident as recovered. That would be a dead tunnel reported as fixed. Instead the alert freezes: it stops paging, it stops resolving, and it waits for real data. Resolutions are worded honestly too, so a peer that was removed from the config says it is no longer reported rather than claiming it recovered.

Tailscale has no dedicated trigger - you alert on it with a metric threshold, which is the same mechanism as any other metric here. The recipe worth setting up is key-expiry days below seven, so you are warned while the fix is still a login rather than after the node has already dropped off the tailnet. Node state works as a threshold too, because an off-tailnet daemon reports a real zero rather than a gap. What a threshold cannot see is a daemon that is gone entirely, since there is then no value to compare - for that, watch the tailscaled unit with a systemd trigger.

Every one of the 9 metrics can carry a threshold, with the same sustained-duration rules, escalation gates and maintenance windows as any other alert. Incidents never carry a public key: the identifier attached to one is a hash, and the notification names the peer by its alias.

Alerts go where your team works: email, Slack, Microsoft Teams, Telegram, Discord, Pushover, PagerDuty or webhooks. Which of those you can use depends on your plan - email, Telegram and Discord are on every plan, and the rest unlock as you move up.

Deep dive

Where Each Collector Runs

WireGuard monitoring is Linux-only, and that is a real boundary rather than a roadmap gap. The collector parses the output of wg show all dump, which is the Linux and BSD userspace tooling, so a Linux host is where peer data comes from. The toggle is hidden on Windows outright; on anything else it is available, and a machine without that tooling simply reports nothing rather than reporting a broken tunnel.

Tailscale monitoring runs on Linux, Windows and macOS, because tailscale status is identical on all three. So a mixed fleet is covered for the Tailscale half wherever it runs, and for the WireGuard half wherever the tunnels actually terminate - which on a site-to-site setup is a Linux box in nearly every case.

Both collectors are off until you turn them on, per host, and enabling one does not enable the other. Both also need an agent new enough to carry them: an older one will let you turn the toggle on and then simply report nothing, so update the agent if a host stays empty after you enable it.

What the agent reads, module by module, is documented in the agent security model, which lists WireGuard and Tailscale alongside every other optional collector.

Common VPN Monitoring Scenarios

MSP site-to-site tunnels

One WireGuard hub, a tunnel to each client site, keepalive set on the client end. Every tunnel is a peer with its own incident, so a broken site pages once and names itself - rather than surfacing as a dozen unrelated hosts that all stopped reporting at the same time.

Remote access for a team

Laptops connecting to an office gateway. Most of those peers are idle most of the time, which is exactly the population that would flood you with false pages elsewhere; here they sit outside the watch set until you give them keepalive.

Tailscale-connected fleet

Machines joined to a tailnet, each with a node key that expires on a schedule you set once and then forget. A threshold on remaining days turns a silent drop-off into a warning with a week of notice.

How It Compares

How It Compares
Approach Setup Per-Peer Health Idle Peers Tailscale Keys Alerting
Prometheus + Grafana 2-4 hours Exporter required Rule you write Scrape + rule Manual rules
Zabbix 1-2 hours Community script Trigger you write Community script Supported
wg show / tailscale status Built-in Live only Read it yourself Live only Not supported
Fivenines 2 min Per peer Keepalive-aware Days remaining Built-in

Included on every plan

No per-tunnel and no per-peer charge - a monitored tunnel is part of the instance the agent runs on.

Frequently Asked Questions

What does Fivenines watch on a WireGuard tunnel? +
Every peer on every interface, keyed by its public key and read straight from wg show. For each one: how long ago it last completed a handshake, bytes received and sent, its endpoint, its allowed IPs and whether persistent-keepalive is configured. Handshake age is the signal that matters - a tunnel that has stopped handshaking has stopped carrying traffic, which is exactly the failure that makes everything behind it go quiet without anything looking broken. Per interface you also get how many peers exist and how many are currently active. WireGuard collection is Linux-only, because wg show and the dump format the agent parses are the Linux userspace tools.
Will it page me for an idle peer that is perfectly healthy? +
No, and that is the part most tools get wrong. WireGuard is silent by design: it only handshakes when there is data to send, so a peer with no traffic and no persistent-keepalive can have an arbitrarily old handshake and be completely healthy. Handshake age is simply not a liveness signal for that peer, so alerting on it is a false positive by construction rather than something you tune away. The alert therefore watches only peers that have persistent-keepalive configured, because only those have a guaranteed handshake cadence - which is also the normal setup for a site-to-site tunnel, since at least one end usually sits behind NAT and needs keepalive to hold the mapping open. Set PersistentKeepalive = 25 on that end to make a tunnel monitorable. If your tunnels carry constant traffic you can switch the alert to watch every peer, and the config panel spells out what that costs you.
What does Fivenines watch on Tailscale? +
The daemon's backend state, the node's own name, how long until its node key expires, and how many tailnet peers exist versus how many are online. Key expiry is the one that matters: when a node key expires the machine is silently dropped off the tailnet, with no error anywhere on the box, so the first sign is usually that something behind it stopped answering. Alert on the remaining days and you get warned before it happens. Tailscale runs on Linux, Windows and macOS, so unlike WireGuard the toggle is available on every host. There are deliberately no per-peer Tailscale rows: every node in a tailnet sees every other node, so per-peer data would cost hosts times tailnet-peers - 50 hosts in a 60-node tailnet is 3,000 series describing 60 devices. The rollups answer the operational question at fixed cost, and each device's own liveness belongs to the agent on that device.
Does the agent ever see or send my private keys? +
No. wg show all dump does include the interface private key and any preshared keys, and the agent never transmits them - there is no column for them and no surface that could render one. What is stored is the peer's public key, which is public by construction, and even that is never displayed: peers are shown by the alias from your wg-quick config, or by a short fingerprint when the config carries no name. That holds everywhere, including in the alert itself and in the identifier attached to an incident, which carries a hash of the key rather than the key. The reason the public key is still the stored identity is that it is the only stable one: renaming a peer in wg0.conf keeps its history and its open incident instead of minting a new peer and falsely resolving the old one.
What can I be alerted on, and is it included in my plan? +
One alert ships as a one-click workflow template, VPN Tunnel Down, which opens an incident per tunnel and closes it when that peer handshakes again. Tailscale has no dedicated trigger - you alert on it with a metric threshold, and the recipe worth setting up is remaining key-expiry days below seven. Every one of the 9 VPN metrics can carry a threshold, with the same sustained-duration, escalation and maintenance-window rules as any other alert, and all 9 can go on a custom dashboard. Nothing here is plan-gated: VPN monitoring is included on every plan, and a monitored tunnel is part of the instance the agent already runs on rather than something extra to buy.

Find out a tunnel died before your client does

14-day trial. No credit card required.

No credit card · 2-minute setup · Cancel anytime