Monitoring & Alerting for WireGuard VPN

Introduction

WireGuard is a fast, modern, and secure VPN tunnel software by Jason A. Donenfeld. It aims to be faster, simpler, leaner, and more useful than IPsec or considerably more performant than OpenVPN.

When you have a WireGuard VPN tunnel powering critical services, it’s important to monitor the VPN tunnel's health and set up an alert.

In this article, we’ll set up the Prometheus WireGuard exporter, Grafana Dashboard, and Alerts Manager.

WireGuard Prometheus Exporter

Firstly, we’ll install WireGuard Prometheus exporter on the WireGuard instance. Basically, the exporter exposes wg show all dump results in a format Prometheus understands.

The exporter is written in Rust and is very light on server resources, both in terms of memory and CPU usage.

For the moment, there are no pre-built binaries for the exporter. Thus, we’ll have to build it. Since it’s written in Rust, it’s fairly straightforward.

NOTE: yum is used, you can any package manager.

1. Build and install wireguard prometheus exporter

$ yum install cargo  # RedHat-based
$ cargo install prometheus_wireguard_exporter
$ install -m755 /root/.cargo/bin/prometheus_wireguard_exporter /usr/local/bin/
$ yum remove cargo

2. Install systemd service for the exporter

NOTE: If you’re using custom WireGuard configuration, specify that in-place of /etc/wireguard/wg0.conf

$ cat <<EOF  > /etc/systemd/system/prometheus-wireguard-exporter.service
[Unit]
Description=Prometheus WireGuard Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/local/bin/prometheus_wireguard_exporter -n /etc/wireguard/wg0.conf

[Install]
WantedBy=multi-user.target
EOF

And enable the exporter service by running the following command:

$ systemctl enable --now prometheus-wireguard-exporter.service

3. Verify exporter service is running

$ curl localhost:9586/metrics

Configure Prometheus

Next, we’ll configure Prometheus to scrape the Wireguard exporter metrics.

Add the following scape config job to /etc/prometheus/prometheus.yaml

- job_name: wireguard-exporter
static_configs:
- labels:
instance: my-wireguard-tunnel
targets:
- IP_OF_EXPORTER:9586

And reload the prometheus service

$ systemctl reload prometheus

Wireguard Grafana Dashboard

  1. Login to your Grafana UI
  2. Download the following JSON file and import dashboard as JSON file

https://github.com/tuladhar/wireguard-connectivity-monitoring/blob/main/wireguard-grafana-dashboard.json

Fig: Import dashboard button screen
Fig: Import from file screen

3. Finally, hit import.

Fig: Import dashboard screen

Now, duplicate the“Last Handshake” panel and customize it so we can create alerts on it.

  1. Create a duplicate panel of “Last Handshake”
Fig: Duplicate Last Handshake” panel

2. Edit the duplicate panel

3. Modify the metrics to the following:

time() - wireguard_latest_handshake_seconds

3. Set the Legend to {{instance}}

4. Turn off the Instant metrics.

3. Choose the Graph Visualization from the Panel tab

4. From theField tab and change Unit to short from From Now

Fig: Unit change screen

5. Finally, click Save

Fig: Customized panel

Alert Manager

Now, let’s create alerts if the WireGuard connection is lost.

  1. Edit the panel
Fig: Edit panel screen

2. Click on the Alerts tab and click “Create Alert”

Fig: Create alert screen

3. Set the condition as WHEN avg() OF query(A, 1m, now) IS ABOVE 180

NOTICE: Alert threshold bar should appear in the dashboard.

Fig: Alert condition screen

4. Create Pagerduty alert or Slack alert

Fig: Send to screen

5. Finally click “Save”

NOTE: Normally WireGuard sends a health check every 2 minutes, so it’s safe to keep 3 minutes, i.e, 180 seconds as alerting threshold.

Conclusion

Alongside WireGuard tunnel monitoring, it’s important to monitor WireGuard tunnel instances as well, which is not covered in this article.

I hope you found this article helpful — Stay safe👋

References

Make Complex Simple.