SSH к машине через средний хост - PullRequest
10 голосов
/ 16 июня 2011

В моей работе с моим профессором я должен подключиться к нашему серверу через ssh, а оттуда - через каждый узел ssh для запуска наших программ.Я пытаюсь написать программу на Python, которая позволит мне делать все, что мне нужно сделать на удаленном узле, с моей локальной машины.Команды, которые я буду выполнять на узлах:

  • cp файлы с локального компьютера на удаленные узлы
  • запуск программы на каждом узле
  • получение файлов изузлы на моем локальном компьютере
  • , возможно, позволяют копировать фортран-программу и компилировать ее на узлах, а также проверять узлы, чтобы увидеть, запущены ли какие-либо программы.

Сейчас я создаю свои входные файлы на своем локальном компьютере, копирую их на сервер, затем копирую файлы на каждый узел и запускаю нашу программу Fluid_dynamics на каждом узле.Затем я делаю обратное, чтобы вернуть наш вывод обратно на мою локальную машину.

Я смотрел на paramiko, но не могу понять, как я могу использовать его для передачи с моей локальной машины на узлы, потому что я должен идтичерез сервер.local -ssh -> server -ssh -> node

Есть ли способ сделать это в python или я должен попробовать что-то еще, например: using:

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

илискрипты bash на сервере для каждой из различных команд (compile.sh, move_inputs.sh, retrieve_outputs.sh), а затем просто подключитесь к серверу и запустите скрипты bash.

Извините, если этого не произойдетимеет смысл или, если он сформулирован плохо, любая помощь приветствуется.

Дополнительная информация: причина, по которой я использую python, заключается в том, что я хочу, чтобы программа могла создавать входные файлы, отправлять их на узлы и получать выходные файлы, и, наконец, генерировать графики наших данных.У меня уже есть некоторый код для генерации наших входных файлов и для построения графиков из выходных данных.

Ответы [ 5 ]

7 голосов
/ 16 июня 2011

Вам не нужен Python для этого.Проверьте параметр конфигурации ProxyCommand для SSH .Вот учебник , который объясняет детали.

5 голосов
/ 16 июня 2011

С трюком моего коллеги вы можете напрямую подключаться по ssh / scp к узлам.

Отредактируйте ~ / .ssh / config:

Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

Host node1 node2 or node*
ProxyCommand ssh server 'nc -w 5 %h 22'

Веселись!

4 голосов
/ 28 октября 2013

Вы можете сделать это с 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()

Работает с 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)
3 голосов
/ 15 ноября 2012

Вы можете сделать это, создав туннель через сервер к узлу:

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()

После настройки туннеля вы можете подключиться к узлам по ftp:

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

Или вы можете подключиться и выполнить команду с помощью paramiko.SSHClient (). Connect ("127.0.0.1", port = port, username = user, password = pw) и paramiko.SSHClient (). Exec_command (command).

Тогда туннельный процесс можно убить так:

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)
1 голос
/ 07 ноября 2011

Используйте plink root@10.112.10.1 -pw password ls -l

Загрузите plink и скопируйте его на свой компьютер с Windows

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...