通过ssh隧道访问远程数据库(Python 3)

时间:2017-07-20 11:41:28

标签: python ssh remote-access ssh-tunnel

我无法理解(甚至在阅读了几篇专门用于ssh调整的文章之后)CLI ssh命令的哪些参数在此脚本中的位置。 基本上我必须连接到某个服务器(我称之为'ssh_tunnel_host:22'),而不是使用此隧道连接到db_host。

with SSHTunnelForwarder(
    ('ssh_tunnel_host', 22),
    ssh_username="ssh_username",
    ssh_pkey="/somepath/id_rsa",
    local_bind_address=('0.0.0.0', 1234),
    remote_bind_address=('127.0.0.1', 3306)
) as tunnel:
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect('127.0.0.1', 1234)
    db_connection = pymysql.connect(host=db_host, port=3306, db='mysql', user='user',
                                    password='password', charset='utf8mb4')

有人可以向我解释一下:

  1. 什么是local_bind_address - 是我的本地地址还是ssh_tunnel_host本地加法器?我在哪里可以学习IP和端口?
  2. 取决于之前的问题 - 什么是remote_bind_address - 是ssh_tunnel_host还是db_host的地址?我在哪里可以学习这些IP和端口?
  3. 我应该在哪里连接client.connect()?本地或远程绑定?
  4. (我确实试过阅读文档,但它仍然在搞乱)

2 个答案:

答案 0 :(得分:4)

将其视为代理连接。您连接到ssh_tunnel_host:22,并告诉它代理其<db host>:3306的连接,即db_host访问ssh_tunnel_host的端口3306给您(客户端)。

您可以指定您希望代理连接可用的本地(对您)ip:端口,或让客户端选择一个免费的。省略local_bind_address后者。

然后连接到本地端口,该端口实际上是remote_bind_address:3306的代理。

local_bind_address&lt; - &gt; ssh_tunnel_host&lt; - &gt; remote_bind_address

代码应该是:

db_host = '<address reachable only by ssh_tunnel_host>'
with SSHTunnelForwarder(
    ('ssh_tunnel_host', 22),
    ssh_username="ssh_username",
    ssh_pkey="/somepath/id_rsa",
    remote_bind_address=(db_host, 3306)
) as tunnel:
    port = tunnel.local_bind_port
    db_connection = pymysql.connect(
        host='127.0.0.1', port=port, db='mysql', user='user',
        password='password', charset='utf8mb4')
  1. 本地到客户地址。设置一个,或者让客户从tunnel.local_bind_port中选择并查找其端口。

  2. 您希望ssh_tunnel_host代理给您的地址。如果它是服务器服务的本地服务器,则IP将是127.0.0.1和服务端口。它可能是ssh_tunnel_host网络中在SSH隧道主机外部不可见的任何其他IP或IP。

  3. 无处。隧道提供代理远程连接的本地ip:端口。隧道启动后,不需要其他客户端。只需连接到本地ip:端口。

答案 1 :(得分:0)

我们的情况很相似,我厌倦了在尝试连接到 MS Sqlserver 数据库之前确保 SSH 隧道已启动并正在运行。所以我们有一个远程服务器(ip1),我们在上面安装了一个带有 MSSqlserver 的 docker。当然,当您登录该服务器时,您可以将 docker ip 转发到该机器上的 localhost。因此,如果您在 ip1 的“内部”,则可以以 localhost 身份访问服务器。

所有版本的 MS Sqlserver 都强制将端口 1433 作为访问端口。

所以你有 ip1->localhost:1433->MSSqlserver

所以SSH使用简单的SSH user@ip1创建了一个访问ip1的隧道,但是你需要在远程服务器上转发localhost:1433才能像本地一样操作。

from sshtunnel import SSHTunnelForwarder
import values

server = SSHTunnelForwarder(
    (values.remote_server_ip, values.remote_server_port),
    ssh_username=values.remote_server_username,
    ssh_pkey=values.rsa_path+values.rsa_file,
    ssh_private_key_password=values.rsa_passphrase,
    remote_bind_address=(values.private_server_ip, values.private_server_port),
    local_bind_address=(values.db_server_ip, values.db_server_port) )
try:
    server.start()
except:
    print("trouble connecting to the tunnel. we will asume it is already up")
else:
    print("server is started and on port ",server.local_bind_port)  # show assigned local port

在这里做一些工作然后 然后

try:
    server.stop()
except:
    print("could not stop the server. assume it is already down")
else:
    print("stopped the server successfully")

和 values.py 包含

的值
remote_server_ip = "....remote ip...."
remote_server_port = 22
private_server_ip = "localhost"
private_server_port = 1433
db_server_ip = "localhost"
db_server_port = 1433
remote_server_username = "...."
rsa_passphrase = "...."
rsa_path = "˜/.ssh/"
rsa_file = "id_rsa"