sshtunnel icon indicating copy to clipboard operation
sshtunnel copied to clipboard

using several bastions

Open patjlm opened this issue 7 years ago • 5 comments

Hello, Is it possible to setup a tunnel going through several chained bastions? It would be nice to support a list of (ip, port) in ssh_address_or_host

patjlm avatar Apr 18 '17 08:04 patjlm

Nope, you've to rely on ProxyCommand directives on your ssh config (i.e. ~/.ssh/config) for that.

fernandezcuesta avatar Apr 18 '17 08:04 fernandezcuesta

I was actually able to implement this by setting up a tunnel for each bastion. The target of the first tunnel is the second bastion, and so on, until the last tunnel which target is the real one. The bastion for each tunnel is then the local_address of the previous one After very qick tests, it seems to work properly. I was just wondering if that could be part of the standard sshtunnel.

Here is an extract of my start() code:

self.tunnels = []
for idx, info in enumerate(self.tunnel_info):
    # if we're not the first element, set the bastion to the local port of the previous tunnel
    if idx > 0:
        info['ssh_address_or_host'] = ('localhost', self.tunnels[-1].local_bind_port)
    # if we are the last element, the target is the real target
    if idx == len(self.tunnel_info) - 1:
        target = (self.target_ip, self.target_port)
    # else, the target is the next bastion
    else:
        if isinstance(self.tunnel_info[idx+1]['ssh_address_or_host'], tuple):
            target = self.tunnel_info[idx+1]['ssh_address_or_host']
        else:
            target = (self.tunnel_info[idx+1]['ssh_address_or_host'], 22)
    logger.debug('Setting up SSH tunnel: target = %s, settings = %s', target, info)
    self.tunnels.append(SSHTunnelForwarder(remote_bind_address=target, **info))
    self.tunnels[idx].start()
    logger.debug('  SSH tunnel bound to local port %d', self.tunnels[idx].local_bind_port)

And during the stop(), tunnels are being closed in the reverse order:

for tunnel in reversed(self.tunnels):
    logger.debug('Stopping SSH tunnel %s', tunnel.local_bind_address)
    tunnel.stop()

patjlm avatar Apr 18 '17 08:04 patjlm

Hello @patjlm - this looks very interesting. I find myself in a similar situation, needing to route through multiple bastion servers. Do you have a Pull Request that shows your proposed code changes, or are the complete code changes listed above?

jswager avatar May 13 '18 00:05 jswager

Hello @jswager - no I don't have a PR and I actually did not even read the sshtunnel code. The code extract above is what I did in my own software to solve my problem, using sshtunnel as is.

patjlm avatar May 13 '18 08:05 patjlm