2016-10-09 3 views
0

Kontext:
Ich versuche, zu einem Remote MySQL installieren über SSH und in Python zu verbinden. Ich benutze Paramiko und SSHTunnel, und derzeit auf Py 2.7.Python SSHTunnel w/paramiko - CLI funktioniert, aber nicht in Skript

Ich hatte Erfolg Verbindung und Abfrage von Datensätzen in der Remote-DB mit bash Shell, paramiko forward.py und sogar SSHTunnel CLI-Befehl.

Problem:
ich in Probleme laufen lasse, wenn diese über zu einem einzigen Skript zu migrieren versuchen, die den Tunnel erstellen, und die Ergebnisse abfragen. Das Problem scheint bei meiner Formatierung/Strukturierung der SSHTunnel-Syntax zu liegen.

Dies ist, was ich in den Tunnel auf der Schale öffnen:

ssh -p SSH_PORT [email protected]_IP -L 33060:127.0.0.1:3306 

Dies ist, was ich mit paramiko des forward.py öffnen verwenden:

python t_forward.py SERVER_IP:SSH_PORT -r 3306 -u SSH_USER -p 33060 -K "/PATH/TO/PRIVATE/KEY" 

Anmerkung: Ich bin zur Zeit einen Schlüssel ohne Passwort verwenden (zum Testen/dev Zwecke)

Dies ist, was ich mit SSHTunnel der Befehlszeile öffnen verwendet:

python -m sshtunnel -U SSH_USER -L :33060 -R 127.0.0.1:3306 -p SSH_PORT SERVER_IP -K "/PATH/TO/PRIVATE/KEY" 

Per oben funktionieren alle diese, und mein py-Skript, das MySQLdb verwendet, um eine Verbindung zur Datenbank herzustellen und Datensätze abzurufen, funktioniert.

Wo die Dinge zusammenbrechen ist, wenn ich versuche, die SSH-Verbindungszeichenfolge in das Skript hinzuzufügen. Dies ist, was es sieht derzeit wie:

con = MySQLdb.connect(user='MYSQLDBUSER',passwd='MYSQLDBUSERPASS',db='DATABASE',host='127.0.0.1', port=33060) 

Da ich bin in der Lage zu verbinden durch BASH und durch beide forward.py und SSHTunnel CLI es:

server = SSHTunnelForwarder(
    ('SERVER_IP', SSH_PORT), 
    ssh_username='SSH_USER', 
    ssh_pkey='/PATH/TO/PRIVATE/KEY', 
    remote_bind_address=('127.0.0.1', 3306), 
    local_bind_address=('0.0.0.0', 33060) 
) 

Die MYSQL Verbindungsleitung wie folgt aussieht scheint kein Problem auf dem Server zu sein, sondern eher, dass mein SSHTunnelForwarder nicht richtig formatiert ist.

Fehlermeldung:

Could not establish connection from ('127.0.0.1', 33060) to remote side of the tunnel 

am var Suchen/log/auth.log auf dem Server, ich sehe, dass es in der Lage ist, zu verbinden, scheint es nur zu brechen, wenn die MySQLDB.connect Kicks.

auth.log Nachrichten, wenn ich diesen Fehler:

Oct 9 17:36:31 HOSTSERVER sshd[21141]: Accepted publickey for SSH_USER from SOURCE_IP port 32918 ssh2: RSA <LONG KEY> 
Oct 9 17:36:31 HOSTSERVER sshd[21141]: pam_unix(sshd:session): session opened for user SSH_USER by (uid=0) 
Oct 9 17:36:31 HOSTSERVER systemd-logind[1217]: New session 144 of user SSH_USER. 
Oct 9 17:36:32 HOSTSERVER sshd[21141]: pam_unix(sshd:session): session closed for user SSH_USER 

auth.log Meldung, wenn ich die SSHTunnel CLI (und die Ergebnisse der Arbeit) verwenden:

Oct 9 17:39:33 HOSTSERVER sshd[21625]: Accepted publickey for SSH_USER from SOURCE_IP port 44132 ssh2: RSA <LONG KEY> 
Oct 9 17:39:33 HOSTSERVER sshd[21625]: pam_unix(sshd:session): session opened for user SSH_USER by (uid=0) 
Oct 9 17:39:33 HOSTSERVER systemd-logind[1217]: Removed session 144. 
Oct 9 17:39:33 HOSTSERVER systemd-logind[1217]: New session 145 of user SSH_USER. 

Es scheint, dass ich hier etwas sehr Grundlegendes vermisse ... Jede Hilfe wäre willkommen.

+0

"Blick auf die var/log/auth.log auf dem Server ..." Welche tatsächlichen Meldungen erscheinen in der Server-Side-Log im Zusammenhang damit? Bitte [bearbeiten] Sie Ihre Frage, um sie einzuschließen. – Kenster

+0

Danke Kenter. Ich habe die Ergebnisse aus dem Protokoll hinzugefügt. Das einzige, was anders ist, ist, dass in dem Fall, in dem es nicht funktioniert, die Verbindung schließt. Ich kann nicht sagen, ob das passiert, bevor der MySQLDB Connector versucht, sich mit der DB zu verbinden oder nicht. – mapboy

Antwort

1

Die Antwort gefunden!

Es stellt sich heraus, dass das Skript weiterhin ausgeführt wird, bevor die Verbindung hergestellt wird.Daher versucht MySQLDB, sich mit dem Port-Mapping zu verbinden, bevor der Tunnel vollständig eingerichtet ist.

Ein einfaches:

import time 
... 
sleep(1) 
... 

funktioniert der Trick.

In meinem Fall habe ich den Schlaf (1) nach "server.start()" und vor dem Code, der auf die Remote-DB zugreifen muss hinzugefügt.

Danke an @kenster, der mich dazu gebracht hat, genauer auf den auth.log zu schauen, was mich dazu brachte, genauer über das Timing nachzudenken.

Verwandte Themen