Nested SSH session with Paramiko

后端 未结 5 953
眼角桃花
眼角桃花 2020-11-27 03:42

I\'m rewriting a Bash script I wrote into Python. The crux of that script was

ssh -t first.com \"ssh second.com very_remote_command\"

I\'m

相关标签:
5条回答
  • 2020-11-27 03:53

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

    0 讨论(0)
  • 2020-11-27 03:58

    For a ready made solution check out pxssh from the pxpect project. Look at the sshls.py and ssh_tunnel.py examples.

    http://www.noah.org/wiki/Pexpect

    0 讨论(0)
  • 2020-11-27 04:03

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

    import paramiko as ssh
    
    class 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 -a
    host = ('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')
    
    0 讨论(0)
  • 2020-11-27 04:12

    Sinas's answer works well but didn't provide all the output from very long commands for me. However, using chan.makefile() allows me to retrieve all the output.

    The below works on a system that requires tty and also prompts for sudo password

    ssh = paramiko.SSHClient()
    ssh.load_system_host_keys()
    ssh.set_missing_host_key_policy(paramiko.WarningPolicy())
    ssh.connect("10.10.10.1", 22, "user", "password")
    chan=ssh.get_transport().open_session()
    chan.get_pty()
    f = chan.makefile()
    chan.exec_command("sudo dmesg")
    chan.send("password\n")
    print f.read()
    ssh.close()
    
    0 讨论(0)
  • 2020-11-27 04:13

    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', buff
    
    ssh.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. :)

    0 讨论(0)
提交回复
热议问题