Monitor WireGuard VPN server with Prometheus and Grafana dashboards

Intermediate 25 min Apr 18, 2026 151 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up comprehensive monitoring for your WireGuard VPN server using Prometheus metrics collection and Grafana visualization. This guide covers installing the WireGuard exporter, configuring alerting rules, and building dashboards to track connection status, bandwidth usage, and peer activity.

Prerequisites

  • WireGuard VPN server installed and configured
  • Root or sudo access
  • Basic understanding of Prometheus and Grafana
  • 4GB RAM minimum for monitoring stack

What this solves

WireGuard VPN servers need monitoring to track peer connections, bandwidth usage, and server health. This tutorial sets up Prometheus to collect WireGuard metrics and Grafana to visualize connection status, data transfer rates, and peer activity with automated alerting for connection failures or performance issues.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions of monitoring tools.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install Go programming language

The WireGuard Prometheus exporter is written in Go, so we need to install the Go compiler to build it from source.

sudo apt install -y golang-go git
sudo dnf install -y golang git

Download and compile WireGuard Prometheus exporter

Clone the official WireGuard exporter repository and build the binary for monitoring WireGuard interfaces.

cd /opt
sudo git clone https://github.com/MindFlavor/prometheus_wireguard_exporter.git
cd prometheus_wireguard_exporter
sudo go build -o wireguard_exporter

Create WireGuard exporter user and directories

Create a dedicated system user for the exporter service with proper permissions to read WireGuard configuration.

sudo useradd --system --shell /bin/false --home /var/lib/wireguard-exporter wireguard-exporter
sudo mkdir -p /var/lib/wireguard-exporter
sudo cp wireguard_exporter /usr/local/bin/
sudo chmod +x /usr/local/bin/wireguard_exporter
sudo chown wireguard-exporter:wireguard-exporter /var/lib/wireguard-exporter

Configure WireGuard exporter systemd service

Create a systemd service file to run the WireGuard exporter as a daemon with proper security settings.

[Unit]
Description=Prometheus WireGuard Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=wireguard-exporter
Group=wireguard-exporter
Type=simple
ExecStart=/usr/local/bin/wireguard_exporter -n /etc/wireguard/wg0.conf
Restart=on-failure
RestartSec=5
CapabilityBoundingSet=CAP_NET_ADMIN
AmbientCapabilities=CAP_NET_ADMIN
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true

[Install]
WantedBy=multi-user.target

Grant WireGuard exporter access to configuration

Add the exporter user to the necessary groups to read WireGuard configuration and interface statistics.

sudo usermod -a -G systemd-network wireguard-exporter
sudo chmod 640 /etc/wireguard/wg0.conf
sudo chgrp systemd-network /etc/wireguard/wg0.conf

Start and enable WireGuard exporter service

Enable the exporter service to start automatically on boot and verify it's collecting metrics properly.

sudo systemctl daemon-reload
sudo systemctl enable --now wireguard-exporter.service
sudo systemctl status wireguard-exporter.service

Install Prometheus server

Install Prometheus to collect and store WireGuard metrics from the exporter endpoint.

sudo apt install -y prometheus
sudo dnf install -y prometheus2

Configure Prometheus to scrape WireGuard metrics

Update the Prometheus configuration to collect metrics from the WireGuard exporter endpoint every 15 seconds.

global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "/etc/prometheus/wireguard-rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - localhost:9093

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']

  - job_name: 'wireguard'
    static_configs:
      - targets: ['localhost:9586']
    scrape_interval: 10s
    metrics_path: /metrics

Create WireGuard alerting rules

Define Prometheus alerting rules to notify when WireGuard peers disconnect or bandwidth thresholds are exceeded.

groups:
  - name: wireguard
    rules:
      - alert: WireGuardPeerDown
        expr: wireguard_peer_up == 0
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "WireGuard peer {{ $labels.peer }} is down"
          description: "WireGuard peer {{ $labels.peer }} on interface {{ $labels.interface }} has been down for more than 2 minutes."

      - alert: WireGuardHighBandwidth
        expr: rate(wireguard_peer_receive_bytes_total[5m]) > 100000000 or rate(wireguard_peer_transmit_bytes_total[5m]) > 100000000
        for: 5m
        labels:
          severity: info
        annotations:
          summary: "High bandwidth usage on WireGuard peer {{ $labels.peer }}"
          description: "WireGuard peer {{ $labels.peer }} is using high bandwidth: {{ $value }} bytes/sec over 5 minutes."

      - alert: WireGuardExporterDown
        expr: up{job="wireguard"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "WireGuard Prometheus exporter is down"
          description: "The WireGuard Prometheus exporter has been down for more than 1 minute."

      - alert: WireGuardOldHandshake
        expr: time() - wireguard_peer_last_handshake_seconds > 300
        for: 0m
        labels:
          severity: warning
        annotations:
          summary: "WireGuard peer {{ $labels.peer }} has stale handshake"
          description: "WireGuard peer {{ $labels.peer }} last handshake was {{ $value }} seconds ago."

Install Prometheus Alertmanager

Install Alertmanager to handle alert notifications from Prometheus rules and send them to external systems.

sudo apt install -y prometheus-alertmanager
sudo dnf install -y alertmanager

Configure Alertmanager for email notifications

Set up Alertmanager to send email notifications when WireGuard monitoring alerts are triggered.

global:
  smtp_smarthost: 'localhost:587'
  smtp_from: 'alertmanager@example.com'
  smtp_auth_username: 'alertmanager@example.com'
  smtp_auth_password: 'your-email-password'

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'wireguard-alerts'

receivers:
  - name: 'wireguard-alerts'
    email_configs:
      - to: 'admin@example.com'
        subject: 'WireGuard Alert: {{ .GroupLabels.alertname }}'
        body: |
          {{ range .Alerts }}
          Alert: {{ .Annotations.summary }}
          Description: {{ .Annotations.description }}
          Labels: {{ .Labels }}
          {{ end }}

Install Grafana dashboard

Install Grafana to create visual dashboards for WireGuard metrics and monitoring data.

sudo apt install -y apt-transport-https software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install -y grafana
sudo dnf install -y grafana

Configure Grafana data source

Create a Grafana configuration file to automatically provision Prometheus as a data source.

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://localhost:9090
    isDefault: true
    editable: true

Create WireGuard Grafana dashboard configuration

Set up a comprehensive dashboard to visualize WireGuard peer connections, bandwidth usage, and handshake status.

{
  "dashboard": {
    "id": null,
    "title": "WireGuard VPN Monitor",
    "tags": ["wireguard", "vpn"],
    "timezone": "browser",
    "panels": [
      {
        "id": 1,
        "title": "Connected Peers",
        "type": "stat",
        "targets": [
          {
            "expr": "sum(wireguard_peer_up)",
            "legendFormat": "Active Peers"
          }
        ],
        "gridPos": {"h": 4, "w": 6, "x": 0, "y": 0}
      },
      {
        "id": 2,
        "title": "Total Bandwidth (In/Out)",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(wireguard_peer_receive_bytes_total[5m]) * 8",
            "legendFormat": "Received - {{ peer }}"
          },
          {
            "expr": "rate(wireguard_peer_transmit_bytes_total[5m]) * 8",
            "legendFormat": "Transmitted - {{ peer }}"
          }
        ],
        "yAxes": [
          {
            "unit": "bps",
            "label": "Bits per second"
          }
        ],
        "gridPos": {"h": 8, "w": 12, "x": 6, "y": 0}
      },
      {
        "id": 3,
        "title": "Peer Status",
        "type": "table",
        "targets": [
          {
            "expr": "wireguard_peer_up",
            "legendFormat": "",
            "format": "table",
            "instant": true
          }
        ],
        "gridPos": {"h": 8, "w": 18, "x": 0, "y": 8}
      }
    ],
    "time": {
      "from": "now-1h",
      "to": "now"
    },
    "refresh": "10s"
  }
}

Start monitoring services

Enable and start all monitoring services to begin collecting and visualizing WireGuard metrics.

sudo systemctl enable --now prometheus
sudo systemctl enable --now prometheus-alertmanager
sudo systemctl enable --now grafana-server

Configure firewall for monitoring ports

Open the necessary ports for Prometheus, Alertmanager, and Grafana web interfaces.

sudo ufw allow 9090/tcp comment 'Prometheus'
sudo ufw allow 9093/tcp comment 'Alertmanager'
sudo ufw allow 3000/tcp comment 'Grafana'
sudo ufw allow 9586/tcp comment 'WireGuard Exporter'
sudo firewall-cmd --permanent --add-port=9090/tcp
sudo firewall-cmd --permanent --add-port=9093/tcp
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --permanent --add-port=9586/tcp
sudo firewall-cmd --reload

Verify your setup

Test that all monitoring components are working correctly and collecting WireGuard metrics.

# Check WireGuard exporter metrics
curl http://localhost:9586/metrics | grep wireguard

Verify Prometheus is scraping targets

curl http://localhost:9090/api/v1/targets

Test Prometheus query for WireGuard peers

curl 'http://localhost:9090/api/v1/query?query=wireguard_peer_up'

Check service status

sudo systemctl status wireguard-exporter prometheus prometheus-alertmanager grafana-server
Note: Access Grafana at http://your-server-ip:3000 with default credentials admin/admin. Prometheus is available at http://your-server-ip:9090 and Alertmanager at http://your-server-ip:9093.

Common issues

SymptomCauseFix
WireGuard exporter returns no metricsInsufficient permissions to read WireGuard configCheck user groups with groups wireguard-exporter and file permissions
Prometheus can't scrape exporterFirewall blocking port 9586Allow port with sudo ufw allow 9586/tcp
Grafana shows no dataPrometheus data source not configuredVerify datasource configuration and Prometheus URL
Alerts not firingAlertmanager not connected to PrometheusCheck alertmanager targets in Prometheus at /targets
Exporter service fails to startWireGuard config file not foundUpdate service file with correct config path

Next steps

Running this in production?

Want this handled for you? Setting up VPN monitoring once is straightforward. Keeping it patched, monitored, backed up and tuned across environments is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.