Skip to main content

Pure python SSH tunnels

Project description

CircleCI AppVeyor coveralls version

DwnMonth DwnWeek DwnDay

pyversions license

Author: Pahaz Blinov


Inspired by, but it doesn’t work on Windows.

See also:



sshtunnel is on PyPI, so simply run:

pip install sshtunnel


easy_install sshtunnel

to have it installed in your environment.

For installing from source, clone the repo and run:

python install

Testing the package

In order to run the tests you first need tox and run:

python test

Usage scenarios

One of the typical scenarios where sshtunnel is helpful is depicted in the figure below. User may need to connect a port of a remote server (i.e. 8080) where only SSH port (usually port 22) is reachable.


-------------+              |    +----------+
    LOCAL    |              |    |  REMOTE  | :22 SSH
    CLIENT   | <== SSH ========> |  SERVER  | :8080 web service
-------------+              |    +----------+
                         FIREWALL (only port 22 is open)


Fig1: How to connect to a service blocked by a firewall through SSH tunnel.

If allowed by the SSH server, it is also possible to reach a private server (from the perspective of REMOTE SERVER) not directly visible from the outside (LOCAL CLIENT’s perspective).


-------------+              |    +----------+               +---------
    LOCAL    |              |    |  REMOTE  |               | PRIVATE
    CLIENT   | <== SSH ========> |  SERVER  | <== local ==> | SERVER
-------------+              |    +----------+               +---------


Fig2: How to connect to PRIVATE SERVER through SSH tunnel.

Usage examples

API allows either initializing the tunnel and starting it or using a with context, which will take care of starting and stopping the tunnel:

Example 1

from sshtunnel import SSHTunnelForwarder

server = SSHTunnelForwarder(
    ('', 22),
    remote_bind_address=('', 5555)


# work with `SECRET SERVICE` through `server.local_bind_port`.


Example 2

Example of a port forwarding for the Vagrant MySQL local port:

from sshtunnel import SSHTunnelForwarder
from time import sleep

with SSHTunnelForwarder(
    ('localhost', 2222),
    remote_bind_address=('', 3306)
) as server:

    while True:
        # press Ctrl-C for stopping


Or simply using the CLI:

$ python -m sshtunnel -U vagrant -P vagrant -L :3306 -R -p 2222 localhost

CLI usage

usage: sshtunnel [-h] [-U SSH_USERNAME] [-p SSH_PORT] [-P SSH_PASSWORD] -R
                 IP:PORT [IP:PORT ...] [-L [IP:PORT [IP:PORT ...]]]
                 [-k SSH_HOST_KEY] [-K KEY_FILE] [-S KEY_PASSWORD] [-t]
                 [-v] [-V] [-x IP:PORT] [-c SSH_CONFIG_FILE] [-z] [-n]

Pure python ssh tunnel utils

positional arguments:
  ssh_address           SSH server IP address (GW for ssh tunnels)
                        set with "-- ssh_address" if immediately after -R or -L

optional arguments:
  -h, --help            show this help message and exit
  -U, --username SSH_USERNAME
                        SSH server account username
  -p, --server_port SSH_PORT
                        SSH server TCP port (default: 22)
  -P, --password SSH_PASSWORD
                        SSH server account password
  -R, --remote_bind_address IP:PORT [IP:PORT ...]
                        Remote bind address sequence: ip_1:port_1 ip_2:port_2 ... ip_n:port_n
                        Equivalent to ssh -Lxxxx:IP_ADDRESS:PORT
                        If omitted, default port is 22.
                        Example: -R
  -L, --local_bind_address [IP:PORT [IP:PORT ...]]
                        Local bind address sequence: ip_1:port_1 ip_2:port_2 ... ip_n:port_n
                        Equivalent to ssh -LPORT:xxxxxxxxx:xxxx, being the local IP address optional.
                        By default it will listen in all interfaces ( and choose a random port.
                        Example: -L :40000
  -k, --ssh_host_key SSH_HOST_KEY
                        Gateway's host key
  -K, --private_key_file KEY_FILE
                        RSA/DSS/ECDSA private key file
  -S, --private_key_file_password KEY_PASSWORD
                        RSA/DSS/ECDSA private key password
  -t, --threaded        Allow concurrent connections to each tunnel
  -v, --verbosity       Increase output verbosity (default: ERROR)
  -V, --version         Show version number and quit
  -x, --proxy IP:PORT   IP and por for SSH proxy to destination
  -c, --config SSH_CONFIG_FILE
                        SSH configuration file, defaults to ~/.ssh/config
  -z, --compress        Request server for compression over SSH transport
  -n, --noagent         Disable looking for keys from an SSH agent

Online documentation

Documentation may be found at readthedocs.


Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for sshtunnel, version
Filename, size File type Python version Upload date Hashes
Filename, size sshtunnel- (28.8 kB) File type Source Python version None Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring DigiCert DigiCert EV certificate Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page