In my Python script, I want to be able to connect to a Postgres DB via an SSH tunnel.
I'm using sshtunnel package to create a tunnel, and using PyGreSQL to connect to the DB. When I try to establish the database connection, the pg.connect call just hangs. I don't get any errors at all. When I use psql to connect to the DB using the tunnel created by sshtunnel, the connection is successful.
When I create the tunnel beforehand using ssh in shell, pg.connect call successfully connects to the database.
So to summarize:
- Tunnel created in Python/sshtunnel -> pg.connect call hangs
- Tunnel created in Python/sshtunnel -> psql works just fine
- Tunnel created using ssh -> pg.connect call is successful
This seems to be a problem with PyGreSQL since psql can access the DB using tunnel by sshtunnel just fine. However, there could be something different about the tunnel by sshtunnel package that I'm not seeing.
This is the command I'm using to create the tunnel using SSH:
ssh -g -L <local_bind_port>:localhost:<remote_bind_port> -f -N root@myip
Following is my code to connect to the DB in Python using SSH Tunnel and pg.connect
from sshtunnel import SSHTunnelForwarder
dbasename = 'db'
username = 'admin'
password = 'admin'
portnum = 5432
tunnel = SSHTunnelForwarder(
<ip_address>,
ssh_username="admin",
ssh_password="admin",
remote_bind_address=('127.0.0.1', portnum)
)
tunnel.start()
# The line below hangs
db = pg.connect(host=tunnel.local_bind_host, port=tunnel.local_bind_port, dbname=dbasename, user=username, passwd=password)
Any ideas about what could cause this problem? Are there any logs etc I that might help identify the problem?
Thanks.
EDIT:
It turns out that if I open a tunnel using python/SSHTunnel in one python shell, but use pg.connect to connect to that tunnel in the 2nd python shell it connects successfully. So if I copy paste the following in the 1st shell:
from sshtunnel import SSHTunnelForwarder
dbasename = 'db'
username = 'admin'
password = 'admin'
portnum = 5432
tunnel = SSHTunnelForwarder(
<ip_address>,
ssh_username="admin",
ssh_password="admin",
remote_bind_address=('127.0.0.1', portnum)
)
tunnel.start()
then open another shell and connect to the tunnel from the 1st shell
import pg
# This works for some reason
db = pg.connect(host='127.0.0.1', port=<local hind port from the 1st shell>, dbname=dbasename, user=username, passwd=password)
the connection is successful