colgar procesos ssh iniciados desde un script

colgar procesos ssh iniciados desde un script

Estoy creando algunas máquinas virtuales mediante un script. Como parte de esto, estoy cambiando los nombres de las máquinas virtuales usando ssh. Por alguna razón, cuando ejecuto el siguiente comando para tres máquinas virtuales, funciona y para el número mágico al crear siete máquinas virtuales, el ssh se bloquea. ¿Alguien puede explicar el comportamiento?

parte del guión. Este script se ejecuta simultáneamente para X vms especificados.

...
ssh-keygen -f ~/.ssh/known_hosts -R $IP
ssh-keyscan $IP >> ~/.ssh/known_hosts
SSH="ssh -i $SSH_KEY -o PasswordAuthentication=no"

echo "hostname $hostname && 
    echo HOSTNAME=$hostname >> /etc/sysconfig/network && 
    echo 127.0.0.1 $hostname >> /etc/hosts " | ssh -i $SSH_KEY -o PasswordAuthentication=no root@IP
...

procesos ssh sin fin

rag       2867  2808  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm4
rag       2869  2812  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm7
rag       2872  2818  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm1
rag       2875  2811  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm6
rag       2879  2814  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm5
rag       2881  2813  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm3
rag       2884  2807  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm2

Tengo rastro de uno de los procesos en ejecución.

...
--- SIGTTOU (Stopped (tty output)) @ 0 (0) ---
rt_sigreturn(0x16)                      = -1 EINTR (Interrupted system call)
rt_sigaction(SIGALRM, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGHUP, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTERM, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTSTP, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTTOU, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
close(4)                                = 0
kill(2867, SIGTTOU)                     = 0
--- SIGTTOU (Stopped (tty output)) @ 0 (0) ---
--- SIGTTOU (Stopped (tty output)) @ 0 (0) ---
open("/dev/tty", O_RDWR)                = 4
rt_sigaction(SIGALRM, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGHUP, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGINT, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGPIPE, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGQUIT, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTERM, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTSTP, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTTIN, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTTOU, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(4, SNDCTL_TMR_CONTINUE or TCSETSF, {B38400 opost isig icanon echo ...}) = ? ERESTARTSYS (To be restarted)
...

Respuesta1

Esto suena como una condición de carrera y, al mirar tu guión, creo que veo dónde.

Según tengo entendido, tiene un script que contiene las siguientes 2 líneas (entre otras):

ssh-keygen -f ~/.ssh/known_hosts -R $IP
ssh-keyscan $IP >> ~/.ssh/known_hosts

Y luego inicias ese script varias veces.

Esta secuencia de eventos puede explicar su problema:

  1. Uno de los scripts se abre ~/.ssh/known_hostspara ejecutar el ssh-keygen -Rcomando. En este punto, el ssh-keygencomando lee todo el archivo en la memoria para poder eliminar la línea de destino.
  2. Otro script acaba de terminar de ejecutarse ssh-keyscany escribir la línea en el archivo.
  3. El proceso del primer script ssh-keygen(el del paso 1) comienza a escribir el archivo, pero debido a que leyó el archivo antes de que finalizara el paso 2, el archivo que está escribiendo no contiene la línea que agregó el paso 2. Entonces la línea del paso 2 se borra.
  4. El segundo script realiza la ejecución ssh, solo que la clave de host no está known_hostsdebido al problema mencionado en el paso 3. Entonces ssh se cuelga y quiere que el usuario confirme la clave.

Más detalles:
los programas en segundo plano no pueden leer desde la terminal; al intentar hacerlo, se envía a ese programa un SIGTTIN. Sin embargo, en su ruta, muestra que el programa obtiene un SIGTTOU. Normalmente, los programas en segundo plano pueden escribir en la terminal sin problemas; sin embargo, OpenSSH activa explícitamente una configuración de terminal llamada tostopque da como resultado este comportamiento. Yendo aún más lejos, OpenSSH tiene un controlador de señales en SIGTTOU (entre otros) que hace que el código OpenSSH entre en un bucle infinito hasta que usted pone el proceso en primer plano (en cuyo momento puede mostrar el mensaje y dejar de recibir señales).

Cómo quieres resolver esto es otra cuestión.

  • Una solución sería agregar bloqueo (hay una flockutilidad que puede usar) y bloquear el known_hostsarchivo antes de esas 2 líneas, y luego desbloquearlo una vez que hayan terminado.
  • Otra solución sería agregar la opción ssh StrictHostKeyChecking=no. Ya estás frustrando el propósito del known_hostsarchivo con esas 2 líneas del script, por lo que también puedes desactivarlo por completo.

información relacionada