How create port forwarding using SSHtunnelForwarder?

Question:

I am trying to replicate: ssh -i [KEY] -L [FROM_PORT]:localhost:[TO_PORT] ubuntu@[REMOTE_SERVER_IP] in python and decided to use sshtunnel for it. The command given above works and I can connect to the remote Theia IDE, but I can’t figure out how I need to configure SSHtunnelForwarder to achieve the same from within python. I am probably misunderstanding its documentation: https://github.com/pahaz/sshtunnel

EDIT: This code is faulty. Look for an answer below.

    # I replaced the remote-ip with `123.45.67.89`.
    # I replaced my ip with `987.65.43.21`.
    with SSHTunnelForwarder(
        ssh_address_or_host="123.45.67.89",  # ip of remote server
        ssh_pkey="PRIVATE_KEY", # I am unsure which one is needed tried both
        ssh_private_key="PRIVATE_KEY", # I am unsure which one is needed tried both
        ssh_username="ubuntu",  # username of remote server
        ssh_bind_address= ("127.0.0.1", 9191),  # where to listen locally
        remote_bind_address= ("127.0.0.1", 8181)  # where to send info coming to 22
        # ssh-port 22 (default port)
        # localhost:9191 -> 123.45.67.89:22 -> localhost:8181
        # which is basically 987.65.43.21:9191 -> 123.45.67.89:22 -> 123.45.67.89:8181
    ) as server:
        server.start()

But when I try to connect to http://localhost:9191/ I receive unable to connect; so the tunneling is probably broken. I added plenty of comments to the code to make it easier to spot my misunderstanding.

Asked By: Natan

||

Answers:

When I run your code then I see error

ValueError: You can't use both 'ssh_private_key' and 'ssh_pkey'. Please only use one of them. 

You have to use one of them and example in your link show what it should be.

ssh_pkey="/var/ssh/rsa_key",

or

ssh_private_key_password="secret",

It needs to generate file rsa_key using program ssh-keygen which should be installed with ssh

(on Linux I would keep this file in user’s folder ~/.ssh)


Next I see error

ValueError: Unknown arguments: {'ssh_bind_address': ('127.0.0.1', 9191)} 

it has to be local_bind_address instead of ssh_bind_address.
Even example in your link uses local_bind_address.

You can see all arguments in commends in source code
or using help(SSHTunnelForwarder) in code.


This code works for me:

I can use pair username, password

    ssh_username = "pi",
    ssh_password = "raspberry",

or pair username and standard file id_rsa with my keys

    ssh_username = "pi",
    ssh_pkey='/home/furas/.ssh/id_rsa',  

Code:

from sshtunnel import SSHTunnelForwarder
import time

#import sshtunnel
#print('author :', sshtunnel.__author__)
#print('version:', sshtunnel.__version__)

#help(SSHTunnelForwarder)

with SSHTunnelForwarder(
    ssh_address_or_host = "192.168.1.29",  # Raspberry Pi in my network

    ssh_username = "pi",
    ssh_password = "raspberry",

    #ssh_username = "pi",
    #ssh_pkey='/home/furas/.ssh/id_rsa',  

    local_bind_address  = ("127.0.0.1", 9191),
    remote_bind_address = ("127.0.0.1", 8181)
) as server:
    print('Starting ...')
    server.start()

    print('Keep running ...')
    while True:
        time.sleep(1)
        
    #print('Stopping ...')
    #server.stop()
Answered By: furas