У меня есть объект JSON, который выглядит так:
{UID_1:{
jumpboxes:[jump_ip1, jump_ip2,...],
hosts: [host_ip1, host_ip2,...],
...},
UID_2:{...
Аутентификация в полях для переадресации выполняется через Kerberos (без пароля), аутентификация для хостов - с паролем, а хосты видны только через хосты перескоков. Из списка IP-адресов я не знаю, какие из них работают, какие застряли или не отвечают, и т. Д., Поэтому мне нужно найти первый путь, который позволил бы мне открыть сеанс SSH.
Что я могу сделать, это проверить коды выхода при подключении к хостам перехода примерно так:
jumpip = ''
for i in json[uid][jumpboxes]:
if os.system('ssh {}@{}'.format(username,i))>0:
continue
else:
jumpip = i
break
Это дает мне первый рабочий IP-адрес Jumpbox без проблем, однако наличие пароля для установки ssh-соединения со вторым хостом не так легко проверить для кода выхода.
Существует несколько способов открыть туннель - либо с помощью os.system (), либо с помощью sshpass с прокси-сервером сеанса (что-то вроде:
if os.system('sshpass -p {} ssh -o ProxyCommand="ssh {}@{} nc {} 22" {}@{} -t {}'.format(password, user, jumpip, hosts[j], user, hosts[j], remote_cmd))>0:....
(для контекста давайте предположим, что команда sshpass будет выглядеть примерно так: sshpass -p Password123! -o ProxyCommand="ssh user@jumpbox nc hostip 22" user@hostip -t ll
или выполнение pint в подоболочке с чем-то вроде os.system('ssh user@jumpbox -t ping {} -c 5'.format(hosts[j]))
, и хотя ping возвращает код завершения, ICMP-эхо-ответы не означают, что я ' я могу открыть туннель (например, демон может застрять или мог произойти сбой и т. д.), или я могу сделать блок try-exc-else, который пытается открыть сессию ssh для удаленного хоста с помощью jumpbox с помощью pexpect или с subrpocess.popen и с передачей по каналу stdio, что позволяет мне нажать пароль и, если это не удается вызвать пользовательское исключение, но я не могу понять, как получить код выхода из клиента ssh, поэтому я могу проверить наличие статус ...
Ни один из них не является достаточно надежным для меня, поэтому я бы предпочел правильно перебирать IP-адреса, для которых я открыт для предложений.
Немного предыстории - туннель будет использоваться для запуска команды nohup-ed, а затем будет закрыт. Скрипт использует многопроцессорную обработку и пул для прохождения всей этой группы, поэтому я запустил их, а затем выполнил цикл, чтобы проверить их состояние и получить результат удаленного скрипта, выполненного на хостах. Я знаю, что os.system устарела, и мне следует использовать подпроцесс, но это не обязательно для варианта использования, поэтому меня это не особо волнует. Я ищу умный способ, как перебрать возможные пути, которые будут принимать, учитывая список с прыгуном с длиной n
и список с узлами с длиной m
и тайм-аут x
секунд максимум n*m*x
секунд чтобы выяснить, а вместо этого сократить это время.
Я также использую pexpect (который сам использует paramiko) для взаимодействия с удаленными хостами, как только я нашел правильные IP-адреса, с которыми мне нужно открыть туннель.
Заранее спасибо!