El problema#
Tengo Wireguard corriendo en mi servidor doméstico hace meses. Funciona bien, pero hay un punto ciego: cuando un peer se desconecta, no me entero hasta que intento usarlo. Un cliente se cae, otro se queda sin conexión, y yo sin saberlo.
Necesitaba algo que:
- Detecte automáticamente cuándo un peer no responde
- Me alerte en tiempo real
- Intente reconectar o ejecutar acciones
- Se integre con Prometheus que ya tengo monitoreando
La solución: wireguard-exporter + scripts#
No reinventé la rueda. Usé wireguard-exporter para exponer métricas a Prometheus y un script Bash que monitorea el estado de los peers.
Paso 1: Instalar wireguard-exporter#
sudo wget https://github.com/MindFlavor/prometheus_wireguard_exporter/releases/download/v4.4.5/prometheus_wireguard_exporter-4.4.5-x86_64-unknown-linux-musl -O /usr/local/bin/wireguard_exporter
sudo chmod +x /usr/local/bin/wireguard_exporterPaso 2: Configurar como servicio systemd#
Creé /etc/systemd/system/wireguard-exporter.service:
[Unit]
Description=Prometheus Wireguard Exporter
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/wireguard_exporter -l 127.0.0.1 -p 9586
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable wireguard-exporter
sudo systemctl start wireguard-exporterPaso 3: Agregar al scrape config de Prometheus#
En /etc/prometheus/prometheus.yml:
scrape_configs:
- job_name: 'wireguard'
static_configs:
- targets: ['127.0.0.1:9586']
scrape_interval: 15sPaso 4: Script de detección de peers caídos#
Creé /opt/wireguard-monitor.sh:
#!/bin/bash
WG_INTERFACE="wg0"
ALERT_EMAIL="user@example.com"
PROMETHEUS_URL="http://127.0.0.1:9090"
LOG_FILE="/var/log/wireguard-monitor.log"
check_peer_handshake() {
local peer=$1
local last_handshake=$(wg show $WG_INTERFACE peers | grep -A10 "$peer" | grep "latest handshake" | awk '{print $(NF-1)}')
if [ -z "$last_handshake" ]; then
echo "[$(date)] ERROR: No se encontró peer $peer" >> $LOG_FILE
return 1
fi
local current_time=$(date +%s)
local time_diff=$((current_time - last_handshake))
local timeout=300 # 5 minutos
if [ $time_diff -gt $timeout ]; then
echo "[$(date)] ALERTA: Peer $peer desconectado (hace ${time_diff}s)" >> $LOG_FILE
return 1
fi
return 0
}
# Obtener lista de peers desde Prometheus
get_active_peers() {
curl -s "$PROMETHEUS_URL/api/v1/query?query=wireguard_peer_allowed_ips" | jq '.data.result[].metric.public_key' | tr -d '"'
}
main() {
for peer in $(get_active_peers); do
if ! check_peer_handshake "$peer"; then
# Enviar alerta (ejemplo con curl + webhook)
curl -X POST http://127.0.0.1:5000/alert \
-H "Content-Type: application/json" \
-d "{\"peer\":\"$peer\",\"status\":\"down\"}"
fi
done
}
mainsudo chmod +x /opt/wireguard-monitor.shPaso 5: Ejecutar cada minuto con cron#
sudo crontab -e* * * * * /opt/wireguard-monitor.shPaso 6: Crear alertas en Prometheus#
En /etc/prometheus/rules.yml:
groups:
- name: wireguard_alerts
interval: 30s
rules:
- alert: WireguardPeerDown
expr: |
(time() - wireguard_peer_last_handshake) > 300
for: 2m
annotations:
summary: "Peer Wireguard desconectado: {{ $labels.public_key }}"
description: "El peer no responde hace más de 5 minutos."Y vincular en prometheus.yml:
rule_files:
- "/etc/prometheus/rules.yml"Resultado#
Ahora tengo:
- Detección automática cada minuto
- Métricas en Prometheus que puedo graficar
- Alertas que se disparan si un peer cae más de 2 minutos
- Log centralizado en
/var/log/wireguard-monitor.log
Probé desconectando un cliente deliberadamente y la alerta llegó en menos de 3 minutos. Suficiente para mi caso.
Lo que quedaría para versión 2.0#
Automatizar reconexión del cliente (reiniciar servicio Wireguard en el peer) y integración con Alertmanager para notificaciones por email/webhook.
Por ahora, tengo visibilidad. Eso era lo importante.