Blog

Juega en tu servidor en la nube desde cualquier lugar con Moonlight y Tailscale

Sin IPv6 en casa y sin abrir puertos: conectamos Moonlight a un servidor Sunshine en la nube a través de una red Tailscale (probado con Headscale): conexión directa, 1080p 60 fps, 0 fotogramas perdidos y los mismos 7,3 a 7,8 ms de procesamiento en el servidor que sin Tailscale.

Juega en tu servidor en la nube desde cualquier lugar con Moonlight y Tailscale

Nuestros servidores son accesibles por IPv6 por defecto. Muchas conexiones domésticas tienen IPv6, pero no todas: algunas redes móviles, el Wi-Fi de los hoteles y los routers antiguos solo tienen IPv4. Puedes añadir una IPv4 dedicada a tu servidor (5 € al mes), pero hay otra forma que además mantiene los puertos de Sunshine cerrados a Internet: Tailscale. Crea una red privada y cifrada (una «tailnet») entre tus dispositivos, basada en WireGuard. Tu servidor y tu móvil reciben cada uno una dirección 100.x.y.z, y Moonlight se conecta a esa dirección como si ambos estuvieran en casa.

Un juego transmitido por Sunshine a Moonlight a través de la dirección de la tailnet (5 segundos, estadísticas de rendimiento de Moonlight arriba a la izquierda).

Resultados de un vistazo

  • Funciona con el cliente oficial de Tailscale en ambos lados: conexión directa entre las dos máquinas (tailscale ping: pong via 203.0.113.10:41641 in 1ms), Moonlight en 100.x.y.1.
  • Tailscale no cuesta nada medible en el stream: pruebas alternas con y sin Tailscale dieron los mismos 1080p 60 fps, 7,3 a 7,8 ms de procesamiento en el servidor por ambas vías, 0 fotogramas perdidos.
  • Sunshine queda cerrado a Internet: sus puertos solo aceptan conexiones que llegan por la tailnet. Solo se usa el túnel; no hay que abrir nada en tu router.
  • Poco coste de CPU: el servicio de Tailscale usaba entre el 3 y el 4 % de un núcleo en el servidor mientras transmitía 1080p a 15 Mbit/s.

Dos formas de tener una tailnet

Cuenta de TailscaleHeadscale
Qué esEl propio servicio de Tailscale gestiona tu red (plan Personal gratuito)Servidor de control de código abierto que alojas tú mismo
Software clienteapps oficiales de Tailscalelas mismas apps oficiales de Tailscale
Puesta en marchainiciar sesión en cada dispositivoinstalar Headscale, crear claves, apuntar cada dispositivo a él
Accesibilidadsiempre accesibleHeadscale debe ser accesible desde todos tus dispositivos

La vía normal es una cuenta de Tailscale: instala Tailscale en el servidor y en tus dispositivos, inicia sesión con la misma cuenta y listo. En nuestra prueba usamos Headscale en su lugar, porque no queríamos crear una cuenta para una prueba: es un servidor de código abierto que cumple la misma función que el servicio de coordinación de Tailscale. La red en sí es la misma: ambas máquinas usaban el cliente oficial de Tailscale (versión 1.104.5), que construye los mismos túneles WireGuard sea cual sea el servidor de control con el que hable.

Configuración de la prueba

ElementoValor
ServidorDebian 13, Intel UHD 770 (GPU compartida), 4 vCPU, Sunshine 2026.914, RetroArch, sway sin pantalla
ClienteDebian 13, Moonlight 6.2, H.264 1080p 60 fps, decodificación por hardware
TailnetTailscale 1.104.5 en ambos, Headscale 0.29.7 en el servidor (.deb oficial de GitHub)
Redcliente y servidor en el mismo centro de datos: por Internet, suma la latencia de tu conexión

1. Instalar Tailscale en el servidor

Tailscale publica paquetes para Debian 13:

curl -fsSL https://pkgs.tailscale.com/stable/debian/trixie.noarmor.gpg \
  -o /usr/share/keyrings/tailscale-archive-keyring.gpg
curl -fsSL https://pkgs.tailscale.com/stable/debian/trixie.tailscale-keyring.list \
  -o /etc/apt/sources.list.d/tailscale.list
apt update && apt install tailscale

Con una cuenta de Tailscale, ejecuta tailscale up y abre el enlace que muestra para iniciar sesión. Después instala la app de Tailscale en tu ordenador, móvil o TV box e inicia sesión con la misma cuenta.

Con Headscale (lo que probamos), instala el servidor desde su release oficial de GitHub, ajusta server_url en /etc/headscale/config.yaml y luego crea un usuario y una clave:

headscale users create gamer
headscale preauthkeys create --user 1 --reusable --expiration 2h
tailscale up --login-server https://headscale.example.com --authkey <key> --hostname retro-server

El cliente se une con el mismo comando tailscale up --login-server … --authkey …. En nuestra prueba, Headscale escuchaba en la dirección privada del servidor, porque ambas máquinas estaban en el mismo centro de datos. Para un uso real, Headscale debe ser accesible desde todos tus dispositivos, por HTTPS: ejecútalo en una máquina con IPv4 pública (por ejemplo con la opción de IPv4 dedicada); si no, un dispositivo sin IPv6 no podrá alcanzarlo. Es la principal razón por la que una cuenta de Tailscale es más sencilla.

2. Comprobar la conexión

$ tailscale status
100.x.y.2  retro-client  gamer  linux  -
100.x.y.1  retro-server  gamer  linux  active; direct 203.0.113.10:41641, tx 750808 rx 128908072

$ tailscale ping 100.x.y.1
pong from retro-server (100.x.y.1) via 203.0.113.10:41641 in 1ms

direct significa que las dos máquinas se comunican sin relé. Por Internet, Tailscale también intenta conectar tus dispositivos directamente a través del router de tu casa (el servidor tiene IPv4 saliente para ello). Cuando no puede, el tráfico pasa por un relé de Tailscale («DERP»): sigue funcionando, pero añade latencia. tailscale status te dice cuál de los dos tienes.

Un ping normal a través del túnel tardaba 1,7 ms de media (0,8 ms en el mejor caso) frente a 0,36 ms sin Tailscale: el cifrado WireGuard añade bastante menos de un milisegundo, algo imperceptible al lado de la latencia de una conexión a Internet.

Gráfico de barras: ida y vuelta del ping sin Tailscale (0,36 ms) y a través de Tailscale (1,73 ms de media)
Ping entre las dos máquinas: 0,36 ms en directo, 1,73 ms de media por el túnel (0,79 ms en el mejor caso, un pico de 8,8 ms).

3. Mantener Sunshine cerrado a Internet

La gracia de la tailnet es que Sunshine no necesita ser accesible desde Internet. En el servidor, una pequeña tabla nftables descarta los puertos de Sunshine salvo en la interfaz tailscale0:

nft -f - <<'EOF'
table inet sunshine_tailnet_only {
  chain input {
    type filter hook input priority 0; policy accept;
    iifname "tailscale0" accept
    iifname "lo" accept
    tcp dport { 47984, 47989, 47990, 48010 } drop
    udp dport 47998-48010 drop
  }
}
EOF

Lo comprobamos desde el cliente: el puerto 47989 de Sunshine ya no respondía en la dirección normal del servidor, y respondía (HTTP 200) en 100.x.y.1. Para emparejar Moonlight, abre la interfaz web de Sunshine a través de un túnel SSH (ssh -L 47990:localhost:47990 you@100.x.y.1).

4. Jugar: Moonlight en la dirección 100.x

En Moonlight, añade el servidor por su dirección en la tailnet (aquí 100.x.y.1), emparéjalo e inicia un juego. Moonlight reconoció el servidor que ya conocía y se conectó sin ningún otro ajuste. La interfaz de la tailnet tiene un tamaño de paquete menor (MTU de 1280 bytes); no tuvimos que cambiar nada en Moonlight por ello.

Para ver si Tailscale cambia algo, transmitimos el mismo juego cuatro veces, alternando la dirección normal del servidor y su dirección en la tailnet:

Moonlight, 1080p 60 fps H.264Sin TailscaleA través de Tailscale
Tasa de fotogramas recibida60,0 a 60,4 fps60,0 fps
Procesamiento en el servidor (captura + codificación), media7,5 a 7,8 ms7,3 a 7,4 ms
Procesamiento en el servidor, máx10,4 a 10,6 ms10,5 a 10,8 ms
Fotogramas perdidos por la red o por jitter0 %0 %
Tiempo de decodificación en el cliente0,23 ms0,24 a 0,25 ms
Gráfico de barras: procesamiento por fotograma en el servidor en cuatro pruebas alternas, directo y a través de Tailscale
Cuatro streams del mismo juego, alternando la dirección directa y la de Tailscale: de 7,3 a 7,8 ms de media en ambos casos.
Moonlight transmitiendo un juego desde el servidor en la nube a través de la dirección de Tailscale, con sus estadísticas de rendimiento
A través de la tailnet: 60 fps, 7,3 ms de procesamiento en el servidor de media, ningún fotograma perdido.

En el servidor, durante el stream, el servicio de Tailscale usaba entre el 2,8 y el 4,2 % de un núcleo, Sunshine entre el 13 y el 17 % y el emulador entre el 3 y el 4 %. En dos pruebas anteriores, hechas mientras otros servidores de prueba usaban intensamente la misma GPU, el procesamiento en el servidor subió a 21 a 27 ms de media: eso se debía a que la GPU estaba compartida en ese momento, no a Tailscale, como muestran las pruebas alternas de arriba.

Gráfico de barras: CPU del servidor durante el streaming a través de Tailscale para Sunshine, tailscaled y RetroArch, en porcentaje de un núcleo
CPU del servidor durante un stream 1080p por el túnel, en porcentaje de un núcleo: el servicio de Tailscale cuesta menos que el emulador.

5. ¿Qué plan?

Tailscale en sí no necesita casi nada. Lo que importa es el juego: iGPU Start (2 vCPU, 8 GB de RAM, 14,99 € al mes sin IVA) basta para consolas retro; para juegos de PC recomendamos iGPU Power (4 vCPU, 14 GB de RAM, el doble de cuota de GPU que Start, 29,99 € al mes sin IVA).

¿Lo quieres listo para jugar? Pídelo por correo al hacer el pedido (contact@linuxgpu.eu): podemos entregarte el servidor con Sunshine, el lanzador de tus juegos y Tailscale ya instalados (en el lado del servidor). Tú instalas Moonlight y la app de Tailscale en tus propios dispositivos.

Lo que puedes ejecutar en él: retro gaming con RetroArch, Sunshine y Moonlight, Windows 11 en la nube con Sunshine y Moonlight y juegos de Windows en Linux con Wine.

Sistemas listos para jugar desde el primer momento. Los sistemas que instalamos por defecto ya están optimizados para ello: Debian 13 con un kernel reciente (7.3), los drivers de GPU de Intel y Mesa (OpenGL, Vulkan, codificación de vídeo VA-API), y Windows 11 (opción) con el driver gráfico de Intel y el Escritorio remoto renderizado en la GPU. Sin buscar drivers: instala tu juego y Sunshine, y a jugar.

Pruébalo

Ver los planes: la opción de IPv4 dedicada cuesta 5 € al mes, pero con Tailscale no la necesitas para jugar.