J'apprends le python. J'ai besoin de créateurs de tunnel pour lire les informations d'une base de données et fermer le tunnel. J'utilise paramiko mais je n'ai pas travaillé avec tonelem par exemple. s'il vous plaît donner un exemple d'un code simple crée un tunnel.
Merci d'avance!
Au travail, nous créons généralement des tunnels ssh transférant des ports. Pour ce faire, utilisez la commande standard ssh -L port:addr:port addr
avec un sous-processus s'exécutant dans un thread séparé ... J'ai trouvé ce lien utile: https://github.com/paramiko/paramiko/blob/master/demos/ forward.py avec un exemple de transfert de port avec paramiko.
J'ai utilisé sshtunnel
pour mes projets. Exemple de transfert du port MySQL local distant vers le port local de l'hôte:
pip install sshtunnel
python -m sshtunnel -U root -P password -L :3306 -R 127.0.0.1:3306 -p 2222 localhost
Même si cela n'utilise pas paramiko, je pense que c'est une solution très propre à implémenter (similaire à la réponse de @ dario mais sans gérer le fil en python).
Il y a cette fonctionnalité peu mentionnée dans le client openssh qui nous permet de contrôler un processus ssh via une socket Unix, en citant man ssh
:
-M Places the ssh client into “master” mode for connection sharing. Multiple -M options places ssh
into “master” mode with confirmation required before slave connections are accepted. Refer to the
description of ControlMaster in ssh_config(5) for details.
-S ctl_path
Specifies the location of a control socket for connection sharing, or the string “none” to disable
connection sharing. Refer to the description of ControlPath and ControlMaster in ssh_config(5)
for details.
Ainsi, vous pouvez démarrer le processus en arrière-plan de ssh
(avec -Nf
), puis le vérifier (ou y mettre fin) avec un autre appel ssh
.
J'utilise ceci dans un projet qui nécessite l'établissement d'un tunnel inverse
from subprocess import call, STDOUT
import os
DEVNULL = open(os.devnull, 'wb')
CONFIG = dict(
SSH_SERVER='ssh.server.com',
SSH_PORT=2222,
SSH_USER='myuser',
SSH_KEY='/path/to/user.key',
REMOTE_PORT=62222,
UNIX_SOCKET='/tmp/ssh_tunnel.sock',
KNOWN_HOSTS='/path/to/specific_known_Host_to_conflicts',
)
def start():
return call(
[
'ssh', CONFIG['SSH_SERVER'],
'-Nfi', CONFIG['SSH_KEY'],
'-MS', CONFIG['UNIX_SOCKET'],
'-o', 'UserKnownHostsFile=%s' % CONFIG['KNOWN_HOSTS'],
'-o', 'ExitOnForwardFailure=yes',
'-p', str(CONFIG['SSH_PORT']),
'-l', CONFIG['SSH_USER'],
'-R', '%d:localhost:22' % CONFIG['REMOTE_PORT']
],
stdout=DEVNULL,
stderr=STDOUT
) == 0
def stop():
return __control_ssh('exit') == 0
def status():
return __control_ssh('check') == 0
def __control_ssh(command):
return call(
['ssh', '-S', CONFIG['UNIX_SOCKET'], '-O', command, 'x'],
stdout=DEVNULL,
stderr=STDOUT
)
-o ExitOnForwardFailure=yes
s'assure que la commande ssh échouera si le tunnel ne peut pas être établi, sinon il ne se fermera pas.
J'ai utilisé paramiko
pour un projet que j'avais eu il y a un an, voici la partie de mon code où je me suis connecté à un autre ordinateur/serveur et ai exécuté un simple fichier python:
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='...', username='...', password='...')
stdin, stdout, stderr = ssh.exec_command('python hello.py')
ssh.close()
stdin
, stdout
et sdterr
contiennent les entrées/sorties de la commande que vous avez exécutée.
À partir de là, je pense que vous pouvez établir la connexion avec la base de données.