纯Python SSH隧道
项目描述
作者: Pahaz
仓库: https://github.com/pahaz/sshtunnel/
受https://github.com/jmagnusson/bgtunnel的启发,它不支持Windows。
另请参阅:https://github.com/paramiko/paramiko/blob/master/demos/forward.py
要求
安装
sshtunnel位于PyPI,因此只需运行
pip install sshtunnel
或
easy_install sshtunnel
或
conda install -c conda-forge sshtunnel
将其安装到您的环境中。
从源安装时,克隆仓库并运行
python setup.py install
测试包
为了运行测试,您首先需要tox并运行
python setup.py test
使用场景
以下图中展示了 sshtunnel 有帮助的典型场景之一。用户可能需要连接远程服务器(例如 8080 端口)的端口,而只有 SSH 端口(通常是端口 22)可以访问。
---------------------------------------------------------------------- | -------------+ | +----------+ LOCAL | | | REMOTE | :22 SSH CLIENT | <== SSH ========> | SERVER | :8080 web service -------------+ | +----------+ | FIREWALL (only port 22 is open) ----------------------------------------------------------------------
图1:如何通过 SSH 隧道连接被防火墙阻止的服务。
如果 SSH 服务器允许,也可以从(REMOTE SERVER 角度)访问外部(LOCAL CLIENT 角度)不可见的私有服务器。
---------------------------------------------------------------------- | -------------+ | +----------+ +--------- LOCAL | | | REMOTE | | PRIVATE CLIENT | <== SSH ========> | SERVER | <== local ==> | SERVER -------------+ | +----------+ +--------- | FIREWALL (only port 443 is open) ----------------------------------------------------------------------
图2:如何通过 SSH 隧道连接 PRIVATE SERVER。
使用示例
API 允许初始化隧道并启动它,或者使用 with 上下文,这将负责启动和停止隧道。
示例 1
以下代码对应于上述 图1,假设远程服务器地址为 pahaz.urfuclub.ru,密码认证,随机分配本地绑定端口。
from sshtunnel import SSHTunnelForwarder
server = SSHTunnelForwarder(
'alfa.8iq.dev',
ssh_username="pahaz",
ssh_password="secret",
remote_bind_address=('127.0.0.1', 8080)
)
server.start()
print(server.local_bind_port) # show assigned local port
# work with `SECRET SERVICE` through `server.local_bind_port`.
server.stop()
示例 2
以下是一个将端口转发到无法直接访问的私有服务器的示例,假设使用密码保护的私钥认证,远程服务器 SSH 服务监听端口 443,并且该端口在防火墙中已开放(图2)。
import paramiko
import sshtunnel
with sshtunnel.open_tunnel(
(REMOTE_SERVER_IP, 443),
ssh_username="",
ssh_pkey="/var/ssh/rsa_key",
ssh_private_key_password="secret",
remote_bind_address=(PRIVATE_SERVER_IP, 22),
local_bind_address=('0.0.0.0', 10022)
) as tunnel:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('127.0.0.1', 10022)
# do some operations with client session
client.close()
print('FINISH!')
示例 3
为 Vagrant MySQL 本地端口进行端口转发的示例。
from sshtunnel import open_tunnel
from time import sleep
with open_tunnel(
('localhost', 2222),
ssh_username="vagrant",
ssh_password="vagrant",
remote_bind_address=('127.0.0.1', 3306)
) as server:
print(server.local_bind_port)
while True:
# press Ctrl-C for stopping
sleep(1)
print('FINISH!')
或者简单地使用 CLI
(bash)$ python -m sshtunnel -U vagrant -P vagrant -L :3306 -R 127.0.0.1:3306 -p 2222 localhost
示例 4
通过跳过两个隧道来打开 SSH 会话。SSH 传输和隧道将被守护,不会在关闭时间等待连接停止。
import sshtunnel
from paramiko import SSHClient
with sshtunnel.open_tunnel(
ssh_address_or_host=('GW1_ip', 20022),
remote_bind_address=('GW2_ip', 22),
) as tunnel1:
print('Connection to tunnel1 (GW1_ip:GW1_port) OK...')
with sshtunnel.open_tunnel(
ssh_address_or_host=('localhost', tunnel1.local_bind_port),
remote_bind_address=('target_ip', 22),
ssh_username='GW2_user',
ssh_password='GW2_pwd',
) as tunnel2:
print('Connection to tunnel2 (GW2_ip:GW2_port) OK...')
with SSHClient() as ssh:
ssh.connect('localhost',
port=tunnel2.local_bind_port,
username='target_user',
password='target_pwd',
)
ssh.exec_command(...)
CLI 使用方法
$ 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 "-- ssh_address" 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's 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 `id_*`) may be found
在线文档
文档可以在 readthedocs 上找到。
贡献者
变更日志
- v.0.3.2 (Pahaz, JM Fernández)
修复主机密钥目录检测
将默认 ssh 配置文件夹统一到 ~/.ssh
- v.0.3.1 (Pahaz)
将打开连接超时增加到 10 秒
- 版本 v.0.2.1(由 Pahaz、Eddie Chiang 和 kkrasovskii 贡献)
修复了DOWN状态隧道中孤儿线程的bug(#170)
- 版本 v.0.2.0(由 Georgy Rylov 贡献)
支持无代理命令的IPv6。使用内置的paramiko创建套接字逻辑。逻辑首先尝试使用IPv6套接字族,然后是IPv4套接字族。
- 版本 v.0.1.5(由 JM Fernández 贡献)
引入 block_on_close 属性
- 版本 v.0.1.4(由 Niels Zeilemaker 贡献)
允许从 ~/.ssh 加载私钥
- 版本 v.0.1.3(由 Ignacio Peluffo 和其他人贡献)
pkey_file 参数更新为接受使用 ~ 的用户文件夹的相对路径
多个bug修复
- 版本 v.0.1.2(由 JM Fernández 贡献)
修复 #77
- 版本 v.0.1.1(由 JM Fernández 贡献)
修复 #72
- 版本 v.0.1.0(由 JM Fernández 贡献)
添加 tunnel_bindings 属性
多个bug修复 (#49, #56, #57, #59, #60, #62, #64, #66, …)(由 Pahaz、JM Fernández 贡献)
添加 TRACE 记录级别(由 JM Fernández 贡献)
代码和测试重构(由 JM Fernández 贡献)
放弃对 python3.2 的支持
- 版本 v.0.0.8(由 JM Fernández 贡献)
合并 #31:支持 Unix 域套接字(本地)转发(由 Dan Harbin 贡献)
简化API(由 JM Fernández 贡献)
添加基于sphinx的文档(由 JM Fernández 贡献)
添加 allow_agent(修复 #36、#46)(由 JM Fernández 贡献)
添加 compression(由 JM Fernández 贡献)
添加 __str__ 方法(由 JM Fernández 贡献)
添加测试函数(由 JM Fernández 贡献)
修复未提供默认用户名时跳过 ssh_config 文件的情况(由 JM Fernández 贡献)
修复无法解析网关IP的异常捕获(由 JM Fernández 贡献)
小修复(由 JM Fernández 贡献)
添加 AppVeyor 支持(由 JM Fernández 贡献)
- 版本 v.0.0.7(由 JM Fernández 贡献)
隧道现在可以安全地停止和启动(由 #41)(由 JM Fernández 贡献)
添加 SSH 网关和 keep-alive 消息的超时(由 #29)(由 JM Fernández 贡献)
添加 -V CLI 选项以显示当前版本(由 JM Fernández 贡献)
添加覆盖率(由 JM Fernández 贡献)
重构(由 JM Fernández 贡献)
- 版本 v.0.0.5(由 Pahaz 贡献)
添加 ssh_proxy 参数,以及 ssh_config(5) 的 ProxyCommand 支持(《Lewis Thompson》)
添加一些 Python 2.6 兼容性修复(《Mart Sõmermaa》)
paramiko.transport 继承了传递给 SSHTunnelForwarder 的日志记录器的处理器(《JM Fernández》)
修复 #34、#33,代码风格和文档(《JM Fernández》)
添加测试(《Pahaz》)
添加 CI 集成(《Pahaz》)
正常打包(《Pahaz》)
通过 SSHTunnelForwarder.local_is_up 禁用检查目标套接字连接(《Pahaz》)[更改默认行为]
- v.0.0.4.2(《Pahaz》)
修复 Python < 3.3 的 Thread.daemon 模式问题 #16、#21(《Lewis Thompson》、《Erik Rogers》)
- v.0.0.4(《Pahaz》)
默认情况下,所有线程使用守护线程模式 - 不兼容(《JM Fernández》、《Pahaz》)
将 make_ssh_forward_server 移动到 SSHTunnelForwarder.make_ssh_forward_server(《Pahaz》、《JM Fernández》)- 不兼容
将 make_ssh_forward_handler 移动到 SSHTunnelForwarder.make_ssh_forward_handler_class(《Pahaz》、《JM Fernández》)- 不兼容
将 open 重命名为 open_tunnel(《JM Fernández》)- 不兼容
添加 CLI 界面(《JM Fernández》)
支持同时打开多个隧道(《JM Fernández》)
提高稳定性和可读性(《JM Fernández》、《Pahaz》)
改进日志(《JM Fernández》、《Pahaz》)
为同时打开多个隧道添加 raise_exception_if_any_forwarder_have_a_problem 参数(《Pahaz》)
添加 ssh_config_file 参数支持(《JM Fernández》)
添加 Python 3 支持(《JM Fernández》、《Pahaz》)
- v.0.0.3(《Pahaz》)
添加 threaded 选项(《Cameron Maske》)
修复异常错误消息,正确打印目标地址(《Gustavo Machado》)
修复 pip install 失败问题(由 Colin Jermain,Pahaz 负责)
项目详情
下载文件
下载适用于您平台文件的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。
源分布
构建分布
sshtunnel-0.4.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e7cb0ea774db81bf91844db22de72a40aae8f7b0f9bb9ba0f666d474ef6bf9fc |
|
MD5 | 4b523e55fa2b2c09acf9dbe2189fb1d1 |
|
BLAKE2b-256 | 8dad4c587adf79865be268ee0b6bd52cfaa7a75d827a23ced072dc5ab554b4af |
sshtunnel-0.4.0-py3.8.egg 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 4a07cf989712e8ba76a370584bec922d14775054b3ff18e5d075507a298dc3ed |
|
MD5 | b5e59486675a206772f7111ee8bd8302 |
|
BLAKE2b-256 | fbb95bfdda9649c33b01e2a6c9a1b11a7925c82418d9e264f362b088bb84cda5 |
sshtunnel-0.4.0-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 98e54c26f726ab8bd42b47a3a21fca5c3e60f58956f0f70de2fb8ab0046d0606 |
|
MD5 | b1bdc8f01c63c61012de6ef8262afbcb |
|
BLAKE2b-256 | 58138476c4328dcadfe26f8bd7f3a1a03bf9ddb890a7e7b692f54a179bc525bf |