Cloudflare Tunnel en Ubuntu Server: publicar servicios sin abrir puertos
Decir «instalar Cloudflare en un servidor» puede llevar a equívoco. La CDN, el DNS y el WAF viven en la red de Cloudflare; lo que sí podemos instalar en Ubuntu es cloudflared, el pequeño servicio que crea un túnel saliente entre nuestro servidor y Cloudflare. Es una forma cómoda de publicar un panel o una aplicación sin abrir su puerto directamente a Internet.
En este ejemplo parto de Ubuntu Server, un dominio que ya utiliza los nameservers de Cloudflare y una aplicación escuchando en 127.0.0.1:8080. Esa última parte es importante: si el servicio solo debe entrar por el túnel, no tiene sentido dejarlo expuesto también por la IP pública.
Instalar cloudflared desde su repositorio
La ventaja de usar el repositorio oficial es que las actualizaciones llegan por APT. Primero añadimos el llavero y la fuente:
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 any main" \
| sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt-get update
sudo apt-get install cloudflared
cloudflared --version
No ejecuto un script remoto a ciegas y puedo ver exactamente qué repositorio queda configurado. Si el servidor usa otra arquitectura, APT seleccionará el paquete compatible.
Crear el túnel desde el panel
En Cloudflare se crea desde Networking → Tunnels. Elegimos un nombre, indicamos el sistema operativo y copiamos el comando de instalación que muestra el panel:
sudo cloudflared service install <TOKEN_DEL_TUNEL>
Ese token da acceso al túnel. No debe acabar en una captura, un ticket, un repositorio ni el historial compartido de la terminal. Si se filtra, se rota desde el panel.
Después asociamos un hostname, por ejemplo panel.example.com, con el servicio local http://127.0.0.1:8080. Cloudflare crea la ruta DNS y cloudflared mantiene la conexión saliente. No hay que redirigir el puerto 8080 en el router.
Comprobar el servicio antes de celebrarlo
sudo systemctl status cloudflared --no-pager
sudo journalctl -u cloudflared -n 100 --no-pager
curl -I http://127.0.0.1:8080
curl -I https://panel.example.com
Estas cuatro pruebas separan los problemas. Si falla el primer curl, la aplicación local no está lista. Si funciona localmente pero falla el hostname, toca mirar el túnel, el DNS o la política de acceso. El estado «active» de systemd por sí solo no demuestra que la aplicación responda.
No abras por detrás lo que acabas de proteger por delante
Un túnel no arregla una aplicación insegura. Mantengo el servicio ligado a localhost, aplico autenticación y reviso qué encabezados de proxy utiliza. Si el origen sigue escuchando en 0.0.0.0:8080 y el firewall permite el puerto, cualquiera podría saltarse Cloudflare y entrar por la IP.
Conviene comprobar los sockets y las reglas existentes:
sudo ss -lntup
sudo ufw status numbered
Para un panel privado también usaría Cloudflare Access o la autenticación propia del servicio. El túnel cifra y transporta la conexión; no decide por sí solo quién debe entrar.
Una prueba rápida, solo para desarrollo
Cloudflare ofrece un túnel temporal sin configurar un dominio:
cloudflared tunnel --url http://127.0.0.1:8080
Genera una URL aleatoria de trycloudflare.com. Me parece útil para una demo puntual, pero no lo dejaría como despliegue estable: tiene límites y no sustituye a un túnel administrado.
Actualizar y revisar
sudo apt-get update
sudo apt-get install --only-upgrade cloudflared
sudo systemctl restart cloudflared
sudo journalctl -u cloudflared -n 50 --no-pager
La instalación termina cuando también sabemos diagnosticarla. Me quedo con una ruta sencilla: aplicación en localhost, túnel como servicio, puerto del origen cerrado y una prueba desde dentro y desde fuera.
Referencias: descargas de cloudflared, configuración de Cloudflare Tunnel y actualización del servicio.
0 comentarios
Sé concreto, añade contexto (versión, distro, stack) y si puedes pega logs en bloque de código. Menos drama, más señales.