Access remote DB via ssh tunnel (Python 3)

Think of it like a proxy connection. You connect to ssh_tunnel_host:22 and you tell it to proxy connections from its <db host>:3306, meaning port 3306 on db_host accessed by ssh_tunnel_host to you, the client.

You can either specify the local (to you) ip:port you want the proxy connection to be available on, or let the client choose a free one. Omitting local_bind_address does the latter.

You then connect to your local port which is actually a proxy to remote_bind_address:3306.

local_bind_address <-> ssh_tunnel_host <-> remote_bind_address

Code should be:

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. Local to client address. Either set one, or let client choose and find its port from tunnel.local_bind_port.

  2. The address you want ssh_tunnel_host to proxy back to you. If it's a local to the server service, the IP will be 127.0.0.1 and port of the service. It could well be any other IP or an IP in ssh_tunnel_host's network that is not visible outside SSH tunnel host.

  3. Nowhere. The tunnel provides a local ip:port that proxies the remote connection. Once the tunnel is up, no other client is needed. Just connect to the local ip:port.