Multiplexación SSH con ControlMaster y ControlPersist

Añade ControlMaster auto, ControlPath ~/.ssh/cm/%C y ControlPersist 10m a un bloque Host de ~/.ssh/config, y crea la carpeta con mkdir -m 700 ~/.ssh/cm. El primer ssh abre la conexión y los siguientes la reutilizan sin volver a autenticarse. ssh -O check server muestra si está activa y ssh -O exit server la cierra.

Actualizada el . Cliente OpenSSH 10.0 contra OpenSSH 10.0 en Debian 13, en contenedores desechables.

La configuración

mkdir -m 700 ~/.ssh/cm
Host server
  HostName example.com
  User user
  ControlMaster auto
  ControlPath ~/.ssh/cm/%C
  ControlPersist 10m
  • ControlMaster auto usa una conexión existente si la hay y, si no, abre una nueva que otras sesiones pueden compartir.
  • ControlPath es el archivo de socket que las sesiones usan para encontrar la conexión. %C es un hash del host local, el host remoto, el puerto, el usuario y el jump host, de modo que distintos accesos no se mezclan.
  • ControlPersist 10m mantiene la conexión abierta 10 minutos después de que termine la última sesión. Con no, el valor por defecto, la conexión vive dentro del primer ssh que abriste, que sigue abierto hasta que terminan todas las sesiones que la usan. Con yes, queda abierta hasta que la cierres.

En nuestra prueba, entre dos contenedores de la misma máquina, el primer ssh server true tardó 74 ms y el segundo 3 ms. El segundo se salta el intercambio de claves y la autenticación, así que tampoco aparece ninguna petición nueva de contraseña ni de frase de contraseña. En una red real el primer acceso es más lento, así que la diferencia es mayor.

El mismo bloque puede contener el resto de ajustes del host. Para más, consulta ejemplos del archivo de configuración de SSH.

Controlar la conexión

ComandoQué hace
ssh -O check serverMuestra Master running (pid=1534), código de salida 0
ssh -O conninfo serverMuestra las direcciones y los algoritmos de la conexión
ssh -O forward -L 8080:localhost:80 serverAñade un reenvío de puerto a la conexión abierta
ssh -O cancel -L 8080:localhost:80 serverQuita ese reenvío
ssh -O stop serverNo acepta sesiones nuevas, y las que están en marcha continúan
ssh -O exit serverCierra la conexión y todas las sesiones que lleva
ssh -S none serverAbre una conexión aparte e ignora la compartida

Cuando no hay nada en marcha, -O check termina con código 255:

Control socket connect(/home/user/.ssh/cm/936446a2...): No such file or directory

Límites y trampas

Todas las sesiones corren la misma suerte

Si la conexión muere, mueren todas las sesiones que lleva. En nuestra prueba, ssh -O exit terminó una sesión en marcha con código de salida 255. La secuencia de escape ~. también termina todas las sesiones de la conexión, como dice el propio ssh en su lista de ~?.

El servidor limita las sesiones por conexión

MaxSessions en sshd_config vale 10 por defecto. Abrimos 12 sesiones a la vez y las 2 últimas fallaron con:

mux_client_request_session: session request failed: Session open refused by peer

Esos comandos fallaron sin más. No recurrieron a una conexión nueva, así que los scripts que lanzan muchos comandos en paralelo necesitan un límite más alto o -S none.

La ruta del socket puede ser demasiado larga

Las rutas de los sockets Unix tienen un límite de longitud corto. Una ruta demasiado larga detiene la conexión:

unix_listener: path "/very/long/path/..." too long for Unix domain socket

Una carpeta corta con %C lo evita. El hash tiene una longitud fija, a diferencia de %r@%h:%p.

El socket da acceso sin autenticación

Cualquiera que pueda usar el archivo del socket puede abrir sesiones en tu conexión sin contraseña. Guárdalo en una carpeta donde solo tú puedas escribir, por eso ~/.ssh/cm tiene modo 700. El manual también lo advierte.

Los túneles de larga duración deben usar su propia conexión

Un reenvío iniciado a través de una conexión compartida pertenece al master. En nuestra prueba, con la multiplexación activada, un segundo ssh -f -N -o ExitOnForwardFailure=yes -R 2222:localhost:22 server sobre un puerto ya en uso devolvió código de salida 0. Sin multiplexación, el mismo comando mostró un error y devolvió 255. Para un túnel del que dependen scripts, añade -S none.

Un master terminado a la fuerza deja un socket obsoleto

Tras un kill -9 al master, el archivo del socket queda y -O check informa Connection refused. El siguiente ssh server normal funcionó en nuestra prueba y reemplazó el socket. Si alguna vez se atasca, borra el archivo de ~/.ssh/cm.

Preguntas

¿Es segura la multiplexación SSH?

Sí, si el socket está en una carpeta donde solo tú puedes escribir, como ~/.ssh/cm con modo 700. Cualquiera que pueda usar el socket puede abrir sesiones en tu conexión sin iniciar sesión.

¿ControlMaster funciona con el cliente OpenSSH de Windows?

El cliente OpenSSH que trae Windows no admite ControlMaster, porque depende de sockets de dominio Unix. Funciona en WSL.

¿Cómo cierro una conexión SSH compartida?

Ejecuta ssh -O exit con el nombre del host. Cierra la conexión y todas sus sesiones. ssh -O stop rechaza sesiones nuevas y deja terminar las que están en marcha.

Fuentes

Más en Configuración y muchos servidores

Todas las guías