ManiAm
ManiAm

Reputation: 1851

Two step SSH local port forwarding using sshtunnel package

I am trying to open a bi-directional tunnel between host1 and host3 with host2 in the middle.

host1 <--> host2 <--> host3

Here is the (blocking) bash command I am running on host1 to forward port 51672.

ssh -g -L 51672:host2:51672 host2_username@host2 \'/tmp/sshpass -p host3_pass ssh -g -L 51672:host3:51672 host3_username@host3 \'\'"while true; do : ; sleep 5; done"\'\'\'

I have a script running on host3 listening to port 51672. When I create a TCP socket on host1 and connect to host2:51672, I can communicate with the script on host3 through that socket.

In the next step, I am trying to port this into python and use the sshtunnel package. I am a little bit confused which option in here is equivalent to my scenario.

Here is my first attempt:

import paramiko
import sshtunnel

with sshtunnel.open_tunnel(
        ssh_address_or_host=(host2, 22),
        ssh_username=host2_username,
        ssh_password=host2_pass,
        local_bind_address=('0.0.0.0', 51672),
        remote_bind_address=(host3, 22),
        block_on_close=False
) as tunnel1:
    log.info('Tunnel to host2 is established.')
    with sshtunnel.open_tunnel(
            ssh_address_or_host=('localhost', tunnel1.local_bind_port),
            ssh_username=host3_username,
            ssh_password=host3_password,
            remote_bind_address=(host3, 51672),
            block_on_close=False
    ) as tunnel2:
        log.info('Tunnel to host3 is established.')
        while True:
            time.sleep(1)

I can confirm that the tunnel is open from host1 to host2, because the following command returns 0 on host1.

nc -z localhost 51672

However, the tunnel between host2 and host3 seems to be not working.

Upvotes: 2

Views: 1580

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202504

The first step is to tunnel SSH. Then you tunnel your custom port.

Simpler to grasp approach (although not optimal) is:

  • Open direct SSH connection to host2.
  • Forward a local host1:A port via host2 connection to host3:22
  • Open SSH connection to host3 using the the forwarded port host1:A.
  • Forward another local host1:B port via host3 to host3:51672.
  • Connect to host1:B to get to host3:51672.

But you actually do not need to do the first physical port forwarding, you can use the sock approach as seen for example in Nested SSH using Python Paramiko.

(I believe that even your original ssh approach is unnecessarily complicated, with its two forwardings)

Upvotes: 1

Related Questions