Muy buenas a todos 👋
Hoy quiero hablaros de cómo exponer los servicios que tengáis en vuestro servidor personal (en mi caso, un mini-PC comprado en Aliexpress) al mundo exterior, es decir, a Internet. Y lo interesante es hacerlo sin abrir puertos en el firewall, sin depender de una IP fija y, sobre todo, sin comprometer la seguridad más de la cuenta.
Digo comprometer porque, siendo sinceros, los riesgos de seguridad siempre están ahí. Yo no me considero un experto en ciberseguridad, pero precisamente por eso me gustaría que cualquier lector con más experiencia aporte sus comentarios para mejorar esta infraestructura.
La herramienta protagonista de este post son los túneles de Cloudflare (Cloudflare Tunnels). Para quien no los conozca, son un servicio que permite crear un canal seguro entre tu máquina y la red global de Cloudflare.
Este artículo pretende ser una primera aproximación: una guía básica para montar y exponer servicios mediante Cloudflare Tunnel. Mi idea es ir iterando en futuros posts, añadiendo más robustez, automatización y configuración avanzada a la solución. A la vez, quiero usarlo como un espacio para recopilar y ordenar parte de lo que he ido aprendiendo a base de cacharrear, leer foros como Reddit y consultar otros blogs técnicos.
Uno que me ha sido especialmente útil para motivarme a lanzar este post ha sido el de Dan’s Garden, en particular External access with Cloudflare tunnels.
TL;DR #
- Con Cloudflare Tunnel puedes exponer servicios de tu servidor a Internet sin abrir puertos ni usar IP fija.
- Solo necesitas un dominio,
cloudflareden tu servidor y un túnel configurado en Cloudflare. - Ejemplo práctico: desplegar un Jupyter Notebook accesible desde cualquier parte del mundo.
Antes de empezar ¿qué pinta tiene todo esto? #
No voy a entrar en la definición formal de qué es un Cloudflare Tunnel. Para eso ya tenéis la documentación oficial o incluso el post de Dan que mencioné antes. Lo que sí quiero explicaros es la idea detrás de la infraestructura y por qué merece la pena.
Imaginad que vuestro servidor abre una conexión hacia la red de Cloudflare. Esa conexión es gestionada íntegramente por ellos, y lo que consigue es que vuestro servidor pase a formar parte de la red privada global de Cloudflare. En otras palabras, es como si vuestro mini-PC en casa se enchufara directamente a su infraestructura distribuida.
Una vez tu servidor está dentro de su red, cualquier servicio que levantéis en vuestro servidor, podrá estar disponible dentro de esa “red local gigantesca” de Cloudflare.
Para entenderlo mejor: en vuestra casa sabéis que un PC puede estar en 192.168.2.1 y otro en 192.168.3.1, y basta con usar esa dirección IP para llegar de uno a otro. Con Cloudflare ocurre algo parecido, solo que a una escala planetaria. La diferencia es que en esta red global no podéis acceder libremente a cualquier dirección: solo a aquellas para las que tengáis autorización.
Ahora bien, ¿cómo entra un cliente (por ejemplo, vuestro navegador) en juego? Muy fácil: accediendo a un dominio que tenga los DNS gestionados por Cloudflare. Cuando visitáis www.example.com, Cloudflare recibe la petición y, en lugar de apuntar a un servidor con IP pública en Internet, la enruta hacia el túnel que conecta con vuestro servidor. El efecto es el mismo que si accedierais a un equipo en vuestra LAN doméstica, pero a través de la red de Cloudflare.
Más o menos esa es la idea de lo que vamos a hacer. ¿Y por qué usar Cloudflare? Aquí entra lo personal. Seguro al 100% no hay nada, pero hoy por hoy Cloudflare ofrece un ecosistema muy completo para exponer servicios en Internet:
- DNS rápidos y fiables
- Certificados TLS automáticos
- Protección contra ataques DDoS
- Workers, Pages y más servicios para complementar la infraestructura
Todo ello con un nivel de facilidad que roza el one-click y, lo más interesante, en la mayoría de casos sin coste.
Otro tema es qué pasará dentro de unos años, cuando su cuota de mercado sea todavía mayor… Pero mientras tanto, vamos a aprovecharnos.
Requisitos previos #
Antes de meternos en faena, vamos a repasar lo que necesitamos para levantar nuestro túnel:
- Un dispositivo que actúe como servidor: puede ser una Raspberry Pi, un mini-PC o incluso una máquina virtual. En mi caso uso un mini-PC que compré en Aliexpress por unos ~170 € (sí, funciona de maravilla y para estos proyectos va sobrado).
- Un dominio propio: cualquier proveedor sirve. Yo suelo usar Namecheap, pero si quieres simplificar, Cloudflare también ofrece la compra y gestión de dominios directamente desde su plataforma. Para este post usaré
example.comcomo dominio de ejemplo. - Docker y Docker Compose instalados en el servidor: no es estrictamente obligatorio, ya que podríamos instalar / configurar mediante binarios, pero tener Docker te va a simplificar la vida, sobre todo cuando quieras escalar o mantener varios servicios.
Configuración del dominio en Cloudflare #
El primer paso es conseguir que Cloudflare gestione los DNS de tu dominio. Esto es fundamental, porque los túneles funcionan gracias a que Cloudflare actúa como intermediario entre los clientes (navegadores, apps, etc.) y tu servidor.
Los pasos son los siguientes:
- Accede a tu Cloudflare Dashboard. En el menú principal selecciona: Account Home → Onboard a domain.
- Introduce tu dominio (por ejemplo:
example.com) y deja activada la opción Quick scan for DNS records para que Cloudflare detecte automáticamente los registros existentes.
-
En el último paso, Cloudflare te pedirá que cambies los nameservers de tu dominio en el proveedor donde lo compraste (Namecheap, GoDaddy, Google Domains, etc.). Para este ejemplo, supongamos que los nameservers asignados son:
keanu.ns.cloudflare.commaisie.ns.cloudflare.com
⚠️ Ten en cuenta que los nameservers que te muestre Cloudflare pueden variar en tu caso.
- Una vez actualizados, vuelve a Cloudflare y haz clic en Continue. En pocos minutos (normalmente menos de 5), la propagación de DNS se completará y tu dominio quedará bajo la gestión de Cloudflare.
Y con esto ya tenemos la pieza clave: un dominio gestionado por Cloudflare, listo para conectarse a nuestro túnel.
Creación del túnel #
Con el dominio ya gestionado por Cloudflare, es hora de dar el siguiente paso: crear el túnel que conectará nuestro servidor con la red de Cloudflare.
-
Accede al Cloudflare Dashboard y entra en la sección Zero Trust. Si es la primera vez que usas esta parte de Cloudflare, te pedirá pasar por la pasarela de pago. No te asustes: el plan gratuito es bastante generoso y más que suficiente para nuestro escenario.
-
Una vez dentro, navega hasta: Networks → Tunnels → Add Tunnel.
-
Cloudflare te dará dos opciones de conector:
- Cloudflared → el más común y recomendado para servidores caseros o VPS.
- Warp Connector → pensado más para escenarios corporativos con redes completas.
Para nuestro caso, seleccionamos Cloudflared.
internal-labs. Luego haz clic en Save Tunnel.
- Una vez creado, Cloudflare te mostrará varias formas de instalar y ejecutar el conector en tu servidor. Puedes elegir entre:
- Instalación directa con el binario
cloudflared. - Uso de un paquete (Debian, RPM, etc.).
- Ejecución en Docker.
- Instalación directa con el binario
En mi caso, elegí la opción con Docker, porque simplifica la gestión y actualización del túnel. Pero cualquiera de las alternativas es válida: lo importante es que el conector quede corriendo en tu servidor.
Conectándonos al túnel #
Aunque podríamos ejecutar cloudflared directamente, lo más práctico es levantarlo con Docker Compose. Así podremos integrarlo fácilmente en una infraestructura con otros contenedores.
Aquí tienes un docker-compose.yml mínimo para poner en marcha el túnel:
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: always
command: tunnel run
env_file:
- ./.env
En el mismo directorio, crea un archivo .env con el token del túnel que te proporcionó Cloudflare al crearlo:
TUNNEL_TOKEN=eyJhIjoiMDdmNjJhNzRjN...
⚠️ Importante: este token es único para tu túnel, así que no lo compartas públicamente.
Ahora, en tu servidor, ejecuta docker compose up -d. Si todo ha ido bien verás que el túnel aparece como activo y con un conector conectado.
Externalizando servicios #
Llegamos a la parte más interesante: exponer servicios de nuestro servidor al exterior mediante el túnel. Para este ejemplo vamos a usar un Jupyter Notebook.
Importante: lo desplegaremos sin contraseña ni token, únicamente con fines didácticos para ilustrar el funcionamiento. No hagáis esto en producción, porque cualquiera que acceda tendría control completo sobre el sistema de ficheros de la máquina.
1. Dockerizar el servicio #
Primero levantamos el contenedor de Jupyter en nuestro servidor. Podemos hacerlo con el siguiente docker-compose.yml:
services:
jupyter:
image: quay.io/jupyter/pyspark-notebook:spark-4.0.0
container_name: notebook
restart: unless-stopped
# expose the internal port 8888 on 5001 of the host
ports:
- "5001:8888"
volumes:
# persist notebooks and other work
- ./data:/home/jovyan/work
- ./config:/home/jovyan/.jupyter
command:
- start-notebook.sh
- --ServerApp.token=
- --NotebookApp.password=
- --ServerApp.root_dir=/home/jovyan/work
- --ServerApp.allow_remote_access=True
- --ServerApp.ip=0.0.0.0
- --ServerApp.port=8888
2. Exponerlo mediante Cloudflare Tunnel #
Ahora vamos al Cloudflare Dashboard, abrimos la configuración de nuestro túnel y pulsamos Next para continuar con la creación de un Public Hostname.
Aquí configuraremos cómo acceder desde el exterior: básicamente le diremos a Cloudflare que redirija el tráfico de un subdominio hacia el servicio Jupyter de nuestro servidor.
En este primer post vamos a hacerlo de la forma más básica posible: sin reglas de acceso avanzadas, sin autenticación Zero Trust. Lo justo para que el servicio quede accesible desde un dominio público.
Publicando el servicio en un subdominio #
En nuestro ejemplo, partimos del dominio example.com y crearemos el subdominio notebook-internal-labs.
Quizá os preguntéis por qué uso guiones (
-) en vez de puntos (.). Cloudflare interpreta los puntos como subzones, y para poder gestionarlas se necesita activar el servicio de Advanced Certificate Manager (unos $10/mes). En el plan gratuito no es posible, así que tiraremos de guiones.
Selección del protocolo #
Aquí seleccionamos HTTP. En teoría no importa demasiado, porque el tráfico entre Cloudflare y vuestro servidor sí será HTTP sin cifrado, pero:
- El tráfico entre el cliente y Cloudflare siempre viaja en HTTPS.
- Para el usuario final, la conexión es segura gracias al certificado TLS que Cloudflare gestiona automáticamente.
En posts futuros veremos cómo securizar también el tramo interno y gestionar certificados propios, para tener cifrado extremo a extremo. Aunque para los que quieran adelantarse, recomiendo de nuevo leer el artículo External access with Cloudflare tunnels de Dan’s Garden o sencillamente esperan al siguiente post 🙂
Dirección del servicio interno #
En la URL debemos poner la IP local de nuestro servidor dentro de la red. Ni localhost ni 0.0.0.0 funcionan aquí. En Linux puedes obtener la IP mediante el comando ifconfig, o, si no lo tienes instalado ip addr show.
Una vez que lo tengamos, guardamos la configuración, y accedemos a nuestro Jupyter desde https://notebook-internal-labs.example.com. !Voilá!
Ya tenemos un Jupyter Notebook accesible desde cualquier parte del mundo, corriendo en nuestro servidor personal, utilizando sus recursos y su sistema de ficheros como si estuviéramos en local. De esta forma podemos mantener nuestro trabajo siempre online y disponible, sin depender de estar físicamente conectados a la misma red.
Conclusión #
Con unos pocos pasos hemos conseguido algo muy potente: exponer un servicio casero a Internet de manera sencilla y gratuita usando Cloudflare Tunnel.
Lo mejor es que no hemos tenido que abrir puertos en el router, ni depender de una IP estática, ni complicarnos con configuraciones de red inseguras.
En este ejemplo hemos desplegado un Jupyter Notebook como prueba de concepto, pero la misma idea se puede aplicar a prácticamente cualquier servicio: un dashboard personal, un servidor de juegos, una API o una aplicación web.
Eso sí, lo que hemos montado aquí es solo la base mínima. Aún quedan muchas piezas por mejorar. En este primer post hemos usado una configuración básica para entender cómo funciona Cloudflare Tunnel y cómo podemos usarlo para externalizar servicios caseros de forma sencilla y gratuita.
En próximas entregas veremos cómo darle una vuelta de tuerca más:
- Securizar el acceso con TLS extremo a extremo
- Añadir políticas Zero Trust para controlar quién puede entrar
- Y explorar cómo integrar más servicios detrás del mismo túnel.
Mientras tanto, te animo a probar este setup, experimentar con tus propios servicios y, si te surge alguna idea o mejora, compartirla en los comentarios 🤘