Mosh: el shell que no se cae cuando el WiFi te odia
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:
- Si cambias de red (WiFi a datos), tu IP cambia y el tubo se rompe.
- Si se te duerme el móvil, el tubo expira.
- Si hay pérdida de paquetes, TCP se atasca esperando retransmisiones (el famoso head-of-line blocking): escribes y no aparece nada durante segundos.
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:
- mosh arregla el transporte: la conexión cliente↔︎servidor sobrevive a cortes, cambios de red y latencia.
- zellij arregla la sesión en el
servidor: aunque te desconectes del todo —se acabe la batería,
cierres el móvil, mosh se rinda tras horas—, tus paneles, tus procesos y
tu trabajo siguen vivos en el servidor, esperando a que reenganches con
zellij attach.
┌────────────────── 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@servidorSi tu SSH escucha en un puerto no estándar:
mosh --ssh="ssh -p 2222" usuario@servidorEn el móvil, con Termux, es tan simple como:
pkg install mosh
mosh usuario@servidormosh 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:
- No tiene scrollback propio. Solo sincroniza la pantalla visible; no puedes hacer scroll hacia arriba en el histórico. Por eso se usa con zellij/tmux, que te dan el scrollback (y la persistencia de sesión).
- No reenvía X11 ni hace túneles de puertos. Para un
ssh -Lossh -X, sigues necesitando SSH. mosh es para la shell interactiva, no para todo lo que SSH sabe hacer. - Necesita UDP. Si estás detrás de un firewall que solo deja salir el puerto 443, mosh no pasa. (Para el 99% de las redes, no es problema.)
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.
Comentarios (0)
Sin comentarios todavia. Se el primero!
Deja un comentario