.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "SSHTUNNEL" "1" "Nov 29, 2024" "0.4.0" "sshtunnel" .SH NAME sshtunnel \- sshtunnel Documentation .sp \X'tty: link https://circleci.com/gh/pahaz/sshtunnel'\fI\%CircleCI\fP\X'tty: link' \X'tty: link https://ci.appveyor.com/project/pahaz/sshtunnel'\fI\%AppVeyor\fP\X'tty: link' \X'tty: link http://sshtunnel.readthedocs.io/en/latest/?badge=latest'\fI\%Documentation Status\fP\X'tty: link' \X'tty: link https://coveralls.io/github/pahaz/sshtunnel?branch=master'\fI\%coveralls\fP\X'tty: link' \X'tty: link https://pypi.python.org/pypi/sshtunnel'\fI\%version\fP\X'tty: link' .sp [image: pyversions] [image] \X'tty: link https://github.com/pahaz/sshtunnel/blob/master/LICENSE'\fI\%license\fP\X'tty: link' .sp \fBAuthor\fP: \X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link' .sp \fBRepo\fP: \X'tty: link https://github.com/pahaz/sshtunnel/'\fI\%https://github.com/pahaz/sshtunnel/\fP\X'tty: link' .sp Inspired by \X'tty: link https://github.com/jmagnusson/bgtunnel'\fI\%https://github.com/jmagnusson/bgtunnel\fP\X'tty: link', which doesn\(aqt work on Windows. .sp See also: \X'tty: link https://github.com/paramiko/paramiko/blob/master/demos/forward.py'\fI\%https://github.com/paramiko/paramiko/blob/master/demos/forward.py\fP\X'tty: link' .SH REQUIREMENTS .INDENT 0.0 .IP \(bu 2 \X'tty: link http://www.paramiko.org/'\fI\%paramiko\fP\X'tty: link' .UNINDENT .sp \X'tty: link https://pypi.python.org/pypi/sshtunnel'\fI\%sshtunnel\fP\X'tty: link' is on PyPI, so simply run: .INDENT 0.0 .INDENT 3.5 .sp .EX pip install sshtunnel .EE .UNINDENT .UNINDENT .sp or .INDENT 0.0 .INDENT 3.5 .sp .EX easy_install sshtunnel .EE .UNINDENT .UNINDENT .sp or .INDENT 0.0 .INDENT 3.5 .sp .EX conda install \-c conda\-forge sshtunnel .EE .UNINDENT .UNINDENT .sp to have it installed in your environment. .sp For installing from source, clone the \X'tty: link https://github.com/pahaz/sshtunnel'\fI\%repo\fP\X'tty: link' and run: .INDENT 0.0 .INDENT 3.5 .sp .EX python setup.py install .EE .UNINDENT .UNINDENT .SH TESTING THE PACKAGE .sp In order to run the tests you first need \X'tty: link https://testrun.org/tox/latest/'\fI\%tox\fP\X'tty: link' and run: .INDENT 0.0 .INDENT 3.5 .sp .EX python setup.py test .EE .UNINDENT .UNINDENT .sp One of the typical scenarios where \fBsshtunnel\fP 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. .INDENT 0.0 .INDENT 3.5 .sp .EX \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- | \-\-\-\-\-\-\-\-\-\-\-\-\-+ | +\-\-\-\-\-\-\-\-\-\-+ LOCAL | | | REMOTE | :22 SSH CLIENT | <== SSH ========> | SERVER | :8080 web service \-\-\-\-\-\-\-\-\-\-\-\-\-+ | +\-\-\-\-\-\-\-\-\-\-+ | FIREWALL (only port 22 is open) \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- .EE .UNINDENT .UNINDENT .sp \fBFig1\fP: How to connect to a service blocked by a firewall through SSH tunnel. .sp If allowed by the SSH server, it is also possible to reach a private server (from the perspective of \fBREMOTE SERVER\fP) not directly visible from the outside (\fBLOCAL CLIENT\fP\(aqs perspective). .INDENT 0.0 .INDENT 3.5 .sp .EX \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- | \-\-\-\-\-\-\-\-\-\-\-\-\-+ | +\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-\- LOCAL | | | REMOTE | | PRIVATE CLIENT | <== SSH ========> | SERVER | <== local ==> | SERVER \-\-\-\-\-\-\-\-\-\-\-\-\-+ | +\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-\- | FIREWALL (only port 443 is open) \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- .EE .UNINDENT .UNINDENT .sp \fBFig2\fP: How to connect to \fBPRIVATE SERVER\fP through SSH tunnel. .sp API allows either initializing the tunnel and starting it or using a \fBwith\fP context, which will take care of starting \fBand stopping\fP the tunnel: .SH EXAMPLE 1 .sp Code corresponding to \fBFig1\fP above follows, given remote server\(aqs address is \fBpahaz.urfuclub.ru\fP, password authentication and randomly assigned local bind port. .INDENT 0.0 .INDENT 3.5 .sp .EX from sshtunnel import SSHTunnelForwarder server = SSHTunnelForwarder( \(aqalfa.8iq.dev\(aq, ssh_username=\(dqpahaz\(dq, ssh_password=\(dqsecret\(dq, remote_bind_address=(\(aq127.0.0.1\(aq, 8080) ) server.start() print(server.local_bind_port) # show assigned local port # work with \(gaSECRET SERVICE\(ga through \(gaserver.local_bind_port\(ga. server.stop() .EE .UNINDENT .UNINDENT .SH EXAMPLE 2 .sp Example of a port forwarding to a private server not directly reachable, assuming password protected pkey authentication, remote server\(aqs SSH service is listening on port 443 and that port is open in the firewall (\fBFig2\fP): .INDENT 0.0 .INDENT 3.5 .sp .EX import paramiko import sshtunnel with sshtunnel.open_tunnel( (REMOTE_SERVER_IP, 443), ssh_username=\(dq\(dq, ssh_pkey=\(dq/var/ssh/rsa_key\(dq, ssh_private_key_password=\(dqsecret\(dq, remote_bind_address=(PRIVATE_SERVER_IP, 22), local_bind_address=(\(aq0.0.0.0\(aq, 10022) ) as tunnel: client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(\(aq127.0.0.1\(aq, 10022) # do some operations with client session client.close() print(\(aqFINISH!\(aq) .EE .UNINDENT .UNINDENT .SH EXAMPLE 3 .sp Example of a port forwarding for the Vagrant MySQL local port: .INDENT 0.0 .INDENT 3.5 .sp .EX from sshtunnel import open_tunnel from time import sleep with open_tunnel( (\(aqlocalhost\(aq, 2222), ssh_username=\(dqvagrant\(dq, ssh_password=\(dqvagrant\(dq, remote_bind_address=(\(aq127.0.0.1\(aq, 3306) ) as server: print(server.local_bind_port) while True: # press Ctrl\-C for stopping sleep(1) print(\(aqFINISH!\(aq) .EE .UNINDENT .UNINDENT .sp Or simply using the CLI: .INDENT 0.0 .INDENT 3.5 .sp .EX (bash)$ python \-m sshtunnel \-U vagrant \-P vagrant \-L :3306 \-R 127.0.0.1:3306 \-p 2222 localhost .EE .UNINDENT .UNINDENT .SH EXAMPLE 4 .sp Opening an SSH session jumping over two tunnels. SSH transport and tunnels will be daemonised, which will not wait for the connections to stop at close time. .INDENT 0.0 .INDENT 3.5 .sp .EX import sshtunnel from paramiko import SSHClient with sshtunnel.open_tunnel( ssh_address_or_host=(\(aqGW1_ip\(aq, 20022), remote_bind_address=(\(aqGW2_ip\(aq, 22), ) as tunnel1: print(\(aqConnection to tunnel1 (GW1_ip:GW1_port) OK...\(aq) with sshtunnel.open_tunnel( ssh_address_or_host=(\(aqlocalhost\(aq, tunnel1.local_bind_port), remote_bind_address=(\(aqtarget_ip\(aq, 22), ssh_username=\(aqGW2_user\(aq, ssh_password=\(aqGW2_pwd\(aq, ) as tunnel2: print(\(aqConnection to tunnel2 (GW2_ip:GW2_port) OK...\(aq) with SSHClient() as ssh: ssh.connect(\(aqlocalhost\(aq, port=tunnel2.local_bind_port, username=\(aqtarget_user\(aq, password=\(aqtarget_pwd\(aq, ) ssh.exec_command(...) .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX $ sshtunnel \-\-help 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] [\-d [FOLDER [FOLDER ...]]] ssh_address Pure python ssh tunnel utils Version 0.4.0 positional arguments: ssh_address SSH server IP address (GW for SSH tunnels) set with \(dq\-\- ssh_address\(dq if immediately after \-R or \-L optional arguments: \-h, \-\-help show this help message and exit \-U SSH_USERNAME, \-\-username SSH_USERNAME SSH server account username \-p SSH_PORT, \-\-server_port SSH_PORT SSH server TCP port (default: 22) \-P SSH_PASSWORD, \-\-password SSH_PASSWORD SSH server account password \-R IP:PORT [IP:PORT ...], \-\-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 port is omitted, defaults to 22. Example: \-R 10.10.10.10: 10.10.10.10:5900 \-L [IP:PORT [IP:PORT ...]], \-\-local_bind_address [IP:PORT [IP:PORT ...]] Local bind address sequence: ip_1:port_1 ip_2:port_2 ... ip_n:port_n Elements may also be valid UNIX socket domains: /tmp/foo.sock /tmp/bar.sock ... /tmp/baz.sock Equivalent to ssh \-LPORT:xxxxxxxxx:xxxx, being the local IP address optional. By default it will listen in all interfaces (0.0.0.0) and choose a random port. Example: \-L :40000 \-k SSH_HOST_KEY, \-\-ssh_host_key SSH_HOST_KEY Gateway\(aqs host key \-K KEY_FILE, \-\-private_key_file KEY_FILE RSA/DSS/ECDSA private key file \-S KEY_PASSWORD, \-\-private_key_password KEY_PASSWORD RSA/DSS/ECDSA private key password \-t, \-\-threaded Allow concurrent connections to each tunnel \-v, \-\-verbose Increase output verbosity (default: ERROR) \-V, \-\-version Show version number and quit \-x IP:PORT, \-\-proxy IP:PORT IP and port of SSH proxy to destination \-c SSH_CONFIG_FILE, \-\-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 \-d [FOLDER [FOLDER ...]], \-\-host_pkey_directories [FOLDER [FOLDER ...]] List of directories where SSH pkeys (in the format \(gaid_*\(ga) may be found .EE .UNINDENT .UNINDENT .sp \fIsshtunnel\fP \- Initiate SSH tunnels via a remote gateway. .sp \fBsshtunnel\fP works by opening a port forwarding SSH connection in the background, using threads. .sp The connection(s) are closed when explicitly calling the \fI\%SSHTunnelForwarder.stop()\fP method or using it as a context. .INDENT 0.0 .TP .B sshtunnel.SSH_TIMEOUT = 0.1 Timeout (seconds) for transport socket (\fBsocket.settimeout\fP) .UNINDENT .INDENT 0.0 .TP .B sshtunnel.TUNNEL_TIMEOUT = 10.0 Timeout (seconds) for tunnel connection (open_channel timeout) .UNINDENT .INDENT 0.0 .TP .B sshtunnel.DEFAULT_LOGLEVEL = 40 default level if no logger passed (ERROR) .UNINDENT .INDENT 0.0 .TP .B sshtunnel.DEFAULT_SSH_DIRECTORY = \(aq~/.ssh\(aq Path of optional ssh configuration file .UNINDENT .INDENT 0.0 .TP .B sshtunnel.check_address(address) Check if the format of the address is correct .INDENT 7.0 .TP .B Arguments: .INDENT 7.0 .TP .B address (tuple): (\fBstr\fP, \fBint\fP) representing an IP address and port, respectively .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 alternatively a local \fBaddress\fP can be a \fBstr\fP when working with UNIX domain sockets, if supported by the platform .UNINDENT .UNINDENT .UNINDENT .TP .B Raises: .INDENT 7.0 .TP .B ValueError: raised when address has an incorrect format .UNINDENT .TP .B Example: .sp .EX >>> check_address((\(aq127.0.0.1\(aq, 22)) .EE .UNINDENT .UNINDENT .INDENT 0.0 .TP .B sshtunnel.check_addresses(address_list, is_remote=False) Check if the format of the addresses is correct .INDENT 7.0 .TP .B Arguments: .INDENT 7.0 .TP .B address_list (list[tuple]): Sequence of (\fBstr\fP, \fBint\fP) pairs, each representing an IP address and port respectively .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 when supported by the platform, one or more of the elements in the list can be of type \fBstr\fP, representing a valid UNIX domain socket .UNINDENT .UNINDENT .TP .B is_remote (boolean): Whether or not the address list .UNINDENT .TP .B Raises: .INDENT 7.0 .TP .B AssertionError: raised when \fBaddress_list\fP contains an invalid element .TP .B ValueError: raised when any address in the list has an incorrect format .UNINDENT .UNINDENT .sp Example: .sp .EX >>> check_addresses([(\(aq127.0.0.1\(aq, 22), (\(aq127.0.0.1\(aq, 2222)]) .EE .UNINDENT .INDENT 0.0 .TP .B sshtunnel.create_logger(logger=None, loglevel=None, capture_warnings=True, add_paramiko_handler=True) Attach or create a new logger and add a console handler if not present .sp Arguments: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .TP .B logger (Optional[logging.Logger]): \X'tty: link https://docs.python.org/3/library/logging.html#logging.Logger'\fI\%logging.Logger\fP\X'tty: link' instance; a new one is created if this argument is empty .TP .B loglevel (Optional[str or int]): \X'tty: link https://docs.python.org/3/library/logging.html#logging.Logger'\fI\%logging.Logger\fP\X'tty: link'\(aqs level, either as a string (i.e. \fBERROR\fP) or in numeric format (10 == \fBDEBUG\fP) .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 a value of 1 == \fBTRACE\fP enables Tracing mode .UNINDENT .UNINDENT .TP .B capture_warnings (boolean): Enable/disable capturing the events logged by the warnings module into \fBlogger\fP\(aqs handlers .sp Default: True .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 ignored in python 2.6 .UNINDENT .UNINDENT .TP .B add_paramiko_handler (boolean): Whether or not add a console handler for \fBparamiko.transport\fP\(aqs logger if no handler present .sp Default: True .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B Return: \X'tty: link https://docs.python.org/3/library/logging.html#logging.Logger'\fI\%logging.Logger\fP\X'tty: link' .UNINDENT .UNINDENT .INDENT 0.0 .TP .B exception sshtunnel.BaseSSHTunnelForwarderError(*args, **kwargs) Exception raised by \fI\%SSHTunnelForwarder\fP errors .UNINDENT .INDENT 0.0 .TP .B exception sshtunnel.HandlerSSHTunnelForwarderError(*args, **kwargs) Exception for Tunnel forwarder errors .UNINDENT .INDENT 0.0 .TP .B class sshtunnel.SSHTunnelForwarder(ssh_address_or_host=None, ssh_config_file=\(aq~/.ssh/config\(aq, ssh_host_key=None, ssh_password=None, ssh_pkey=None, ssh_private_key_password=None, ssh_proxy=None, ssh_proxy_enabled=True, ssh_username=None, local_bind_address=None, local_bind_addresses=None, logger=None, mute_exceptions=False, remote_bind_address=None, remote_bind_addresses=None, set_keepalive=5.0, threaded=True, compression=None, allow_agent=True, host_pkey_directories=None, *args, **kwargs) \fBSSH tunnel class\fP .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 Initialize a SSH tunnel to a remote host according to the input arguments .IP \(bu 2 .INDENT 2.0 .TP .B Optionally: .INDENT 7.0 .IP \(bu 2 Read an SSH configuration file (typically \fB~/.ssh/config\fP) .IP \(bu 2 Load keys from a running SSH agent (i.e. Pageant, GNOME Keyring) .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .sp Raises: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .TP .B \fI\%BaseSSHTunnelForwarderError\fP: raised by SSHTunnelForwarder class methods .TP .B \fI\%HandlerSSHTunnelForwarderError\fP: raised by tunnel forwarder threads .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 Attributes \fBmute_exceptions\fP and \fBraise_exception_if_any_forwarder_have_a_problem\fP (deprecated) may be used to silence most exceptions raised from this class .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .sp Keyword Arguments: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .TP .B ssh_address_or_host (tuple or str): IP or hostname of \fBREMOTE GATEWAY\fP\&. It may be a two\-element tuple (\fBstr\fP, \fBint\fP) representing IP and port respectively, or a \fBstr\fP representing the IP address only .sp Added in version 0.0.4. .TP .B ssh_config_file (str): SSH configuration file that will be read. If explicitly set to \fBNone\fP, parsing of this configuration is omitted .sp Default: \fBSSH_CONFIG_FILE\fP .sp Added in version 0.0.4. .TP .B ssh_host_key (str): Representation of a line in an OpenSSH\-style \(dqknown hosts\(dq file. .sp \fBREMOTE GATEWAY\fP\(aqs key fingerprint will be compared to this host key in order to prevent against SSH server spoofing. Important when using passwords in order not to accidentally do a login attempt to a wrong (perhaps an attacker\(aqs) machine .TP .B ssh_username (str): Username to authenticate as in \fBREMOTE SERVER\fP .sp Default: current local user name .TP .B ssh_password (str): Text representing the password used to connect to \fBREMOTE SERVER\fP or for unlocking a private key. .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 Avoid coding secret password directly in the code, since this may be visible and make your service vulnerable to attacks .UNINDENT .UNINDENT .TP .B ssh_port (int): Optional port number of the SSH service on \fBREMOTE GATEWAY\fP, when \fIssh_address_or_host\(ga\fP is a \fBstr\fP representing the IP part of \fBREMOTE GATEWAY\fP\(aqs address .sp Default: 22 .TP .B ssh_pkey (str or paramiko.PKey): \fBPrivate\fP key file name (\fBstr\fP) to obtain the public key from or a \fBpublic\fP key (\X'tty: link https://docs.paramiko.org/en/latest/api/keys.html#paramiko.pkey.PKey'\fI\%paramiko.pkey.PKey\fP\X'tty: link') .TP .B ssh_private_key_password (str): Password for an encrypted \fBssh_pkey\fP .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 Avoid coding secret password directly in the code, since this may be visible and make your service vulnerable to attacks .UNINDENT .UNINDENT .TP .B ssh_proxy (socket\-like object or tuple): Proxy where all SSH traffic will be passed through. It might be for example a \X'tty: link https://docs.paramiko.org/en/latest/api/proxy.html#paramiko.proxy.ProxyCommand'\fI\%paramiko.proxy.ProxyCommand\fP\X'tty: link' instance. See either the \X'tty: link https://docs.paramiko.org/en/latest/api/transport.html#paramiko.transport.Transport'\fI\%paramiko.transport.Transport\fP\X'tty: link'\(aqs sock parameter documentation or \fBProxyCommand\fP in \fBssh_config(5)\fP for more information. .sp It is also possible to specify the proxy address as a tuple of type (\fBstr\fP, \fBint\fP) representing proxy\(aqs IP and port .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 Ignored if \fBssh_proxy_enabled\fP is False .UNINDENT .UNINDENT .sp Added in version 0.0.5. .TP .B ssh_proxy_enabled (boolean): Enable/disable SSH proxy. If True and user\(aqs \fBssh_config_file\fP contains a \fBProxyCommand\fP directive that matches the specified \fBssh_address_or_host\fP, a \X'tty: link https://docs.paramiko.org/en/latest/api/proxy.html#paramiko.proxy.ProxyCommand'\fI\%paramiko.proxy.ProxyCommand\fP\X'tty: link' object will be created where all SSH traffic will be passed through .sp Default: \fBTrue\fP .sp Added in version 0.0.4. .TP .B local_bind_address (tuple): Local tuple in the format (\fBstr\fP, \fBint\fP) representing the IP and port of the local side of the tunnel. Both elements in the tuple are optional so both \fB(\(aq\(aq, 8000)\fP and \fB(\(aq10.0.0.1\(aq, )\fP are valid values .sp Default: \fB(\(aq0.0.0.0\(aq, RANDOM_PORT)\fP .sp Changed in version 0.0.8: Added the ability to use a UNIX domain socket as local bind address .TP .B local_bind_addresses (list[tuple]): In case more than one tunnel is established at once, a list of tuples (in the same format as \fBlocal_bind_address\fP) can be specified, such as [(ip1, port_1), (ip_2, port2), ...] .sp Default: \fB[local_bind_address]\fP .sp Added in version 0.0.4. .TP .B remote_bind_address (tuple): Remote tuple in the format (\fBstr\fP, \fBint\fP) representing the IP and port of the remote side of the tunnel. .TP .B remote_bind_addresses (list[tuple]): In case more than one tunnel is established at once, a list of tuples (in the same format as \fBremote_bind_address\fP) can be specified, such as [(ip1, port_1), (ip_2, port2), ...] .sp Default: \fB[remote_bind_address]\fP .sp Added in version 0.0.4. .TP .B allow_agent (boolean): Enable/disable load of keys from an SSH agent .sp Default: \fBTrue\fP .sp Added in version 0.0.8. .TP .B host_pkey_directories (list): Look for pkeys in folders on this list, for example [\(aq~/.ssh\(aq]. .sp Default: \fBNone\fP (disabled) .sp Added in version 0.1.4. .TP .B compression (boolean): Turn on/off transport compression. By default compression is disabled since it may negatively affect interactive sessions .sp Default: \fBFalse\fP .sp Added in version 0.0.8. .TP .B logger (logging.Logger): logging instance for sshtunnel and paramiko .sp Default: \X'tty: link https://docs.python.org/3/library/logging.html#logging.Logger'\fI\%logging.Logger\fP\X'tty: link' instance with a single \X'tty: link https://docs.python.org/3/library/logging.handlers.html#logging.StreamHandler'\fI\%logging.StreamHandler\fP\X'tty: link' handler and \fI\%DEFAULT_LOGLEVEL\fP level .sp Added in version 0.0.3. .TP .B mute_exceptions (boolean): Allow silencing \fI\%BaseSSHTunnelForwarderError\fP or \fI\%HandlerSSHTunnelForwarderError\fP exceptions when enabled .sp Default: \fBFalse\fP .sp Added in version 0.0.8. .TP .B set_keepalive (float): Interval in seconds defining the period in which, if no data was sent over the connection, a \fI\(aqkeepalive\(aq\fP packet will be sent (and ignored by the remote host). This can be useful to keep connections alive over a NAT. You can set to 0.0 for disable keepalive. .sp Default: 5.0 (no keepalive packets are sent) .sp Added in version 0.0.7. .TP .B threaded (boolean): Allow concurrent connections over a single tunnel .sp Default: \fBTrue\fP .sp Added in version 0.0.3. .TP .B ssh_address (str): Superseded by \fBssh_address_or_host\fP, tuple of type (str, int) representing the IP and port of \fBREMOTE SERVER\fP .sp Deprecated since version 0.0.4. .TP .B ssh_host (str): Superseded by \fBssh_address_or_host\fP, tuple of type (str, int) representing the IP and port of \fBREMOTE SERVER\fP .sp Deprecated since version 0.0.4. .TP .B ssh_private_key (str or paramiko.PKey): Superseded by \fBssh_pkey\fP, which can represent either a \fBprivate\fP key file name (\fBstr\fP) or a \fBpublic\fP key (\X'tty: link https://docs.paramiko.org/en/latest/api/keys.html#paramiko.pkey.PKey'\fI\%paramiko.pkey.PKey\fP\X'tty: link') .sp Deprecated since version 0.0.8. .TP .B raise_exception_if_any_forwarder_have_a_problem (boolean): Allow silencing \fI\%BaseSSHTunnelForwarderError\fP or \fI\%HandlerSSHTunnelForwarderError\fP exceptions when set to False .sp Default: \fBTrue\fP .sp Added in version 0.0.4. .sp Deprecated since version 0.0.8: (use \fBmute_exceptions\fP instead) .UNINDENT .UNINDENT .UNINDENT .sp Attributes: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .TP .B tunnel_is_up (dict): Describe whether or not the other side of the tunnel was reported to be up (and we must close it) or not (skip shutting down that tunnel) .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 This attribute should not be modified .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 When \fBskip_tunnel_checkup\fP is disabled or the local bind is a UNIX socket, the value will always be \fBTrue\fP .UNINDENT .UNINDENT .sp \fBExample\fP: .INDENT 7.0 .INDENT 3.5 .sp .EX {(\(aq127.0.0.1\(aq, 55550): True, # this tunnel is up (\(aq127.0.0.1\(aq, 55551): False} # this one isn\(aqt .EE .UNINDENT .UNINDENT .sp where 55550 and 55551 are the local bind ports .TP .B skip_tunnel_checkup (boolean): Disable tunnel checkup (default for backwards compatibility). .sp Added in version 0.1.0. .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B daemon_forward_servers = True flag tunnel threads in daemon mode .UNINDENT .INDENT 7.0 .TP .B daemon_transport = True flag SSH transport thread in daemon mode .UNINDENT .INDENT 7.0 .TP .B local_is_up(target) Check if a tunnel is up (remote target\(aqs host is reachable on TCP target\(aqs port) .INDENT 7.0 .TP .B Arguments: .INDENT 7.0 .TP .B target (tuple): tuple of type (\fBstr\fP, \fBint\fP) indicating the listen IP address and port .UNINDENT .TP .B Return: boolean .UNINDENT .sp Deprecated since version 0.1.0: Replaced by \fI\%check_tunnels()\fP and \fBtunnel_is_up\fP .UNINDENT .INDENT 7.0 .TP .B check_tunnels() Check that if all tunnels are established and populates \fBtunnel_is_up\fP .UNINDENT .INDENT 7.0 .TP .B static get_agent_keys(logger=None) Load public keys from any available SSH agent .INDENT 7.0 .TP .B Arguments: logger (Optional[logging.Logger]) .TP .B Return: list .UNINDENT .UNINDENT .INDENT 7.0 .TP .B static get_keys(logger=None, host_pkey_directories=None, allow_agent=False) Load public keys from any available SSH agent or local \&.ssh directory. .INDENT 7.0 .TP .B Arguments: logger (Optional[logging.Logger]) .INDENT 7.0 .TP .B host_pkey_directories (Optional[list[str]]): List of local directories where host SSH pkeys in the format \(dqid_*\(dq are searched. For example, [\(aq~/.ssh\(aq] .sp Added in version 0.1.0. .TP .B allow_agent (Optional[boolean]): Whether or not load keys from agent .sp Default: False .UNINDENT .TP .B Return: list .UNINDENT .UNINDENT .INDENT 7.0 .TP .B static read_private_key_file(pkey_file, pkey_password=None, key_type=None, logger=None) Get SSH Public key from a private key file, given an optional password .INDENT 7.0 .TP .B Arguments: .INDENT 7.0 .TP .B pkey_file (str): File containing a private key (RSA, DSS or ECDSA) .UNINDENT .TP .B Keyword Arguments: .INDENT 7.0 .TP .B pkey_password (Optional[str]): Password to decrypt the private key .UNINDENT .sp logger (Optional[logging.Logger]) .TP .B Return: paramiko.Pkey .UNINDENT .UNINDENT .INDENT 7.0 .TP .B start() Start the SSH tunnels .UNINDENT .INDENT 7.0 .TP .B stop(force=False) Shut the tunnel down. By default we are always waiting until closing all connections. You can use \fIforce=True\fP to force close connections .INDENT 7.0 .TP .B Keyword Arguments: .INDENT 7.0 .TP .B force (bool): Force close current connections .sp Default: False .sp Added in version 0.2.2. .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 This \fBhad\fP to be handled with care before \fB0.1.0\fP: .INDENT 0.0 .IP \(bu 2 if a port redirection is opened .IP \(bu 2 the destination is not reachable .IP \(bu 2 we attempt a connection to that tunnel (\fBSYN\fP is sent and acknowledged, then a \fBFIN\fP packet is sent and never acknowledged... weird) .IP \(bu 2 we try to shutdown: it will not succeed until \fBFIN_WAIT_2\fP and \fBCLOSE_WAIT\fP time out. .UNINDENT .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 Handle these scenarios with \fBtunnel_is_up\fP: if False, server \fBshutdown()\fP will be skipped on that tunnel .UNINDENT .UNINDENT .UNINDENT .INDENT 7.0 .TP .B close() Stop the an active tunnel, alias to \fI\%stop()\fP .UNINDENT .INDENT 7.0 .TP .B restart() Restart connection to the gateway and tunnels .UNINDENT .INDENT 7.0 .TP .B property local_bind_ports Return a list containing the ports of local side of the TCP tunnels .UNINDENT .INDENT 7.0 .TP .B property local_bind_hosts Return a list containing the IP addresses listening for the tunnels .UNINDENT .INDENT 7.0 .TP .B property local_bind_addresses Return a list of (IP, port) pairs for the local side of the tunnels .UNINDENT .INDENT 7.0 .TP .B property tunnel_bindings Return a dictionary containing the active local<>remote tunnel_bindings .UNINDENT .INDENT 7.0 .TP .B property is_active Return True if the underlying SSH transport is up .UNINDENT .UNINDENT .INDENT 0.0 .TP .B sshtunnel.open_tunnel(*args, **kwargs) Open an SSH Tunnel, wrapper for \fI\%SSHTunnelForwarder\fP .INDENT 7.0 .TP .B Arguments: .INDENT 7.0 .TP .B destination (Optional[tuple]): SSH server\(aqs IP address and port in the format (\fBssh_address\fP, \fBssh_port\fP) .UNINDENT .TP .B Keyword Arguments: .INDENT 7.0 .TP .B debug_level (Optional[int or str]): log level for \X'tty: link https://docs.python.org/3/library/logging.html#logging.Logger'\fI\%logging.Logger\fP\X'tty: link' instance, i.e. \fBDEBUG\fP .TP .B skip_tunnel_checkup (boolean): Enable/disable the local side check and populate \fBtunnel_is_up\fP .sp Default: True .sp Added in version 0.1.0. .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 A value of \fBdebug_level\fP set to 1 == \fBTRACE\fP enables tracing mode .UNINDENT .UNINDENT .sp \fBNOTE:\fP .INDENT 7.0 .INDENT 3.5 See \fI\%SSHTunnelForwarder\fP for keyword arguments .UNINDENT .UNINDENT .sp \fBExample\fP: .INDENT 7.0 .INDENT 3.5 .sp .EX from sshtunnel import open_tunnel with open_tunnel(SERVER, ssh_username=SSH_USER, ssh_port=22, ssh_password=SSH_PASSWORD, remote_bind_address=(REMOTE_HOST, REMOTE_PORT), local_bind_address=(\(aq\(aq, LOCAL_PORT)) as server: def do_something(port): pass print(\(dqLOCAL PORTS:\(dq, server.local_bind_port) do_something(server.local_bind_port) .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \X'tty: link https://github.com/cameronmaske'\fI\%Cameron Maske\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/gdmachado'\fI\%Gustavo Machado\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/cjermain'\fI\%Colin Jermain\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link' \- (big thanks!) .IP \(bu 2 \X'tty: link https://github.com/lewisthompson'\fI\%Lewis Thompson\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/ewrogers'\fI\%Erik Rogers\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/mrts'\fI\%Mart Sõmermaa\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/Chronial'\fI\%Chronial\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/RasterBurn'\fI\%Dan Harbin\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/ipeluffo'\fI\%Ignacio Peluffo\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/NielsZeilemaker'\fI\%Niels Zeilemaker\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/g0djan'\fI\%Georgy Rylov\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/eddie-chiang'\fI\%Eddie Chiang\fP\X'tty: link' .IP \(bu 2 \X'tty: link https://github.com/kkrasovskii'\fI\%kkrasovskii\fP\X'tty: link' .UNINDENT .INDENT 0.0 .IP \(bu 2 .INDENT 2.0 .TP .B v.0.4.0 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Change the daemon mod flag for all tunnel threads (is not fully backward compatible) to prevent unexpected hangs (\X'tty: link https://github.com/pahaz/sshtunnel/issues/219'\fI\%#219\fP\X'tty: link') .IP \(bu 2 Add docker based end to end functinal tests for Mongo/Postgres/MySQL (\X'tty: link https://github.com/pahaz/sshtunnel/issues/219'\fI\%#219\fP\X'tty: link') .IP \(bu 2 Add docker based end to end hangs tests (\X'tty: link https://github.com/pahaz/sshtunnel/issues/219'\fI\%#219\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.3.2 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link', \X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Fix host key directory detection .IP \(bu 2 Unify default ssh config folder to \fI~/.ssh\fP .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.3.1 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Increase open connection timeout to 10 secods .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.3.0 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Change default with context behavior to use \fI\&.stop(force=True)\fP on exit (is not fully backward compatible) .IP \(bu 2 Remove useless \fIdaemon_forward_servers = True\fP hack for hangs prevention (is not fully backward compatible) .IP \(bu 2 Set transport keepalive to 5 second by default (disabled for version < 0.3.0) .IP \(bu 2 Set default transport timeout to 0.1 .IP \(bu 2 Deprecate and remove \fIblock_on_close\fP option .IP \(bu 2 Fix \(dqdeadlocks\(dq / \(dqtunneling hangs\(dq (\X'tty: link https://github.com/pahaz/sshtunnel/issues/173'\fI\%#173\fP\X'tty: link', \X'tty: link https://github.com/pahaz/sshtunnel/issues/201'\fI\%#201\fP\X'tty: link', \X'tty: link https://github.com/pahaz/sshtunnel/issues/162'\fI\%#162\fP\X'tty: link', \X'tty: link https://github.com/pahaz/sshtunnel/issues/211'\fI\%#211\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.2.2 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Add \fI\&.stop(force=True)\fP for force close active connections (\X'tty: link https://github.com/pahaz/sshtunnel/issues/201'\fI\%#201\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.2.1 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link', \X'tty: link https://github.com/eddie-chiang'\fI\%Eddie Chiang\fP\X'tty: link' and \X'tty: link https://github.com/kkrasovskii'\fI\%kkrasovskii\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Fixes bug with orphan thread for a tunnel that is DOWN (\X'tty: link https://github.com/pahaz/sshtunnel/issues/170'\fI\%#170\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.2.0 (\X'tty: link https://github.com/g0djan'\fI\%Georgy Rylov\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Support IPv6 without proxy command. Use built\-in paramiko create socket logic. The logic tries to use ipv6 socket family first, then ipv4 socket family. .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.1.5 (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Introduce \fIblock_on_close\fP attribute .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.1.4 (\X'tty: link https://github.com/NielsZeilemaker'\fI\%Niels Zeilemaker\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Allow loading pkeys from \fI~/.ssh\fP .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.1.3 (\X'tty: link https://github.com/ipeluffo'\fI\%Ignacio Peluffo\fP\X'tty: link' and others) .INDENT 7.0 .IP \(bu 2 \fBpkey_file\fP parameter updated to accept relative paths to user folder using \fB~\fP .IP \(bu 2 Several bugfixes .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.1.2 (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Fix #77 .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.1.1 (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Fix #72 .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.1.0 (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Add \fItunnel_bindings\fP property .IP \(bu 2 Several bugfixes (#49, #56, #57, #59, #60, #62, #64, #66, ...) (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link', \X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add TRACE logging level (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Code and tests refactoring (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Drop python3.2 support .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.8 (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Merge \X'tty: link https://github.com/pahaz/sshtunnel/issues/31'\fI\%#31\fP\X'tty: link': Support Unix domain socket (local) forwarding (\X'tty: link https://github.com/RasterBurn'\fI\%Dan Harbin\fP\X'tty: link') .IP \(bu 2 Simplify API (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add sphinx\-based documentation (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add \fBallow_agent\fP (fixes \X'tty: link https://github.com/pahaz/sshtunnel/issues/36'\fI\%#36\fP\X'tty: link', \X'tty: link https://github.com/pahaz/sshtunnel/issues/46'\fI\%#46\fP\X'tty: link') (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add \fBcompression\fP (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add \fB__str__\fP method (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add test functions (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Fix default username when not provided and ssh_config file is skipped (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Fix gateway IP unresolvable exception catching (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Minor fixes (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add AppVeyor support (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.7 (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 Tunnels can now be stopped and started safely (\X'tty: link https://github.com/pahaz/sshtunnel/issues/41'\fI\%#41\fP\X'tty: link') (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add timeout to SSH gateway and keep\-alive messages (\X'tty: link https://github.com/pahaz/sshtunnel/issues/29'\fI\%#29\fP\X'tty: link') (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Allow sending a pkey directly (\X'tty: link https://github.com/pahaz/sshtunnel/issues/43'\fI\%#43\fP\X'tty: link') (\X'tty: link https://github.com/Chronial'\fI\%Chronial\fP\X'tty: link') .IP \(bu 2 Add \fB\-V\fP CLI option to show current version (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Add coverage (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 Refactoring (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.6 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 add \fB\-S\fP CLI options for ssh private key password support (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.5 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 add \fBssh_proxy\fP argument, as well as \fBssh_config(5)\fP \fBProxyCommand\fP support (\X'tty: link https://github.com/lewisthompson'\fI\%Lewis Thompson\fP\X'tty: link') .IP \(bu 2 add some python 2.6 compatibility fixes (\X'tty: link https://github.com/mrts'\fI\%Mart Sõmermaa\fP\X'tty: link') .IP \(bu 2 \fBparamiko.transport\fP inherits handlers of loggers passed to \fBSSHTunnelForwarder\fP (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 fix \X'tty: link https://github.com/pahaz/sshtunnel/issues/34'\fI\%#34\fP\X'tty: link', \X'tty: link https://github.com/pahaz/sshtunnel/issues/33'\fI\%#33\fP\X'tty: link', code style and docs (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 add tests (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .IP \(bu 2 add CI integration (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .IP \(bu 2 normal packaging (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .IP \(bu 2 disable check distenation socket connection by \fBSSHTunnelForwarder.local_is_up\fP (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') [changed default behavior] .IP \(bu 2 use daemon mode = False in all threads by default; \X'tty: link https://github.com/pahaz/sshtunnel/commit/64af238b799b0e0057c4f9b386cda247e0006da9#diff-76bc1662a114401c2954deb92b740081R127'\fI\%detail\fP\X'tty: link' (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') [changed default behavior] .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.4.4 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 fix issue \X'tty: link https://github.com/pahaz/sshtunnel/issues/24'\fI\%#24\fP\X'tty: link' \- hide ssh password in logs (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.4.3 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 fix default port issue \X'tty: link https://github.com/pahaz/sshtunnel/issues/19'\fI\%#19\fP\X'tty: link' (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.4.2 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 fix Thread.daemon mode for Python < 3.3 \X'tty: link https://github.com/pahaz/sshtunnel/issues/16'\fI\%#16\fP\X'tty: link', \X'tty: link https://github.com/pahaz/sshtunnel/issues/21'\fI\%#21\fP\X'tty: link' (\X'tty: link https://github.com/lewisthompson'\fI\%Lewis Thompson\fP\X'tty: link', \X'tty: link https://github.com/ewrogers'\fI\%Erik Rogers\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.4.1 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 fix CLI issues \X'tty: link https://github.com/pahaz/sshtunnel/issues/13'\fI\%#13\fP\X'tty: link' (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.4 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 daemon mode by default for all threads (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link', \X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') \- \fIincompatible\fP .IP \(bu 2 move \fBmake_ssh_forward_server\fP to \fBSSHTunnelForwarder.make_ssh_forward_server\fP (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link', \X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') \- \fIincompatible\fP .IP \(bu 2 move \fBmake_ssh_forward_handler\fP to \fBSSHTunnelForwarder.make_ssh_forward_handler_class\fP (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link', \X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') \- \fIincompatible\fP .IP \(bu 2 rename \fBopen\fP to \fBopen_tunnel\fP (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') \- \fIincompatible\fP .IP \(bu 2 add CLI interface (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 support opening several tunnels at once (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 improve stability and readability (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link', \X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .IP \(bu 2 improve logging (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link', \X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .IP \(bu 2 add \fBraise_exception_if_any_forwarder_have_a_problem\fP argument for opening several tunnels at once (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .IP \(bu 2 add \fBssh_config_file\fP argument support (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link') .IP \(bu 2 add Python 3 support (\X'tty: link https://github.com/fernandezcuesta'\fI\%JM Fernández\fP\X'tty: link', \X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.3 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 add \fBthreaded\fP option (\X'tty: link https://github.com/cameronmaske'\fI\%Cameron Maske\fP\X'tty: link') .IP \(bu 2 fix exception error message, correctly printing destination address (\X'tty: link https://github.com/gdmachado'\fI\%Gustavo Machado\fP\X'tty: link') .IP \(bu 2 fix \fBpip install\fP failure (\X'tty: link https://github.com/cjermain'\fI\%Colin Jermain\fP\X'tty: link', \X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .UNINDENT .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B v.0.0.1 (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .INDENT 7.0 .IP \(bu 2 \fBSSHTunnelForwarder\fP class (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .IP \(bu 2 \fBopen\fP function (\X'tty: link https://github.com/pahaz'\fI\%Pahaz\fP\X'tty: link') .UNINDENT .UNINDENT .UNINDENT .sp Copyright (c) 2014\-2019 Pahaz White .sp Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \(dqSoftware\(dq), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: .sp The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. .sp THE SOFTWARE IS PROVIDED \(dqAS IS\(dq, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .SH AUTHOR Pahaz White .SH COPYRIGHT 2014-2020, Pahaz White and contributors .\" Generated by docutils manpage writer. .