使Python能够通过SSH隧道连接到MySQL

Nyx*_*nyx 20 python mysql ssh python-2.7

我正在使用MySqldbPython 2.7来允许Python与另一个MySQL服务器建立连接

import MySQLdb
db = MySQLdb.connect(host="sql.domain.com",
     user="dev", 
      passwd="*******", 
      db="appdb")
Run Code Online (Sandbox Code Playgroud)

不是像这样正常连接,如何使用SSH密钥对通过SSH隧道建立连接?

理想情况下,SSH隧道应该由Python打开.SSH隧道主机和MySQL服务器是同一台机器.

小智 21

我猜你需要端口转发.我建议sshtunnel.SSHTunnelForwarder

import mysql.connector
import sshtunnel

with sshtunnel.SSHTunnelForwarder(
        (_host, _ssh_port),
        ssh_username=_username,
        ssh_password=_password,
        remote_bind_address=(_remote_bind_address, _remote_mysql_port),
        local_bind_address=(_local_bind_address, _local_mysql_port)
) as tunnel:
    connection = mysql.connector.connect(
        user=_db_user,
        password=_db_password,
        host=_local_bind_address,
        database=_db_name,
        port=_local_mysql_port)
    ...
Run Code Online (Sandbox Code Playgroud)


Kat*_*hah 15

只有这对我有用

import pymysql
import paramiko
import pandas as pd
from paramiko import SSHClient
from sshtunnel import SSHTunnelForwarder
from os.path import expanduser

home = expanduser('~')
mypkey = paramiko.RSAKey.from_private_key_file(home + pkeyfilepath)
# if you want to use ssh password use - ssh_password='your ssh password', bellow

sql_hostname = 'sql_hostname'
sql_username = 'sql_username'
sql_password = 'sql_password'
sql_main_database = 'db_name'
sql_port = 3306
ssh_host = 'ssh_hostname'
ssh_user = 'ssh_username'
ssh_port = 22
sql_ip = '1.1.1.1.1'

with SSHTunnelForwarder(
        (ssh_host, ssh_port),
        ssh_username=ssh_user,
        ssh_pkey=mypkey,
        remote_bind_address=(sql_hostname, sql_port)) as tunnel:
    conn = pymysql.connect(host='127.0.0.1', user=sql_username,
            passwd=sql_password, db=sql_main_database,
            port=tunnel.local_bind_port)
    query = '''SELECT VERSION();'''
    data = pd.read_sql_query(query, conn)
    conn.close()
Run Code Online (Sandbox Code Playgroud)


kar*_*k r 7

如果您的私钥文件已加密,这对我有用:

    mypkey = paramiko.RSAKey.from_private_key_file(<<file location>>, password='password')
    sql_hostname = 'sql_hostname'
    sql_username = 'sql_username'
    sql_password = 'sql_password'
    sql_main_database = 'sql_main_database'
    sql_port = 3306
    ssh_host = 'ssh_host'
    ssh_user = 'ssh_user'
    ssh_port = 22


    with SSHTunnelForwarder(
            (ssh_host, ssh_port),
            ssh_username=ssh_user,
            ssh_pkey=mypkey,
            ssh_password='ssh_password',
            remote_bind_address=(sql_hostname, sql_port)) as tunnel:
        conn = pymysql.connect(host='localhost', user=sql_username,
                               passwd=sql_password, db=sql_main_database,
                               port=tunnel.local_bind_port)
        query = '''SELECT VERSION();'''
        data = pd.read_sql_query(query, conn)
        print(data)
        conn.close()
Run Code Online (Sandbox Code Playgroud)


小智 6

您只能写入私钥文件的路径:(ssh_pkey='/home/userName/.ssh/id_ed25519'文档位于: https: //sshtunnel.readthedocs.io/en/latest/)。

如果您使用 Oracle 中的 mysql.connector,则必须使用构造 cnx = mysql.connector.MySQLConnection(... 重要提示:构造 cnx = mysql.connector.connect(...无法通过 SSh 工作!这是一个错误。(文档位于: https: //dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html)。

另外,您的 SQL 语句必须是理想的。如果 SQL 服务器端出现错误,您不会收到来自 SQL 服务器的错误消息。

import sshtunnel
import numpy as np

with sshtunnel.SSHTunnelForwarder(ssh_address_or_host='ssh_host',
                                  ssh_username="ssh_username",
                                  ssh_pkey='/home/userName/.ssh/id_ed25519',
                                  remote_bind_address=('localhost', 3306),
                                  ) as tunnel:
    cnx = mysql.connector.MySQLConnection(user='sql_username',
                                          password='sql_password',
                                          host='127.0.0.1',
                                          database='db_name',
                                          port=tunnel.local_bind_port)
    cursor = cnx.cursor()
    cursor.execute('SELECT * FROM db_name.tableName;')
    arr = np.array(cursor.fetchall())
    cursor.close()
    cnx.close()
Run Code Online (Sandbox Code Playgroud)


Hem*_*rma 6

from sshtunnel import SSHTunnelForwarder
import pymysql
import pandas as pd

tunnel = SSHTunnelForwarder(('SSH_HOST', 22), ssh_password=SSH_PASS, ssh_username=SSH_UNAME,
     remote_bind_address=(DB_HOST, 3306)) 
tunnel.start()
conn = pymysql.connect(host='127.0.0.1', user=DB_UNAME, passwd=DB_PASS, port=tunnel.local_bind_port)
data = pd.read_sql_query("SHOW DATABASES;", conn)
Run Code Online (Sandbox Code Playgroud)

归功于https://www.reddit.com/r/learnpython/comments/53wph1/connecting_to_a_mysql_database_in_a_python_script/


yea*_*ske -1

Paramiko 是进行 ssh 隧道的最佳 Python 模块。在此处查看代码: https ://github.com/paramiko/paramiko/blob/master/demos/forward.py

正如评论中所说,这个效果完美。 用于 Python MySQLdb 连接的 SSH 隧道