Problema

Los administradores de homelab suelen depender de una VPN tradicional (WireGuard, OpenVPN) para conectarse a sus servidores desde cualquier ubicación. En redes públicas —hospitales, aeropuertos, campus— los firewalls pueden bloquear puertos UDP o protocolos desconocidos, dejando la VPN inoperativa. La alternativa que muchos están probando es un túnel Cloudflare + WARP: el cliente WARP se conecta a la red de Cloudflare y, mediante cloudflared, se expone un túnel HTTPS que lleva el tráfico a la máquina interna.

El dilema es decidir cuál de los dos enfoques usar como método principal de acceso remoto. Cada solución tiene ventajas operativas y riesgos de seguridad que pueden afectar la disponibilidad, la exposición de la IP pública y la superficie de ataque.

Causa

  1. Bloqueo de puertos/protocolos

    • WireGuard usa UDP (por defecto puerto 51820). Muchos puntos de acceso Wi‑Fi restringen tráfico UDP o cualquier puerto no estándar.
    • WARP funciona sobre TLS (puerto 443) y suele pasar desapercibido para los filtros, pero depende de la infraestructura de Cloudflare.
  2. Gestión de credenciales

    • WireGuard requiere generar pares de claves, distribuir archivos .conf y mantenerlos sincronizados. Un cambio de dispositivo implica crear una nueva clave y actualizar la configuración del servidor.
    • Cloudflared usa tokens de acceso a la cuenta Cloudflare y el cliente WARP se enlaza a una cuenta Google/Apple. La rotación de credenciales es más automática, pero introduce dependencia externa.
  3. Modelo de confianza

    • Con WireGuard el tráfico está cifrado de extremo a extremo; solo el cliente y el servidor conocen las claves.
    • Con Cloudflared el tráfico atraviesa los nodos de Cloudflare. Si la conexión TLS está habilitada, Cloudflare no puede leer el contenido, pero la metadata (IP de origen, puertos) sí pasa por sus puntos de presencia.
  4. Visibilidad de la IP pública

    • WireGuard expone la IP del cliente al servidor y, si se usa NAT‑traversal, la IP pública del cliente puede quedar visible en logs externos.
    • Cloudflared oculta la IP del cliente detrás de la IP de Cloudflare, reduciendo la superficie de escaneo, pero también dificulta auditorías de origen.

Solución

Adoptar un enfoque híbrido que permita usar WireGuard cuando la red lo permita y caer automáticamente a Cloudflared + WARP cuando el primer método falle. La arquitectura se basa en:

  1. WireGuard como canal primario

    • Configura una interfaz wg0 en el router o en la máquina de salto (por ejemplo, el Dream Router).
    • Mantén reglas de firewall que permitan tráfico UDP 51820 solo desde rangos de IP confiables (tu ISP, móvil, etc.).
  2. Cloudflared como fallback

    • Instala cloudflared en el mismo host que ejecuta WireGuard.
    • Crea un túnel ssh y/o http que apunte al puerto interno del servicio SSH (o cualquier otro puerto que necesites).
    • Configura el cliente WARP en los dispositivos móviles/portátiles. El cliente detecta automáticamente si el túnel Cloudflare está disponible y lo usa.
  3. Detección de conectividad

    • Usa un script de systemd o cron que pruebe la conectividad UDP al servidor WireGuard cada 5 min. Si falla, habilita el túnel Cloudflare y notifica al usuario (por ejemplo, mediante notify-send o un webhook).
    • Cuando la prueba UDP vuelva a pasar, desactiva el túnel para evitar tráfico innecesario por Cloudflare.
  4. Gestión centralizada de credenciales

    • Mantén las claves de WireGuard en un repositorio cifrado (por ejemplo, git-crypt).
    • Usa los tokens de Cloudflare almacenados en un secret de systemd o en pass.
    • Automatiza la rotación de claves WireGuard con wg genkey y wg genpsk mediante un playbook Ansible o un script Bash.

Configuración mínima

WireGuard (servidor)

apt-get install wireguard
umask 077
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key

cat > /etc/wireguard/wg0.conf <<EOF
[Interface]
PrivateKey = $(cat /etc/wireguard/server_private.key)
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT

# ejemplo cliente
#[Peer]
#PublicKey = CLIENT_PUBLIC_KEY
#AllowedIPs = 10.0.0.2/32
EOF

systemctl enable --now wg-quick@wg0

Cloudflared (túnel SSH)

curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
dpkg -i cloudflared.deb
cloudflared tunnel login   # abre navegador para autorizar la cuenta
cloudflared tunnel create homelab-ssh
cloudflared tunnel route dns homelab-ssh ssh.example.com
cat > ~/.cloudflared/config.yml <<EOF
tunnel: HOMELAB_SSH_TUNNEL_ID
credentials-file: /root/.cloudflared/HOMELAB_SSH_TUNNEL_ID.json

ingress:
  - hostname: ssh.example.com
    service: ssh://127.0.0.1:22
  - service: http_status:404
EOF
systemctl enable --now cloudflared

Script de detección

#!/usr/bin/env bash
WG_HOST="your.public.ip"
WG_PORT=51820
if timeout 2 bash -c "echo > /dev/udp/$WG_HOST/$WG_PORT" 2>/dev/null; then
  systemctl stop cloudflared
else
  systemctl start cloudflared
fi

Guárdalo como /usr/local/bin/check-wg.sh y añádelo a systemd con OnBootSec=5min y OnUnitActiveSec=5min.

Cuándo aplicar esta solución

  • Redes mixtas: Si frecuentemente te conectas desde Wi‑Fi públicos, campus o hospitales donde el tráfico UDP está filtrado.
  • Entorno homelab con pocos usuarios: El coste de mantener dos túneles es bajo y la complejidad añadida se justifica por la disponibilidad.
  • Requisitos de Zero‑Trust: Cuando tu organización o cliente exige que el acceso pase por un proveedor de identidad (Google, Microsoft) y no quieras gestionar claves manualmente.

No aplicar si:

  • Solo usas la red doméstica y nunca sales a redes públicas; la sobrecarga de Cloudflare no aporta valor.
  • Necesitas latencia mínima para aplicaciones sensibles (p.ej., streaming de video en tiempo real) donde el salto a Cloudflare añade 30‑50 ms.
  • Tienes políticas de cumplimiento que prohiben el tránsito de datos por terceros, incluso cifrados.

Verificación

  1. Conexión WireGuard

    • Ejecuta wg show en el cliente y verifica que la interfaz wg0 está connected y que el tráfico hacia 10.0.0.1 responde (ping 10.0.0.1).
  2. Fallback Cloudflare

    • Desconecta el cliente de la red que permite UDP (por ejemplo, apaga Wi‑Fi y conecta a una red de hospital).
    • Comprueba que el servicio cloudflared está activo (systemctl status cloudflared).
    • Intenta ssh [email protected]. La conexión debe establecerse sin solicitar la clave de WireGuard.
  3. Registro de eventos

    • Revisa /var/log/cloudflared.log y journalctl -u wg-quick@wg0 para confirmar que el script cambió de modo correctamente.
  4. Auditoría de IP

    • Desde el servidor, ejecuta last -i o revisa los logs de SSH. La IP mostrada debe ser la de Cloudflare cuando el fallback está activo, y la IP del cliente cuando WireGuard funciona.

Notas adicionales

  • TLS inspection: Si en algún punto la red corporativa aplica inspección TLS, el tráfico HTTPS del túnel Cloudflare puede ser descifrado. Asegúrate de que la política de inspección esté desactivada o usa certificados de cliente mutuo.
  • Límites de Cloudflare: Los túneles gratuitos tienen un límite de 1 GB de tráfico por día y 30 s de tiempo de inactividad antes de que el túnel se cierre. Para uso intensivo considera el plan “Pro”.
  • Rotación de claves: Programa una rotación trimestral de claves WireGuard y actualiza los tokens de Cloudflare al mismo tiempo para evitar desalineaciones.
  • Monitorización: Añade métricas de wg y cloudflared a Prometheus (exporters disponibles) para detectar caídas antes de que el usuario lo note.
  • Backup de configuración: Guarda /etc/wireguard y ~/.cloudflared en un backup cifrado; una pérdida de estos archivos implica perder acceso remoto.