Tailscale sin redirección de puertos: cómo funciona
Accede a un NAS, Raspberry Pi o servidor de Minecraft sin abrir puertos del router. Tailscale atraviesa NAT, usa un relay si es necesario y tiene límites.
¿Tailscale necesita redirección de puertos?
Tailscale no necesita redirección de puertos y, para acceder a sus propios equipos, la sustituye por completo. Cada dispositivo de su tailnet (la red privada que Tailscale crea entre sus dispositivos) abre sus propias conexiones salientes. No cambia nada en el router doméstico: no hay puertos redirigidos, host en la DMZ (zona desmilitarizada), registro de DNS dinámico ni requisito de una IP pública. Un NAS (dispositivo de almacenamiento conectado a la red), una Raspberry Pi o un servidor de juegos detrás de un router ipTIME o Fritz!Box se vuelve accesible desde su portátil desde cualquier lugar, mediante su propia dirección privada, mientras el tráfico entrante del router permanece bloqueado.
También es breve lo que no hace. Tailscale conecta los dispositivos que han iniciado sesión en su tailnet o que se han compartido con ella. Un desconocido en Internet o un amigo que no se haya unido no puede acceder a nada a través de ella. Exponer un servicio a todo Internet público es otra tarea, que se explica cerca del final.
Cómo Tailscale atraviesa NAT sin un puerto reenviado
El reenvío de puertos existe debido a NAT (traducción de direcciones de red). En la mayoría de las conexiones domésticas, el router tiene la única dirección IPv4 pública y cada dispositivo situado detrás tiene una dirección privada. Un paquete entrante que llega al router no indica qué dispositivo privado lo necesita, por lo que el router lo descarta. Un reenvío de puertos es una regla manual que indica que «el puerto 25565 pertenece a 192.168.0.20». Tailscale obtiene el mismo resultado sin esa regla, mediante cuatro pasos.
Primero, cada nodo inicia conexiones salientes. Al arrancar, tailscaled se conecta al servidor de coordinación. Prefiere HTTP sin formato en TCP 80, encapsulado en su propio transporte cifrado, y usa HTTPS en TCP 443 como alternativa cuando el puerto 80 no responde. Envía su clave pública de WireGuard y obtiene las claves públicas y las direcciones de todos los demás nodos de la tailnet. El servidor de coordinación nunca transporta el tráfico; sólo gestiona las claves y la libreta de direcciones.
Segundo, cada nodo descubre cómo se ve desde el exterior. Envía una solicitud STUN (session traversal utilities for NAT) mediante UDP al puerto 3478 de los servidores de retransmisión de Tailscale. La respuesta contiene la IP pública y el puerto que el router asignó a ese paquete saliente. Esta es la asignación que un reenvío de puertos habría creado manualmente, con la diferencia de que el router la creó por sí solo para un flujo saliente. Si el router admite UPnP o NAT-PMP, Tailscale también le solicita automáticamente una asignación. Esto ayuda, pero no es necesario.
Tercero, ambos extremos atraviesan el NAT. El nodo A y el nodo B obtienen el endpoint público del otro mediante el servidor de coordinación. Ambos envían al mismo tiempo paquetes UDP desde su propio listener, que usa el puerto 41641 de forma predeterminada, hacia el endpoint público del otro extremo. Cada router ya mantiene una asignación saliente para su nodo, por lo que el paquete que llega desde el otro extremo coincide con esa asignación y se permite su entrada. A partir de ese momento, los dos nodos se comunican directamente mediante WireGuard y el router sigue sin tener ninguna regla.
Cuarto, cuando el atravesamiento falla, el tráfico sigue usando una retransmisión. Cada conexión comienza en realidad mediante un servidor DERP (designated encrypted relay for packets), que transporta los paquetes WireGuard cifrados mediante HTTPS en TCP 443. Después, Tailscale intenta actualizarla a la ruta UDP directa del tercer paso. CGNAT (NAT a escala de operador, donde el ISP sitúa al cliente detrás de un segundo NAT bajo su control) y el NAT simétrico (donde el router elige un puerto nuevo para cada destino, por lo que la respuesta de STUN no sirve) impiden esa actualización. También la impide un firewall corporativo que bloquee UDP. Si la actualización falla, Tailscale intenta primero una retransmisión entre pares: un dispositivo de su propia tailnet que haya configurado para retransmitir tráfico mediante UDP. Si no hay ninguno disponible, la conexión permanece en DERP. El servidor de retransmisión sólo ve texto cifrado. Esta opción también aumenta la latencia y reduce el rendimiento; por qué una conexión de Tailscale mediante retransmisión es lenta y cómo hacerla directa explica cómo identificar la ruta utilizada y qué cambiar.
Ninguno de esos cuatro pasos es una conexión entrante al router. Por eso no se necesita un reenvío de puertos.
Instale el cliente y compruebe la ruta
La instalación consiste en un script y un inicio de sesión en cada dispositivo.
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4tailscale up muestra una URL de inicio de sesión. Ábrala, inicie sesión y el dispositivo se unirá a la tailnet. tailscale ip -4 muestra la dirección tailnet del dispositivo dentro del rango 100.64.0.0/10. Esta dirección no cambia al reiniciar ni al cambiar de red. Por tanto, es la que debe escribir en las configuraciones de SSH y en los clientes de juegos.
Desde un segundo dispositivo de la tailnet, compruebe la ruta hasta el primero:
tailscale ping nasUse el nombre de host o la dirección tailnet. La primera respuesta suele indicar via DERP, porque todas las conexiones comienzan mediante un relay mientras se negocia la ruta directa. En unos segundos, las respuestas deberían cambiar a una IP pública y un puerto. Esto indica que el hole punching funcionó. Si después de un minuto las respuestas siguen indicando via DERP, el hole punching no pudo completarse. Normalmente, esto ocurre porque uno de los extremos está detrás de un NAT que no se puede atravesar o en una red que bloquea UDP. En ese caso, la conexión usa un relay.
La única regla de firewall que merece la pena añadir
Tailscale funciona sin cambios en el firewall en la mayoría de las redes, porque normalmente se permite el tráfico UDP saliente. Una regla opcional mejora las probabilidades de establecer una ruta directa: permita la salida de UDP desde el puerto 41641.
En un router doméstico o en un firewall corporativo que restrinja el tráfico UDP saliente, esto significa permitir que los dispositivos envíen UDP desde el puerto de origen 41641 a cualquier dirección y a cualquier puerto de destino, además de permitir UDP saliente al puerto de destino 3478 para STUN. Permitir sólo el puerto de destino 41641 no es suficiente, porque la NAT o la configuración de un peer pueden situar su extremo de la conexión en cualquier puerto. La mayoría de los routers domésticos ya permiten todo el tráfico UDP saliente, por lo que no es necesario hacer nada.
En un VPS, la dirección útil es la entrante. Normalmente, un VPS tiene su IP pública en su propia interfaz de red o, como mucho, usa una NAT fija uno a uno, como la que proporciona un internet gateway de AWS. Por tanto, una regla entrante para UDP 41641 proporciona a todos los peers un destino estable y accesible. Un peer situado detrás de una NAT problemática aún puede conectarse directamente en muchos casos, siempre que su propia red permita la salida de UDP. Un peer situado en una red que bloquea UDP seguirá usando un relay, independientemente de lo que permita el VPS. Con ufw:
sudo ufw allow 41641/udp
sudo ufw statusufw status debería mostrar 41641/udp como ALLOW desde Anywhere. Los proveedores que ejecutan un firewall de red independiente en su panel de control necesitan la misma regla allí, porque un paquete bloqueado en el perímetro del proveedor nunca llega a ufw. Esta regla es una comodidad, no un requisito. Con el puerto cerrado, el VPS sigue uniéndose al tailnet y los peers siguen accediendo a él, aunque algunos lo hagan a través de un relay en lugar de directamente.
Acceder a un NAS doméstico o a una Raspberry Pi desde fuera
El primer caso es el más sencillo y es lo que la mayoría de las personas entiende por «redirección de puertos con Tailscale»: acceder a un equipo de casa desde un portátil o un teléfono que no están en casa.
Instale el cliente en el equipo doméstico y en el portátil. Esa es toda la configuración necesaria. El NAS o la Pi responderá ahora en su dirección del tailnet para cada servicio que escuche en todas sus interfaces, sin redirecciones. Un servicio vinculado sólo a 127.0.0.1 o a la dirección de la LAN seguirá siendo invisible en el tailnet hasta que cambie la dirección en la que escucha.
ssh pi@100.101.102.103
curl -I http://100.101.102.103:8080/Sustituya la dirección por la salida de tailscale ip -4 en el equipo doméstico. El acceso SSH debería comportarse exactamente igual que en la Wi-Fi doméstica, y curl -I debería mostrar la línea de estado HTTP de la aplicación web que ejecute el equipo. Como la conexión se autentica mediante claves de WireGuard asociadas a un dispositivo con una sesión iniciada, un servicio que sería peligroso en un puerto redirigido, como un recurso compartido SMB (server message block) o un panel de administración web, resulta razonable en este caso: sólo sus propios dispositivos pueden enviarle paquetes. El ipTIME o Fritz!Box intermedio nunca recibe una conexión entrante y no requiere ningún cambio. Si su ISP le ha situado detrás de CGNAT, esto sigue funcionando porque el equipo doméstico sólo inicia conexiones salientes y, en el peor de los casos, la ruta pasa por un relay.
MagicDNS, habilitado de forma predeterminada en los tailnets nuevos, también asigna un nombre a cada nodo, por lo que ssh pi@nas funciona cuando el portátil está conectado al tailnet.
Cuando el dispositivo no puede ejecutar Tailscale: un router de subred
Algunos dispositivos no pueden ejecutar el cliente: una impresora, una cámara IP, un NAS antiguo con un sistema operativo restringido o un televisor inteligente. Un router de subred resuelve este problema. Un equipo de la red doméstica que pueda ejecutar Tailscale (una Pi es suficiente) anuncia toda la subred doméstica, y los demás dispositivos del tailnet enrutan el tráfico hacia esa subred a través de él.
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
sudo sysctl --system
sudo tailscale up --advertise-routes=192.168.0.0/24Use la subred doméstica real. Después, la ruta debe aprobarse en la consola de administración, en la configuración de rutas del equipo, y los clientes Linux deben habilitarla explícitamente con sudo tailscale set --accept-routes. A partir de ese momento, ping 192.168.0.50 desde el portátil llega a la cámara de casa. El parámetro sysctl de reenvío es importante porque, sin él, la Pi descarta todos los paquetes que no estén dirigidos a ella, y la ruta aparece como aprobada aunque ningún dispositivo situado detrás responda. El proceso de aprobación, la habilitación en el cliente y las otras situaciones en las que una ruta aparece aprobada pero no es accesible se explican en ejecutar un router de subred de Tailscale, que usa un VPS como router, pero se aplica sin cambios a una Pi en el salón.
Permitir que los amigos se unan a un servidor de Minecraft sin abrir el router
Caso dos: un servidor de Minecraft en un PC de casa y amigos que quieren conectarse. La respuesta tradicional es redirigir TCP 25565 en el router y proporcionar la IP pública, que también queda expuesta a todos los escáneres de Internet. Tailscale sustituye este método por el uso compartido.
Hay dos opciones. La primera es invitar a los amigos al tailnet como usuarios. Funciona, pero las plazas de usuario del plan gratuito son limitadas, y, de forma predeterminada, un usuario invitado puede acceder a todos los dispositivos del tailnet, algo innecesario para un juego salvo que escriba reglas de acceso para limitarlo. La segunda opción, más sencilla, es compartir el nodo. En la consola de administración, abra la página Machines, busque el PC del juego, abra su menú y seleccione Share. Tailscale crea un enlace de invitación. Cada amigo necesita su propia cuenta gratuita de Tailscale, que lo convierte en propietario de su propio tailnet pequeño, y debe aceptar el enlace desde esa cuenta. La máquina compartida aparece entonces en su lista de máquinas, y sólo aparece esa máquina. El uso compartido proporciona al destinatario acceso a la máquina compartida y a ningún otro elemento del tailnet, y una máquina compartida queda aislada de forma predeterminada: puede responder a conexiones desde el tailnet del amigo, pero no puede iniciar ninguna.
Los amigos añaden el servidor en Minecraft usando su dirección del tailnet, 100.101.102.103:25565, o simplemente la dirección cuando el puerto es el predeterminado. El PC del juego funciona sin ningún puerto redirigido y el router no se modifica. Las máquinas compartidas no anuncian rutas de subred, por lo que el uso compartido funciona con un servicio que se ejecuta en la propia máquina compartida, que es exactamente el caso de un servidor de juego.
La limitación es que todos los jugadores deben ejecutar Tailscale y aceptar el uso compartido. Para un grupo de amigos, esto es suficiente. Para un servidor público al que pueda unirse cualquiera, no lo es, y las dos secciones siguientes ofrecen la solución.
Ejecute el servidor del juego en un VPS y mantenga RCON en la tailnet
Otra forma de evitar el reenvío de puertos es dejar de alojar el juego en casa. Un VPS tiene una IP pública que permite acceder directamente a él, por lo que el puerto del juego puede quedar expuesto a Internet sin utilizar el router doméstico. Ejecutar un servidor de Minecraft en un VPS explica cómo dimensionarlo, las opciones de Java, las copias de seguridad y la unidad de systemd. Aquí importa qué puertos quedan expuestos a Internet.
Un servidor de Minecraft abre dos puertos. TCP 25565 es el puerto del juego y los jugadores necesitan acceder a él. TCP 25575 es RCON (consola remota), que acepta una contraseña y después ejecuta cualquier comando del servidor, incluidos op y stop. Un puerto RCON expuesto a Internet puede recibir intentos de adivinar la contraseña. Añada el VPS a su tailnet y aplique reglas distintas a los dos puertos:
sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw allow in on tailscale0 to any port 25575 proto tcp
sudo ufw enable
sudo ufw statusLa segunda regla abre el juego a todo el mundo. La tercera permite RCON sólo a los paquetes que llegan por la interfaz tailscale0, es decir, únicamente desde dispositivos de su tailnet y desde las personas con las que haya compartido el VPS. Si comparte el VPS, use reglas de acceso en la política de su tailnet para impedir que los usuarios compartidos accedan al puerto 25575, porque la regla de la interfaz por sí sola no puede distinguirlos de sus propios dispositivos. La IP pública sigue respondiendo en 25565, y ufw descarta por su política predeterminada de denegación las conexiones al puerto 25575 que llegan desde el lado público. Compruebe ambos puertos desde su portátil, que está en la tailnet:
nc -zv 100.101.102.103 25575
nc -zv <vps-public-ip> 25575El primero debería imprimir succeeded. El segundo debería quedar esperando y después agotar el tiempo de espera, porque el paquete llegó por la interfaz pública y no coincidió con ninguna regla de permiso. El mismo patrón sirve para SSH, un mapa web, una base de datos o un panel de métricas: el puerto público en la IP pública y los puertos de administración sólo en tailscale0.
Exponer un servicio a todo Internet: Funnel o un túnel inverso mediante VPS
El tercer caso es el que Tailscale no resuelve por sí solo. Un blog, una API pública, un servidor de juegos público o una página de estado: los visitantes no están en su tailnet ni lo estarán nunca. Hay dos herramientas para este caso y cada una se explica en su propio artículo.
Tailscale Funnel publica un servicio HTTPS de un nodo en Internet público mediante los relays de Tailscale. Sólo funciona con TLS (seguridad de la capa de transporte) y únicamente en los puertos 443, 8443 y 10000. Por tanto, sirve para una aplicación web, pero no para un protocolo de juego sin procesar en 25565. Tailscale Serve frente a Funnel explica qué expone cada opción y quién puede acceder.
Un túnel inverso mediante VPS se encarga del resto. El equipo de casa abre un túnel saliente hacia un VPS con una IP pública y el VPS reenvía un puerto público de vuelta por el túnel, mediante TCP o UDP y con cualquier número de puerto. Esta es la herramienta adecuada para alojar en casa un servidor público de Minecraft detrás de CGNAT. Un túnel inverso mediante VPS para un servidor doméstico detrás de CGNAT explica el procedimiento. Elija una de estas dos opciones y deje de buscar una configuración de Tailscale que abra un puerto al mundo. No existe.
Qué no hace Tailscale
- No reenvía un puerto para clientes públicos arbitrarios. Un paquete procedente de alguien ajeno al tailnet nunca llega a su nodo porque no existe una clave de WireGuard para ese cliente. Un paquete de WireGuard sin una clave válida se descarta sin enviar respuesta.
- No ofrece al público una vía de entrada. Los usuarios deben ser miembros de su tailnet o haber aceptado un nodo compartido.
- No garantiza una ruta directa. En una situación de NAT compleja, la conexión se retransmite, lo que la hace más lenta.
- No abre el router. El router permanece cerrado, y ese es precisamente el objetivo.
FAQ
¿Tailscale necesita el reenvío de puertos?
No. Cada nodo de Tailscale sólo establece conexiones salientes. Se conecta al servidor de coordinación mediante TCP 80 y cambia a HTTPS mediante TCP 443 cuando el puerto 80 no responde. También obtiene su dirección pública mediante STUN en UDP 3478. Cada conexión entre pares comienza retransmitida mediante DERP sobre TCP 443, también de forma saliente, y después cambia a una ruta directa mediante UDP hole punching desde el puerto 41641. Si el hole punching falla, el tráfico pasa a un relay de pares si ha configurado uno, o permanece en DERP. Un router doméstico nunca necesita un puerto reenviado ni un host en la DMZ. Un dispositivo detrás de CGNAT se conecta de la misma forma.
¿Puede Tailscale sustituir el reenvío de puertos para un servidor de Minecraft?
Sí, para un servidor al que se conecten sus amigos. Instale Tailscale en el PC donde se ejecuta el juego, comparta ese equipo con cada amigo desde la página Machines de la consola de administración y ellos se conectarán a su dirección de tailnet en el puerto 25565 sin reenviar ningún puerto. No sustituye el reenvío de puertos para un servidor público, porque los jugadores que están fuera de su tailnet no pueden alcanzar el nodo. En ese caso, aloje el juego en un VPS con una IP pública y mantenga RCON en la tailnet, o use un túnel inverso desde el equipo doméstico hasta un VPS.
¿Qué puertos utiliza Tailscale?
Cuatro. TCP 80 saliente es la conexión preferida con el servidor de coordinación y se transporta mediante el transporte cifrado propio de Tailscale. TCP 443 saliente es el mecanismo alternativo para esa conexión cuando el puerto 80 no responde, y siempre transporta el tráfico retransmitido de DERP. UDP 3478 saliente se utiliza para STUN, que descubre la dirección pública. UDP 41641 es el puerto local predeterminado de WireGuard para las conexiones directas: los paquetes salen desde él hacia el puerto que utilice el lado del par, y se puede cambiar si 41641 está ocupado. Ninguno debe abrirse para conexiones entrantes. Bloquear TCP 80 no supone un problema porque el cliente cambia a 443. Permitir UDP 41641 entrante en un VPS es opcional y permite obtener una ruta directa con más frecuencia.
¿Por qué mi conexión de Tailscale usa un relay en lugar de una conexión directa?
tailscale ping sigue respondiendo via DERP cuando el UDP hole punching no puede completarse. Las causas habituales son una NAT que el hole punching no puede atravesar (CGNAT o una NAT simétrica que asigna un puerto nuevo para cada destino) y un firewall que bloquea el UDP saliente. Corrija lo que esté bajo su control: permita que el UDP saliente use el puerto 41641 hacia cualquier puerto de destino, permita el UDP saliente hacia el puerto 3478 o coloque un par en un VPS con el UDP 41641 entrante abierto, para que el hole punching del otro lado tenga un destino fijo y accesible. Un par cuya propia red bloquee el UDP seguirá usando un relay en cualquier caso.