[SIP-91] - Enable SSH Tunneling on Database Connections
See original GitHub issueMotivation
Users are currently blocked on setting up ssh tunneling entirely through superset. This is causing us to lose potential users to leverage this product as their analytics tool.
Proposed Change
Describe how the feature will be implemented, or the problem will be solved. If possible, include mocks, screenshots, or screencasts (even if from different tools).
- wrap
@contextmanageraroundget_sqla_engine()- @contextmanager logic for blocking
localhost- Does the DB have ssh tunnel metadata associated with it (stored in a separate table or column)? If it has, create the tunnel binding on 127.0.0.1 and a random port, replace the host and port in the SQLAlchemy URI with 127.0.0.1 and the port that the ssh tunnel created.
- If the DB has no ssh tunnel metadata, check the host of the SQL Alchemy URI. If it’s localhost or some variation (127.0.0.1, ::1, 0:0:0:0:0:0:0:1, etc.) then block it (unless the config allows). 1. checking for host name for that resolve to [localhost](http://localhost) as well (library) [there will be a feature flag that will users to override this)
- We’ll be able to grab the local_binding_port from
serverobject thatsshtunnelpackage returns in the contextmanager - We are blocking localhost due to security concerns for users who main try to get access to other ports within a given deployment/instance. Specifically for Preset, we want to make sure get user’s cannot get access to other’s db without proper credentials
- @contextmanager logic for blocking
@contextmanager
def get_sqla_engine_with_context()
# enable ssh
# check if ssh tunnel enabled
# true -> create tunnel with creds
# false -> verify that user isn't connecting to localhost (under config flag)
yield engine
# tear down ssh
- Refactor all the places trying to create_engine to have new
withformat
with get_sqla_engine as engine:
# use engine with ssh tunnel created
- Define schema that is needed for the client to properly SSH tunnel to a remote host
class SSHTunnelCredentials(Schema):
database_id: int
server_host: str
server_port: int
username: str
password: Optional[str]
private_key: Optional[str]
private_key_password: Optional[str]
bind_host: str
bind_port: int
- Create table for TunnelConfig that mapped to
Database(fk: database_id)- migration required and schema should match
TunnelConfig
- migration required and schema should match
- Create tunnel using information provided in the
TunnelConfigtable for a specific database
with sshtunnel.open_tunnel(
# ...
) as server:
- Inside get_sqla_engine with ssh if current db has
encrypted_credentials.ssh_tunnelenable tunnel and deconstruct before returning- if doing 2, we’d leave the connection open for this client
- Managing SSL with ssh tunnel
- if ssh tunnel is enabled + ssl we need allow the certificates to be ignored
- For Postgres if you pass
sslmode=verify-cait will ignore the names in the certificates.sslmode=verify-fullwould fail in this case.
New or Changed Public Interfaces
Describe any new additions to the model, views or REST endpoints. Describe any changes to existing visualizations, dashboards and React components. Describe changes that affect the Superset CLI and how Superset is deployed.
I will be creating a new table name ssh_tunnel_config. This table will hold all the necessary information for the client to establish the connection to any Database living between the proxy.
class SSHTunnelCredentials(Schema):
database_id: int
server_host: str
server_port: int
username: str
password: Optional[str]
private_key: Optional[str]
private_key_password: Optional[str]
bind_host: str
bind_port: int
- the
bind_host+bind_portwill be built based upon the information provided in thesqlalchemy_uri.
New dependencies
We’ll be leveraging sshtunnel pip package to help establish connections.
https://pypi.org/project/sshtunnel/
Issue Analytics
- State:
- Created a year ago
- Reactions:4
- Comments:7 (7 by maintainers)

Top Related StackOverflow Question
@hughhhh Can we change the title to Enable SSH Tunneling on Database Connections? SSH Tunneling is a generic concept that may be applied in many parts of the application and this SIP is just one part.
+1 to @betodealmeida’s comments
Closing as approved, and updating the project board! Please continue to reference this issue in related PRs whenever relevant!