Por qué dejé de abrir puertos en mi router
Antes de este cambio, mi setup para exponer servicios al exterior era el clásico. Registros A en Cloudflare apuntando a mi IP pública, y un puñado de reglas de port forwarding en el router para que el tráfico llegara a donde tocaba.
En mi caso, esto lo usaba para dar acceso externo a varias LXC (contenedores ligeros de Proxmox, básicamente máquinas virtuales pero más eficientes en recursos) que tenía montadas. Immich para fotos, Affine como espacio de notas, Bookstack para documentación, mi propio servidor web, y alguna cosa más que se iba sumando con el tiempo para realizar pruebas tanto en local como en público.
A nivel de router, la cosa era sencilla, la IP del servidor apuntando al puerto de Wireguard, más el 80 y el 443 abiertos para el tráfico web. No es una configuración especialmente compleja ni insegura, pues mucha gente monta su homelab así sin ningún problema.
El nuevo Proxmox
La idea de montar un nuevo Proxmox venía de querer mejorar la infraestructura en general. Concretamente, me apetecía tener backups en ubicaciones físicas distintas, en vez de depender de un único servidor en un único sitio.
Para quien no lo conozca: Proxmox es un hipervisor de código abierto, el software que me permite correr varias máquinas virtuales y contenedores LXC en un mismo servidor físico, cada uno aislado del resto. Es una alternativa a otras opciones como Unraid o ESXi, pensada para quien quiere control total sobre su infraestructura.
El problema (o más bien, la oportunidad) fue que el nuevo servidor iba a estar en una ubicación donde simplemente no podía abrir puertos en el router. Así que tocaba investigar cómo dar acceso externo a los servicios sin depender de port forwarding y ahí es donde entraron en juego Tailscale y Cloudflare Tunnels.
A diferencia de otras migraciones, aquí no hubo convivencia entre el servidor viejo y el nuevo. El Proxmox nuevo se instaló de cero, sin heredar nada del anterior. El servidor antiguo, en mi casa, sigue funcionando con los servicios tal y como estaban montados originalmente pero la idea es, en algún momento, formatearlo y replicar en él la misma configuración que acabo de montar en el nuevo.
Si tuviera que resumir el motivo del cambio en una frase, sería esta: no quería seguir dependiendo del router para dar acceso a mis servicios.
El nuevo servidor se encuentra en una ubicación donde no tengo la opción de abrir puertos, así que el port forwarding tradicional quedaba descartado desde el principio. Esto me obligó a buscar una alternativa, pero cuanto más investigaba, más claro tenía que no era solo una solución de emergencia para ese caso concreto, era directamente, una forma mejor de hacer las cosas. Con la nueva arquitectura, el problema del router desapareció de raíz: no hay puertos que abrir porque no hace falta
La alternativa: mesh + Cloudflare Tunnels
La nueva arquitectura se apoya en dos piezas que trabajan juntas pero resuelven problemas distintos. Tailscale para la conectividad entre servidores (y conmigo mismo), y Cloudflare Tunnels para exponer servicios al público.
Por el lado de Tailscale, tengo un nodo corriendo directamente en el host de Proxmox, que se conecta con el resto de la mesh. Tailscale, para quien no lo conozca, crea una red privada virtual entre tus dispositivos como si estuvieran todos en la misma LAN, da igual dónde estén físicamente y sin necesidad de configurar manualmente un túnel VPN tradicional como haría Wireguard. Esta mesh no la uso solo para que los servidores se vean entre sí, también la utilizo yo mismo, desde el portátil o el móvil, para acceder a servicios internos cuando lo necesito, sin tener que exponerlos públicamente.
Por el lado de Cloudflare Tunnels, tengo una LXC dedicada corriendo cloudflared (el agente que crea el túnel saliente hacia Cloudflare). Esta es la pieza que se encarga de exponer al público lo que realmente necesita ser público y el resto se queda accesible solo a través de la mesh de Tailscale.
El día a día de añadir un servicio nuevo queda de la siguiente forma: cuando levanto una LXC o quiero exponer algo, entro a la LXC de cloudflared y creo el registro correspondiente usando la propia CLI de Cloudflare, sin tener que entrar a la web. El resultado es cero puertos abiertos en el router, cero DMZ, y un único punto de entrada público (el túnel) en vez de una regla de forwarding por servicio.
¿Y que pasa con Wireguard?
No dejé de usar Wireguard porque sea malo. Wireguard es rápido, ligero y lleva años siendo una referencia como protocolo VPN. El propio Tailscale, de hecho, lo usa por debajo, pero no es una alternativa a Wireguard, es una capa encima que te quita el trabajo manual de montarlo tú.
Y ahí está la diferencia real para mi caso. Montar Wireguard "a pelo" implica gestionar tú mismo varias cosas como generar y distribuir las claves de cada peer, mantener la configuración de cada nodo actualizada a mano, y sobre todo, lidiar con el NAT traversal, es decir, hacer que dos dispositivos se encuentren y se conecten aunque ninguno de los dos tenga una IP pública fija o puertos abiertos. Esto último es precisamente lo que antes resolvía yo abriendo puertos en el router.
Tailscale se encarga de todo eso por debajo gestionando las claves automáticamente, cada nuevo nodo se une a la mesh con un simple comando, y el NAT traversal lo resuelve él solo sin que yo tenga que abrir nada en ningún router. Para un servidor como el mío, en una ubicación donde ni siquiera tenía la opción de abrir puertos, esto no es solo comodidad, es lo que hace viable la solución.
Así que la conclusión no es "Wireguard mal, Tailscale bien", sino más bien algo como que si quieres control total y no te importa gestionar la infraestructura a mano, Wireguard puro sigue siendo una opción sólida. Si lo que quieres es que la conectividad simplemente funcione sin tener que pensar en ella, Tailscale te ahorra ese trabajo.
Conclusión
El balance, la verdad, es muy positivo. A nivel de software, no he tenido ningún problema reseñable con Tailscale ni con Cloudflare Tunnels desde que hice el cambio. Ambos han funcionado exactamente como esperaba, sin sustos ni configuraciones raras que mantener.
Si tuviera que quedarme con una sola cosa, sería la tranquilidad de no tener que pensar en el router. No hay reglas de forwarding que recordar, no hay que estar pendiente de si la IP pública cambia, no hay una superficie expuesta que vigilar. Todo el acceso pasa por la mesh o por el túnel, y eso simplifica mucho la cabeza a la hora de levantar un servicio nuevo.
¿Le cambiaría algo? Ahora mismo no, al menos no en la parte de software. Es una de esas migraciones donde, una vez montada, te preguntas por qué no lo hiciste antes.
Si estás en una situación parecida, ya sea porque no puedes abrir puertos donde tienes el servidor, o simplemente porque estás cansado de gestionar reglas a mano, te diría que le eches un ojo a esta combinación. No hace falta migrarlo todo de golpe. Puedes probarlo con un solo servicio y ver cómo te encaja.