VPNSmith
self-host-vpnINFO

Monitora il tuo VPS VPN con Prometheus + Grafana (2026)

Stack di monitoraggio completo: node_exporter, wireguard_exporter, dashboard Grafana, avvisi di uptime/throughput, integrazione webhook Discord. Configurazione in 30 minuti.

Di Eric Gerard · Fondateur · VPNSmith — Spécialiste self-host VPN & VPS GDPR8 min letturaPhoto via Unsplash

Il tuo tunnel WireGuard è attivo. Ma ti chiedi: quanti Mbps raggiunge al picco? Quali peer si connettono e quando? Il VPS Contabo raggiunge effettivamente i 200 Mbps pubblicizzati? Potresti aprire un terminale e usare tail -f journalctl ogni volta, oppure installare uno stack Prometheus + Grafana in 30 minuti che ti fornisce risposte visive, avvisi sugli incidenti e conserva la cronologia.

Questa guida implementa una configurazione di livello produttivo per un VPS Contabo S. node_exporter per il sistema, wireguard_exporter per i peer, Prometheus per l'archiviazione, Grafana per la visualizzazione, Alertmanager + webhook Discord per gli avvisi.

Perché monitorare una VPN self-hosted (e non solo guardare wg show)

Eseguire wg show in un terminale ti dà lo stato istantaneo: peer connessi, ultima stretta di mano, byte totali scambiati dall'inizio del tunnel. Utile per un debug occasionale, ma non ti dirà mai quanta larghezza di banda hai usato ieri alle 22, quale peer monopolizza il tuo upload per tre giorni, o se la latenza Parigi-Norimberga è raddoppiata silenziosamente a causa di un peering BGP rotto a monte di Contabo. Per questo hai bisogno di serie temporali: registra una metrica ogni 15 secondi, conserva 30 giorni di cronologia e sii in grado di interrogare "throughput medio tra le 18 e le 22 nelle ultime due settimane lavorative". Questo è esattamente ciò che fa Prometheus, ed è esattamente il motivo per cui esiste Grafana sopra di esso.

L'altro motivo sottovalutato sono gli avvisi proattivi. Senza monitoraggio, scopri un tunnel rotto quando un peer ti invia un messaggio su Telegram dicendo "non funziona per me". Con Alertmanager + un webhook Discord, ricevi la notifica entro il minuto successivo all'interruzione, generalmente prima che i tuoi utenti se ne accorgano. I tipi di incidenti che questo rileva in anticipo: un OOM sul processo WireGuard innescato da un peer configurato male che apre centinaia di connessioni parallele, un disco che si riempie silenziosamente a causa di una rotazione dei log rotta, o un'interruzione a monte durante una manutenzione non annunciata. Senza monitoraggio, diagnosticare questi casi è una lotta.

Infine, questa è la base della trasparenza per gli utenti. Se ospiti una VPN per la tua famiglia o azienda, essere in grado di mostrare loro una dashboard pubblica in sola lettura con uptime + larghezza di banda consumata dà credibilità che nessuno offre sul lato consumer (NordVPN non pubblica il suo uptime, ExpressVPN neanche).

Architettura

Tutto gira sullo stesso VPS Contabo. Tre processi systemd:

  • node_exporter (porta 9100): metriche di sistema (CPU, RAM, disco, rete)
  • wireguard_exporter (porta 9586): metriche dei peer WireGuard (handshake, bytes_in/out, last_seen)
  • prometheus (porta 9090): raccoglie dati dagli exporter ogni 15s, conserva 30 giorni
  • grafana (porta 3000): dashboard
  • alertmanager (porta 9093): regole di avviso + webhook Discord

Costo: ~250 MB di RAM, ~3% di CPU costante su un VPS con 4 vCPU. Nessun impatto percepibile sul tunnel.

Passo 1 — Installa node_exporter

# Sul VPS, con 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

unità systemd /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

Importante: ci colleghiamo su 127.0.0.1 (non 0.0.0.0) — nessuna esposizione pubblica. Prometheus accede tramite localhost.

sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
curl -s http://127.0.0.1:9100/metrics | head -20
# Dovrebbe restituire metriche come "node_cpu_seconds_total"

Passo 2 — Installa prometheus-wireguard-exporter

L'exporter che usiamo: github.com/MindFlavor/prometheus_wireguard_exporter (Rust, ~3 MB binario, raccoglie l'output di wg show).

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

unità systemd /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

Il flag -n /etc/wireguard/wg0.conf consente all'exporter di utilizzare i nomi dei peer (commentati nel .conf) come etichette Prometheus. Più leggibile in Grafana rispetto alle chiavi pubbliche.

sudo systemctl daemon-reload
sudo systemctl enable --now wireguard_exporter
curl -s http://127.0.0.1:9586/metrics | grep wireguard_
# Dovrebbe restituire wireguard_sent_bytes_total, wireguard_received_bytes_total, ecc.

Passo 3 — Installa 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

Configura /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

Regole di avviso /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% su {{ $labels.instance }}"

      - alert: WireGuardPeerDown
        expr: time() - wireguard_latest_handshake_seconds > 600
        for: 5m
        annotations:
          summary: "Il peer WG {{ $labels.peer }} non ha effettuato handshake da >10min"

      - alert: HighBandwidth
        expr: rate(node_network_transmit_bytes_total{device="eth0"}[5m]) * 8 > 180000000
        for: 10m
        annotations:
          summary: "Larghezza di banda > 180 Mbps su eth0 — avvicinandosi al limite di Contabo"

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

unità systemd /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

Passo 4 — Installa 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

Modifica /etc/grafana/grafana.ini per collegarsi solo a localhost:

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

Passo 5 — Accedi a Grafana in modo sicuro

Invece di aprire la porta 3000 pubblicamente, tunnel SSH dal tuo laptop:

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

Quindi apri http://127.0.0.1:3000 nel tuo browser locale. Login admin / admin (cambia immediatamente).

Alternativa: accedi tramite il tunnel WireGuard. Se il tuo VPS è 10.66.66.1 sul lato VPN, accedi a http://10.66.66.1:3000 da qualsiasi peer connesso. Nessuna porta esposta a Internet pubblico.

Passo 6 — Configura la fonte dati Prometheus

Un corridoio di una sala server
Un corridoio di una sala server

In Grafana:

  1. Impostazioni → Fonti dati → Aggiungi fonte dati → Prometheus
  2. URL: http://127.0.0.1:9090
  3. Salva & Testa → "La fonte dati funziona"

Passo 7 — Importa dashboard

Dashboard pronte all'uso:

  • Node Exporter Full: ID 1860 su grafana.com — metriche di sistema complete
  • WireGuard: ID 12557 o più recente — peer, larghezza di banda, last_seen

In Grafana: Dashboard → Importa → incolla l'ID → scegli la fonte dati Prometheus → Importa.

Per una dashboard personalizzata VPS-VPN, abbiamo pubblicato il nostro JSON su GitHub (link nel repo VPNSmith). Contiene:

  • Panoramica: RAM/CPU/disco/uptime
  • Larghezza di banda eth0 (in/out, 1h/24h/7d)
  • Peer WireGuard: nome, ultima stretta di mano, byte scambiati
  • Top peer per utilizzo
  • Avvisi attivi

Passo 8 — Avvisi Discord tramite webhook

Installa 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

Configura /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

Genera il webhook Discord: Impostazioni Server → Integrazioni → Webhook → Nuovo Webhook. Copia l'URL. Il formato grezzo di Prometheus non è bello su Discord — usiamo il bridge alertmanager-discord o un semplice parser che produce embed Discord puliti.

unità systemd /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

Query utili per un VPS VPN

In Grafana, queste query Prometheus sono le più utili giorno per giorno:

Larghezza di banda totale WireGuard (Mbps):

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

Top 5 peer per byte ricevuti (24h):

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

Ultima stretta di mano per peer (umanizzata):

time() - wireguard_latest_handshake_seconds

Utilizzo CPU %:

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

Utilizzo disco %:

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

Backup e conservazione

Prometheus conserva 30 giorni per impostazione predefinita (--storage.tsdb.retention.time=30d). Oltre, puoi aumentare la conservazione (aggiungi disco) o ridurre il campionamento con Thanos o VictoriaMetrics (eccessivo per un VPS personale).

/var/lib/prometheus/ consuma ~50-100 MB al giorno per questo stack. A 30 giorni, ~2-3 GB max. Il tuo VPS Contabo ha 50 GB NVMe, ampio margine.

Ulteriore rafforzamento

  • fail2ban su Grafana: costruisci un filtro per i tentativi di login. 5× autenticazione fallita → ban di 15 minuti.
  • Proxy inverso con autenticazione di base: Caddy o Nginx davanti a Grafana se vuoi condividere la dashboard con un collega senza tunnel SSH. Ma preferisci sempre il tunnel WireGuard se possibile.
  • TLS: se esponi Grafana fuori dalla LAN/tunnel, certbot + Caddy in 5 minuti.

Verdetto

Con questo stack ottieni visibilità in tempo reale su tutto ciò che passa sulla tua VPS VPN. Vedi immediatamente quando un peer scarica 200 GB durante la notte (probabilmente un ISO Linux, o backup Plex), quando la CPU sale (spesso un OOM configurato male), quando un peer non ha effettuato handshake in 1 ora (client morto o scomparso).

Sono 30 minuti di configurazione una volta, per una pace duratura su un VPS Contabo S con il suo link pubblicizzato a 200 Mbit/s.

Per iniziare:

Il VPS che consigliamo: Contabo VPS S Cloud — 4,99 €/mese, link pubblicizzato a 200 Mbit/s, giurisdizione GDPR tedesca. Vedi la nostra recensione completa del VPS Contabo.

★ Datacenter GDPR di Norimberga · ✓ IPv4 dedicato incluso · 200+ Mbps garantiti

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