Install & Compatibility
Where this runs
tested against v0.4.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.840s · 42.6MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 3.2s · import 0.778s · 43MB
41MB installed
● package 41MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
SSHTunnelForwarder
✓ from sshtunnel import SSHTunnelForwarder
open_tunnel
✓ from sshtunnel import open_tunnel
Recommended wrapper function for context manager usage.
This quickstart demonstrates how to establish an SSH tunnel using `SSHTunnelForwarder` to access a remote service, such as a database. It uses environment variables for secure credential handling. The `with` statement ensures the tunnel is properly started and stopped.
import os
from sshtunnel import SSHTunnelForwarder
import time
# --- Configuration from Environment Variables ---
# SSH Host (the jump server)
SSH_HOST = os.environ.get('SSH_JUMP_HOST', 'your_ssh_jump_host.com')
SSH_PORT = int(os.environ.get('SSH_JUMP_PORT', '22'))
SSH_USERNAME = os.environ.get('SSH_JUMP_USER', 'your_ssh_user')
SSH_PASSWORD = os.environ.get('SSH_JUMP_PASSWORD', '') # Optional, use SSH keys preferrably
SSH_PKEY = os.environ.get('SSH_JUMP_PKEY_PATH', '~/.ssh/id_rsa') # Path to private key
SSH_PKEY_PASSWD = os.environ.get('SSH_JUMP_PKEY_PASSWD', '') # Password for private key, if encrypted
# Remote Bind Address (the actual service you want to reach, from the perspective of the SSH Host)
REMOTE_BIND_HOST = os.environ.get('DB_HOST_PRIVATE_IP', '10.0.0.5')
REMOTE_BIND_PORT = int(os.environ.get('DB_PORT', '5432')) # e.g., 5432 for PostgreSQL, 3306 for MySQL
# Local Bind Address (where the tunnel will be accessible on your local machine)
LOCAL_BIND_HOST = os.environ.get('LOCAL_TUNNEL_HOST', '127.0.0.1')
LOCAL_BIND_PORT = int(os.environ.get('LOCAL_TUNNEL_PORT', 'auto')) # 'auto' for a random available port
# Example of connecting to a PostgreSQL database via an SSH tunnel
try:
with SSHTunnelForwarder(
(SSH_HOST, SSH_PORT),
ssh_username=SSH_USERNAME,
ssh_password=SSH_PASSWORD if SSH_PASSWORD else None,
ssh_pkey=SSH_PKEY if os.path.exists(os.path.expanduser(SSH_PKEY)) else None,
ssh_private_key_password=SSH_PKEY_PASSWD if SSH_PKEY_PASSWD else None,
remote_bind_address=(REMOTE_BIND_HOST, REMOTE_BIND_PORT),
local_bind_address=(LOCAL_BIND_HOST, LOCAL_BIND_PORT) if LOCAL_BIND_PORT != 'auto' else (LOCAL_BIND_HOST, 0)
) as tunnel:
print(f"SSH tunnel established. Local port: {tunnel.local_bind_port}")
print(f"Accessing {REMOTE_BIND_HOST}:{REMOTE_BIND_PORT} via localhost:{tunnel.local_bind_port}")
# In a real application, you would now connect your database client to:
# host='127.0.0.1', port=tunnel.local_bind_port
# For demonstration, we just keep the tunnel open for a few seconds.
print("Tunnel active for 10 seconds. Press Ctrl+C to stop sooner.")
time.sleep(10)
print("Tunnel closing.")
except Exception as e:
print(f"An error occurred: {e}")
print("Please check your SSH configuration, network connectivity, and credentials.")
sshtunnel --version
Upgrade
Version history
0.4.0latest on PyPI · released Jan 11, 2021
Audit
Dependencies
paramikorequiredCore dependency for SSH client functionality.