VPNSmith
self-host-vpnINFO

Überwachen Sie Ihr VPS VPN mit Prometheus + Grafana (2026)

Vollständiger Überwachungs-Stack: node_exporter, wireguard_exporter, Grafana-Dashboards, Uptime-/Durchsatzwarnungen, Discord-Webhook-Integration. Einrichtung in 30 Minuten.

Von Eric Gerard · Fondateur · VPNSmith — Spécialiste self-host VPN & VPS GDPR8 Min. LesezeitPhoto via Unsplash

Ihr WireGuard-Tunnel läuft. Aber Sie fragen sich: Wie viele Mbps zieht er in der Spitze? Welche Peers verbinden sich wann? Erreicht das Contabo VPS tatsächlich die beworbenen 200 Mbps? Sie könnten jedes Mal ein Terminal öffnen und tail -f journalctl ausführen, oder Sie installieren in 30 Minuten einen Prometheus + Grafana Stack, der Ihnen visuelle Antworten liefert, Vorfälle meldet und die Historie speichert.

Diese Anleitung implementiert eine produktionsreife Einrichtung für ein Contabo VPS S. node_exporter für das System, wireguard_exporter für Peers, Prometheus für die Speicherung, Grafana für die Visualisierung, Alertmanager + Discord-Webhook für Warnungen.

Warum ein selbst gehostetes VPN überwachen (und nicht nur wg show ansehen)

Das Ausführen von wg show in einem Terminal gibt Ihnen den aktuellen Zustand: verbundene Peers, letzter Handshake, insgesamt ausgetauschte Bytes seit dem Start des Tunnels. Nützlich für ein einmaliges Debuggen, aber es wird Ihnen nie sagen, wie viel Bandbreite Sie gestern um 22 Uhr genutzt haben, welcher Peer Ihren Upload drei Tage lang monopolisiert hat oder ob Ihre Paris-Nürnberg-Latenz sich unbemerkt verdoppelt hat, weil ein BGP-Peering beim Contabo-Upstream defekt ist. Dafür benötigen Sie Zeitreihen: alle 15 Sekunden eine Metrik aufzeichnen, 30 Tage Historie behalten und in der Lage sein, „durchschnittlichen Durchsatz zwischen 18 und 22 Uhr in den letzten zwei Arbeitswochen“ abzufragen. Genau das macht Prometheus, und genau dafür existiert Grafana.

Ein weiterer Grund, warum es unterschätzt wird, sind proaktive Warnungen. Ohne Überwachung entdecken Sie einen defekten Tunnel, wenn ein Peer Ihnen eine Telegram-Nachricht sendet, die sagt: „Es funktioniert nicht für mich“. Mit Alertmanager + einem Discord-Webhook erhalten Sie die Benachrichtigung innerhalb der Minute, die auf den Ausfall folgt, in der Regel bevor Ihre Benutzer es bemerken. Die Arten von Vorfällen, die dies frühzeitig erkennt: ein OOM im WireGuard-Prozess, ausgelöst durch einen falsch konfigurierten Peer, der Hunderte paralleler Verbindungen öffnet, eine Festplatte, die sich stillschweigend füllt, weil die Protokolldrehung defekt ist, oder ein Upstream-Ausfall während einer unangekündigten Wartung. Ohne Überwachung ist die Diagnose dieser Fälle ein Kampf.

Schließlich ist dies die Grundlage für Transparenz gegenüber den Benutzern. Wenn Sie ein VPN für Ihre Familie oder Ihr Unternehmen hosten, können Sie ihnen ein öffentliches schreibgeschütztes Dashboard mit Uptime + verbrauchter Bandbreite zeigen, was Glaubwürdigkeit verleiht, die niemand auf der Verbraucherseite bietet (NordVPN veröffentlicht seine Uptime nicht, ExpressVPN auch nicht).

Architektur

Alles läuft auf dem gleichen Contabo VPS. Drei systemd-Prozesse:

  • node_exporter (Port 9100): Systemmetriken (CPU, RAM, Festplatte, Netzwerk)
  • wireguard_exporter (Port 9586): WireGuard-Peer-Metriken (Handshake, bytes_in/out, last_seen)
  • prometheus (Port 9090): ruft alle 15s Exporteure ab, speichert 30 Tage
  • grafana (Port 3000): Dashboards
  • alertmanager (Port 9093): Alarmregeln + Discord-Webhook

Kosten: ~250 MB RAM, ~3% CPU konstant auf einem VPS mit 4 vCPUs. Keine spürbare Auswirkung auf den Tunnel.

Schritt 1 — Installieren Sie node_exporter

# Auf dem VPS, mit sudo
sudo useradd --no-create-home --shell /usr/sbin/nologin node_exporter

cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
sudo cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter

systemd-Einheit /etc/systemd/system/node_exporter.service:

[Unit]
Description=Node Exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter --web.listen-address=127.0.0.1:9100

[Install]
WantedBy=multi-user.target

Wichtig: Wir binden an 127.0.0.1 (nicht 0.0.0.0) — keine öffentliche Exposition. Prometheus greift über localhost zu.

sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
curl -s http://127.0.0.1:9100/metrics | head -20
# Sollte Metriken wie "node_cpu_seconds_total" zurückgeben

Schritt 2 — Installieren Sie prometheus-wireguard-exporter

Der Exporter, den wir verwenden: github.com/MindFlavor/prometheus_wireguard_exporter (Rust, ~3 MB Binärdatei, ruft wg show-Ausgabe ab).

cd /tmp
wget https://github.com/MindFlavor/prometheus_wireguard_exporter/releases/download/3.6.6/prometheus_wireguard_exporter_3.6.6_linux_amd64.tar.gz
tar xzf prometheus_wireguard_exporter_3.6.6_linux_amd64.tar.gz
sudo cp prometheus_wireguard_exporter /usr/local/bin/
sudo chmod +x /usr/local/bin/prometheus_wireguard_exporter

systemd-Einheit /etc/systemd/system/wireguard_exporter.service:

[Unit]
Description=WireGuard Prometheus Exporter
After=network.target wg-quick@wg0.service
Requires=wg-quick@wg0.service

[Service]
User=root
ExecStart=/usr/local/bin/prometheus_wireguard_exporter -a 127.0.0.1 -p 9586 -n /etc/wireguard/wg0.conf
Restart=on-failure

[Install]
WantedBy=multi-user.target

Das Flag -n /etc/wireguard/wg0.conf ermöglicht es dem Exporter, Peer-Namen (im .conf kommentiert) als Prometheus-Labels zu verwenden. In Grafana lesbarer als bloße Pubkeys.

sudo systemctl daemon-reload
sudo systemctl enable --now wireguard_exporter
curl -s http://127.0.0.1:9586/metrics | grep wireguard_
# Sollte wireguard_sent_bytes_total, wireguard_received_bytes_total usw. zurückgeben

Schritt 3 — Installieren Sie Prometheus

sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus /var/lib/prometheus

cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.55.1/prometheus-2.55.1.linux-amd64.tar.gz
tar xzf prometheus-2.55.1.linux-amd64.tar.gz
sudo cp prometheus-2.55.1.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.55.1.linux-amd64/promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool

Konfiguration /etc/prometheus/prometheus.yml:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - 127.0.0.1:9093

rule_files:
  - "alert_rules.yml"

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: [127.0.0.1:9090]

  - job_name: node
    static_configs:
      - targets: [127.0.0.1:9100]
        labels:
          instance: vps-contabo-nuremberg

  - job_name: wireguard
    static_configs:
      - targets: [127.0.0.1:9586]
        labels:
          instance: vps-contabo-nuremberg

Alarmregeln /etc/prometheus/alert_rules.yml:

groups:
  - name: vpn_alerts
    interval: 30s
    rules:
      - alert: HighCPU
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        annotations:
          summary: "CPU > 80% auf {{ $labels.instance }}"

      - alert: WireGuardPeerDown
        expr: time() - wireguard_latest_handshake_seconds > 600
        for: 5m
        annotations:
          summary: "WG-Peer {{ $labels.peer }} hat seit >10min keinen Handshake durchgeführt"

      - alert: HighBandwidth
        expr: rate(node_network_transmit_bytes_total{device="eth0"}[5m]) * 8 > 180000000
        for: 10m
        annotations:
          summary: "Bandbreite > 180 Mbps auf eth0 — nähert sich dem Contabo-Limit"

      - alert: DiskAlmostFull
        expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 15
        for: 10m
        annotations:
          summary: "Festplatte < 15% frei auf {{ $labels.instance }}"

systemd-Einheit /etc/systemd/system/prometheus.service:

[Unit]
Description=Prometheus
After=network.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
  --config.file /etc/prometheus/prometheus.yml \
  --storage.tsdb.path /var/lib/prometheus/ \
  --storage.tsdb.retention.time=30d \
  --web.listen-address=127.0.0.1:9090

[Install]
WantedBy=multi-user.target
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml /etc/prometheus/alert_rules.yml
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus

Schritt 4 — Installieren Sie Grafana

sudo apt install -y apt-transport-https software-properties-common
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/grafana.gpg
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install -y grafana

Bearbeiten Sie /etc/grafana/grafana.ini, um nur localhost zu binden:

[server]
http_addr = 127.0.0.1
http_port = 3000
sudo systemctl enable --now grafana-server

Schritt 5 — Greifen Sie sicher auf Grafana zu

Anstatt Port 3000 öffentlich zu öffnen, SSH-Tunnel von Ihrem Laptop:

ssh -L 3000:127.0.0.1:3000 eric@vpn.example.com

Öffnen Sie dann http://127.0.0.1:3000 in Ihrem lokalen Browser. Login admin / admin (sofort ändern).

Alternative: Zugriff über den WireGuard-Tunnel. Wenn Ihr VPS auf der VPN-Seite 10.66.66.1 ist, erreichen Sie http://10.66.66.1:3000 von jedem verbundenen Peer. Kein Port im öffentlichen Internet exponiert.

Schritt 6 — Konfigurieren Sie die Prometheus-Datenquelle

Ein Serverraum-Gang
Ein Serverraum-Gang

In Grafana:

  1. Einstellungen → Datenquellen → Datenquelle hinzufügen → Prometheus
  2. URL: http://127.0.0.1:9090
  3. Speichern & Testen → "Datenquelle funktioniert"

Schritt 7 — Dashboards importieren

Fertig konfigurierte Dashboards:

  • Node Exporter Full: ID 1860 auf grafana.com — vollständige Systemmetriken
  • WireGuard: ID 12557 oder neuer — Peers, Bandbreite, last_seen

In Grafana: Dashboards → Importieren → ID einfügen → Prometheus-Datenquelle auswählen → Importieren.

Für ein benutzerdefiniertes VPS-VPN-Dashboard haben wir unser JSON auf GitHub veröffentlicht (Link im VPNSmith-Repo). Es enthält:

  • Übersicht: RAM/CPU/Festplatte/Uptime
  • eth0-Bandbreite (in/out, 1h/24h/7d)
  • WireGuard-Peers: Name, letzter Handshake, ausgetauschte Bytes
  • Top-Peers nach Nutzung
  • Aktive Warnungen

Schritt 8 — Discord-Warnungen über Webhook

Installieren Sie Alertmanager:

cd /tmp
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
tar xzf alertmanager-0.27.0.linux-amd64.tar.gz
sudo cp alertmanager-0.27.0.linux-amd64/alertmanager /usr/local/bin/
sudo cp alertmanager-0.27.0.linux-amd64/amtool /usr/local/bin/
sudo useradd --no-create-home --shell /usr/sbin/nologin alertmanager
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo chown alertmanager:alertmanager /etc/alertmanager /var/lib/alertmanager

Konfiguration /etc/alertmanager/alertmanager.yml:

global:
  resolve_timeout: 5m

route:
  receiver: discord

receivers:
  - name: discord
    webhook_configs:
      - url: 'https://discord.com/api/webhooks/XXXXXXX/YYYYYYY?wait=true'
        send_resolved: true

Erstellen Sie den Discord-Webhook: Servereinstellungen → Integrationen → Webhooks → Neuer Webhook. URL kopieren. Das rohe Prometheus-Format sieht in Discord nicht schön aus — wir verwenden die Brücke alertmanager-discord oder einen einfachen Parser, der saubere Discord-Einbettungen erzeugt.

systemd-Einheit /etc/systemd/system/alertmanager.service:

[Unit]
Description=Alertmanager
After=network.target

[Service]
User=alertmanager
Group=alertmanager
Type=simple
ExecStart=/usr/local/bin/alertmanager \
  --config.file=/etc/alertmanager/alertmanager.yml \
  --storage.path=/var/lib/alertmanager \
  --web.listen-address=127.0.0.1:9093

[Install]
WantedBy=multi-user.target
sudo chown alertmanager:alertmanager /etc/alertmanager/alertmanager.yml
sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager

Nützliche Abfragen für ein VPN VPS

In Grafana sind diese Prometheus-Abfragen im Alltag am nützlichsten:

Gesamte WireGuard-Bandbreite (Mbps):

rate(wireguard_sent_bytes_total[5m]) * 8 / 1e6 + rate(wireguard_received_bytes_total[5m]) * 8 / 1e6

Top 5 Peers nach empfangenen Bytes (24h):

topk(5, increase(wireguard_received_bytes_total[24h]))

Letzter Handshake pro Peer (menschlich lesbar):

time() - wireguard_latest_handshake_seconds

CPU-Auslastung %:

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Festplattennutzung %:

100 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100

Backup und Aufbewahrung

Prometheus speichert standardmäßig 30 Tage (--storage.tsdb.retention.time=30d). Darüber hinaus entweder die Aufbewahrung erhöhen (Festplatte hinzufügen) oder mit Thanos oder VictoriaMetrics herunterstufen (übertrieben für ein persönliches VPS).

/var/lib/prometheus/ verbraucht ~50-100 MB pro Tag für diesen Stack. Bei 30 Tagen, ~2-3 GB maximal. Ihr Contabo VPS hat 50 GB NVMe, reichlich Spielraum.

Zusätzliche Absicherung

  • fail2ban auf Grafana: Erstellen Sie einen Filter für Anmeldeversuche. 5× fehlgeschlagene Authentifizierung → 15-minütige Sperre.
  • Reverse Proxy mit Basis-Authentifizierung: Caddy oder Nginx vor Grafana, wenn Sie das Dashboard mit einem Kollegen ohne SSH-Tunnel teilen möchten. Aber immer den WireGuard-Tunnel bevorzugen, wenn möglich.
  • TLS: Wenn Sie Grafana außerhalb des LAN/Tunnels exponieren, certbot + Caddy in 5 Minuten.

Fazit

Mit diesem Stack erhalten Sie Echtzeit-Einblicke in alles, was über Ihr VPS VPN läuft. Sie sehen sofort, wenn ein Peer über Nacht 200 GB zieht (wahrscheinlich ein Linux-ISO oder Plex-Backup), wenn die CPU-Spitzenwerte erreicht (oft ein falsch konfigurierter OOM-Kill), wenn ein Peer seit 1 Stunde keinen Handshake durchgeführt hat (toter oder verschwundener Client).

Es sind 30 Minuten Einrichtung einmalig, für dauerhaften Seelenfrieden auf einem Contabo VPS S mit seinem beworbenen 200 Mbit/s-Link.

Um loszulegen:

Das von uns empfohlene VPS: Contabo VPS S Cloud — 4,99 €/Monat, beworbener 200 Mbit/s-Link, deutsche DSGVO-Jurisdiktion. Sehen Sie sich unsere vollständige Contabo VPS-Bewertung an.

★ Nürnberger DSGVO-Rechenzentrum · ✓ Dedizierte IPv4 inklusive · 200+ Mbps garantiert

Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region