python ssh in to a jumpserver and then ssh in to a host from the jumpserver to execute a command

StackOverflow https://stackoverflow.com/questions/17913540

  •  04-06-2022
  •  | 
  •  

Question

I want SSH to a jumpserver. From the jumpserver, I want SSH to a host and execute a command: 'rpm -qa | grep package' and get the output. Once done, I want successfully logout of the host first and then logout of the jump server.

Below is what I have tried thus far:

Import pexpect

options = '-q -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oPubkeyAuthentication=no'

child = pexpect.spawn('ssh ssheth@jumpserver %s'%(options), timeout=None)
child.expect(['password: '])
child.sendline('hello123')
child.expect('#')
child.sendline('ssh ssheth@host "rpm -qa | grep -v watch | grep extractor"')
child.expect(['password: '])
child.sendline(password)
child.logfile = fout
child.expect(".*\$ ", timeout=None)
child.close()

This throws the below exception:

Timeout exceeded in read_nonblocking().
<pexpect.spawn object at 0x7f007800d190>
version: 2.4 ($Revision: 516 $)
command: /usr/bin/ssh
args: ['/usr/bin/ssh', 'ssheth@jumpserver', '-q', '-oStrictHostKeyChecking=no', '-oUserKnownHostsFile=/dev/null', '-oPubkeyAuthentication=no']
searcher: searcher_re:
    0: re.compile("#")
buffer (last 100 chars): ssheth@jumpserver:~[ssheth@jumpserver ~]$ 
[ssheth@jumpserver ~]$ 
before (last 100 chars): ssheth@jumpserver:~[ssheth@jumpserver ~]$ 
[ssheth@jumpserver ~]$ 
after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 27286
child_fd: 91
closed: False
timeout: 2
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
Was it helpful?

Solution

Simplest answer is to open a port forwarding to the remote server.

This works best in bash, but you can subprocess, or whatever you prefer to run it through python.

Suppose the IPs are:

  • jumpserver IP is 151.121.121.121
  • finalserver IP is 10.1.2.3

Like follows

# Open a local port 13000 that will map through jumpserver and 
# connect to finalserver on port 22
ssh -L 13000:10.1.2.3:22 username@151.121.121.121
# Then open an ssh session to localhost:13000 (which will forward to the
# finalserver.com and run your command)
ssh username@localhost -p 13000 'rpm -qa | grep package'

Aside: looking at your expect script and remembering the old days. Python has some ssh wrappers. Paramiko is used with Fabric.

OTHER TIPS

You can install jumpssh pypi using pip

pip install jumpssh
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top