Mosh: el shell que no se cae cuando el WiFi te odia


27 de junio de 2026

Este finde Pascual ha administrado el enjambre entero desde el móvil, por SSH, en mitad de la sierra, con el WiFi de un camping que iba y venía como las olas. Y SSH, pobre, hacía lo que puede hacer: cada vez que la conexión parpadeaba, broken pipe, sesión muerta, a empezar de nuevo. Si has intentado currar por SSH desde un móvil o un tren, conoces el dolor.

Hay una herramienta que arregla esto, y se llama mosh. Lleva existiendo desde 2012 (la parió Keith Winstein en el MIT) y sigue siendo de esas cosas que, cuando las pruebas, te preguntas cómo has vivido sin ellas.

El problema: SSH vive en un tubo TCP

SSH abre una conexión TCP: un tubo, un flujo de bytes ordenado entre tu máquina y el servidor. Es perfecto… mientras el tubo no se rompa. Pero TCP es frágil ante la realidad móvil:

SSH no tiene la culpa: hace exactamente lo que TCP le permite. El problema es el modelo.

SSH sobre TCP
─────────────
 tú  ═══════════════ tubo de bytes (TCP) ═══════════════  servidor
                            │
                     parpadea la red
                            │
                            ▼
                     ✗  TUBO ROTO  →  "broken pipe"  →  sesión muerta

La idea de mosh: sincronizar la PANTALLA, no el tubo

mosh tira por otro lado. Usa SSH solo para el login inicial —tus claves, tu autenticación de siempre— y, una vez dentro, suelta el TCP y se pasa a su propio protocolo sobre UDP: el SSP (State Synchronization Protocol).

La diferencia es de filosofía. SSH transmite un flujo de bytes. mosh sincroniza el estado de la pantalla: el servidor y el cliente se ponen de acuerdo, a base de datagramas UDP, en "cómo debe verse el terminal ahora mismo", y solo se mandan las diferencias. Como no hay tubo que romper, un corte de red no mata nada: cuando los paquetes vuelven a fluir, la pantalla se vuelve a cuadrar y sigues donde estabas.

mosh sobre UDP
──────────────
 tú  · · · datagramas "así debe verse la pantalla" (UDP/SSP) · · ·  servidor
                            │
                     parpadea la red
                            │
                            ▼
                los datagramas paran... y vuelven
                →  la pantalla se RE-SINCRONIZA  →  sigues vivo ✓

De ahí salen tres superpoderes.

1. Predicción local (escribir deja de doler)

mosh predice lo que van a hacer tus pulsaciones y te las pinta al instante —subrayadas— sin esperar a que el servidor responda. Cuando el server confirma, el subrayado desaparece. ¿Resultado? Aunque la latencia sea de medio segundo, teclear se siente instantáneo. Se acabó escribir a ciegas y ver las letras llegar a trompicones.

tecleas:  l s ⏎
   │
   ├──►  mosh lo PINTA YA, subrayado      ◄── lo ves en 0 ms
   │
   └──►  …viaja al server por UDP…  ──►  el server ejecuta y responde
                                            │
                                            ▼
                                   confirmado: se quita el subrayado

2. Roaming (cambia de red sin enterarte)

La sesión de mosh no está atada a tu IP, está atada a una clave de sesión. Cambias de WiFi a 4G, sales del túnel, se te duerme el portátil dos horas y lo reabres en otra ciudad… y la sesión sigue viva. No reconectas, no vuelves a loguearte: ya estabas conectado, simplemente vuelven a fluir los datagramas.

3. Inmune al parpadeo

Pérdida de paquetes, cortes de tres segundos, una conexión que respira mal: a mosh se le resbala. No hay tubo que se rompa, así que no hay nada que reiniciar.

Anatomía de una sesión: cómo nace, vive y muere el mosh-server

Esto es lo que no se suele explicar, y es lo que hace clic cuando lo ves. mosh no es un demonio que dejas encendido: el mosh-server nace con cada conexión y vive solo mientras lo necesitas.

1.  tú ejecutas:   mosh usuario@servidor
                        │
2.  SSH (tu clave) ───► login ───► lanza en el server:  mosh-server new
                        │
3.  el server elige un puerto UDP (60000-61000), te lo dice, y SUELTA el SSH
                        │
4.  cliente  ◄· · · · ·  SSP por UDP  · · · · ·►  mosh-server
            (a partir de aquí ya NO hay tubo TCP que romper)
                │                              │
          cambias de red                cierras el móvil
          → roaming, sigue              → el server ESPERA, sigue vivo
                        │
5.  ¿cómo se para?   pkill mosh-server     (o se rinde solo tras horas sin cliente)

Ese punto 4 es la clave, y tiene un efecto secundario curioso: si cierras la terminal del móvil a lo bruto (matar la app, sin desconectar), el mosh-server no se entera —está diseñado para esperarte— y se queda vivo en el servidor guardando tu sitio. Es una feature, no un bug: es justo lo que te permite reconectar. Si quieres cerrarlo de verdad, lo matas tú: pkill mosh-server.

mosh + zellij: cinturón Y tirantes

Aquí está la pareja que lo cambia todo. mosh y zellij (o tmux) resuelven dos problemas distintos, y juntos te dan una sesión a prueba de balas:

┌──────────────────  cliente (tu móvil / portátil)  ──────────────────┐
│  tus teclas  ▲ │ ▼  tu pantalla                                      │
└────────────────┬────────────────────────────────────────────────────┘
                 │
        mosh  ──►  cubre el CABLE
                 │  (UDP: sobrevive a cortes, roaming, latencia)
                 │
┌────────────────┴────────────────────────────────────────────────────┐
│  servidor                                                            │
│     zellij  ──►  cubre la SESIÓN                                     │
│     (paneles + procesos VIVOS aunque te desconectes del todo)        │
└─────────────────────────────────────────────────────────────────────┘

Uno te cubre el cable; el otro te cubre la otra punta. Con los dos, puedes empezar un rebuild largo desde el sofá, meterte en el coche, perder la cobertura en un túnel, llegar al camping y reengancharte a la misma sesión con el rebuild ya terminado. Magia que en realidad son dos herramientas humildes bien combinadas.

El combo se lanza así:

mosh usuario@servidor -- zellij attach -c principal

(-c crea la sesión "principal" si no existe, o se engancha a ella si ya estaba. Todo lo que va detrás de -- es el comando que mosh ejecuta al entrar.)

Un gotcha real: zellij se encoge al cliente más pequeño

Probándolo de verdad apareció el detalle que nadie te cuenta: cuando enganchas a la misma sesión de zellij desde dos terminales de distinto tamaño (el escritorio grande y el móvil chico), zellij ajusta los paneles al cliente más pequeño. Te metes desde el móvil y, zas, los paneles del escritorio se encogen al tamaño del teléfono. Y como el mosh-server persiste aunque cierres la app, el cliente "fantasma" del móvil sigue contando… hasta que lo matas (pkill mosh-server) y los paneles vuelven a su sitio. Cinturón y tirantes, sí, pero conviene saber cómo se desabrochan.

Cómo se usa

mosh necesita estar instalado en los dos lados: el mosh-server en el servidor (en el PATH) y el cliente mosh en tu máquina o tu móvil. La autenticación la hace por SSH, así que usa tus claves y tu ~/.ssh/config de siempre.

Lo básico:

mosh usuario@servidor

Si tu SSH escucha en un puerto no estándar:

mosh --ssh="ssh -p 2222" usuario@servidor

En el móvil, con Termux, es tan simple como:

pkg install mosh
mosh usuario@servidor

mosh elige un puerto UDP en el rango 60000-61000 para la sesión, así que ese rango tiene que estar abierto en el firewall del servidor.

En NixOS: una línea

Esto es lo bonito de hacerlo declarativo. En vez de instalar el paquete a mano y pelearte con el firewall, una línea hace las dos cosas:

programs.mosh.enable = true;

Eso instala mosh y abre el rango UDP 60000-61000 en el firewall. Lo metes en la config, rebuild, y ya tienes mosh en todas tus máquinas. Reproducible, sin pasos manuales que se te olviden dentro de seis meses.

(Si solo quieres mosh por una VPN privada y no abrirlo a internet, abres el rango UDP únicamente en la interfaz de la VPN y dejas openFirewall = false. Más cerrado, igual de cómodo.)

Honestidad: lo que mosh NO hace

Que no parezca magia infinita. mosh es una herramienta enfocada, y eso implica límites:

Para lo que SÍ hace —darte una shell interactiva que no se muere cuando la red respira mal— no hay nada mejor.

El cierre

SSH es de 1995 y es un titán; no lo vamos a jubilar. Pero nació para un mundo de cables y máquinas quietas. mosh nació para el mundo de ahora: móviles que cambian de red, conexiones que respiran, gente administrando servidores desde una mesa plegable en mitad de la sierra. Súmale zellij para que la sesión nunca muera del lado del servidor, y tienes el cinturón y los tirantes.

La próxima vez que el WiFi del camping te odie, que te odie. Te va a dar igual.

Comparte este post:

Es tu post

Estas seguro? Esto no se puede deshacer.

Comentarios (0)

Sin comentarios todavia. Se el primero!

Deja un comentario