Diagnóstico y configuración de un Cloudflare Tunnel paso a paso

Cloudflare Tunnel (cloudflared) permite exponer un servicio interno a internet sin abrir puertos en el router ni depender de una IP pública — el túnel establece una conexión saliente desde el servidor hacia la red de Cloudflare, y Cloudflare enruta el tráfico entrante hacia esa conexión. Este es un caso real de diagnóstico cuando el servicio falla al arrancar.

Problema inicial

El servicio cloudflared fallaba continuamente con este error:

Tunnel credentials file '/root/.cloudflared/<tunnel-uuid>.json' doesn't exist or is not a file

Causa

El archivo de configuración /etc/cloudflared/config.yml tenía placeholders (texto de ejemplo) en lugar del UUID real del túnel — un error común al copiar una configuración de plantilla sin reemplazar los valores genéricos por los datos reales generados al crear el túnel.

¿Qué es cada pieza de la configuración?

  • UUID del túnel — identificador único que Cloudflare asigna al crear el túnel (cloudflared tunnel create nombre). Es lo que conecta la configuración local con el túnel registrado en la cuenta de Cloudflare.
  • Archivo de credenciales (.json) — se genera automáticamente en el mismo momento que el UUID, y contiene la clave privada que autentica al servidor ante Cloudflare como el dueño legítimo de ese túnel específico.
  • Ingress rules — las reglas que determinan a qué servicio local se debe redirigir cada hostname que llega a través del túnel.

Solución aplicada

1. Editar el archivo de configuración

vi /etc/cloudflared/config.yml

Contenido correcto (con el UUID real reemplazando el placeholder):

tunnel: TUNNEL-UUID-REAL
credentials-file: /root/.cloudflared/TUNNEL-UUID-REAL.json
ingress:
  - hostname: subdominio.tudominio.com
    service: http://localhost:8443
  - service: http_status:404

La última línea (service: http_status:404) es obligatoria en cualquier configuración de ingress: actúa como regla de respaldo, devolviendo un 404 a cualquier hostname que llegue por el túnel y no coincida con ninguna regla anterior — sin ella, cloudflared no arranca.

2. Verificar permisos del archivo de credenciales

chmod 600 /root/.cloudflared/TUNNEL-UUID-REAL.json

El archivo de credenciales contiene una clave privada — permisos 600 (solo lectura/escritura para el propietario) son necesarios tanto por seguridad como porque algunas versiones de cloudflared se niegan a cargar el archivo si los permisos son demasiado permisivos.

3. Reiniciar el servicio

systemctl restart cloudflared
systemctl status cloudflared

Configuración DNS en Cloudflare

Además de la configuración local, el túnel necesita un registro DNS que apunte hacia él. Se crea como un CNAME apuntando al dominio especial de Cloudflare Tunnels (cfargotunnel.com), nunca a una IP directa:

CampoValor
TypeCNAME
Namesubdominio
TargetTUNNEL-UUID-REAL.cfargotunnel.com
Proxy statusProxied

El estado Proxied (la nube naranja en el panel de Cloudflare) es lo que hace que el tráfico pase por la red de Cloudflare y llegue al túnel — si se deja en modo «DNS only», el CNAME resuelve a la URL de cfargotunnel.com directamente, lo cual no funciona como se espera para el usuario final.

Comandos de verificación

Estado del túnel

systemctl status cloudflared
journalctl -u cloudflared -f
cloudflared tunnel info TUNNEL-UUID-REAL
cloudflared tunnel list

Probar conectividad desde el servidor

# Servicio local, sin pasar por el túnel
curl -I http://localhost:8443

# A través del túnel, desde afuera
curl -I https://subdominio.tudominio.com
curl https://subdominio.tudominio.com

Probar primero localhost aísla el problema: si el servicio local no responde, el problema es de la aplicación en sí, no del túnel. Si localhost responde pero el dominio público no, el problema está en la configuración del túnel o del DNS.

Verificar DNS

# Consulta general, usando el DNS configurado en el sistema
nslookup subdominio.tudominio.com

# Consulta directa a los nameservers de Cloudflare (evita cachés intermedias)
dig @ns1.cloudflare.com subdominio.tudominio.com
nslookup subdominio.tudominio.com ns1.cloudflare.com

# Limpiar la caché DNS local (Linux con systemd-resolved)
sudo systemd-resolve --flush-caches
sudo systemd-resolve --statistics

Consultar directamente a los nameservers de Cloudflare, en vez del resolver local, descarta que el problema sea una caché DNS local desactualizada mostrando un resultado viejo.

Probar desde Windows

# PowerShell nativo
Invoke-WebRequest -Uri https://subdominio.tudominio.com

# curl real de Windows (no el alias de PowerShell)
curl.exe -I https://subdominio.tudominio.com

# Test de conectividad a nivel de puerto TCP
Test-NetConnection -ComputerName subdominio.tudominio.com -Port 443
# Desde CMD
curl -I https://subdominio.tudominio.com

Resultado

  • Túnel configurado y funcionando correctamente.
  • Conexiones establecidas con los edge servers de Cloudflare más cercanos.
  • DNS configurado correctamente, resolviendo hacia el túnel.

Nota importante: las VPNs corporativas pueden bloquear el acceso a dominios detrás de Cloudflare Tunnel, dependiendo de las políticas de firewall/proxy de esa red. Si un usuario reporta que no puede acceder estando conectado a la VPN de su empresa, conviene probar primero desde una conexión sin VPN (o datos móviles) antes de asumir que el problema es del túnel.

Archivos involucrados

  • Config: /etc/cloudflared/config.yml
  • Credenciales: /root/.cloudflared/TUNNEL-UUID-REAL.json
  • Certificado: /root/.cloudflared/cert.pem
  • Servicio: /etc/systemd/system/cloudflared.service