HiI'mJaanus.Blog,Works.

Opening multiple SSH tunnels/portforwards with only one password prompt

Someone recently asked me “how can I open multiple SSH tunnels with only one password prompt?” And to make things more complicated, let’s assume that we only work with passwords, i.e we can’t use the PKI where public/private keys would do the authentication.

Now there’s a hard way and an easy way.

The hard way, is of course, to write a script. I knew of the “expect” utility that can interact with app prompts from things like SSH, but I haven’t really worked with the Tcl syntax and I couldn’t get it working. So I went with Python. There’s a very useful pexpect module that lets you do exactly what “expect” does, but in the familiar Python environment.

So here’s my script. Prompts for password only once and re-uses it in the subsequent tunnel setups.

#!/usr/bin/env python
# to run this, install http://pexpect.sourceforge.net/
import getpass
import pexpect
import time
tunnels = (
# some cvs server
'ssh -Nf -L2401:cvs.server:2401 me@my.forwardinghost.net',
# some sftp server
'ssh -Nf -L2222:somesftp.com:22 me@my.forwardinghost.net',
# another sftp server
'ssh -Nf -L2223:anothersftp.com:22 me@my.forwardinghost.net',
)
X = getpass.getpass('Password: ')
for t in tunnels:
    try:
        print "Opening " + t
        ssh_tunnel = pexpect.spawn (t)
        ssh_tunnel.expect ('Password:')
        time.sleep (0.1)
        ssh_tunnel.sendline (X)
        ssh_tunnel.expect (pexpect.EOF)
    except Exception, e:
        print str(e)

Now… this could of course be improved a lot. It’s actually a scaled-down version of a pexpect example script.

Oh, and the easier way… as you see, all those tunnels are using the same forwarding server. And when running ssh from the command line, you can give it multiple -L arguments, i.e multiple tunnels to create. So when going through the same forwarding server, just put the multiple -L arguments on the commandline and be done with it.

Comments