Si autoalojas aplicaciones en casa o en una oficina — un servidor de medios, un panel de automatización del hogar, un entorno de desarrollo, una wiki personal — tradicionalmente has necesitado abrir puertos en tu router, configurar reglas NAT, configurar DNS dinámico y esperar que tu ISP no bloquee las conexiones entrantes. Cada puerto abierto es un vector de ataque potencial, y la configuración es frágil.

Cloudflare Tunnels elimina todo eso. Ejecutas un daemon ligero (cloudflared) en tu máquina local que crea una conexión cifrada de solo salida a la red de borde de Cloudflare. El tráfico fluye desde internet a través de Cloudflare hacia tu servicio, sin ningún puerto entrante abierto en tu firewall.

Esta guía cubre todo, desde la instalación hasta configuraciones avanzadas incluyendo políticas de acceso Zero Trust, túneles SSH y configuraciones de múltiples servicios.

¿Por qué Cloudflare Tunnels?

Sin necesidad de redirección de puertos

El autoalojamiento tradicional requiere redirigir los puertos 80/443 (y posiblemente otros) a través de tu router hacia tu servidor. Con Cloudflare Tunnels, tu firewall puede bloquear todas las conexiones entrantes. El daemon cloudflared inicia conexiones de salida a Cloudflare, y el tráfico se retransmite a través de esas conexiones.

Sin necesidad de IP pública

Incluso si tu ISP usa NAT de grado carrier (CGNAT) y no tienes una dirección IP pública, Cloudflare Tunnels funcionan perfectamente. La conexión es de salida desde tu red hacia Cloudflare.

Protección DDoS integrada

Todo el tráfico pasa a través de la red de Cloudflare, que proporciona mitigación automática de DDoS, limitación de tasa y protección contra bots. Tu dirección IP doméstica nunca queda expuesta.

Plan gratuito

Cloudflare Tunnels están incluidos en el plan gratuito de Cloudflare. Necesitas una cuenta de Cloudflare y un dominio administrado por Cloudflare DNS, pero no hay costo adicional por el túnel en sí.

TLS automático

Cloudflare maneja los certificados SSL/TLS automáticamente. Tu servicio local puede ejecutarse en HTTP simple, y Cloudflare termina TLS en su borde, presentando un certificado válido a los visitantes.

Cómo funcionan los Cloudflare Tunnels

La arquitectura es directa:

  1. Instalas cloudflared en la máquina que ejecuta tus servicios
  2. cloudflared se autentica con tu cuenta de Cloudflare
  3. cloudflared establece conexiones persistentes de salida (usando HTTP/2 o QUIC) a los centros de datos más cercanos de Cloudflare
  4. Cuando un visitante solicita app.knowledgexchange.xyz, Cloudflare enruta la solicitud a través del túnel a tu instancia local de cloudflared
  5. cloudflared reenvía la solicitud a tu servicio local (por ejemplo, http://localhost:8080)
  6. La respuesta viaja de regreso por el mismo túnel
Visitante -> Borde Cloudflare (TLS) -> Túnel -> cloudflared -> localhost:8080

Punto clave: Tu servidor nunca acepta conexiones entrantes. Todas las conexiones del túnel son iniciadas de salida por cloudflared. Esto significa que incluso si alguien conoce tu dirección IP doméstica, no pueden alcanzar tus servicios directamente.

Requisitos previos

Antes de comenzar, necesitas:

  • Una cuenta de Cloudflare (el plan gratuito es suficiente)
  • Un nombre de dominio con DNS administrado por Cloudflare (puedes transferir un dominio existente o registrar uno nuevo a través de Cloudflare Registrar)
  • Una máquina Linux, macOS o Windows ejecutando el servicio que quieres exponer
  • El servicio ejecutándose y accesible en localhost (por ejemplo, una aplicación web en el puerto 8080)

Instalando cloudflared

Debian/Ubuntu

# Agregar la clave GPG de Cloudflare y el repositorio
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg > /dev/null

echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/cloudflared.list

sudo apt-get update
sudo apt-get install -y cloudflared

RHEL/CentOS/Fedora

# Agregar el repositorio de Cloudflare
sudo rpm --import https://pkg.cloudflare.com/cloudflare-main.gpg
curl -fsSL https://pkg.cloudflare.com/cloudflared-ascii.repo | sudo tee /etc/yum.repos.d/cloudflared.repo

sudo yum install -y cloudflared

macOS

brew install cloudflared

Windows

Descarga el instalador de los releases de Cloudflare en GitHub o usa winget:

winget install --id Cloudflare.cloudflared

Docker

docker pull cloudflare/cloudflared:latest

Verificar la instalación

cloudflared --version
# cloudflared version 2026.1.x (built ...)

Autenticarse con Cloudflare

Antes de crear túneles, autentica cloudflared con tu cuenta de Cloudflare:

cloudflared tunnel login

Esto abre una ventana del navegador donde seleccionas el dominio que quieres usar con túneles. Después de la autorización, un certificado se guarda en ~/.cloudflared/cert.pem.

Nota: Este paso solo necesita hacerse una vez por máquina. El certificado se usa para todas las operaciones futuras de túneles.

Crear un túnel

Crear el túnel

cloudflared tunnel create my-homelab

Esto genera:

  • Un ID de túnel único (un UUID como a1b2c3d4-e5f6-7890-abcd-ef1234567890)
  • Un archivo de credenciales en ~/.cloudflared/<TUNNEL_ID>.json
Tunnel credentials written to /home/user/.cloudflared/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json
Created tunnel my-homelab with id a1b2c3d4-e5f6-7890-abcd-ef1234567890

Listar tus túneles

cloudflared tunnel list

Configurar DNS

Enruta un subdominio a tu túnel:

cloudflared tunnel route dns my-homelab app.knowledgexchange.xyz

Esto crea un registro CNAME en tu DNS de Cloudflare apuntando app.knowledgexchange.xyz a <TUNNEL_ID>.cfargotunnel.com.

Configurar reglas de ingreso

Crea un archivo de configuración en ~/.cloudflared/config.yml:

Servicio único

tunnel: a1b2c3d4-e5f6-7890-abcd-ef1234567890
credentials-file: /home/user/.cloudflared/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json

ingress:
  - hostname: app.knowledgexchange.xyz
    service: http://localhost:8080
  - service: http_status:404

Importante: La última regla de ingreso debe ser un catch-all (sin hostname especificado). Esto maneja solicitudes que no coinciden con ningún hostname definido. Usar http_status:404 devuelve un 404 para solicitudes no coincidentes.

Múltiples servicios en subdominios

Aquí es donde los Cloudflare Tunnels realmente brillan. Un solo túnel puede exponer múltiples servicios en diferentes subdominios:

tunnel: a1b2c3d4-e5f6-7890-abcd-ef1234567890
credentials-file: /home/user/.cloudflared/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json

ingress:
  # Proxy inverso a una aplicación web
  - hostname: app.knowledgexchange.xyz
    service: http://localhost:8080

  # Instancia de Home Assistant
  - hostname: home.knowledgexchange.xyz
    service: http://localhost:8123

  # Servidor Git autoalojado Gitea
  - hostname: git.knowledgexchange.xyz
    service: http://localhost:3000

  # Panel de monitoreo Grafana
  - hostname: grafana.knowledgexchange.xyz
    service: http://localhost:3001

  # Servidor de medios Jellyfin
  - hostname: media.knowledgexchange.xyz
    service: http://localhost:8096

  # Regla catch-all (requerida)
  - service: http_status:404

Para cada hostname, crea una ruta DNS:

cloudflared tunnel route dns my-homelab app.knowledgexchange.xyz
cloudflared tunnel route dns my-homelab home.knowledgexchange.xyz
cloudflared tunnel route dns my-homelab git.knowledgexchange.xyz
cloudflared tunnel route dns my-homelab grafana.knowledgexchange.xyz
cloudflared tunnel route dns my-homelab media.knowledgexchange.xyz

Opciones avanzadas de ingreso

Puedes ajustar cada regla de ingreso con opciones adicionales:

ingress:
  - hostname: app.knowledgexchange.xyz
    service: http://localhost:8080
    originRequest:
      # Tiempo de espera para conectar al servicio local
      connectTimeout: 10s
      # Deshabilitar verificación TLS para certificados autofirmados en servicios locales
      noTLSVerify: true
      # Reenviar el encabezado Host original
      httpHostHeader: app.knowledgexchange.xyz
      # Configuración de keep-alive
      keepAliveConnections: 100
      keepAliveTimeout: 90s

  - hostname: secure.knowledgexchange.xyz
    service: https://localhost:8443
    originRequest:
      # Si tu servicio local usa HTTPS con certificado autofirmado
      noTLSVerify: true

  - service: http_status:404

Ejecutar el túnel

Inicio manual (para pruebas)

cloudflared tunnel run my-homelab

Deberías ver una salida indicando que el túnel está conectado:

INF Starting tunnel tunnelID=a1b2c3d4-e5f6-7890-abcd-ef1234567890
INF Connection established connIndex=0 location=DFW
INF Connection established connIndex=1 location=IAH
INF Connection established connIndex=2 location=DFW
INF Connection established connIndex=3 location=IAH

Nota: cloudflared establece múltiples conexiones a diferentes centros de datos de Cloudflare para redundancia. Si una conexión cae, el tráfico se enruta automáticamente a través de las conexiones restantes.

Validar tu configuración

Antes de ejecutar, valida la configuración:

cloudflared tunnel ingress validate

Prueba qué regla de ingreso coincide con una URL específica:

cloudflared tunnel ingress rule https://app.knowledgexchange.xyz
# Using rules from /home/user/.cloudflared/config.yml
# Matched rule #0: hostname=app.knowledgexchange.xyz service=http://localhost:8080

Ejecutar como servicio systemd

Para uso en producción, ejecuta cloudflared como un servicio del sistema que se inicia automáticamente al arrancar:

Instalar el servicio

sudo cloudflared service install

Esto crea una unidad de servicio systemd y copia tu configuración a /etc/cloudflared/config.yml y tus credenciales a /etc/cloudflared/.

Administrar el servicio

# Iniciar el servicio
sudo systemctl start cloudflared

# Habilitar inicio automático al arrancar
sudo systemctl enable cloudflared

# Verificar estado
sudo systemctl status cloudflared

# Ver logs
sudo journalctl -u cloudflared -f

Unidad systemd manual (Alternativa)

Si prefieres crear el servicio manualmente:

# /etc/systemd/system/cloudflared.service
[Unit]
Description=Cloudflare Tunnel
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/cloudflared tunnel --config /etc/cloudflared/config.yml run
Restart=on-failure
RestartSec=5s
User=cloudflared
Group=cloudflared

# Endurecimiento de seguridad
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/var/log/cloudflared

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now cloudflared

Administración desde el panel

Los Cloudflare Tunnels también se pueden crear y administrar completamente desde el panel de Cloudflare Zero Trust:

  1. Inicia sesión en el Panel de Cloudflare Zero Trust
  2. Navega a Networks > Tunnels
  3. Haz clic en Create a Tunnel
  4. Sigue el asistente para nombrar el túnel y obtener un comando de instalación
  5. Configura hostnames públicos y servicios en la interfaz web

El enfoque por panel genera un comando de conector basado en token:

sudo cloudflared service install <TOKEN>

Consejo: Los túneles administrados desde el panel son recomendados para equipos porque la configuración se almacena centralmente en Cloudflare, no en un archivo local en el servidor. Múltiples miembros del equipo pueden actualizar las reglas de enrutamiento sin acceso SSH al servidor.

Políticas de acceso con Cloudflare Zero Trust

Para servicios que no deberían ser accesibles públicamente (paneles de administración, dashboards, herramientas internas), agrega políticas de Cloudflare Access:

Configurar una política de acceso

  1. En el panel de Zero Trust, ve a Access > Applications
  2. Haz clic en Add an Application
  3. Elige Self-hosted
  4. Configura:
    • Nombre de la aplicación: Dashboard Grafana
    • Duración de sesión: 24 horas
    • Dominio de la aplicación: grafana.knowledgexchange.xyz
  5. Agrega una política:
    • Nombre de la política: Usuarios permitidos
    • Acción: Allow
    • Regla de inclusión: Correos electrónicos que terminen en @knowledgexchange.xyz
  6. Guarda

Ahora, cualquiera que acceda a grafana.knowledgexchange.xyz se le presentará una página de inicio de sesión de Cloudflare Access. Solo los usuarios con direcciones de correo electrónico autorizadas podrán continuar.

Opciones de autenticación

Cloudflare Access soporta múltiples proveedores de identidad:

  • PIN de un solo uso (correo electrónico) — no requiere IdP, Cloudflare envía un código al correo del usuario
  • Google Workspace
  • Microsoft Azure AD / Entra ID
  • GitHub / GitLab
  • Okta, OneLogin, SAML, OIDC

SSH a través de Cloudflare Tunnels

Puedes usar Cloudflare Tunnels para proporcionar acceso SSH seguro sin exponer el puerto 22:

Configuración del lado del servidor

Agrega una regla de ingreso SSH en tu config.yml:

ingress:
  - hostname: ssh.knowledgexchange.xyz
    service: ssh://localhost:22
  - hostname: app.knowledgexchange.xyz
    service: http://localhost:8080
  - service: http_status:404

Enruta el DNS:

cloudflared tunnel route dns my-homelab ssh.knowledgexchange.xyz

Configuración del lado del cliente

En la máquina cliente, instala cloudflared y agrega esto a ~/.ssh/config:

Host ssh.knowledgexchange.xyz
    ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h

Ahora puedes usar SSH normalmente:

ssh [email protected]

La conexión SSH se tuneliza a través de Cloudflare. Si tienes una política de Access en ssh.knowledgexchange.xyz, se le pedirá al usuario que se autentique a través del navegador antes de que se establezca la conexión SSH.

Certificados SSH de corta duración

Para una seguridad aún más fuerte, configura Cloudflare para emitir certificados SSH de corta duración, eliminando la necesidad de claves SSH estáticas:

  1. Genera un par de claves CA a través del panel de Zero Trust
  2. Configura tu servidor SSH para confiar en la CA de Cloudflare
  3. Los usuarios se autentican a través de Cloudflare Access y reciben un certificado temporal

Este enfoque significa que no hay claves SSH que administrar, rotar o revocar.

Túneles TCP y UDP

Más allá de HTTP y SSH, los Cloudflare Tunnels soportan protocolos TCP y UDP arbitrarios:

Ejemplo TCP (Acceso a base de datos)

ingress:
  - hostname: db.knowledgexchange.xyz
    service: tcp://localhost:5432  # PostgreSQL
  - service: http_status:404

Acceso del lado del cliente:

cloudflared access tcp --hostname db.knowledgexchange.xyz --url localhost:5432

Luego conecta tu cliente de base de datos a localhost:5432, y el tráfico se tuneliza hacia tu servidor PostgreSQL remoto.

Ejemplo UDP

ingress:
  - hostname: dns.knowledgexchange.xyz
    service: udp://localhost:53  # Servidor DNS
  - service: http_status:404

Monitoreo y métricas

Métricas integradas

cloudflared expone métricas de Prometheus en el puerto 60123 por defecto:

# En config.yml
metrics: localhost:60123

Accede a las métricas en http://localhost:60123/metrics. Las métricas clave incluyen:

  • cloudflared_tunnel_request_per_second — Tasa de solicitudes
  • cloudflared_tunnel_response_by_code — Distribución de códigos de respuesta HTTP
  • cloudflared_tunnel_concurrent_requests_per_tunnel — Conexiones activas

Monitoreo desde el panel de Cloudflare

En el panel de Zero Trust bajo Networks > Tunnels, puedes ver:

  • Estado de conexión (saludable/degradado/caído)
  • Ubicaciones de centros de datos conectados
  • Conteo de conexiones activas
  • Tiempo de actividad del túnel

Solución de problemas

El túnel no conecta

# Verificar si cloudflared puede alcanzar Cloudflare
cloudflared tunnel run --loglevel debug my-homelab

# Verificar que tu archivo de credenciales existe
ls -la ~/.cloudflared/

# Verificar resolución DNS
dig app.knowledgexchange.xyz CNAME

Errores 502 Bad Gateway

Esto generalmente significa que cloudflared no puede alcanzar tu servicio local:

# Verificar que el servicio local está ejecutándose
curl -v http://localhost:8080

# Verificar si el servicio está vinculado a localhost vs 0.0.0.0
ss -tlnp | grep 8080

Error común: Si tu servicio está ejecutándose en Docker con -p 127.0.0.1:8080:8080, es accesible desde cloudflared en el host. Pero si ejecutas cloudflared en Docker también, necesitan estar en la misma red Docker. Usa Docker Compose para asegurar que ambos contenedores compartan una red.

Caídas de conexión

Si las conexiones caen frecuentemente:

# Verificar los logs del sistema
sudo journalctl -u cloudflared --since "1 hour ago"

# Asegúrate de que tu red permita conexiones de salida en los puertos 443 y 7844
# El puerto 7844 se usa para conexiones QUIC

Errores de permisos

# Asegurar que el archivo de credenciales sea legible
chmod 600 ~/.cloudflared/*.json

# Para el servicio systemd, asegurar que /etc/cloudflared/ tenga los permisos correctos
sudo chown -R cloudflared:cloudflared /etc/cloudflared/
sudo chmod 700 /etc/cloudflared/

Resumen

Los Cloudflare Tunnels cambian fundamentalmente cómo expones servicios autoalojados a internet. No más redirección de puertos, no más DNS dinámico, no más preocuparse por restricciones del ISP o direcciones IP expuestas. El modelo de conexión de solo salida significa que tu firewall se mantiene bloqueado mientras tus servicios permanecen accesibles.

Combinado con las políticas de acceso de Cloudflare Zero Trust, obtienes autenticación y autorización de grado empresarial para tus aplicaciones autoalojadas — todo en el plan gratuito. Ya sea que estés ejecutando un laboratorio doméstico, un servidor de pequeña empresa o un entorno de desarrollo, los Cloudflare Tunnels proporcionan una solución segura, confiable y gratuita.

Para temas relacionados de redes y seguridad, consulta nuestros artículos sobre configurar Nginx y conectarse a sistemas remotos usando SSH.