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
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? –