I need to forward to multiple ports which are sits behind a server
server1(22) -> Server2(mysql, 3360) = local 3360
-> Server3(http, 8080) = local 8080
-> Server4(oracle,1234) = local 1234
I can only access Server2,3, and 4 via server1.
I am using Python ssltunnel package https://pypi.org/project/sshtunnel/
In example1&2, I can only specify one remote&local bind address. Not sure how to connect multiple servers(2,3,4)
Example1
from sshtunnel import SSHTunnelForwarder
server = SSHTunnelForwarder(
'pahaz.urfuclub.ru',
ssh_username="pahaz",
ssh_password="secret",
remote_bind_address=('127.0.0.1', 8080)
)
server.start()
print(server.local_bind_port) # show assigned local port
# work with `SECRET SERVICE` through `server.local_bind_port`.
server.stop()
Example 2
import paramiko
import sshtunnel
with sshtunnel.open_tunnel(
(REMOTE_SERVER_IP, 443),
ssh_username="",
ssh_pkey="/var/ssh/rsa_key",
ssh_private_key_password="secret",
remote_bind_address=(PRIVATE_SERVER_IP, 22),
local_bind_address=('0.0.0.0', 10022)
) as tunnel:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('127.0.0.1', 10022)
# do some operations with client session
client.close()
print('FINISH!')
I could use any other Python package that can do the job.
Both examples can be modified slightly to work the way you want.
There is the singular versions of bindings (local_bind_address
& remote_bind_address
) and the plural versions of bindings (local_bind_addresses
& remote_bind_addresses
.
The singular verisons expects a tuple
containing variables for the connections, while the plural versions expects a list
of one or more tuple(s)
.
Here is a modified version of your example 2:
import paramiko
import sshtunnel
tunnels = [("172.16.0.1", 80),
("172.16.0.2", 22)]
localPorts = [("127.0.0.1", 1180),
("127.0.0.1", 10022)]
with sshtunnel.open_tunnel(
(REMOTE_SERVER_IP, 22),
ssh_username="",
ssh_pkey="/var/ssh/rsa_key",
ssh_private_key_password="secret",
remote_bind_addresses=tunnels,
local_bind_addresses=localPorts
) as tunnel:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('127.0.0.1', 10022)
# do some operations with client session
client.close()
If the lengths of the lists are the same length, then the IP-addresses / ports will correspond with each other.
In my example above, the following is happening:
Connection: 172.16.0.1 Port: 80, Is tunneled via: 127.0.0.1 Port: 1180
Connection: 172.16.0.2 Port: 22, Is tunneled via: 127.0.0.1 Port: 10022