↓ Ir al contenido

Recuperación ante fallos de Wireguard: detección automática de peers desconectados y alertas con Prometheus

Rogelio Guerra Riverón
Autor
Rogelio Guerra Riverón
Construyendo mi propia infraestructura web desde cero. Aquí documento cada paso: servidores, redes, contenedores y lo que vaya surgiendo.

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:

  1. Detecte automáticamente cuándo un peer no responde
  2. Me alerte en tiempo real
  3. Intente reconectar o ejecutar acciones
  4. 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_exporter

Paso 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.target
sudo systemctl daemon-reload
sudo systemctl enable wireguard-exporter
sudo systemctl start wireguard-exporter

Paso 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: 15s

Paso 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
}

main
sudo chmod +x /opt/wireguard-monitor.sh

Paso 5: Ejecutar cada minuto con cron
#

sudo crontab -e
* * * * * /opt/wireguard-monitor.sh

Paso 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.