0

J'ai besoin d'utiliser le transfert de port en Python pour communiquer avec une base de données MySQL distante via un tunnel SSH. J'ai téléchargé le paquet paramiko et essayé la démo de redirection de port (forward.py). Cela fonctionne très bien, mais j'ai du mal à l'intégrer dans mes propres scripts (similaire à celui ci-dessous). Lorsque la fonction de transfert principale est appelée, elle entre dans une boucle infinie et le reste de mon code ne s'exécute pas. Comment puis-je utiliser la démo forward.py et passer la boucle infinie?Comment puis-je éviter la boucle infinie lors de l'utilisation de la démo avant paramiko port?

Mon script:

import paramiko 
import forward 
import MySQLdb 
import cfg 
import sys 

client = paramiko.SSHClient() 
client.load_system_host_keys() 
client.set_missing_host_key_policy(paramiko.WarningPolicy()) 

try: 
    client.connect(cfg.remhost, cfg.remport, username=cfg.user, password=cfg.password) 
except Exception, e: 
    print '*** Failed to connect to %s:%d: %r' % (cfg.remhost, cfg.remport, e) 
    sys.exit(1) 


try: 
    forward.forward_tunnel(3306, cfg.remhost, 3306, client.get_transport()) 
except KeyboardInterrupt: 
    print 'C-c: Port forwarding stopped.' 
    sys.exit(0) 

try: 
    db = MySQLdb.connect('127.0.0.1', cfg.dbuser, cfg.dbpass, cfg.dbname) 
except Exception, e: 
    print 'Failed to connect to database' 
    sys.exit(1) 

try: 
    cursor = self.db.cursor(MySQLdb.cursors.DictCursor) 
    sql = 'SELECT * FROM ' + cfg.dbtable 
    cursor.execute(sql) 
    results = cursor.fetchall() 
    print str(len(results)) 
except Exception, e: 
    print 'Failed to query database' 
    sys.exit(1) 

Voici le morceau principal du code de démonstration forward.py:

class ForwardServer (SocketServer.ThreadingTCPServer): 
    daemon_threads = True 
    allow_reuse_address = True 


class Handler (SocketServer.BaseRequestHandler): 

    def handle(self): 
     try: 
      chan = self.ssh_transport.open_channel('direct-tcpip', 
                (self.chain_host, self.chain_port), 
                self.request.getpeername()) 
     except Exception, e: 
      verbose('Incoming request to %s:%d failed: %s' % (self.chain_host, 
                   self.chain_port, 
                   repr(e))) 
      return 
     if chan is None: 
      verbose('Incoming request to %s:%d was rejected by the SSH server.' % 
        (self.chain_host, self.chain_port)) 
      return 

     verbose('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(), 
                  chan.getpeername(), (self.chain_host, self.chain_port))) 
     while True: 
      r, w, x = select.select([self.request, chan], [], []) 
      if self.request in r: 
       data = self.request.recv(1024) 
       if len(data) == 0: 
        break 
       chan.send(data) 
      if chan in r: 
       data = chan.recv(1024) 
       if len(data) == 0: 
        break 
       self.request.send(data) 
     chan.close() 
     self.request.close() 
     verbose('Tunnel closed from %r' % (self.request.getpeername(),)) 


def forward_tunnel(local_port, remote_host, remote_port, transport): 
    # this is a little convoluted, but lets me configure things for the Handler 
    # object. (SocketServer doesn't give Handlers any way to access the outer 
    # server normally.) 
    class SubHander (Handler): 
     chain_host = remote_host 
     chain_port = remote_port 
     ssh_transport = transport 
    ForwardServer(('', local_port), SubHander).serve_forever() 


def verbose(s): 
    if g_verbose: 
     print s 
+1

OK, puisque personne ne semble vouloir répondre à cette question, mes nouvelles questions sont: Qu'en est-il de ma question originale qui est rebutante pour tout le monde? Que devrais-je changer pour que les gens réagissent réellement? Ai-je besoin de le reformuler ou d'ajouter plus d'informations? –

Répondre

1

Je pense que vous avez besoin du gestionnaire de code avant d'exécuter dans son propre fil et l'utilisation files d'attente pour communiquer avec lui.

Ou de sortir les appels pertinents et les choses qu'il est dans votre propre boucle. Hmmm, je ne suis pas sûr comment cela fonctionne exactement.

Voulez-vous que vos appels mysql fonctionnent dans votre programme ou à partir d'un programme différent?

+0

Merci pour votre réponse. On dirait que j'ai besoin d'apprendre à exécuter des threads en Python. Je n'ai pas besoin du script de transfert pour faire partie de mon script de base de données, et ils n'ont pas vraiment besoin de communiquer entre eux. Les appels de base de données sont envoyés à 127.0.0.1:3306, que le script de transfert transfère déjà au serveur distant. Je suis juste surpris que je ne peux pas trouver un exemple de ceci déjà posté quelque part. –

+0

J'ai essayé de le faire et je n'ai pas réussi à le faire fonctionner. C'est parce que mon hébergeur rejette la redirection de port. J'ai essayé de le faire en écrivant ma propre application qui s'exécute sur l'hôte distant après avoir créé une connexion SSH, mais je n'ai pas réussi à le faire fonctionner. J'ai reçu un peu de texte, mais il ne pouvait pas gérer correctement le serveur mysql. Désolé je ne peux pas être plus d'aide que j'ai arrêté de jouer avec les choses de Paramiko quand j'ai réalisé que mon hébergeur est un hôte partagé et bloque le transfert de port. – Demolishun

1

Je suis l'auteur en amont d'un module Pyhon appelé Python X2Go qui utilise fortement Paramiko pour la gestion de session SSH.

S'il vous plaît jeter un oeil au fichier forward.py dans le code: http://code.x2go.org/gitweb?p=python-x2go.git;a=blob;f=x2go/forward.py

Le code de Python X2Go utilise Python fortement gevent pour la communication client-serveur, la redirection de port, etc.

, Greets Mike

+1

Bienvenue dans Stack Overflow. S'il vous plaît lire notre [faq]. [S'il vous plaît ne pas poster des réponses qui ne sont qu'un lien] (http://stackoverflow.com/questions/how-to-answer): inclure du contenu utile dans votre message, et fournir le lien pour référence. Ici, pourriez-vous inclure du code (10-20 lignes serait génial) qui démontrent la redirection de port? – Gilles

Questions connexes