SSH para mecanizar a través de un host intermedio

En mi trabajo con mi profesor, tengo que ssh en nuestro servidor y desde allí ssh en cada nodo para ejecutar nuestros progtwigs. Estoy tratando de escribir un progtwig de python que me permita hacer todo lo que necesito hacer en el nodo remoto desde mi máquina local. Los comandos que ejecutaré en los nodos son:

  • Archivos cp de la máquina local a nodos remotos
  • ejecutar un progtwig en cada nodo
  • recuperar archivos de los nodos a mi máquina local
  • tal vez sea posible copiar un progtwig fortran y comstackrlo en los nodos y también comprobar los nodos para ver si hay algún progtwig en ejecución.

Ahora mismo hago mis archivos de entrada en mi máquina local, los extiendo al servidor, luego copio los archivos a cada nodo y ejecuto nuestro progtwig fluid_dynamics en cada nodo. Luego hago lo contrario para devolver nuestra salida a mi máquina local.

Estaba mirando paramiko pero no puedo averiguar cómo puedo usarlo para ir de mi máquina local a los nodos porque debo pasar por el servidor. local -ssh -> servidor -ssh -> nodos

¿Hay alguna manera de hacer esto en python o debería intentar algo más como: usando:

os.system(ssh -t server ssh node 'command') 

o hacer una secuencia de comandos bash en el servidor para cada uno de los diferentes comandos (compile.sh, move_inputs.sh, retrieve_outputs.sh) y luego simplemente conectarse al servidor y ejecutar las secuencias de comandos bash.

Lo siento si esto no tiene sentido o si está mal redactado, cualquier ayuda es apreciada.

Información adicional: la razón por la que estoy usando python es porque quiero que el progtwig pueda crear los archivos de entrada, enviarlos a los nodos y recuperar los archivos de salida, y finalmente generar gráficos de nuestros datos. Ya tengo algo de código para generar nuestros archivos de entrada y para hacer los gráficos a partir de las salidas.

No necesitas a Python para hacer esto. Verifique la opción de configuración de ProxyCommand para SSH . Aquí hay un tutorial que explica los detalles.

Con un truco de mi colega, puede ssh / scp de local a nodos directamente.

Edite su ~ / .ssh / config:

 Host * ControlMaster auto ControlPath ~/.ssh/master-%r@%h:%p Host node1 node2 or node* ProxyCommand ssh server 'nc -w 5 %h 22' 

¡Que te diviertas!

Puedes hacerlo con Paramiko:

 proxy_command = 'ssh -i %s %s@%s nc %s %s' % (proxy_key, proxy_user, proxy_host, host, 22) proxy = paramiko.ProxyCommand(proxy_command) client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(host, username=user, password=password, sock=proxy) stdin, stdout, stderr = client.exec_command('echo HELLO') print "Echo: %s" % (", ".join(stdout.readlines())) client.close() 

También funciona con SFTPClient :

 proxy_command = 'ssh -i %s %s@%s nc %s %s' % (proxy_key, proxy_user, proxy_host, host, 22) proxy = paramiko.ProxyCommand(proxy_command) transport = paramiko.Transport(proxy) transport.connect(username=user, password=password) sftp = paramiko.SFTPClient.from_transport(transport) 

Puede hacer esto creando un túnel a través de su servidor al nodo:

 import os, sys, shlex import subprocess import paramiko cmd = "ssh -f -N -p " + str(serverport) + " -l " + serveruser + " -L " + str(tunnelport) + ":" + nodehost + ":" + str(nodeport) + " " + serverhost args = shlex.split(cmd) tun = subprocess.Popen(args) stat = tun.poll() 

Una vez que el túnel está configurado, puede ftp a los nodos:

 transport = paramiko.Transport(("127.0.0.1", tunnelport)) transport.connect(username=nodeusername, password=nodepw) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(localfile, remotefile) 

O puede conectarse y ejecutar un comando usando paramiko.SSHClient (). Connect (“127.0.0.1”, puerto = puerto, nombre de usuario = usuario, contraseña = pw) y paramiko.SSHClient (). Exec_command (comando).

Entonces el proceso del túnel se puede matar así:

 p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE) out, err = p.communicate() for line in out.splitlines(): if cmd in line: pid = int(line.split(None, 1)[0]) os.kill(pid, signal.SIGKILL) 

Utilice plink root@10.112.10.1 -pw password ls -l

Descarga plink y cópialo en tu máquina windows.