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
-
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.
-
Gestión de credenciales
- WireGuard requiere generar pares de claves, distribuir archivos
.confy 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.
- WireGuard requiere generar pares de claves, distribuir archivos
-
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.
-
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:
-
WireGuard como canal primario
- Configura una interfaz
wg0en 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.).
- Configura una interfaz
-
Cloudflared como fallback
- Instala
cloudflareden el mismo host que ejecuta WireGuard. - Crea un túnel
sshy/ohttpque 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.
- Instala
-
Detección de conectividad
- Usa un script de
systemdocronque pruebe la conectividad UDP al servidor WireGuard cada 5 min. Si falla, habilita el túnel Cloudflare y notifica al usuario (por ejemplo, mediantenotify-sendo un webhook). - Cuando la prueba UDP vuelva a pasar, desactiva el túnel para evitar tráfico innecesario por Cloudflare.
- Usa un script de
-
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
secretdesystemdo enpass. - Automatiza la rotación de claves WireGuard con
wg genkeyywg genpskmediante un playbook Ansible o un script Bash.
- Mantén las claves de WireGuard en un repositorio cifrado (por ejemplo,
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
-
Conexión WireGuard
- Ejecuta
wg showen el cliente y verifica que la interfazwg0estáconnectedy que el tráfico hacia10.0.0.1responde (ping 10.0.0.1).
- Ejecuta
-
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
cloudflaredestá activo (systemctl status cloudflared). - Intenta
ssh [email protected]. La conexión debe establecerse sin solicitar la clave de WireGuard.
-
Registro de eventos
- Revisa
/var/log/cloudflared.logyjournalctl -u wg-quick@wg0para confirmar que el script cambió de modo correctamente.
- Revisa
-
Auditoría de IP
- Desde el servidor, ejecuta
last -io 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.
- Desde el servidor, ejecuta
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
wgycloudflareda Prometheus (exporters disponibles) para detectar caídas antes de que el usuario lo note. - Backup de configuración: Guarda
/etc/wireguardy~/.cloudflareden un backup cifrado; una pérdida de estos archivos implica perder acceso remoto.