Como mencioné en el capítulo 4 de la Biblia del SysAdmin ciertas tareas críticas (como migraciones de sistemas operativos, actualizaciones de aplicaciones críticas, y otros procesos sobre sistemas en producción) deben realizarse desde la terminal serie (ya sea virtual o un consola remota). Sin embargo, a veces no tenemos acceso a ninguna de las opciones (especialmente en tiempos de coronavirus y cuarentena donde los cortes en los enlaces de los proveedores de Internet parecen más frecuentes que nunca) y no nos queda otra opción que realizar una tarea crítica desde una sesión SSH. Pero ¿qué pasa si se corta el enlace o nuestra conexión y se cierra la sesión? Podríamos correr el riesgo de dejar el sistema en un estado inconsistente o desconocido.

Afortunadamente, la herramienta tmux permite crear sesiones persistentes que sobrevivan a cortes de red de duración indefinida. Puede ser una herramienta de gran ayuda para correr algunas tareas críticas sin riesgo (al menos aquellas que no involucren cambios en firewalls, o configuraciones o dispositivos de red.

Este artículo demuestra un ejemplo de uso de tmux para crear una sesión persistente en un servidor a través de SSH que sobreviva a desconexiones o cortes de red.

Ciertas aplicaciones provistas por terceros se actualizan mediante utilitarios específicos los cuales trabajan de forma interactiva. Suele ocurrir que, si se pierde el acceso al actualizador/instalador en una sesión interactiva, el sistema quede en un estado inconsistente que requiera recuperar el sistema desde un backup y comenzar nuevamente desde el principio. Algo extremadamente tedioso y terrible en cuanto a uptime respecta.

Este es un caso real en mi organización: ciertos sistemas en producción se actualizan mediante un instalador interactivo que, en caso de cerrarse la sesión, deja a la aplicación y su base de datos en un estado inconsistente que debe ser restaurado desde una copia de seguridad. Por otro lado cabe destacar que no es posible correrlo en testing y pasarlo a producción, ya que el actualizador hace cambios en los datos de la base de datos. A lo sumo se puede clonar toda la infraestructura y en caso de fallo borrar y volver a clonar. Pero este proceso demora más que recuperar desde un backup en caso de fallo (cosa que ha ocurrido), así que estamos "en la misma".

Lo que se suele hacer es correr estos procesos desde la terminal serie o desde una estación de trabajo en la misma red. Aunque no es necesario tomar tantos recaudos si se recurre a tmux.

tmux es un multiplexor de terminales: permite crear varias terminales accesibles y controladas desde una única pantalla. Pero además tiene la capacidad de ser removido de una pantalla (detach) y continuar corriendo en segundo plano, para luego ser reconectado a la pantalla. Muchos SysAdmins utilizan tmux a diario para mantener varias conexiones SSH a diferentes sistemas en una única vista. No es mi caso, personalmente me siento más cómodo con ventanas más grandes y múltiples tabs, en conjunto con scripts Bash y autenticación con clave pública. Sin embargo, esta capacidad de detach de una pantalla que tiene tmux puede resultar de extrema utilidad para no perder sesiones a causa de fallos de red.

A tal fin, es necesario instalar tmux en el servidor donde se ejecutarán tareas críticas:

# apt-get install tmux

Veamos un ejemplo de uso y funcionamiento:

Desde una terminal de XFCE (xfce4-terminal) estoy conectado por SSH a un servidor. Procedo a ejecutar tmux en la sesión remota (es decir, lanzar tmux en el servidor a través de SSH):

# tmux

Al lanzar tmux se observa una barra de estado en la parte inferior de la ventana, la cual muestra información de la sesión actual y es utilizada para ingresar comandos interactivos. En la sesión de tmux puedo ejecutar cualquier tipo de comandos como en una sesión Bash normal. A modo de ejemplo, lanzo ping cada 5 segundos para generar salida en la pantalla:

Ahora voy a emular un corte de red. Para ello, cierro la ventana para matar la conexión SSH sin salir de tmux:

La terminal me avisa que hay procesos en ejecución (el cliente SSH precisamente) y que al cerrarla serán terminados. Es precisamente lo que quiero: matar el cliente SSH.

Inmediatamente vuelvo a conectarme por SSH al servidor desde una nueva terminal:

Se observa que el proceso tmux quedó en ejecución, a pesar de haberse cerrado la sesión SSH. El comando tmux list-sessions permite listar las sesiones disponibles. Efectivamente se trata de la sesión que hemos dejado abierta previamente.

Para conectarse a una sesión existente, ejecutar el subcomando attach:

# tmux attach

Al recuperar la sesión previa, se comprueba que se recupera no sólo la salida antes de perder la conexión, sino toda la salida que se generó mientras no estábamos conectados a la sesión. Efectivamente la sesión quedó "viva" en segundo plano y es posible acceder a toda su salida.

De esto se trata una sesión persistente, resguarda la salida y se mantiene activa a pesar de no tener una pantalla asociada a la misma.

De esta forma es posible aprovechar tmux no tanto para multiplexar sesiones sino para mantener sesiones activas a pesar de probables cortes de red o enlaces.

Compartí este artículo