New upstream snapshot.
Debian Janitor
4 years ago
0 | version: 2 | |
1 | ||
2 | jobs: | |
3 | build: | |
4 | docker: &docker | |
5 | - image: circleci/python:latest | |
6 | steps: &steps | |
7 | - run: sudo chmod -R a+r /tmp | |
8 | - checkout | |
9 | - restore_cache: &restore_cache | |
10 | keys: | |
11 | - v2-deps-{{ .Environment.CIRCLE_JOB }}-{{ checksum "sshtunnel.py" }} | |
12 | - run: &install_sshtunnel | |
13 | name: Install sshtunnel | |
14 | command: sudo python setup.py install | |
15 | - run: sudo pip install mock pytest{,-cov,-xdist} coveralls | |
16 | - run: pip list | |
17 | - save_cache: &save_cache | |
18 | paths: | |
19 | - ~/.cache/pip | |
20 | key: v2-deps-{{ .Environment.CIRCLE_JOB }}-{{ checksum "sshtunnel.py" }} | |
21 | - run: py.test --showlocals --cov sshtunnel --durations=10 -n4 tests | |
22 | -W ignore::DeprecationWarning | |
23 | - run: coveralls | |
24 | ||
25 | python_2.7: | |
26 | docker: | |
27 | - image: circleci/python:2.7 | |
28 | steps: *steps | |
29 | ||
30 | python_3.4: | |
31 | docker: | |
32 | - image: circleci/python:3.4 | |
33 | steps: *steps | |
34 | ||
35 | python_3.5: | |
36 | docker: | |
37 | - image: circleci/python:3.5 | |
38 | steps: *steps | |
39 | ||
40 | python_3.6: | |
41 | docker: | |
42 | - image: circleci/python:3.6 | |
43 | steps: *steps | |
44 | ||
45 | python_3.7: | |
46 | docker: | |
47 | - image: circleci/python:3.7 | |
48 | steps: *steps | |
49 | ||
50 | docs: | |
51 | docker: *docker | |
52 | steps: | |
53 | - checkout | |
54 | - run: *install_sshtunnel | |
55 | - restore_cache: *restore_cache | |
56 | - run: sudo pip install -r docs/requirements-docs.txt | |
57 | - run: sphinx-build -WavE -b html docs _build/html | |
58 | - save_cache: *save_cache | |
59 | ||
60 | syntax: | |
61 | docker: *docker | |
62 | steps: | |
63 | - checkout | |
64 | - run: *install_sshtunnel | |
65 | - restore_cache: *restore_cache | |
66 | - run: | |
67 | name: installing testing dependencies | |
68 | command: sudo pip install bashtest check-manifest docutils flake8 | |
69 | mccabe pygments readme twine | |
70 | - run: | |
71 | name: checking MANIFEST.in | |
72 | command: sudo check-manifest --ignore "tox.ini,tests*,*.yml" | |
73 | - run: | |
74 | name: checking RST syntax | |
75 | command: sudo python setup.py sdist ; twine check dist/* | |
76 | - run: | |
77 | name: checking PEP8 compliancy | |
78 | command: flake8 --ignore=W504 . | |
79 | - run: | |
80 | name: checking CLI help | |
81 | command: bashtest README.rst | |
82 | - save_cache: *save_cache | |
83 | ||
84 | workflows: | |
85 | version: 2 | |
86 | tests: | |
87 | jobs: | |
88 | - build # python3.7 | |
89 | - python_2.7 | |
90 | - python_3.4 | |
91 | - python_3.5 | |
92 | - python_3.6 | |
93 | - python_3.7 | |
94 | syntax_and_docs: | |
95 | jobs: | |
96 | - syntax | |
97 | - docs |
0 | # sshtunnel | |
1 | .python-version | |
2 | .venv | |
3 | .idea | |
4 | .env | |
5 | ||
6 | # general things to ignore | |
7 | build/ | |
8 | dist/ | |
9 | *.egg-info/ | |
10 | *.egg*/ | |
11 | *.py[cod] | |
12 | __pycache__/ | |
13 | *.so | |
14 | .*cache*/ | |
15 | #*~ | |
16 | ||
17 | # due to using tox and pytest | |
18 | .tox | |
19 | .cache | |
20 | .coverage* | |
21 | *cov* | |
22 | pytestdebug.log | |
23 | ||
24 | # due to sphinx | |
25 | docs/_build/ |
0 | Copyright (c) 2014-2016 Pahaz Blinov | |
0 | Copyright (c) 2014-2019 Pahaz Blinov | |
1 | 1 | |
2 | 2 | Permission is hereby granted, free of charge, to any person obtaining a copy |
3 | 3 | of this software and associated documentation files (the "Software"), to deal |
0 | 0 | # Include the data files recursive-include data * |
1 | ||
2 | # If using Python 2.6 or less, then have to include package data, even though | |
3 | # it's already declared in setup.py | |
4 | # include sample/*.dat | |
5 | 1 | |
6 | 2 | include LICENSE |
7 | 3 | include *.rst |
10 | 6 | include docs/*.rst |
11 | 7 | include docs/*.txt |
12 | 8 | include tests/* |
9 | include .circleci/* | |
10 |
0 | Metadata-Version: 1.1 | |
1 | Name: sshtunnel | |
2 | Version: 0.1.4 | |
3 | Summary: Pure python SSH tunnels | |
4 | Home-page: https://github.com/pahaz/sshtunnel | |
5 | Author: Pahaz Blinov | |
6 | Author-email: pahaz.blinov@gmail.com | |
7 | License: MIT | |
8 | Download-URL: https://pypi.python.org/packages/source/s/sshtunnel/sshtunnel-0.1.4.zip | |
9 | Description-Content-Type: UNKNOWN | |
10 | Description: |CircleCI| |AppVeyor| |readthedocs| |coveralls| |version| | |
11 | ||
12 | |pyversions| |license| | |
13 | ||
14 | **Author**: `Pahaz Blinov`_ | |
15 | ||
16 | **Repo**: https://github.com/pahaz/sshtunnel/ | |
17 | ||
18 | Inspired by https://github.com/jmagnusson/bgtunnel, but it doesn't work on | |
19 | Windows. | |
20 | ||
21 | See also: https://github.com/paramiko/paramiko/blob/master/demos/forward.py | |
22 | ||
23 | Requirements | |
24 | ------------- | |
25 | ||
26 | * `paramiko`_ | |
27 | ||
28 | Installation | |
29 | ============ | |
30 | ||
31 | `sshtunnel`_ is on PyPI, so simply run: | |
32 | ||
33 | :: | |
34 | ||
35 | pip install sshtunnel | |
36 | ||
37 | or :: | |
38 | ||
39 | easy_install sshtunnel | |
40 | ||
41 | or :: | |
42 | ||
43 | conda install -c conda-forge sshtunnel | |
44 | ||
45 | to have it installed in your environment. | |
46 | ||
47 | For installing from source, clone the | |
48 | `repo <https://github.com/pahaz/sshtunnel>`_ and run:: | |
49 | ||
50 | python setup.py install | |
51 | ||
52 | Testing the package | |
53 | ------------------- | |
54 | ||
55 | In order to run the tests you first need | |
56 | `tox <https://testrun.org/tox/latest/>`_ and run:: | |
57 | ||
58 | python setup.py test | |
59 | ||
60 | Usage scenarios | |
61 | =============== | |
62 | ||
63 | One of the typical scenarios where ``sshtunnel`` is helpful is depicted in the | |
64 | figure below. User may need to connect a port of a remote server (i.e. 8080) | |
65 | where only SSH port (usually port 22) is reachable. :: | |
66 | ||
67 | ---------------------------------------------------------------------- | |
68 | ||
69 | | | |
70 | -------------+ | +----------+ | |
71 | LOCAL | | | REMOTE | :22 SSH | |
72 | CLIENT | <== SSH ========> | SERVER | :8080 web service | |
73 | -------------+ | +----------+ | |
74 | | | |
75 | FIREWALL (only port 22 is open) | |
76 | ||
77 | ---------------------------------------------------------------------- | |
78 | ||
79 | **Fig1**: How to connect to a service blocked by a firewall through SSH tunnel. | |
80 | ||
81 | ||
82 | If allowed by the SSH server, it is also possible to reach a private server | |
83 | (from the perspective of ``REMOTE SERVER``) not directly visible from the | |
84 | outside (``LOCAL CLIENT``'s perspective). :: | |
85 | ||
86 | ---------------------------------------------------------------------- | |
87 | ||
88 | | | |
89 | -------------+ | +----------+ +--------- | |
90 | LOCAL | | | REMOTE | | PRIVATE | |
91 | CLIENT | <== SSH ========> | SERVER | <== local ==> | SERVER | |
92 | -------------+ | +----------+ +--------- | |
93 | | | |
94 | FIREWALL (only port 443 is open) | |
95 | ||
96 | ---------------------------------------------------------------------- | |
97 | ||
98 | **Fig2**: How to connect to ``PRIVATE SERVER`` through SSH tunnel. | |
99 | ||
100 | ||
101 | Usage examples | |
102 | ============== | |
103 | ||
104 | API allows either initializing the tunnel and starting it or using a ``with`` | |
105 | context, which will take care of starting **and stopping** the tunnel: | |
106 | ||
107 | Example 1 | |
108 | --------- | |
109 | ||
110 | Code corresponding to **Fig1** above follows, given remote server's address is | |
111 | ``pahaz.urfuclub.ru``, password authentication and randomly assigned local bind | |
112 | port. | |
113 | ||
114 | .. code-block:: py | |
115 | ||
116 | from sshtunnel import SSHTunnelForwarder | |
117 | ||
118 | server = SSHTunnelForwarder( | |
119 | 'pahaz.urfuclub.ru', | |
120 | ssh_username="pahaz", | |
121 | ssh_password="secret", | |
122 | remote_bind_address=('127.0.0.1', 8080) | |
123 | ) | |
124 | ||
125 | server.start() | |
126 | ||
127 | print(server.local_bind_port) # show assigned local port | |
128 | # work with `SECRET SERVICE` through `server.local_bind_port`. | |
129 | ||
130 | server.stop() | |
131 | ||
132 | Example 2 | |
133 | --------- | |
134 | ||
135 | Example of a port forwarding to a private server not directly reachable, | |
136 | assuming password protected pkey authentication, remote server's SSH service is | |
137 | listening on port 443 and that port is open in the firewall (**Fig2**): | |
138 | ||
139 | .. code-block:: py | |
140 | ||
141 | import paramiko | |
142 | from sshtunnel import SSHTunnelForwarder | |
143 | ||
144 | with SSHTunnelForwarder( | |
145 | (REMOTE_SERVER_IP, 443), | |
146 | ssh_username="", | |
147 | ssh_pkey="/var/ssh/rsa_key", | |
148 | ssh_private_key_password="secret", | |
149 | remote_bind_address=(PRIVATE_SERVER_IP, 22), | |
150 | local_bind_address=('0.0.0.0', 10022) | |
151 | ) as tunnel: | |
152 | client = paramiko.SSHClient() | |
153 | client.load_system_host_keys() | |
154 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | |
155 | client.connect('127.0.0.1', 10022) | |
156 | # do some operations with client session | |
157 | client.close() | |
158 | ||
159 | print('FINISH!') | |
160 | ||
161 | Example 3 | |
162 | --------- | |
163 | ||
164 | Example of a port forwarding for the Vagrant MySQL local port: | |
165 | ||
166 | .. code-block:: py | |
167 | ||
168 | from sshtunnel import SSHTunnelForwarder | |
169 | from time import sleep | |
170 | ||
171 | with SSHTunnelForwarder( | |
172 | ('localhost', 2222), | |
173 | ssh_username="vagrant", | |
174 | ssh_password="vagrant", | |
175 | remote_bind_address=('127.0.0.1', 3306) | |
176 | ) as server: | |
177 | ||
178 | print(server.local_bind_port) | |
179 | while True: | |
180 | # press Ctrl-C for stopping | |
181 | sleep(1) | |
182 | ||
183 | print('FINISH!') | |
184 | ||
185 | Or simply using the CLI: | |
186 | ||
187 | .. code-block:: console | |
188 | ||
189 | (bash)$ python -m sshtunnel -U vagrant -P vagrant -L :3306 -R 127.0.0.1:3306 -p 2222 localhost | |
190 | ||
191 | CLI usage | |
192 | ========= | |
193 | ||
194 | :: | |
195 | ||
196 | $ sshtunnel --help | |
197 | usage: sshtunnel [-h] [-U SSH_USERNAME] [-p SSH_PORT] [-P SSH_PASSWORD] -R | |
198 | IP:PORT [IP:PORT ...] [-L [IP:PORT [IP:PORT ...]]] | |
199 | [-k SSH_HOST_KEY] [-K KEY_FILE] [-S KEY_PASSWORD] [-t] [-v] | |
200 | [-V] [-x IP:PORT] [-c SSH_CONFIG_FILE] [-z] [-n] [-d [FOLDER [FOLDER ...]]] | |
201 | ssh_address | |
202 | ||
203 | Pure python ssh tunnel utils | |
204 | Version 0.1.4 | |
205 | ||
206 | positional arguments: | |
207 | ssh_address SSH server IP address (GW for SSH tunnels) | |
208 | set with "-- ssh_address" if immediately after -R or -L | |
209 | ||
210 | optional arguments: | |
211 | -h, --help show this help message and exit | |
212 | -U SSH_USERNAME, --username SSH_USERNAME | |
213 | SSH server account username | |
214 | -p SSH_PORT, --server_port SSH_PORT | |
215 | SSH server TCP port (default: 22) | |
216 | -P SSH_PASSWORD, --password SSH_PASSWORD | |
217 | SSH server account password | |
218 | -R IP:PORT [IP:PORT ...], --remote_bind_address IP:PORT [IP:PORT ...] | |
219 | Remote bind address sequence: ip_1:port_1 ip_2:port_2 ... ip_n:port_n | |
220 | Equivalent to ssh -Lxxxx:IP_ADDRESS:PORT | |
221 | If port is omitted, defaults to 22. | |
222 | Example: -R 10.10.10.10: 10.10.10.10:5900 | |
223 | -L [IP:PORT [IP:PORT ...]], --local_bind_address [IP:PORT [IP:PORT ...]] | |
224 | Local bind address sequence: ip_1:port_1 ip_2:port_2 ... ip_n:port_n | |
225 | Elements may also be valid UNIX socket domains: | |
226 | /tmp/foo.sock /tmp/bar.sock ... /tmp/baz.sock | |
227 | Equivalent to ssh -LPORT:xxxxxxxxx:xxxx, being the local IP address optional. | |
228 | By default it will listen in all interfaces (0.0.0.0) and choose a random port. | |
229 | Example: -L :40000 | |
230 | -k SSH_HOST_KEY, --ssh_host_key SSH_HOST_KEY | |
231 | Gateway's host key | |
232 | -K KEY_FILE, --private_key_file KEY_FILE | |
233 | RSA/DSS/ECDSA private key file | |
234 | -S KEY_PASSWORD, --private_key_password KEY_PASSWORD | |
235 | RSA/DSS/ECDSA private key password | |
236 | -t, --threaded Allow concurrent connections to each tunnel | |
237 | -v, --verbose Increase output verbosity (default: ERROR) | |
238 | -V, --version Show version number and quit | |
239 | -x IP:PORT, --proxy IP:PORT | |
240 | IP and port of SSH proxy to destination | |
241 | -c SSH_CONFIG_FILE, --config SSH_CONFIG_FILE | |
242 | SSH configuration file, defaults to ~/.ssh/config | |
243 | -z, --compress Request server for compression over SSH transport | |
244 | -n, --noagent Disable looking for keys from an SSH agent | |
245 | -d [FOLDER [FOLDER ...]], --host_pkey_directories [FOLDER [FOLDER ...]] | |
246 | List of directories where SSH pkeys (in the format `id_*`) may be found | |
247 | ||
248 | .. _Pahaz Blinov: https://github.com/pahaz | |
249 | .. _sshtunnel: https://pypi.python.org/pypi/sshtunnel | |
250 | .. _paramiko: http://www.paramiko.org/ | |
251 | .. |CircleCI| image:: https://circleci.com/gh/pahaz/sshtunnel.svg?style=svg | |
252 | :target: https://circleci.com/gh/pahaz/sshtunnel | |
253 | .. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/oxg1vx2ycmnw3xr9?svg=true&passingText=Windows%20-%20OK&failingText=Windows%20-%20Fail | |
254 | :target: https://ci.appveyor.com/project/pahaz/sshtunnel | |
255 | .. |readthedocs| image:: https://readthedocs.org/projects/sshtunnel/badge/?version=latest | |
256 | :target: http://sshtunnel.readthedocs.io/en/latest/?badge=latest | |
257 | :alt: Documentation Status | |
258 | .. |coveralls| image:: https://coveralls.io/repos/github/pahaz/sshtunnel/badge.svg?branch=master | |
259 | :target: https://coveralls.io/github/pahaz/sshtunnel?branch=master | |
260 | .. |pyversions| image:: https://img.shields.io/pypi/pyversions/sshtunnel.svg | |
261 | .. |version| image:: https://img.shields.io/pypi/v/sshtunnel.svg | |
262 | :target: `sshtunnel`_ | |
263 | .. |license| image:: https://img.shields.io/pypi/l/sshtunnel.svg | |
264 | :target: https://github.com/pahaz/sshtunnel/blob/master/LICENSE | |
265 | ||
266 | Online documentation | |
267 | ==================== | |
268 | ||
269 | Documentation may be found at `readthedocs`_. | |
270 | ||
271 | .. _readthedocs: https://sshtunnel.readthedocs.org/ | |
272 | ||
273 | CONTRIBUTORS | |
274 | ============ | |
275 | ||
276 | - `Cameron Maske`_ | |
277 | - `Gustavo Machado`_ | |
278 | - `Colin Jermain`_ | |
279 | - `JM Fernández`_ - (big thanks!) | |
280 | - `Lewis Thompson`_ | |
281 | - `Erik Rogers`_ | |
282 | - `Mart Sõmermaa`_ | |
283 | - `Chronial`_ | |
284 | - `Dan Harbin`_ | |
285 | - `Ignacio Peluffo`_ | |
286 | - `Niels Zeilemaker`_ | |
287 | ||
288 | CHANGELOG | |
289 | ========= | |
290 | ||
291 | - v.0.1.4 (`Niels Zeilemaker`_) | |
292 | + Allow loading pkeys from `~/.ssh` | |
293 | ||
294 | - v.0.1.3 (`Ignacio Peluffo`_ and others) | |
295 | + ``pkey_file`` parameter updated to accept relative paths to user folder using ``~`` | |
296 | + Several bugfixes | |
297 | ||
298 | - v.0.1.2 (`JM Fernández`_) | |
299 | + Fix #77 | |
300 | ||
301 | - v.0.1.1 (`JM Fernández`_) | |
302 | + Fix #72 | |
303 | ||
304 | - v.0.1.0 (`JM Fernández`_) | |
305 | + Add `tunnel_bindings` property | |
306 | + Several bugfixes (#49, #56, #57, #59, #60, #62, #64, #66, ...) | |
307 | (`Pahaz Blinov`_, `JM Fernández`_) | |
308 | + Add TRACE logging level (`JM Fernández`_) | |
309 | + Code and tests refactoring (`JM Fernández`_) | |
310 | + Drop python3.2 support | |
311 | ||
312 | - v.0.0.8 (`JM Fernández`_) | |
313 | + Merge `#31`_: Support Unix domain socket (local) forwarding (`Dan Harbin`_) | |
314 | + Simplify API (`JM Fernández`_) | |
315 | + Add sphinx-based documentation (`JM Fernández`_) | |
316 | + Add ``allow_agent`` (fixes `#36`_, `#46`_) (`JM Fernández`_) | |
317 | + Add ``compression`` (`JM Fernández`_) | |
318 | + Add ``__str__`` method (`JM Fernández`_) | |
319 | + Add test functions (`JM Fernández`_) | |
320 | + Fix default username when not provided and ssh_config file is skipped (`JM Fernández`_) | |
321 | + Fix gateway IP unresolvable exception catching (`JM Fernández`_) | |
322 | + Minor fixes (`JM Fernández`_) | |
323 | + Add AppVeyor support (`JM Fernández`_) | |
324 | ||
325 | - v.0.0.7 (`JM Fernández`_) | |
326 | + Tunnels can now be stopped and started safely (`#41`_) (`JM Fernández`_) | |
327 | + Add timeout to SSH gateway and keep-alive messages (`#29`_) (`JM Fernández`_) | |
328 | + Allow sending a pkey directly (`#43`_) (`Chronial`_) | |
329 | + Add ``-V`` CLI option to show current version (`JM Fernández`_) | |
330 | + Add coverage (`JM Fernández`_) | |
331 | + Refactoring (`JM Fernández`_) | |
332 | ||
333 | - v.0.0.6 (`Pahaz Blinov`_) | |
334 | + add ``-S`` CLI options for ssh private key password support (`Pahaz Blinov`_) | |
335 | ||
336 | - v.0.0.5 (`Pahaz Blinov`_) | |
337 | + add ``ssh_proxy`` argument, as well as ``ssh_config(5)`` ``ProxyCommand`` support (`Lewis Thompson`_) | |
338 | + add some python 2.6 compatibility fixes (`Mart Sõmermaa`_) | |
339 | + ``paramiko.transport`` inherits handlers of loggers passed to ``SSHTunnelForwarder`` (`JM Fernández`_) | |
340 | + fix `#34`_, `#33`_, code style and docs (`JM Fernández`_) | |
341 | + add tests (`Pahaz Blinov`_) | |
342 | + add CI integration (`Pahaz Blinov`_) | |
343 | + normal packaging (`Pahaz Blinov`_) | |
344 | + disable check distenation socket connection by ``SSHTunnelForwarder.local_is_up`` (`Pahaz Blinov`_) [changed default behavior] | |
345 | + use daemon mode = False in all threads by default; detail_ (`Pahaz Blinov`_) [changed default behavior] | |
346 | ||
347 | - v.0.0.4.4 (`Pahaz Blinov`_) | |
348 | + fix issue `#24`_ - hide ssh password in logs (`Pahaz Blinov`_) | |
349 | ||
350 | - v.0.0.4.3 (`Pahaz Blinov`_) | |
351 | + fix default port issue `#19`_ (`Pahaz Blinov`_) | |
352 | ||
353 | - v.0.0.4.2 (`Pahaz Blinov`_) | |
354 | + fix Thread.daemon mode for Python < 3.3 `#16`_, `#21`_ (`Lewis Thompson`_, `Erik Rogers`_) | |
355 | ||
356 | - v.0.0.4.1 (`Pahaz Blinov`_) | |
357 | + fix CLI issues `#13`_ (`Pahaz Blinov`_) | |
358 | ||
359 | - v.0.0.4 (`Pahaz Blinov`_) | |
360 | + daemon mode by default for all threads (`JM Fernández`_, `Pahaz Blinov`_) - *incompatible* | |
361 | + move ``make_ssh_forward_server`` to ``SSHTunnelForwarder.make_ssh_forward_server`` (`Pahaz Blinov`_, `JM Fernández`_) - *incompatible* | |
362 | + move ``make_ssh_forward_handler`` to ``SSHTunnelForwarder.make_ssh_forward_handler_class`` (`Pahaz Blinov`_, `JM Fernández`_) - *incompatible* | |
363 | + rename ``open`` to ``open_tunnel`` (`JM Fernández`_) - *incompatible* | |
364 | + add CLI interface (`JM Fernández`_) | |
365 | + support opening several tunnels at once (`JM Fernández`_) | |
366 | + improve stability and readability (`JM Fernández`_, `Pahaz Blinov`_) | |
367 | + improve logging (`JM Fernández`_, `Pahaz Blinov`_) | |
368 | + add ``raise_exception_if_any_forwarder_have_a_problem`` argument for opening several tunnels at once (`Pahaz Blinov`_) | |
369 | + add ``ssh_config_file`` argument support (`JM Fernández`_) | |
370 | + add Python 3 support (`JM Fernández`_, `Pahaz Blinov`_) | |
371 | ||
372 | - v.0.0.3 (`Pahaz Blinov`_) | |
373 | + add ``threaded`` option (`Cameron Maske`_) | |
374 | + fix exception error message, correctly printing destination address (`Gustavo Machado`_) | |
375 | + fix ``pip install`` failure (`Colin Jermain`_, `Pahaz Blinov`_) | |
376 | ||
377 | - v.0.0.1 (`Pahaz Blinov`_) | |
378 | + ``SSHTunnelForwarder`` class (`Pahaz Blinov`_) | |
379 | + ``open`` function (`Pahaz Blinov`_) | |
380 | ||
381 | ||
382 | .. _Cameron Maske: https://github.com/cameronmaske | |
383 | .. _Gustavo Machado: https://github.com/gdmachado | |
384 | .. _Colin Jermain: https://github.com/cjermain | |
385 | .. _JM Fernández: https://github.com/fernandezcuesta | |
386 | .. _Lewis Thompson: https://github.com/lewisthompson | |
387 | .. _Erik Rogers: https://github.com/ewrogers | |
388 | .. _Mart Sõmermaa: https://github.com/mrts | |
389 | .. _Chronial: https://github.com/Chronial | |
390 | .. _Dan Harbin: https://github.com/RasterBurn | |
391 | .. _Ignacio Peluffo: https://github.com/ipeluffo | |
392 | .. _Niels Zeilemaker: https://github.com/NielsZeilemaker | |
393 | .. _#13: https://github.com/pahaz/sshtunnel/issues/13 | |
394 | .. _#16: https://github.com/pahaz/sshtunnel/issues/16 | |
395 | .. _#19: https://github.com/pahaz/sshtunnel/issues/19 | |
396 | .. _#21: https://github.com/pahaz/sshtunnel/issues/21 | |
397 | .. _#24: https://github.com/pahaz/sshtunnel/issues/24 | |
398 | .. _#29: https://github.com/pahaz/sshtunnel/issues/29 | |
399 | .. _#31: https://github.com/pahaz/sshtunnel/issues/31 | |
400 | .. _#33: https://github.com/pahaz/sshtunnel/issues/33 | |
401 | .. _#34: https://github.com/pahaz/sshtunnel/issues/34 | |
402 | .. _#36: https://github.com/pahaz/sshtunnel/issues/36 | |
403 | .. _#41: https://github.com/pahaz/sshtunnel/issues/41 | |
404 | .. _#43: https://github.com/pahaz/sshtunnel/issues/43 | |
405 | .. _#46: https://github.com/pahaz/sshtunnel/issues/46 | |
406 | .. _detail: https://github.com/pahaz/sshtunnel/commit/64af238b799b0e0057c4f9b386cda247e0006da9#diff-76bc1662a114401c2954deb92b740081R127 | |
407 | ||
408 | Keywords: ssh tunnel paramiko proxy tcp-forward | |
409 | Platform: unix | |
410 | Platform: macos | |
411 | Platform: windows | |
412 | Classifier: Development Status :: 3 - Alpha | |
413 | Classifier: Intended Audience :: Developers | |
414 | Classifier: Topic :: Software Development :: Build Tools | |
415 | Classifier: License :: OSI Approved :: MIT License | |
416 | Classifier: Programming Language :: Python :: 2 | |
417 | Classifier: Programming Language :: Python :: 2.7 | |
418 | Classifier: Programming Language :: Python :: 3 | |
419 | Classifier: Programming Language :: Python :: 3.4 | |
420 | Classifier: Programming Language :: Python :: 3.5 | |
421 | Classifier: Programming Language :: Python :: 3.6 |
1 | 1 | |
2 | 2 | |pyversions| |license| |
3 | 3 | |
4 | **Author**: `Pahaz Blinov`_ | |
4 | **Author**: `Pahaz`_ | |
5 | 5 | |
6 | 6 | **Repo**: https://github.com/pahaz/sshtunnel/ |
7 | 7 | |
8 | Inspired by https://github.com/jmagnusson/bgtunnel, but it doesn't work on | |
8 | Inspired by https://github.com/jmagnusson/bgtunnel, which doesn't work on | |
9 | 9 | Windows. |
10 | 10 | |
11 | 11 | See also: https://github.com/paramiko/paramiko/blob/master/demos/forward.py |
101 | 101 | ``pahaz.urfuclub.ru``, password authentication and randomly assigned local bind |
102 | 102 | port. |
103 | 103 | |
104 | .. code-block:: py | |
104 | .. code-block:: python | |
105 | 105 | |
106 | 106 | from sshtunnel import SSHTunnelForwarder |
107 | 107 | |
126 | 126 | assuming password protected pkey authentication, remote server's SSH service is |
127 | 127 | listening on port 443 and that port is open in the firewall (**Fig2**): |
128 | 128 | |
129 | .. code-block:: py | |
129 | .. code-block:: python | |
130 | 130 | |
131 | 131 | import paramiko |
132 | from sshtunnel import SSHTunnelForwarder | |
133 | ||
134 | with SSHTunnelForwarder( | |
132 | import sshtunnel | |
133 | ||
134 | with sshtunnel.open_tunnel( | |
135 | 135 | (REMOTE_SERVER_IP, 443), |
136 | 136 | ssh_username="", |
137 | 137 | ssh_pkey="/var/ssh/rsa_key", |
153 | 153 | |
154 | 154 | Example of a port forwarding for the Vagrant MySQL local port: |
155 | 155 | |
156 | .. code-block:: py | |
157 | ||
158 | from sshtunnel import SSHTunnelForwarder | |
156 | .. code-block:: python | |
157 | ||
158 | from sshtunnel import open_tunnel | |
159 | 159 | from time import sleep |
160 | 160 | |
161 | with SSHTunnelForwarder( | |
161 | with open_tunnel( | |
162 | 162 | ('localhost', 2222), |
163 | 163 | ssh_username="vagrant", |
164 | 164 | ssh_password="vagrant", |
177 | 177 | .. code-block:: console |
178 | 178 | |
179 | 179 | (bash)$ python -m sshtunnel -U vagrant -P vagrant -L :3306 -R 127.0.0.1:3306 -p 2222 localhost |
180 | ||
181 | Example 4 | |
182 | --------- | |
183 | ||
184 | Opening an SSH session jumping over two tunnels. SSH transport and tunnels | |
185 | will be daemonised, which will not wait for the connections to stop at close | |
186 | time. | |
187 | ||
188 | .. code-block:: python | |
189 | ||
190 | import sshtunnel | |
191 | from paramiko import SSHClient | |
192 | ||
193 | ||
194 | with sshtunnel.open_tunnel( | |
195 | ssh_address_or_host=('GW1_ip', 20022), | |
196 | remote_bind_address=('GW2_ip', 22), | |
197 | block_on_close=False | |
198 | ) as tunnel1: | |
199 | print('Connection to tunnel1 (GW1_ip:GW1_port) OK...') | |
200 | with sshtunnel.open_tunnel( | |
201 | ssh_address_or_host=('localhost', tunnel1.local_bind_port), | |
202 | remote_bind_address=('target_ip', 22), | |
203 | ssh_username='GW2_user', | |
204 | ssh_password='GW2_pwd', | |
205 | block_on_close=False | |
206 | ) as tunnel2: | |
207 | print('Connection to tunnel2 (GW2_ip:GW2_port) OK...') | |
208 | with SSHClient() as ssh: | |
209 | ssh.connect('localhost', | |
210 | port=tunnel2.local_bind_port, | |
211 | username='target_user', | |
212 | password='target_pwd', | |
213 | ) | |
214 | ssh.exec_command(...) | |
215 | ||
180 | 216 | |
181 | 217 | CLI usage |
182 | 218 | ========= |
191 | 227 | ssh_address |
192 | 228 | |
193 | 229 | Pure python ssh tunnel utils |
194 | Version 0.1.4 | |
230 | Version 0.1.5 | |
195 | 231 | |
196 | 232 | positional arguments: |
197 | 233 | ssh_address SSH server IP address (GW for SSH tunnels) |
235 | 271 | -d [FOLDER [FOLDER ...]], --host_pkey_directories [FOLDER [FOLDER ...]] |
236 | 272 | List of directories where SSH pkeys (in the format `id_*`) may be found |
237 | 273 | |
238 | .. _Pahaz Blinov: https://github.com/pahaz | |
274 | .. _Pahaz: https://github.com/pahaz | |
239 | 275 | .. _sshtunnel: https://pypi.python.org/pypi/sshtunnel |
240 | 276 | .. _paramiko: http://www.paramiko.org/ |
241 | 277 | .. |CircleCI| image:: https://circleci.com/gh/pahaz/sshtunnel.svg?style=svg |
0 | platform: x64 | |
1 | ||
2 | environment: | |
3 | ||
4 | matrix: | |
5 | - PYTHON: "C:\\Python27" | |
6 | PYTHON_VERSION: "2.7.x" | |
7 | PYTHON_ARCH: "32" | |
8 | ||
9 | - PYTHON: "C:\\Python27-x64" | |
10 | PYTHON_VERSION: "2.7.x" | |
11 | PYTHON_ARCH: "64" | |
12 | ||
13 | - PYTHON: "C:\\Python36" | |
14 | PYTHON_VERSION: "3.6.x" | |
15 | PYTHON_ARCH: "32" | |
16 | ||
17 | - PYTHON: "C:\\Python36-x64" | |
18 | PYTHON_VERSION: "3.6.x" | |
19 | PYTHON_ARCH: "64" | |
20 | ||
21 | - PYTHON: "C:\\Python37" | |
22 | PYTHON_VERSION: "3.7.x" | |
23 | PYTHON_ARCH: "32" | |
24 | ||
25 | - PYTHON: "C:\\Python37-x64" | |
26 | PYTHON_VERSION: "3.7.x" | |
27 | PYTHON_ARCH: "64" | |
28 | init: | |
29 | - "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%" | |
30 | ||
31 | install: | |
32 | - set "PATH=%PYTHON%;%PYTHON%\\Scripts;%PYTHON%\\Tools\\Scripts;%PATH%" | |
33 | - "python -m pip install --upgrade pip" | |
34 | - "pip install paramiko" | |
35 | - "pip install mock pytest pytest-cov pytest-xdist" | |
36 | ||
37 | build: off | |
38 | ||
39 | test_script: | |
40 | - "python setup.py install" | |
41 | - "py.test --showlocals --durations=10 -n4 tests" | |
42 |
15 | 15 | CHANGELOG |
16 | 16 | ========= |
17 | 17 | |
18 | - v.0.1.5 (`JM Fernández`_) | |
19 | + Introduce `block_on_close` attribute | |
20 | ||
18 | 21 | - v.0.1.4 (`Niels Zeilemaker`_) |
19 | 22 | + Allow loading pkeys from `~/.ssh` |
20 | 23 | |
31 | 34 | - v.0.1.0 (`JM Fernández`_) |
32 | 35 | + Add `tunnel_bindings` property |
33 | 36 | + Several bugfixes (#49, #56, #57, #59, #60, #62, #64, #66, ...) |
34 | (`Pahaz Blinov`_, `JM Fernández`_) | |
37 | (`Pahaz`_, `JM Fernández`_) | |
35 | 38 | + Add TRACE logging level (`JM Fernández`_) |
36 | 39 | + Code and tests refactoring (`JM Fernández`_) |
37 | 40 | + Drop python3.2 support |
57 | 60 | + Add coverage (`JM Fernández`_) |
58 | 61 | + Refactoring (`JM Fernández`_) |
59 | 62 | |
60 | - v.0.0.6 (`Pahaz Blinov`_) | |
61 | + add ``-S`` CLI options for ssh private key password support (`Pahaz Blinov`_) | |
63 | - v.0.0.6 (`Pahaz`_) | |
64 | + add ``-S`` CLI options for ssh private key password support (`Pahaz`_) | |
62 | 65 | |
63 | - v.0.0.5 (`Pahaz Blinov`_) | |
66 | - v.0.0.5 (`Pahaz`_) | |
64 | 67 | + add ``ssh_proxy`` argument, as well as ``ssh_config(5)`` ``ProxyCommand`` support (`Lewis Thompson`_) |
65 | 68 | + add some python 2.6 compatibility fixes (`Mart Sõmermaa`_) |
66 | 69 | + ``paramiko.transport`` inherits handlers of loggers passed to ``SSHTunnelForwarder`` (`JM Fernández`_) |
67 | 70 | + fix `#34`_, `#33`_, code style and docs (`JM Fernández`_) |
68 | + add tests (`Pahaz Blinov`_) | |
69 | + add CI integration (`Pahaz Blinov`_) | |
70 | + normal packaging (`Pahaz Blinov`_) | |
71 | + disable check distenation socket connection by ``SSHTunnelForwarder.local_is_up`` (`Pahaz Blinov`_) [changed default behavior] | |
72 | + use daemon mode = False in all threads by default; detail_ (`Pahaz Blinov`_) [changed default behavior] | |
71 | + add tests (`Pahaz`_) | |
72 | + add CI integration (`Pahaz`_) | |
73 | + normal packaging (`Pahaz`_) | |
74 | + disable check distenation socket connection by ``SSHTunnelForwarder.local_is_up`` (`Pahaz`_) [changed default behavior] | |
75 | + use daemon mode = False in all threads by default; detail_ (`Pahaz`_) [changed default behavior] | |
73 | 76 | |
74 | - v.0.0.4.4 (`Pahaz Blinov`_) | |
75 | + fix issue `#24`_ - hide ssh password in logs (`Pahaz Blinov`_) | |
77 | - v.0.0.4.4 (`Pahaz`_) | |
78 | + fix issue `#24`_ - hide ssh password in logs (`Pahaz`_) | |
76 | 79 | |
77 | - v.0.0.4.3 (`Pahaz Blinov`_) | |
78 | + fix default port issue `#19`_ (`Pahaz Blinov`_) | |
80 | - v.0.0.4.3 (`Pahaz`_) | |
81 | + fix default port issue `#19`_ (`Pahaz`_) | |
79 | 82 | |
80 | - v.0.0.4.2 (`Pahaz Blinov`_) | |
83 | - v.0.0.4.2 (`Pahaz`_) | |
81 | 84 | + fix Thread.daemon mode for Python < 3.3 `#16`_, `#21`_ (`Lewis Thompson`_, `Erik Rogers`_) |
82 | 85 | |
83 | - v.0.0.4.1 (`Pahaz Blinov`_) | |
84 | + fix CLI issues `#13`_ (`Pahaz Blinov`_) | |
86 | - v.0.0.4.1 (`Pahaz`_) | |
87 | + fix CLI issues `#13`_ (`Pahaz`_) | |
85 | 88 | |
86 | - v.0.0.4 (`Pahaz Blinov`_) | |
87 | + daemon mode by default for all threads (`JM Fernández`_, `Pahaz Blinov`_) - *incompatible* | |
88 | + move ``make_ssh_forward_server`` to ``SSHTunnelForwarder.make_ssh_forward_server`` (`Pahaz Blinov`_, `JM Fernández`_) - *incompatible* | |
89 | + move ``make_ssh_forward_handler`` to ``SSHTunnelForwarder.make_ssh_forward_handler_class`` (`Pahaz Blinov`_, `JM Fernández`_) - *incompatible* | |
89 | - v.0.0.4 (`Pahaz`_) | |
90 | + daemon mode by default for all threads (`JM Fernández`_, `Pahaz`_) - *incompatible* | |
91 | + move ``make_ssh_forward_server`` to ``SSHTunnelForwarder.make_ssh_forward_server`` (`Pahaz`_, `JM Fernández`_) - *incompatible* | |
92 | + move ``make_ssh_forward_handler`` to ``SSHTunnelForwarder.make_ssh_forward_handler_class`` (`Pahaz`_, `JM Fernández`_) - *incompatible* | |
90 | 93 | + rename ``open`` to ``open_tunnel`` (`JM Fernández`_) - *incompatible* |
91 | 94 | + add CLI interface (`JM Fernández`_) |
92 | 95 | + support opening several tunnels at once (`JM Fernández`_) |
93 | + improve stability and readability (`JM Fernández`_, `Pahaz Blinov`_) | |
94 | + improve logging (`JM Fernández`_, `Pahaz Blinov`_) | |
95 | + add ``raise_exception_if_any_forwarder_have_a_problem`` argument for opening several tunnels at once (`Pahaz Blinov`_) | |
96 | + improve stability and readability (`JM Fernández`_, `Pahaz`_) | |
97 | + improve logging (`JM Fernández`_, `Pahaz`_) | |
98 | + add ``raise_exception_if_any_forwarder_have_a_problem`` argument for opening several tunnels at once (`Pahaz`_) | |
96 | 99 | + add ``ssh_config_file`` argument support (`JM Fernández`_) |
97 | + add Python 3 support (`JM Fernández`_, `Pahaz Blinov`_) | |
100 | + add Python 3 support (`JM Fernández`_, `Pahaz`_) | |
98 | 101 | |
99 | - v.0.0.3 (`Pahaz Blinov`_) | |
102 | - v.0.0.3 (`Pahaz`_) | |
100 | 103 | + add ``threaded`` option (`Cameron Maske`_) |
101 | 104 | + fix exception error message, correctly printing destination address (`Gustavo Machado`_) |
102 | + fix ``pip install`` failure (`Colin Jermain`_, `Pahaz Blinov`_) | |
105 | + fix ``pip install`` failure (`Colin Jermain`_, `Pahaz`_) | |
103 | 106 | |
104 | - v.0.0.1 (`Pahaz Blinov`_) | |
105 | + ``SSHTunnelForwarder`` class (`Pahaz Blinov`_) | |
106 | + ``open`` function (`Pahaz Blinov`_) | |
107 | - v.0.0.1 (`Pahaz`_) | |
108 | + ``SSHTunnelForwarder`` class (`Pahaz`_) | |
109 | + ``open`` function (`Pahaz`_) | |
107 | 110 | |
108 | 111 | |
109 | 112 | .. _Cameron Maske: https://github.com/cameronmaske |
0 | machine: | |
1 | environment: | |
2 | CIRCLE_BUILD_IMAGE: ubuntu-14.04 | |
3 | TOX_PY27: '2.7.12' | |
4 | TOX_PY34: '3.4.4' | |
5 | TOX_PY35: '3.5.3' | |
6 | TOX_PY36: '3.6.2' | |
7 | TOX_PY37: '3.7.5' | |
8 | ||
9 | dependencies: | |
10 | override: | |
11 | - pip -V | |
12 | - pip install -U pip | |
13 | - pip install -U ipdb | |
14 | - pip install --upgrade tox | |
15 | - pip install --upgrade tox-pyenv | |
16 | - pip install coveralls | |
17 | - pyenv local $TOX_PY36 $TOX_PY35 $TOX_PY34 $TOX_PY27 | |
18 | - python setup.py install | |
19 | ||
20 | test: | |
21 | override: | |
22 | - tox -v --recreate | |
23 | - coveralls |
0 | sshtunnel (0.1.4-3) UNRELEASED; urgency=medium | |
0 | sshtunnel (0.1.5+git20200114.5a15021-1) UNRELEASED; urgency=medium | |
1 | 1 | |
2 | 2 | [ Ondřej Nový ] |
3 | 3 | * Use debhelper-compat instead of debian/compat. |
6 | 6 | * Bump debhelper from old 10 to 12. |
7 | 7 | * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, |
8 | 8 | Repository-Browse. |
9 | * New upstream snapshot. | |
9 | 10 | |
10 | -- Ondřej Nový <onovy@debian.org> Fri, 19 Jul 2019 23:42:43 +0200 | |
11 | -- Debian Janitor <janitor@jelmer.uk> Tue, 28 Jan 2020 11:20:47 +0000 | |
11 | 12 | |
12 | 13 | sshtunnel (0.1.4-2) unstable; urgency=medium |
13 | 14 |
14 | 14 | |
15 | 15 | import sys |
16 | 16 | import os |
17 | ||
18 | import sshtunnel | |
17 | 19 | |
18 | 20 | # Patch to disable warning on non-local image |
19 | 21 | import sphinx.environment |
60 | 62 | |
61 | 63 | # General information about the project. |
62 | 64 | project = 'sshtunnel' |
63 | copyright = '2014-2016, Pahaz Blinov and contributors' | |
65 | copyright = '2014-2019, Pahaz Blinov and contributors' | |
64 | 66 | author = 'Pahaz Blinov' |
65 | 67 | |
66 | 68 | # The version info for the project you're documenting, acts as replacement for |
68 | 70 | # built documents. |
69 | 71 | # |
70 | 72 | # The short X.Y version. |
71 | version = '0.0.8' | |
73 | version = sshtunnel.__version__ | |
72 | 74 | # The full version, including alpha/beta/rc tags. |
73 | release = '0.0.8' | |
75 | release = sshtunnel.__version__ | |
74 | 76 | |
75 | 77 | # The language for content autogenerated by Sphinx. Refer to documentation |
76 | 78 | # for a list of supported languages. |
6 | 6 | |
7 | 7 | API |
8 | 8 | === |
9 | ||
10 | .. toctree:: | |
11 | :maxdepth: 3 | |
12 | 9 | |
13 | 10 | .. automodule:: sshtunnel |
14 | 11 | :members: |
20 | 17 | License |
21 | 18 | ======= |
22 | 19 | |
23 | .. include:: ../LICENSE⏎ | |
20 | .. include:: ../LICENSE |
0 | docutils==0.12 | |
1 | sphinx==1.3.5 | |
2 | sphinxcontrib-napoleon==0.5.0 | |
0 | docutils | |
1 | sphinx | |
2 | sphinxcontrib-napoleon |
0 | 0 | [bdist_wheel] |
1 | universal = 1 | |
1 | # This flag says that the code is written to work on both Python 2 and Python | |
2 | # 3. If at all possible, it is good practice to do this. If you cannot, you | |
3 | # will need to generate wheels for each Python version that you support. | |
4 | universal=1 | |
2 | 5 | |
3 | 6 | [check-manifest] |
4 | ignore = | |
5 | .travis.yml | |
6 | circle.yml | |
7 | tox.ini | |
7 | ignore = | |
8 | .travis.yml | |
9 | circle.yml | |
10 | tox.ini | |
8 | 11 | |
9 | 12 | [build_sphinx] |
10 | 13 | source-dir = docs/ |
11 | 14 | build-dir = docs/_build |
12 | ||
13 | [egg_info] | |
14 | tag_build = | |
15 | tag_date = 0 | |
16 |
91 | 91 | 'Programming Language :: Python :: 3.4', |
92 | 92 | 'Programming Language :: Python :: 3.5', |
93 | 93 | 'Programming Language :: Python :: 3.6', |
94 | 'Programming Language :: Python :: 3.7', | |
94 | 95 | ], |
95 | 96 | |
96 | 97 | platforms=['unix', 'macos', 'windows'], |
118 | 119 | # dependencies). You can install these using the following syntax, |
119 | 120 | # for example: |
120 | 121 | # $ pip install -e .[dev,test] |
122 | tests_require=[ | |
123 | 'tox>=1.8.1', | |
124 | ], | |
121 | 125 | extras_require={ |
122 | 126 | 'dev': ['check-manifest'], |
123 | 127 | 'test': [ |
0 | Metadata-Version: 1.1 | |
1 | Name: sshtunnel | |
2 | Version: 0.1.4 | |
3 | Summary: Pure python SSH tunnels | |
4 | Home-page: https://github.com/pahaz/sshtunnel | |
5 | Author: Pahaz Blinov | |
6 | Author-email: pahaz.blinov@gmail.com | |
7 | License: MIT | |
8 | Download-URL: https://pypi.python.org/packages/source/s/sshtunnel/sshtunnel-0.1.4.zip | |
9 | Description-Content-Type: UNKNOWN | |
10 | Description: |CircleCI| |AppVeyor| |readthedocs| |coveralls| |version| | |
11 | ||
12 | |pyversions| |license| | |
13 | ||
14 | **Author**: `Pahaz Blinov`_ | |
15 | ||
16 | **Repo**: https://github.com/pahaz/sshtunnel/ | |
17 | ||
18 | Inspired by https://github.com/jmagnusson/bgtunnel, but it doesn't work on | |
19 | Windows. | |
20 | ||
21 | See also: https://github.com/paramiko/paramiko/blob/master/demos/forward.py | |
22 | ||
23 | Requirements | |
24 | ------------- | |
25 | ||
26 | * `paramiko`_ | |
27 | ||
28 | Installation | |
29 | ============ | |
30 | ||
31 | `sshtunnel`_ is on PyPI, so simply run: | |
32 | ||
33 | :: | |
34 | ||
35 | pip install sshtunnel | |
36 | ||
37 | or :: | |
38 | ||
39 | easy_install sshtunnel | |
40 | ||
41 | or :: | |
42 | ||
43 | conda install -c conda-forge sshtunnel | |
44 | ||
45 | to have it installed in your environment. | |
46 | ||
47 | For installing from source, clone the | |
48 | `repo <https://github.com/pahaz/sshtunnel>`_ and run:: | |
49 | ||
50 | python setup.py install | |
51 | ||
52 | Testing the package | |
53 | ------------------- | |
54 | ||
55 | In order to run the tests you first need | |
56 | `tox <https://testrun.org/tox/latest/>`_ and run:: | |
57 | ||
58 | python setup.py test | |
59 | ||
60 | Usage scenarios | |
61 | =============== | |
62 | ||
63 | One of the typical scenarios where ``sshtunnel`` is helpful is depicted in the | |
64 | figure below. User may need to connect a port of a remote server (i.e. 8080) | |
65 | where only SSH port (usually port 22) is reachable. :: | |
66 | ||
67 | ---------------------------------------------------------------------- | |
68 | ||
69 | | | |
70 | -------------+ | +----------+ | |
71 | LOCAL | | | REMOTE | :22 SSH | |
72 | CLIENT | <== SSH ========> | SERVER | :8080 web service | |
73 | -------------+ | +----------+ | |
74 | | | |
75 | FIREWALL (only port 22 is open) | |
76 | ||
77 | ---------------------------------------------------------------------- | |
78 | ||
79 | **Fig1**: How to connect to a service blocked by a firewall through SSH tunnel. | |
80 | ||
81 | ||
82 | If allowed by the SSH server, it is also possible to reach a private server | |
83 | (from the perspective of ``REMOTE SERVER``) not directly visible from the | |
84 | outside (``LOCAL CLIENT``'s perspective). :: | |
85 | ||
86 | ---------------------------------------------------------------------- | |
87 | ||
88 | | | |
89 | -------------+ | +----------+ +--------- | |
90 | LOCAL | | | REMOTE | | PRIVATE | |
91 | CLIENT | <== SSH ========> | SERVER | <== local ==> | SERVER | |
92 | -------------+ | +----------+ +--------- | |
93 | | | |
94 | FIREWALL (only port 443 is open) | |
95 | ||
96 | ---------------------------------------------------------------------- | |
97 | ||
98 | **Fig2**: How to connect to ``PRIVATE SERVER`` through SSH tunnel. | |
99 | ||
100 | ||
101 | Usage examples | |
102 | ============== | |
103 | ||
104 | API allows either initializing the tunnel and starting it or using a ``with`` | |
105 | context, which will take care of starting **and stopping** the tunnel: | |
106 | ||
107 | Example 1 | |
108 | --------- | |
109 | ||
110 | Code corresponding to **Fig1** above follows, given remote server's address is | |
111 | ``pahaz.urfuclub.ru``, password authentication and randomly assigned local bind | |
112 | port. | |
113 | ||
114 | .. code-block:: py | |
115 | ||
116 | from sshtunnel import SSHTunnelForwarder | |
117 | ||
118 | server = SSHTunnelForwarder( | |
119 | 'pahaz.urfuclub.ru', | |
120 | ssh_username="pahaz", | |
121 | ssh_password="secret", | |
122 | remote_bind_address=('127.0.0.1', 8080) | |
123 | ) | |
124 | ||
125 | server.start() | |
126 | ||
127 | print(server.local_bind_port) # show assigned local port | |
128 | # work with `SECRET SERVICE` through `server.local_bind_port`. | |
129 | ||
130 | server.stop() | |
131 | ||
132 | Example 2 | |
133 | --------- | |
134 | ||
135 | Example of a port forwarding to a private server not directly reachable, | |
136 | assuming password protected pkey authentication, remote server's SSH service is | |
137 | listening on port 443 and that port is open in the firewall (**Fig2**): | |
138 | ||
139 | .. code-block:: py | |
140 | ||
141 | import paramiko | |
142 | from sshtunnel import SSHTunnelForwarder | |
143 | ||
144 | with SSHTunnelForwarder( | |
145 | (REMOTE_SERVER_IP, 443), | |
146 | ssh_username="", | |
147 | ssh_pkey="/var/ssh/rsa_key", | |
148 | ssh_private_key_password="secret", | |
149 | remote_bind_address=(PRIVATE_SERVER_IP, 22), | |
150 | local_bind_address=('0.0.0.0', 10022) | |
151 | ) as tunnel: | |
152 | client = paramiko.SSHClient() | |
153 | client.load_system_host_keys() | |
154 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | |
155 | client.connect('127.0.0.1', 10022) | |
156 | # do some operations with client session | |
157 | client.close() | |
158 | ||
159 | print('FINISH!') | |
160 | ||
161 | Example 3 | |
162 | --------- | |
163 | ||
164 | Example of a port forwarding for the Vagrant MySQL local port: | |
165 | ||
166 | .. code-block:: py | |
167 | ||
168 | from sshtunnel import SSHTunnelForwarder | |
169 | from time import sleep | |
170 | ||
171 | with SSHTunnelForwarder( | |
172 | ('localhost', 2222), | |
173 | ssh_username="vagrant", | |
174 | ssh_password="vagrant", | |
175 | remote_bind_address=('127.0.0.1', 3306) | |
176 | ) as server: | |
177 | ||
178 | print(server.local_bind_port) | |
179 | while True: | |
180 | # press Ctrl-C for stopping | |
181 | sleep(1) | |
182 | ||
183 | print('FINISH!') | |
184 | ||
185 | Or simply using the CLI: | |
186 | ||
187 | .. code-block:: console | |
188 | ||
189 | (bash)$ python -m sshtunnel -U vagrant -P vagrant -L :3306 -R 127.0.0.1:3306 -p 2222 localhost | |
190 | ||
191 | CLI usage | |
192 | ========= | |
193 | ||
194 | :: | |
195 | ||
196 | $ sshtunnel --help | |
197 | usage: sshtunnel [-h] [-U SSH_USERNAME] [-p SSH_PORT] [-P SSH_PASSWORD] -R | |
198 | IP:PORT [IP:PORT ...] [-L [IP:PORT [IP:PORT ...]]] | |
199 | [-k SSH_HOST_KEY] [-K KEY_FILE] [-S KEY_PASSWORD] [-t] [-v] | |
200 | [-V] [-x IP:PORT] [-c SSH_CONFIG_FILE] [-z] [-n] [-d [FOLDER [FOLDER ...]]] | |
201 | ssh_address | |
202 | ||
203 | Pure python ssh tunnel utils | |
204 | Version 0.1.4 | |
205 | ||
206 | positional arguments: | |
207 | ssh_address SSH server IP address (GW for SSH tunnels) | |
208 | set with "-- ssh_address" if immediately after -R or -L | |
209 | ||
210 | optional arguments: | |
211 | -h, --help show this help message and exit | |
212 | -U SSH_USERNAME, --username SSH_USERNAME | |
213 | SSH server account username | |
214 | -p SSH_PORT, --server_port SSH_PORT | |
215 | SSH server TCP port (default: 22) | |
216 | -P SSH_PASSWORD, --password SSH_PASSWORD | |
217 | SSH server account password | |
218 | -R IP:PORT [IP:PORT ...], --remote_bind_address IP:PORT [IP:PORT ...] | |
219 | Remote bind address sequence: ip_1:port_1 ip_2:port_2 ... ip_n:port_n | |
220 | Equivalent to ssh -Lxxxx:IP_ADDRESS:PORT | |
221 | If port is omitted, defaults to 22. | |
222 | Example: -R 10.10.10.10: 10.10.10.10:5900 | |
223 | -L [IP:PORT [IP:PORT ...]], --local_bind_address [IP:PORT [IP:PORT ...]] | |
224 | Local bind address sequence: ip_1:port_1 ip_2:port_2 ... ip_n:port_n | |
225 | Elements may also be valid UNIX socket domains: | |
226 | /tmp/foo.sock /tmp/bar.sock ... /tmp/baz.sock | |
227 | Equivalent to ssh -LPORT:xxxxxxxxx:xxxx, being the local IP address optional. | |
228 | By default it will listen in all interfaces (0.0.0.0) and choose a random port. | |
229 | Example: -L :40000 | |
230 | -k SSH_HOST_KEY, --ssh_host_key SSH_HOST_KEY | |
231 | Gateway's host key | |
232 | -K KEY_FILE, --private_key_file KEY_FILE | |
233 | RSA/DSS/ECDSA private key file | |
234 | -S KEY_PASSWORD, --private_key_password KEY_PASSWORD | |
235 | RSA/DSS/ECDSA private key password | |
236 | -t, --threaded Allow concurrent connections to each tunnel | |
237 | -v, --verbose Increase output verbosity (default: ERROR) | |
238 | -V, --version Show version number and quit | |
239 | -x IP:PORT, --proxy IP:PORT | |
240 | IP and port of SSH proxy to destination | |
241 | -c SSH_CONFIG_FILE, --config SSH_CONFIG_FILE | |
242 | SSH configuration file, defaults to ~/.ssh/config | |
243 | -z, --compress Request server for compression over SSH transport | |
244 | -n, --noagent Disable looking for keys from an SSH agent | |
245 | -d [FOLDER [FOLDER ...]], --host_pkey_directories [FOLDER [FOLDER ...]] | |
246 | List of directories where SSH pkeys (in the format `id_*`) may be found | |
247 | ||
248 | .. _Pahaz Blinov: https://github.com/pahaz | |
249 | .. _sshtunnel: https://pypi.python.org/pypi/sshtunnel | |
250 | .. _paramiko: http://www.paramiko.org/ | |
251 | .. |CircleCI| image:: https://circleci.com/gh/pahaz/sshtunnel.svg?style=svg | |
252 | :target: https://circleci.com/gh/pahaz/sshtunnel | |
253 | .. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/oxg1vx2ycmnw3xr9?svg=true&passingText=Windows%20-%20OK&failingText=Windows%20-%20Fail | |
254 | :target: https://ci.appveyor.com/project/pahaz/sshtunnel | |
255 | .. |readthedocs| image:: https://readthedocs.org/projects/sshtunnel/badge/?version=latest | |
256 | :target: http://sshtunnel.readthedocs.io/en/latest/?badge=latest | |
257 | :alt: Documentation Status | |
258 | .. |coveralls| image:: https://coveralls.io/repos/github/pahaz/sshtunnel/badge.svg?branch=master | |
259 | :target: https://coveralls.io/github/pahaz/sshtunnel?branch=master | |
260 | .. |pyversions| image:: https://img.shields.io/pypi/pyversions/sshtunnel.svg | |
261 | .. |version| image:: https://img.shields.io/pypi/v/sshtunnel.svg | |
262 | :target: `sshtunnel`_ | |
263 | .. |license| image:: https://img.shields.io/pypi/l/sshtunnel.svg | |
264 | :target: https://github.com/pahaz/sshtunnel/blob/master/LICENSE | |
265 | ||
266 | Online documentation | |
267 | ==================== | |
268 | ||
269 | Documentation may be found at `readthedocs`_. | |
270 | ||
271 | .. _readthedocs: https://sshtunnel.readthedocs.org/ | |
272 | ||
273 | CONTRIBUTORS | |
274 | ============ | |
275 | ||
276 | - `Cameron Maske`_ | |
277 | - `Gustavo Machado`_ | |
278 | - `Colin Jermain`_ | |
279 | - `JM Fernández`_ - (big thanks!) | |
280 | - `Lewis Thompson`_ | |
281 | - `Erik Rogers`_ | |
282 | - `Mart Sõmermaa`_ | |
283 | - `Chronial`_ | |
284 | - `Dan Harbin`_ | |
285 | - `Ignacio Peluffo`_ | |
286 | - `Niels Zeilemaker`_ | |
287 | ||
288 | CHANGELOG | |
289 | ========= | |
290 | ||
291 | - v.0.1.4 (`Niels Zeilemaker`_) | |
292 | + Allow loading pkeys from `~/.ssh` | |
293 | ||
294 | - v.0.1.3 (`Ignacio Peluffo`_ and others) | |
295 | + ``pkey_file`` parameter updated to accept relative paths to user folder using ``~`` | |
296 | + Several bugfixes | |
297 | ||
298 | - v.0.1.2 (`JM Fernández`_) | |
299 | + Fix #77 | |
300 | ||
301 | - v.0.1.1 (`JM Fernández`_) | |
302 | + Fix #72 | |
303 | ||
304 | - v.0.1.0 (`JM Fernández`_) | |
305 | + Add `tunnel_bindings` property | |
306 | + Several bugfixes (#49, #56, #57, #59, #60, #62, #64, #66, ...) | |
307 | (`Pahaz Blinov`_, `JM Fernández`_) | |
308 | + Add TRACE logging level (`JM Fernández`_) | |
309 | + Code and tests refactoring (`JM Fernández`_) | |
310 | + Drop python3.2 support | |
311 | ||
312 | - v.0.0.8 (`JM Fernández`_) | |
313 | + Merge `#31`_: Support Unix domain socket (local) forwarding (`Dan Harbin`_) | |
314 | + Simplify API (`JM Fernández`_) | |
315 | + Add sphinx-based documentation (`JM Fernández`_) | |
316 | + Add ``allow_agent`` (fixes `#36`_, `#46`_) (`JM Fernández`_) | |
317 | + Add ``compression`` (`JM Fernández`_) | |
318 | + Add ``__str__`` method (`JM Fernández`_) | |
319 | + Add test functions (`JM Fernández`_) | |
320 | + Fix default username when not provided and ssh_config file is skipped (`JM Fernández`_) | |
321 | + Fix gateway IP unresolvable exception catching (`JM Fernández`_) | |
322 | + Minor fixes (`JM Fernández`_) | |
323 | + Add AppVeyor support (`JM Fernández`_) | |
324 | ||
325 | - v.0.0.7 (`JM Fernández`_) | |
326 | + Tunnels can now be stopped and started safely (`#41`_) (`JM Fernández`_) | |
327 | + Add timeout to SSH gateway and keep-alive messages (`#29`_) (`JM Fernández`_) | |
328 | + Allow sending a pkey directly (`#43`_) (`Chronial`_) | |
329 | + Add ``-V`` CLI option to show current version (`JM Fernández`_) | |
330 | + Add coverage (`JM Fernández`_) | |
331 | + Refactoring (`JM Fernández`_) | |
332 | ||
333 | - v.0.0.6 (`Pahaz Blinov`_) | |
334 | + add ``-S`` CLI options for ssh private key password support (`Pahaz Blinov`_) | |
335 | ||
336 | - v.0.0.5 (`Pahaz Blinov`_) | |
337 | + add ``ssh_proxy`` argument, as well as ``ssh_config(5)`` ``ProxyCommand`` support (`Lewis Thompson`_) | |
338 | + add some python 2.6 compatibility fixes (`Mart Sõmermaa`_) | |
339 | + ``paramiko.transport`` inherits handlers of loggers passed to ``SSHTunnelForwarder`` (`JM Fernández`_) | |
340 | + fix `#34`_, `#33`_, code style and docs (`JM Fernández`_) | |
341 | + add tests (`Pahaz Blinov`_) | |
342 | + add CI integration (`Pahaz Blinov`_) | |
343 | + normal packaging (`Pahaz Blinov`_) | |
344 | + disable check distenation socket connection by ``SSHTunnelForwarder.local_is_up`` (`Pahaz Blinov`_) [changed default behavior] | |
345 | + use daemon mode = False in all threads by default; detail_ (`Pahaz Blinov`_) [changed default behavior] | |
346 | ||
347 | - v.0.0.4.4 (`Pahaz Blinov`_) | |
348 | + fix issue `#24`_ - hide ssh password in logs (`Pahaz Blinov`_) | |
349 | ||
350 | - v.0.0.4.3 (`Pahaz Blinov`_) | |
351 | + fix default port issue `#19`_ (`Pahaz Blinov`_) | |
352 | ||
353 | - v.0.0.4.2 (`Pahaz Blinov`_) | |
354 | + fix Thread.daemon mode for Python < 3.3 `#16`_, `#21`_ (`Lewis Thompson`_, `Erik Rogers`_) | |
355 | ||
356 | - v.0.0.4.1 (`Pahaz Blinov`_) | |
357 | + fix CLI issues `#13`_ (`Pahaz Blinov`_) | |
358 | ||
359 | - v.0.0.4 (`Pahaz Blinov`_) | |
360 | + daemon mode by default for all threads (`JM Fernández`_, `Pahaz Blinov`_) - *incompatible* | |
361 | + move ``make_ssh_forward_server`` to ``SSHTunnelForwarder.make_ssh_forward_server`` (`Pahaz Blinov`_, `JM Fernández`_) - *incompatible* | |
362 | + move ``make_ssh_forward_handler`` to ``SSHTunnelForwarder.make_ssh_forward_handler_class`` (`Pahaz Blinov`_, `JM Fernández`_) - *incompatible* | |
363 | + rename ``open`` to ``open_tunnel`` (`JM Fernández`_) - *incompatible* | |
364 | + add CLI interface (`JM Fernández`_) | |
365 | + support opening several tunnels at once (`JM Fernández`_) | |
366 | + improve stability and readability (`JM Fernández`_, `Pahaz Blinov`_) | |
367 | + improve logging (`JM Fernández`_, `Pahaz Blinov`_) | |
368 | + add ``raise_exception_if_any_forwarder_have_a_problem`` argument for opening several tunnels at once (`Pahaz Blinov`_) | |
369 | + add ``ssh_config_file`` argument support (`JM Fernández`_) | |
370 | + add Python 3 support (`JM Fernández`_, `Pahaz Blinov`_) | |
371 | ||
372 | - v.0.0.3 (`Pahaz Blinov`_) | |
373 | + add ``threaded`` option (`Cameron Maske`_) | |
374 | + fix exception error message, correctly printing destination address (`Gustavo Machado`_) | |
375 | + fix ``pip install`` failure (`Colin Jermain`_, `Pahaz Blinov`_) | |
376 | ||
377 | - v.0.0.1 (`Pahaz Blinov`_) | |
378 | + ``SSHTunnelForwarder`` class (`Pahaz Blinov`_) | |
379 | + ``open`` function (`Pahaz Blinov`_) | |
380 | ||
381 | ||
382 | .. _Cameron Maske: https://github.com/cameronmaske | |
383 | .. _Gustavo Machado: https://github.com/gdmachado | |
384 | .. _Colin Jermain: https://github.com/cjermain | |
385 | .. _JM Fernández: https://github.com/fernandezcuesta | |
386 | .. _Lewis Thompson: https://github.com/lewisthompson | |
387 | .. _Erik Rogers: https://github.com/ewrogers | |
388 | .. _Mart Sõmermaa: https://github.com/mrts | |
389 | .. _Chronial: https://github.com/Chronial | |
390 | .. _Dan Harbin: https://github.com/RasterBurn | |
391 | .. _Ignacio Peluffo: https://github.com/ipeluffo | |
392 | .. _Niels Zeilemaker: https://github.com/NielsZeilemaker | |
393 | .. _#13: https://github.com/pahaz/sshtunnel/issues/13 | |
394 | .. _#16: https://github.com/pahaz/sshtunnel/issues/16 | |
395 | .. _#19: https://github.com/pahaz/sshtunnel/issues/19 | |
396 | .. _#21: https://github.com/pahaz/sshtunnel/issues/21 | |
397 | .. _#24: https://github.com/pahaz/sshtunnel/issues/24 | |
398 | .. _#29: https://github.com/pahaz/sshtunnel/issues/29 | |
399 | .. _#31: https://github.com/pahaz/sshtunnel/issues/31 | |
400 | .. _#33: https://github.com/pahaz/sshtunnel/issues/33 | |
401 | .. _#34: https://github.com/pahaz/sshtunnel/issues/34 | |
402 | .. _#36: https://github.com/pahaz/sshtunnel/issues/36 | |
403 | .. _#41: https://github.com/pahaz/sshtunnel/issues/41 | |
404 | .. _#43: https://github.com/pahaz/sshtunnel/issues/43 | |
405 | .. _#46: https://github.com/pahaz/sshtunnel/issues/46 | |
406 | .. _detail: https://github.com/pahaz/sshtunnel/commit/64af238b799b0e0057c4f9b386cda247e0006da9#diff-76bc1662a114401c2954deb92b740081R127 | |
407 | ||
408 | Keywords: ssh tunnel paramiko proxy tcp-forward | |
409 | Platform: unix | |
410 | Platform: macos | |
411 | Platform: windows | |
412 | Classifier: Development Status :: 3 - Alpha | |
413 | Classifier: Intended Audience :: Developers | |
414 | Classifier: Topic :: Software Development :: Build Tools | |
415 | Classifier: License :: OSI Approved :: MIT License | |
416 | Classifier: Programming Language :: Python :: 2 | |
417 | Classifier: Programming Language :: Python :: 2.7 | |
418 | Classifier: Programming Language :: Python :: 3 | |
419 | Classifier: Programming Language :: Python :: 3.4 | |
420 | Classifier: Programming Language :: Python :: 3.5 | |
421 | Classifier: Programming Language :: Python :: 3.6 |
0 | LICENSE | |
1 | MANIFEST.in | |
2 | README.rst | |
3 | Troubleshoot.rst | |
4 | changelog.rst | |
5 | docs.rst | |
6 | setup.cfg | |
7 | setup.py | |
8 | sshtunnel.py | |
9 | docs/Makefile | |
10 | docs/conf.py | |
11 | docs/index.rst | |
12 | docs/requirements-docs.txt | |
13 | sshtunnel.egg-info/PKG-INFO | |
14 | sshtunnel.egg-info/SOURCES.txt | |
15 | sshtunnel.egg-info/dependency_links.txt | |
16 | sshtunnel.egg-info/entry_points.txt | |
17 | sshtunnel.egg-info/requires.txt | |
18 | sshtunnel.egg-info/top_level.txt | |
19 | tests/__init__.py | |
20 | tests/__init__.pyc | |
21 | tests/test_forwarder.py | |
22 | tests/testconfig | |
23 | tests/testrsa.key | |
24 | tests/testrsa_encrypted.key⏎ |
0 | paramiko>=1.15.2 | |
1 | ||
2 | [build_sphinx] | |
3 | sphinx | |
4 | sphinxcontrib-napoleon | |
5 | ||
6 | [dev] | |
7 | check-manifest | |
8 | ||
9 | [test] | |
10 | tox>=1.8.1 |
35 | 35 | input_ = input |
36 | 36 | |
37 | 37 | |
38 | __version__ = '0.1.4' | |
38 | __version__ = '0.1.5' | |
39 | 39 | __author__ = 'pahaz' |
40 | 40 | |
41 | 41 | |
42 | 42 | DEFAULT_LOGLEVEL = logging.ERROR #: default level if no logger passed (ERROR) |
43 | 43 | TUNNEL_TIMEOUT = 1.0 #: Timeout (seconds) for tunnel connection |
44 | DAEMON = False | |
44 | _DAEMON = False #: Use daemon threads in connections | |
45 | 45 | TRACE_LEVEL = 1 |
46 | 46 | _CONNECTION_COUNTER = 1 |
47 | 47 | _LOCK = threading.Lock() |
313 | 313 | self.remote_address, |
314 | 314 | hexlify(data) |
315 | 315 | )) |
316 | chan.send(data) | |
316 | chan.sendall(data) | |
317 | 317 | if chan in rqst: # else |
318 | 318 | if not chan.recv_ready(): |
319 | 319 | break |
322 | 322 | TRACE_LEVEL, |
323 | 323 | '<<< IN {0} recv: {1} <<<'.format(self.info, hexlify(data)) |
324 | 324 | ) |
325 | self.request.send(data) | |
325 | self.request.sendall(data) | |
326 | 326 | |
327 | 327 | def handle(self): |
328 | 328 | uid = get_connection_id() |
414 | 414 | Allow concurrent connections to each tunnel |
415 | 415 | """ |
416 | 416 | # If True, cleanly stop threads created by ThreadingMixIn when quitting |
417 | daemon_threads = DAEMON | |
417 | daemon_threads = _DAEMON | |
418 | 418 | |
419 | 419 | |
420 | 420 | class _UnixStreamForwardServer(UnixStreamServer): |
458 | 458 | Allow concurrent connections to each tunnel |
459 | 459 | """ |
460 | 460 | # If True, cleanly stop threads created by ThreadingMixIn when quitting |
461 | daemon_threads = DAEMON | |
461 | daemon_threads = _DAEMON | |
462 | 462 | |
463 | 463 | |
464 | 464 | class SSHTunnelForwarder(object): |
613 | 613 | |
614 | 614 | host_pkey_directories (list): |
615 | 615 | Look for pkeys in folders on this list, for example ['~/.ssh']. |
616 | An empty list disables this feature | |
617 | ||
618 | Default: ``None`` | |
616 | ||
617 | Default: ``None`` (disabled) | |
619 | 618 | |
620 | 619 | .. versionadded:: 0.1.4 |
621 | 620 | |
719 | 718 | |
720 | 719 | """ |
721 | 720 | skip_tunnel_checkup = True |
722 | daemon_forward_servers = DAEMON #: flag tunnel threads in daemon mode | |
723 | daemon_transport = DAEMON #: flag SSH transport thread in daemon mode | |
721 | daemon_forward_servers = _DAEMON #: flag tunnel threads in daemon mode | |
722 | daemon_transport = _DAEMON #: flag SSH transport thread in daemon mode | |
724 | 723 | |
725 | 724 | def local_is_up(self, target): |
726 | 725 | """ |
1089 | 1088 | logger.warning('Private key file not found: {0}' |
1090 | 1089 | .format(ssh_pkey)) |
1091 | 1090 | if isinstance(ssh_pkey, paramiko.pkey.PKey): |
1092 | ssh_loaded_pkeys.append(ssh_pkey) | |
1091 | ssh_loaded_pkeys.insert(0, ssh_pkey) | |
1093 | 1092 | |
1094 | 1093 | if not ssh_password and not ssh_loaded_pkeys: |
1095 | 1094 | raise ValueError('No password or public key available!') |
1579 | 1578 | |
1580 | 1579 | .. versionadded:: 0.1.0 |
1581 | 1580 | |
1581 | block_on_close (boolean): | |
1582 | Wait until all connections are done during close by changing the | |
1583 | value of :attr:`~SSHTunnelForwarder.block_on_close` | |
1584 | ||
1585 | Default: True | |
1586 | ||
1582 | 1587 | .. note:: |
1583 | 1588 | A value of ``debug_level`` set to 1 == ``TRACE`` enables tracing mode |
1584 | 1589 | .. note:: |
1614 | 1619 | kwargs |
1615 | 1620 | ) |
1616 | 1621 | |
1617 | ssh_port = kwargs.pop('ssh_port', None) | |
1622 | ssh_port = kwargs.pop('ssh_port', 22) | |
1618 | 1623 | skip_tunnel_checkup = kwargs.pop('skip_tunnel_checkup', True) |
1624 | block_on_close = kwargs.pop('block_on_close', _DAEMON) | |
1619 | 1625 | if not args: |
1620 | 1626 | if isinstance(ssh_address_or_host, tuple): |
1621 | 1627 | args = (ssh_address_or_host, ) |
1623 | 1629 | args = ((ssh_address_or_host, ssh_port), ) |
1624 | 1630 | forwarder = SSHTunnelForwarder(*args, **kwargs) |
1625 | 1631 | forwarder.skip_tunnel_checkup = skip_tunnel_checkup |
1632 | forwarder.daemon_forward_servers = not block_on_close | |
1633 | forwarder.daemon_transport = not block_on_close | |
1626 | 1634 | return forwarder |
1627 | 1635 | |
1628 | 1636 |
0 | [tox] | |
1 | envlist = syntax, py{27,34,35,36,37}, docs | |
2 | ||
3 | [testenv] | |
4 | basepython = | |
5 | py27: python2.7 | |
6 | py34: python3.4 | |
7 | py35: python3.5 | |
8 | py36: python3.6 | |
9 | py37: python3.7 | |
10 | deps = | |
11 | mock | |
12 | pytest | |
13 | pytest-cov | |
14 | pytest-xdist | |
15 | commands = | |
16 | python -V | |
17 | py.test --showlocals --cov sshtunnel --durations=10 -n4 tests -W ignore::DeprecationWarning | |
18 | ||
19 | [testenv:docs] | |
20 | basepython = python | |
21 | changedir = docs | |
22 | deps = | |
23 | -r{toxinidir}/docs/requirements-docs.txt | |
24 | commands= | |
25 | sphinx-build -WavE -b html -d {envtmpdir}/_build/doctrees . {envtmpdir}/_build/html | |
26 | ||
27 | [testenv:syntax] | |
28 | basepython = python | |
29 | skip_install = True | |
30 | deps = | |
31 | bashtest | |
32 | check-manifest | |
33 | docutils | |
34 | flake8 | |
35 | mccabe | |
36 | pygments | |
37 | readme | |
38 | twine | |
39 | commands = | |
40 | check-manifest --ignore "tox.ini,tests*,*.yml" | |
41 | python setup.py sdist | |
42 | twine check dist/* | |
43 | flake8 --ignore=W504 . | |
44 | bashtest README.rst | |
45 | ||
46 | [flake8] | |
47 | exclude = .tox,*.egg,build,data,docs | |
48 | select = E,W,F | |
49 | max-complexity = 10 |