使用Paramiko设置SSH隧道以访问PostgreSQL

问题描述

我目前使用Paramiko访问SFTP服务器并连接到同一服务器上的Postgresql。我发现许多使用sshtunnel登录Postgresql的示例。但是我不知道怎么用纯Paramiko来做。

目前我的代码如下:

# establish SSH tunnel
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(hostname=host,username=user,password=password)

# setup SFTP server
self.sftp = self.ssh.open_sftp()

# connect to datebase
self.engine = create_engine('postgres+psycopg2://{}:{}@{}:{}/{}'.format(user,password,host,port,db))

谢谢您的建议!

解决方法

使用SSH端口转发。

修改Nested SSH using Python Paramiko中用于数据库隧道的代码,您将得到如下代码:

# establish SSH tunnel
self.ssh = paramiko.SSHClient()
# ...
self.ssh.connect(hostname=ssh_host,username=ssh_user,password=ssh_password)

transport = ssh_client.get_transport()
dest_addr = (db_host,db_port)
local_unique_port = 4000 # any unused local port
local_host = 'localhost'
local_addr = (local_host,local_unique_port)
vmchannel = vmtransport.open_channel("direct-tcpip",dest_addr,local_addr)

self.engine = create_engine(
    'postgres+psycopg2://{}:{}@{}:{}/{}'.format(
        db_user,db_password,local_host,local_unique_port,db))

如果PostgreSQL数据库在SSH服务器本身上运行,则通常仅在回送接口上侦听。在这种情况下,db_host应该设置为localhost


请注意,sshtunnel只是Paramiko的包装。因此,通常来说,除非有一些限制阻止您安装其他软件包,否则您可以使用它来简化代码。

例如:Connecting to PostgreSQL database through SSH tunneling in Python


基于有关MongoDB的相同问题:
Connect and query Mongo database over SSH with private key in Python


强制性警告:请勿使用AutoAddPolicy-这样做会失去对MITM attacks的保护。有关正确的解决方案,请参见Paramiko "Unknown Server"