TryCloudflare: exponer tu localhost a internet con un comando

TryCloudflare, que Cloudflare ahora llama Quick Tunnels, te da una URL pública HTTPS para un servidor que corre en tu máquina, con un solo comando y sin cuenta. Instalas cloudflared, ejecutas cloudflared tunnel --url http://localhost:8000 y en unos segundos tienes algo como https://loan-predict-phrases-bought.trycloudflare.com apuntando a tu puerto 8000.
El servicio existe desde hace años. Lo que cambió este mes es el envoltorio: Cloudflare estrenó una landing en try.cloudflare.com que lo reposiciona para "la era de los agentes", con un badge que anuncia "Now with JSON output for coding agents". Esa frase promete más de lo que el flag entrega, y fue lo primero que fui a comprobar.
Cómo exponer localhost a internet sin abrir puertos
Instalas el binario:
# macOS
brew install cloudflared
# Linux (binario directo)
curl -fsSL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflared
sudo install cloudflared /usr/local/bin/Levantas tu aplicación en el puerto que ya usas (npm run dev, php artisan serve, python3 -m http.server 8000, lo que sea) y abres el túnel:
cloudflared tunnel --url http://localhost:8000cloudflared genera un subdominio aleatorio en trycloudflare.com y lo imprime en la terminal dentro de un recuadro ASCII:
INF +--------------------------------------------------------------------------------------------+
INF | Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): |
INF | https://loan-predict-phrases-bought.trycloudflare.com |
INF +--------------------------------------------------------------------------------------------+
La landing promete la URL en unos 3 segundos. En mis dos pruebas con cloudflared 2026.9.1 tardó 5 y 6 segundos entre el arranque del proceso y el recuadro, incluyendo los prechecks de conectividad que la versión 2026.5.2 en adelante ejecuta al iniciar.
La conexión es saliente. Tu máquina abre un túnel QUIC hacia el datacenter de Cloudflare más cercano y el tráfico vuelve por ahí. No abres ningún puerto en el router, no tocas el firewall y la URL sale con HTTPS y mitigación de DDoS de fábrica.
El JSON para agentes está en el puerto de métricas, no en los logs
La landing dice, en la sección de agentes, "Hostname, edge, and health as JSON on stdout, no regex on logs". Y cloudflared sí tiene un flag --output json que convierte cada línea de log en un objeto JSON. El problema es que el hostname sigue viajando dentro del recuadro ASCII, ahora metido en el campo message:
{"level":"info","message":"| Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): |","time":"2026-09-20T03:26:23Z"}
{"level":"info","message":"| https://developed-finances-phillips-spending.trycloudflare.com |","time":"2026-09-20T03:26:23Z"}Sigues necesitando una expresión regular, solo que ahora sobre JSON. Para un agente que arranca el túnel y necesita la URL, eso no sirve de mucho.
Lo que sí resuelve el problema es el servidor de métricas que cloudflared levanta siempre, y que expone dos endpoints útiles. El primero devuelve el hostname:
cloudflared tunnel --url http://localhost:8000 --metrics localhost:20241 &
curl -s localhost:20241/quicktunnel
# {"hostname":"loan-predict-phrases-bought.trycloudflare.com"}El segundo dice si el túnel ya está conectado al edge, que es lo que de verdad necesitas esperar antes de mandar la primera petición:
curl -s localhost:20241/ready
# {"status":200,"readyConnections":1,"connectorId":"09f60e92-242a-4824-99be-951fa99e5419"}/ready responde 503 mientras no haya conexiones activas y 200 cuando las hay, así que sirve directo como condición de espera. El bucle completo para un script o un agente queda así:
#!/usr/bin/env bash
cloudflared tunnel --url http://localhost:8000 --metrics localhost:20241 >/dev/null 2>&1 &
until curl -sf localhost:20241/ready >/dev/null; do sleep 0.5; done
URL="https://$(curl -s localhost:20241/quicktunnel | jq -r .hostname)"
echo "$URL"El detalle que hace falta es --metrics localhost:20241. Sin ese flag, cloudflared recorre los puertos 20241 a 20245 y se queda con el primero libre, y si ninguno lo está elige uno al azar. Con el puerto fijo, el script ya sabe dónde preguntar.
Los nombres de los endpoints y la forma exacta de las respuestas salen del propio código de cloudflared y los verifiqué contra un túnel real con la versión 2026.9.1.
Los límites que muerden
Cloudflare documenta dos límites duros para Quick Tunnels, y uno de los dos falla en silencio.
El primero son 200 peticiones en vuelo, un tope de concurrencia y no de volumen total. Al superarlo, el edge responde 429. Para una demo o un webhook no lo vas a ver; para una prueba de carga sí.
El segundo son los Server-Sent Events. La documentación dice que no están soportados, y lo que no dice es cómo fallan: no hay error, hay buffering. Monté un endpoint que emite cinco eventos, uno por segundo, y lo pedí por las dos vías. En local los eventos llegaron separados un segundo. Por el túnel llegaron los cinco juntos, en 150 milisegundos, cuando el origen cerró el stream:
== por el túnel == == en local ==
762.65 data: tick 0 762.85 data: tick 0
762.70 data: tick 1 763.88 data: tick 1
762.73 data: tick 2 764.88 data: tick 2
762.77 data: tick 3 765.88 data: tick 3
762.80 data: tick 4 766.89 data: tick 4
La respuesta es 200 y el contenido llega completo. Lo que se pierde es la entrega incremental, que es justo para lo que existe SSE. Si estás probando streaming de tokens de un modelo o una barra de progreso en vivo, vas a ver la cosa completarse de golpe y vas a culpar a tu código.
Hay un tercer detalle que no está en la lista de limitaciones pero sí en el código: los Quick Tunnels fuerzan una sola conexión con el edge (HaConnections se fija en 1) y desactivan el enrutamiento de paquetes ICMP. Son túneles de una réplica, a propósito.
Y uno operativo que cuesta un rato de depuración: si existe un config.yaml en tu directorio .cloudflared, los Quick Tunnels no funcionan. Hay que renombrarlo temporalmente.
Wrangler y Vite ya lo traen integrado
Si trabajas con Workers no necesitas ni el binario. Desde marzo de 2026 Wrangler incluye comandos de túnel, incluido wrangler tunnel quick-start, que descarga y gestiona cloudflared por ti en un directorio de caché.
En el día a día lo más cómodo es la tecla. Corres wrangler dev y pulsas t para abrir o cerrar el túnel de la sesión. Con el plugin de Vite es t más Enter. Si lo quieres automático:
npx wrangler dev --tunnelCon vite preview hay que tener cuidado con una cosa: la validación de hosts de Vite sigue aplicando, así que tienes que añadir .trycloudflare.com a preview.allowedHosts o te rebota.
// vite.config.js
export default defineConfig({
preview: {
allowedHosts: [".trycloudflare.com"],
},
});Quién puede entrar por esa URL
Nadie autentica. Cualquiera que tenga el hostname llega a tu servidor de desarrollo, y el subdominio aleatorio es lo único que lo separa del mundo. La documentación de Workers es explícita sobre lo que hay que revisar antes de abrir el túnel: endpoints de preview o de admin sin protección, bindings remotos conectados a recursos reales, y código que hace de proxy hacia servicios internos. Con vite dev, además, el HMR puede exponer rutas de archivos y la estructura del proyecto, así que para compartir algo público es mejor vite preview.
El otro lado del problema es que esa misma facilidad es infraestructura gratis y desechable para quien la quiera usar mal. Proofpoint publicó en agosto de 2024 el análisis de una campaña que abusaba exactamente de esto: túneles de un solo uso sin cuenta, usados para entregar troyanos de acceso remoto como AsyncRAT, VenomRAT, Remcos y Xworm, con la ventaja para el atacante de que la infraestructura se levanta y se tira lo bastante rápido como para esquivar las listas de bloqueo estáticas.
Cloudflare parece estar trabajando en una respuesta. En el master de cloudflared hay código para "protected quick tunnels": un modo que pide un código de un solo uso por email y que se activaría con un flag --allowed-mail. Todavía no está disponible, y el propio código lo dice con un TODO que deja la ruta inalcanzable hasta que registren el flag.
Cuándo esto no alcanza
El aviso legal que cloudflared imprime en cada arranque es bastante claro: estos túneles sin cuenta no tienen garantía de uptime, y Cloudflare los usa para probar funcionalidades nuevas antes de desplegarlas a clientes de producción. Eres el canario.
En cuanto quieras un hostname estable, más de una réplica, control de acceso o los límites levantados, la respuesta es crear una cuenta gratuita y un túnel remoto normal con tu propio dominio. Ahí ya entras en Cloudflare Tunnel de verdad, que es lo que uso, por ejemplo, para acceder a OpenClaw corriendo en una Raspberry Pi.
Para lo otro, que es enseñarle algo a alguien, apuntar un webhook de Stripe o GitHub a tu máquina, o darle a un agente una dirección alcanzable durante los treinta segundos que dura su bucle, un comando y cinco segundos es difícil de mejorar.
Preguntas frecuentes
¿TryCloudflare es gratis?
Sí, y sin cuenta. No hay que registrarse, ni añadir un dominio a Cloudflare, ni configurar DNS. Lo que no hay es garantía de servicio.
¿Cómo sé la URL de mi túnel desde un script?
Arranca con --metrics localhost:20241 y consulta curl -s localhost:20241/quicktunnel, que devuelve {"hostname":"..."}. Es mucho más fiable que parsear los logs, incluso con --output json.
¿Cuánto dura una URL de trycloudflare.com?
Lo que dure el proceso. Cuando matas cloudflared, el túnel muere y el hostname deja de existir. No hay nada que revocar ni que limpiar, y tampoco hay forma de recuperar el mismo subdominio en el siguiente arranque.
¿Puedo usar un dominio propio con un Quick Tunnel?
No. El subdominio aleatorio en trycloudflare.com es parte de la definición. Para un hostname propio necesitas un túnel remoto con cuenta.
¿Por qué mi streaming no funciona por el túnel?
Porque los Quick Tunnels no soportan Server-Sent Events. La petición no falla: la respuesta se acumula y te llega entera cuando el origen cierra el stream. Si necesitas streaming, crea un túnel con cuenta.
¿Sirve para producción?
No, y Cloudflare lo repite en la documentación y en el aviso de cada arranque. Una réplica, sin SLA, con tope de 200 peticiones concurrentes y un hostname que cambia en cada reinicio.
Fuentes
- Quick Tunnels, la landing de try.cloudflare.com
- Quick Tunnels, documentación de Cloudflare One
- Código de
cloudflared:quick_tunnel.goymetrics.go - Compartir un servidor de desarrollo local, documentación de Workers
- Manage Cloudflare Tunnels with Wrangler, changelog del 19 de marzo de 2026
- Threat Actor Abuses Cloudflare Tunnels to Deliver RATs, Proofpoint, 1 de agosto de 2024
¿Tienes un proyecto en mente?
Trabajo con Laravel, WordPress, SEO técnico y servidores MCP. El primer paso es una llamada de descubrimiento, sin costo ni compromiso, donde me cuentas qué necesitas y te digo con honestidad si puedo ayudarte.