
¿Por qué OpenSSH_8.4p1 finaliza otras sesiones que comparten la misma conexión cuando se utiliza ProxyCommand? ¿Hay alguna manera de prevenir esto?
Nota: Este comportamiento no parece ocurrir si se omite el argumento ProxyCommand.
Pasos para reproducir:
- Elimine cualquier conexión compartida existente con localhost:
ssh -o ControlPath=/tmp/%C -O exit 127.0.0.1 2>/dev/null
ssh -o ControlPath=/tmp/%C -O exit localhost 2>/dev/null
- Ejecute el siguiente comando dos veces en paralelo cada una en una terminal diferente:
ssh -F none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
-o ControlMaster=auto -o ControlPath=/tmp/%C -o ControlPersist=1d \
-o ProxyCommand='ssh -W %h:%p 127.0.0.1' \
localhost 'sleep 3600'
- Interrumpa el primer proceso ssh con SIGINT escribiendo control-C.
Comportamiento esperado
- Sólo finaliza el proceso SIGINT.
- Otros procesos continúan ejecutándose sin verse afectados.
Comportamiento real
- Ambos procesos se dan por finalizados.
Respuesta1
Sólo finaliza el proceso SIGINT.
"Proceso" es una premisa falsa. Ctrl+C envía SIGINT
al proceso de primer planogrupode la terminal. Un grupo de procesos puede incluir más de un proceso.
Entonces esto es relevante:
ProxyCommand
Especifica el comando que se utilizará para conectarse al servidor. La cadena de comando se extiende hasta el final de la línea y se ejecuta utilizando laexec
directiva de shell del usuario para evitar un proceso de shell prolongado.
[…]
(fuente)
El comando se ejecuta localmente en el mismo grupo de procesos que el main ssh
. En su ejemplo el comando es ssh …
pero en general puede ser cualquier cosa. En cualquier caso, el comando no lo conoce ControlMaster
y ControlPersist
lo usó para el main ssh
.
Cuando presionas Ctrl+ C, cada proceso en el grupo de procesos de primer plano obtiene SIGINT
. El "principal" ssh
sale sin afectar el socket en el ControlPath
porque en caso de que ControlPersist
no sea no
este socket es manejado desde el principio poraún otra ssh
proceso que se genera deliberadamente en su propio grupo de procesos, esto le permite sobrevivir. En este contexto se le puede llamar el verdaderamente principal ssh
.
El comportamiento inesperado se debe a que el comando especificado con ProxyCommand
se genera en el grupo de procesos de primer plano y se lleva SIGINT
bien con el ssh
que desea interrumpir. El comando reacciona a la señal como lo haría normalmente. En su caso, el comando termina en SIGINT
. Y debido a que se suponía que el comando transmitiría todos los datos, la conexión maestra (la verdaderamente principal ssh
) ahora es inútil. Termina junto con todos ssh
los procesos dependientes.
Por lo tanto, el original ssh
realiza un trabajo adicional para garantizar que ssh
el manejo de la conexión maestra (y el socket) sobreviva Ctrl+ C, pero no lo hace para el comando especificado, ProxyCommand
que es igualmente importante. Creo que puedes llamarlo error.
Probablemente sería mejor si el comando especificado en fuera ProxyCommand
generado por el inmune ssh
enesgrupo de proceso. No he analizado esto lo suficientemente a fondo. De todos modos, por ahora no es el caso, el comando se genera en el grupo de procesos que es el grupo de procesos en primer plano en el momento en que presionas Ctrl+ C, por lo que obtiene SIGINT
.
Una solución alternativa es hacer que el comando sea inmune a SIGINT
. Por dentro ProxyCommand
no se puede usar trap
directamente porque ProxyCommand
se usa exec
automáticamente, exec trap …
no tiene sentido y no funciona. Necesitas otro caparazón:
ssh -F none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
-o ControlMaster=auto -o ControlPath=/tmp/%C -o ControlPersist=1d \
-o ProxyCommand='sh -c "trap \"\" INT; exec ssh -W %h:%p 127.0.0.1"' \
localhost 'sleep 3600'
Mis pruebas indican que ser inmune a SIGINT
no impedirá que este interno ssh
salga cuando llegue el momento y la conexión maestra finalice debido a la ControlPersist
configuración finita.