wimotek-ssh-tunnel
专为 Chromium CDP(Chrome DevTools Protocol)自动化测试、AI Agent 与远程浏览器调试 设计的高可用 SSH 端口转发管理模块。
具备端口冲突智能跳过、TCP 心跳防假死与隧道生命周期自由管理特性,纯 Python 原生标准库实现,零第三方依赖。
🌟 核心特性
- 智能端口防冲突:自动检测本地监听端口(默认
9222)。若端口已被占用,自动打印提示并跳过执行 SSH 命令,绝不重复拉起进程,防止端口冲突。 - 内置心跳防假死:默认注入
ServerAliveInterval=15与ServerAliveCountMax=3,定时向服务器发送心跳包,彻底杜绝中间网关空闲超时导致的“端口还在但网络卡死”现象。 - 生命周期按需自愈:支持配置
auto_close开关。任务执行完毕后可选择自动回收销毁隧道,亦可保留在后台长驻运行。 - 保护既有服务:若启动时检测到端口原本已存在(例如已运行
autossh),即使配置了自动关闭,也绝对不会误杀外部既有进程。 - 跨环境通用:无论是在纯 Python 自动化脚本中直接导入,还是在 Node.js / Electron 项目中通过子进程调用,均可无缝衔接。
📦 安装
在你的项目根目录下使用任意包管理器安装:
# 使用 npm
npm install wimotek-ssh-tunnel
# 使用 yarn
yarn add wimotek-ssh-tunnel
# 使用 pnpm
pnpm add wimotek-ssh-tunnel
##⚠️ 前置要求
本地系统已安装 Python 3.x;
本地系统具备标准的 ssh 客户端命令工具;
本地电脑已配置针对远程主机的 SSH 密钥免密登录(建议通过 ssh-copy-id user@remote_host 预先配置,防止后台启动时阻塞在密码输入)。
##🚀 使用指南
1. 在 Python 项目中直接调用(最推荐)
安装到 node_modules 后,可以直接将 ssh_tunnel.py 引入你的自动化代码中:
'''Python
import asyncio
from playwright.async_api import async_playwright
# 导入模块中提供的核心方法
from ssh_tunnel import start_tunnel, stop_tunnel
# ================= 配置区域 =================
REMOTE_HOST = "root@kr2.wimotek.com" # 远程服务器地址
LOCAL_PORT = 9222 # 本地 CDP 映射端口
AUTO_CLOSE = False # True: 脚本结束时杀掉隧道; False: 保留在后台运行
# ============================================
async def main():
# 1. 启动或复用 SSH 隧道
# (如果 9222 端口已开,直接复用并跳过执行命令;如果没开,自动建立隧道)
tunnel_proc = start_tunnel(remote_host=REMOTE_HOST, port=LOCAL_PORT)
try:
# 2. 连接 CDP 执行你的自动化逻辑
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(f"http://127.0.0.1:{LOCAL_PORT}")
context = browser.contexts[0]
page = context.pages[0] if context.pages else await context.new_page()
await page.goto("https://github.com")
print("当前页面标题:", await page.title())
await browser.close()
finally:
# 3. 按需管理隧道生命周期
stop_tunnel(tunnel_proc, auto_close=AUTO_CLOSE)
if __name__ == "__main__":
asyncio.run(main())
'''
2. 在 Node.js / TypeScript 项目中调度
如果你在开发 Node.js / Electron 自动化任务,可以通过 child_process 引用该模块自带的 Python 脚本:
'''JavaScript
const path = require('path');
const { spawn } = require('child_process');
// 定位到 npm 包中的 ssh_tunnel.py 路径
const tunnelScriptPath = path.resolve(
__dirname,
'node_modules/wimotek-ssh-tunnel/ssh_tunnel.py'
);
console.log('SSH Tunnel 脚本路径:', tunnelScriptPath);
// 你可以直接由 Node.js 调起 Python 守护
const pythonProcess = spawn('python3', [
'-c',
`from ssh_tunnel import start_tunnel; start_tunnel("root@xx.xx.xx", 9222)`
], {
cwd: path.dirname(tunnelScriptPath),
stdio: 'inherit'
});
'''
## 📖 API 说明
模块核心包含以下 3 个函数:
is_port_in_use(port=9222) -> bool
功能:检测指定的本地端口当前是否处于监听(被占用)状态。
参数:
port (int):待检测的端口号,默认 9222。
返回值:True 表示端口已被监听,False 表示空闲。
---
start_tunnel(remote_host="root@kr2.wimotek.com", port=9222) -> subprocess.Popen | None
功能:智能建立安全 SSH 隧道。
运行逻辑:
调用 is_port_in_use(port) 检查端口;
若端口已存在:打印提示信息,返回 None,不触发外部命令;
若端口未占用:执行带心跳保活参数的 ssh -N -L ... 进程,阻塞 1.5 秒确认通道建立后返回 Popen 对象。
参数:
remote_host (str):SSH 登录目标主机(格式:user@host 或 host)。
port (int):本地映射端口登录目标主UUuuuuu与远程映射端口,默认 9222。
---
stop_tunnel(proc, auto_close=True)
功能:管理并关闭由 start_tunnel 建立的临时隧道。
参数:
proc (Popen | None):start_tunnel 返回的进程对象。
auto_close (bool):
True:立即向 SSH 子进程发送终止信号(terminate)释放本地端口;
False:打印保留提示,让子进程脱离并保留在后台持续运行。
安全性保证:如果 proc 为 None(即端口原本就存在、复用了旧连接),该函数直接忽略退出,绝不杀死外部已存在的服务。
---
## 🛠️ 故障排查
1. 为什么有时执行 curl http://127.0.0.1:9222 会卡死?
通常是因为网络静默断开导致 TCP 假死。本模块在构建命令时默认加入了:
'''Text
-o ServerAliveInterval=15 -o ServerAliveCountMax=3 -o TCPKeepAlive=yes
'''
可有效防止路由器和云服务器防火墙在连接空闲时切断网络通道。
2. 报错 Permission denied (publickey)?
这说明本地未配置针对目标主机的免密登录。请在终端执行:
'''Bash
ssh-copy-id root@xx.xx.xx
'''
## 📄 License
本项目基于 MIT 许可证 开源。
Metadata
Release files for wimotek-ssh-tunnel 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| wimotek_ssh_tunnel-1.0.0.tar.gz | 5.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wimotek_ssh_tunnel-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.3 kB
Release files / wimotek_ssh_tunnel-1.0.0.tar.gz
| Download URL | wimotek_ssh_tunnel-1.0.0.tar.gz |
|---|---|
| Size | 5.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
24a3190e69b10b4fad305c9e4150645497c657992865d35d570a53a993685772
|
|
BLAKE2b-256 checksum How to use checksums |
5c79e44c5f5b17bd4d39d457ce0e5545f71cb6cf8ed32df1c565ec37f470b7be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / wimotek_ssh_tunnel-1.0.0-py3-none-any.whl
| Download URL | wimotek_ssh_tunnel-1.0.0-py3-none-any.whl |
|---|---|
| Size | 6.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2da977dea57b0b7456696de4aaa012ddc199410b8697d21b62a6c92a51e17121
|
|
BLAKE2b-256 checksum How to use checksums |
013d317ea1f0f9615166858e5075d2aad17c552d110fa5b7ebfe92559fc0e4dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Security for wimotek-ssh-tunnel 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.