Cloudflare Tunnel publica servicios de tu servidor sin abrir puertos de entrada: el demonio cloudflared establece conexiones salientes cifradas hacia la red de Cloudflare, y Cloudflare envía por ellas las peticiones que llegan a tus nombres de dominio. En este tutorial instalarás cloudflared en Ubuntu 24.04, crearás un túnel que publica una aplicación web y el acceso SSH, lo ejecutarás como servicio de systemd y protegerás los accesos con Cloudflare Access.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con privilegios
sudo. - Un dominio (
your_domain) cuyos servidores de nombres ya estén en Cloudflare, con la zona en estado activo. - Una cuenta de Cloudflare Zero Trust (el plan Free cubre hasta 50 usuarios) para el paso 7.
- En tu equipo local,
cloudflaredinstalado si quieres usar SSH a través del túnel.
Como servicio de ejemplo usarás una aplicación que escucha solo en 127.0.0.1:8080. Si ya tienes una aplicación o un Nginx local, sustituye el puerto.
Paso 1: Instalar cloudflared desde el repositorio de Cloudflare
Instalar desde el repositorio oficial permite actualizar cloudflared con apt como cualquier otro paquete. Añade la clave de firma y el repositorio:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /etc/apt/keyrings/cloudflare-main.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
Instala el paquete y comprueba la versión:
sudo apt update
sudo apt install cloudflared
cloudflared --version
cloudflared version 2026.x.x (built 2026-xx-xx)
Paso 2: Autenticar cloudflared con tu cuenta
cloudflared necesita un certificado de cuenta para crear túneles y registros DNS. Ejecuta el inicio de sesión con tu usuario normal:
cloudflared tunnel login
El comando imprime una URL. Ábrela en un navegador, inicia sesión en Cloudflare y selecciona your_domain. Al autorizarlo, el certificado se guarda en tu directorio personal:
You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/home/your_user/.cloudflared/cert.pem
Paso 3: Crear el túnel
Crea un túnel con un nombre descriptivo:
cloudflared tunnel create web01
Tunnel credentials written to /home/your_user/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json. cloudflared chose this file based on where your origin certificate was found. Keep this file secret. To revoke these credentials, delete the tunnel.
Created tunnel web01 with id 6ff42ae2-765d-4adf-8112-31c55c1551ef
Anota el ID del túnel (your_tunnel_id en adelante). El archivo JSON contiene el secreto del túnel: cualquiera que lo tenga puede ejecutarlo. Muévelo a /etc/cloudflared, donde lo leerá el servicio, con permisos solo para root:
sudo install -d -m 755 /etc/cloudflared
sudo install -m 600 ~/.cloudflared/your_tunnel_id.json /etc/cloudflared/
rm ~/.cloudflared/your_tunnel_id.json
Comprueba que el túnel existe:
cloudflared tunnel list
ID NAME CREATED CONNECTIONS
6ff42ae2-765d-4adf-8112-31c55c1551ef web01 2026-09-25T10:02:11Z
La columna CONNECTIONS está vacía porque el túnel aún no se está ejecutando.
Paso 4: Definir las reglas de ingress
El archivo de configuración indica a cloudflared a qué servicio local enviar cada nombre de host. Las reglas se evalúan en orden y la última, sin hostname, es obligatoria y captura todo lo demás.
sudo nano /etc/cloudflared/config.yml
tunnel: your_tunnel_id
credentials-file: /etc/cloudflared/your_tunnel_id.json
ingress:
- hostname: app.your_domain
service: http://127.0.0.1:8080
- hostname: ssh.your_domain
service: ssh://127.0.0.1:22
- service: http_status:404
Valida la sintaxis y comprueba qué regla corresponde a una URL:
sudo cloudflared tunnel --config /etc/cloudflared/config.yml ingress validate
sudo cloudflared tunnel --config /etc/cloudflared/config.yml ingress rule https://app.your_domain
Validating rules from /etc/cloudflared/config.yml
OK
Using rules from /etc/cloudflared/config.yml
Matched rule #0
hostname: app.your_domain
service: http://127.0.0.1:8080
Paso 5: Crear los registros DNS del túnel
Cada nombre de host necesita un registro CNAME que apunte a your_tunnel_id.cfargotunnel.com. cloudflared los crea por ti usando el certificado del paso 2:
cloudflared tunnel route dns web01 app.your_domain
cloudflared tunnel route dns web01 ssh.your_domain
INF Added CNAME app.your_domain which will route to this tunnel tunnelID=6ff42ae2-765d-4adf-8112-31c55c1551ef
Si ya existe un registro A o CNAME con ese nombre, el comando falla: bórralo antes en DNS > Records. Los registros creados aparecen en el panel con el proxy activado y el tipo Tunnel.
Paso 6: Ejecutar el túnel como servicio
Instala cloudflared como servicio de systemd. El servicio usa /etc/cloudflared/config.yml:
sudo cloudflared service install
sudo systemctl status cloudflared --no-pager
● cloudflared.service - cloudflared
Loaded: loaded (/etc/systemd/system/cloudflared.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-09-25 10:10:42 UTC; 5s ago
En los logs debes ver cuatro conexiones registradas contra centros de datos de Cloudflare:
sudo journalctl -u cloudflared -n 20 --no-pager | grep 'Registered tunnel connection'
INF Registered tunnel connection connIndex=0 ... location=mad01 protocol=quic
INF Registered tunnel connection connIndex=1 ... location=mad05 protocol=quic
Para probar el túnel, arranca un servidor web temporal en el puerto 8080 que escuche solo en localhost:
mkdir -p /tmp/tunnel-test && echo "Hola desde el túnel" > /tmp/tunnel-test/index.html
python3 -m http.server 8080 --bind 127.0.0.1 --directory /tmp/tunnel-test
Desde tu equipo local, abre https://app.your_domain o usa curl:
curl https://app.your_domain
Hola desde el túnel
Detén el servidor de prueba con Ctrl+C cuando termines. El puerto 8080 nunca ha estado abierto a Internet: la petición llegó por la conexión saliente del túnel. Si tu servidor solo publica servicios a través del túnel, puedes cerrar en UFW los puertos 80 y 443 y, cuando hayas comprobado el acceso SSH del paso 8, también el 22.
Paso 7: Proteger las aplicaciones con Cloudflare Access
Sin una política de Access, app.your_domain es pública para cualquiera y ssh.your_domain expone el puerto SSH a Internet a través de Cloudflare. Cloudflare Access exige autenticarse en Cloudflare antes de que la petición llegue al túnel.
En el panel de Cloudflare Zero Trust, ve a Access > Applications y añade una aplicación de tipo Self-hosted:
- Application name:
Servidor web01. - Application domain:
app.your_domain. Añade tambiénssh.your_domaincomo segundo dominio de la misma aplicación. - Crea una política con acción Allow y una regla Include de tipo Emails con las direcciones autorizadas (o Emails ending in con
@your_company.com). - Como método de inicio de sesión basta con One-time PIN, que envía un código al correo. Puedes añadir Google, GitHub, Microsoft Entra ID u otro proveedor en Settings > Authentication.
Guarda la aplicación y comprueba el efecto desde una ventana de incógnito:
curl -sI https://app.your_domain | head -n 1
HTTP/2 302
La redirección 302 lleva a la página de inicio de sesión de Access (your_team.cloudflareaccess.com). Tras introducir el código enviado a una dirección autorizada, ves la aplicación.
Paso 8: Conectarse por SSH a través del túnel
El cliente SSH no habla con Cloudflare directamente; cloudflared en tu equipo local actúa como proxy. Instálalo en tu máquina (en macOS con brew install cloudflared, en Ubuntu con el repositorio del paso 1) y añade este bloque a ~/.ssh/config en tu equipo local:
nano ~/.ssh/config
Host ssh.your_domain
ProxyCommand cloudflared access ssh --hostname %h
User your_user
Conéctate:
ssh ssh.your_domain
La primera vez se abre el navegador para autenticarte en Access; después la sesión SSH se establece como siempre, con tus claves SSH. Cuando funcione, puedes cerrar el puerto 22 en el firewall del servidor:
sudo ufw delete allow OpenSSH
sudo ufw status
Advertenciaantes de cerrar el puerto 22, abre una segunda sesión por el túnel y confirma que funciona. Si el túnel cae, todavía podrás entrar al servidor por la consola web del panel de CubePath.
Solución de problemas
Error 1033 en el navegador: Cloudflare no encuentra ninguna conexión activa del túnel. Comprueba sudo systemctl status cloudflared y cloudflared tunnel info web01, que lista las conexiones activas.
Error 502 Bad Gateway: el túnel funciona pero el servicio local no responde. Comprueba que la aplicación escucha en la dirección de config.yml con ss -tlnp | grep 8080, y revisa sudo journalctl -u cloudflared -n 50 para ver el error de conexión al origen.
Los cambios en config.yml no se aplican: el servicio lee la configuración al arrancar. Tras editarla, valídala y reinicia con sudo systemctl restart cloudflared.
cloudflared tunnel route dns devuelve un error de registro existente: borra el registro A o CNAME antiguo de ese nombre en el panel y repite el comando.
Actualizar cloudflared: al estar instalado desde el repositorio, se actualiza con sudo apt update && sudo apt install --only-upgrade cloudflared y sudo systemctl restart cloudflared.
Conclusión
Tu servidor publica ahora una aplicación web y el acceso SSH a través de Cloudflare Tunnel, sin puertos de entrada abiertos y con autenticación de Cloudflare Access delante de ambos servicios. Como siguientes pasos puedes añadir más servicios internos como nuevas reglas de ingress, activar la renderización de SSH en el navegador desde la configuración de la aplicación de Access, o ejecutar cloudflared en un segundo servidor con el mismo túnel para tener alta disponibilidad.
