Je dois transférer vers plusieurs ports qui se trouvent derrière un serveur

server1(22) -> Server2(mysql, 3360) = local 3360
            -> Server3(http, 8080)  = local 8080
            -> Server4(oracle,1234) = local 1234

Je ne peux accéder qu'à Server2,3 et 4 via server1.

J'utilise le package Python ssltunnel https://pypi.org/project/sshtunnel/

Dans les exemples 1 et 2, je ne peux spécifier qu'une seule adresse de liaison distante et locale. Je ne sais pas comment connecter plusieurs serveurs (2,3,4)

Exemple 1

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()

Exemple 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!')

Je pourrais utiliser n'importe quel autre package Python pouvant faire le travail.

2
learner2017 6 févr. 2020 à 11:19

1 réponse

Meilleure réponse

Les deux exemples peuvent être légèrement modifiés pour fonctionner comme vous le souhaitez.

Il existe les versions singulières des liaisons (local_bind_address & remote_bind_address) et les versions plurielles des liaisons (local_bind_addresses & remote_bind_addresses.

Les versions singulières attendent un tuple contenant des variables pour les connexions, tandis que les versions plurielles attendent un list d'un ou plusieurs tuple(s).

Voici une version modifiée de votre exemple 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()

Si les longueurs des listes sont de la même longueur, alors les adresses IP / ports correspondront les uns aux autres.

Dans mon exemple ci-dessus, il se passe ce qui suit :

Connexion : 172.16.0.1 Port : 80, est tunnelisé via : 127.0.0.1 Port : 1180

Connexion : 172.16.0.2 Port : 22, est tunnelisé via : 127.0.0.1 Port : 10022

0
Hampus Larsson 6 févr. 2020 à 09:33