Nested SSH session with Paramiko Nested SSH session with Paramiko python python

Nested SSH session with Paramiko


I managed to find a solution, but it requires a little manual work. If anyone have a better solution, please tell me.

ssh = paramiko.SSHClient()ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect('first.com', username='luser', password='secret')chan = ssh.invoke_shell()# Ssh and wait for the password prompt.chan.send('ssh second.com\n')buff = ''while not buff.endswith('\'s password: '):    resp = chan.recv(9999)    buff += resp# Send the password and wait for a prompt.chan.send('secret\n')buff = ''while not buff.endswith('some-prompt$ '):    resp = chan.recv(9999)    buff += resp# Execute whatever command and wait for a prompt again.chan.send('ls\n')buff = ''while not buff.endswith('some-prompt$ '):    resp = chan.recv(9999)    buff += resp# Now buff has the data I need.print 'buff', buffssh.close()

The thing to note is that instead of this

t = ssh.get_transport()chan = t.open_session()chan.get_pty()

...you want this

chan = ssh.invoke_shell()

It reminds me of when I tried to write a TradeWars script when I was a kid and gave up coding for ten years. :)


Here is a small example using paramiko only (and port forwarding):

import paramiko as sshclass SSHTool():    def __init__(self, host, user, auth,                 via=None, via_user=None, via_auth=None):        if via:            t0 = ssh.Transport(via)            t0.start_client()            t0.auth_password(via_user, via_auth)            # setup forwarding from 127.0.0.1:<free_random_port> to |host|            channel = t0.open_channel('direct-tcpip', host, ('127.0.0.1', 0))            self.transport = ssh.Transport(channel)        else:            self.transport = ssh.Transport(host)        self.transport.start_client()        self.transport.auth_password(user, auth)    def run(self, cmd):        ch = self.transport.open_session()        ch.set_combine_stderr(True)        ch.exec_command(cmd)        retcode = ch.recv_exit_status()        buf = ''        while ch.recv_ready():            buf += ch.recv(1024)        return (buf, retcode)# The example below is equivalent to# $ ssh 10.10.10.10 ssh 192.168.1.1 uname -a# The code above works as if these 2 commands were executed:# $ ssh -L <free_random_port>:192.168.1.1:22 10.10.10.10# $ ssh 127.0.0.1:<free_random_port> uname -ahost = ('192.168.1.1', 22)via_host = ('10.10.10.10', 22)ssht = SSHTool(host, 'user1', 'pass1',    via=via_host, via_user='user2', via_auth='pass2')print ssht.run('uname -a')


You can create ssh connection using channel from another ssh connection. See here for more detail.