Skip to main content

websocket-tunnel

一个类似 frp 的内网穿透工具:Python + uv 实现,传输层使用 WebSocket 多路复用, 支持任意 TCP 服务(HTTP/HTTPS/SSH/MySQL 等)的字节流透传。构建产物通过 uv build 生成,安装后提供 wtunnel CLI,分为 serverclient 两种模式。

与 frp 的主要差异:代理不区分服务端/客户端。代理条目可以声明在任意节点的 配置中,监听端(listen)与后端(backend)分别用 local / peer 指定在哪一侧, 因此以下四种组合全部支持:

listen 侧 backend 侧 用途
server client 经典 frp:把内网服务暴露到公网服务器端口
client server 反向:把服务端网络里的服务映射到客户端本地端口
server server 服务端本机端口转发(不占用隧道)
client client 客户端本机端口转发(不占用隧道)

安装

要求 Python >= 3.11 与 uv

uv sync            # 开发环境(含测试依赖)
uv build           # 构建 sdist + wheel
uv run wtunnel --version

也可以把 wheel 安装到任意环境:

uv pip install dist/websocket_tunnel-0.1.0-py3-none-any.whl
wtunnel --version

快速开始

1. 启动服务端

wtunnel server -c examples/server.toml

2. 启动客户端

wtunnel client -c examples/client.toml

客户端默认把本机 127.0.0.1:3000 暴露到服务端的 0.0.0.0:8080,访问 http://<server>:8080 即可到达客户端内网的服务。

CLI 参数

wtunnel server -c server.toml [--listen HOST:PORT] [--token TOKEN]
                       [--tls-cert PATH --tls-key PATH] [-v]
wtunnel client -c client.toml [--server HOST:PORT] [--token TOKEN]
                       [--tls] [--tls-skip-verify] [-v]

CLI 参数覆盖配置文件中的同名项;-v 输出 DEBUG 日志。

配置参考

server.toml

listen = "0.0.0.0:7000"          # 控制端口(ws/wss)
token = "secret"                 # 可选,共享认证 token
tls = { cert = "server.crt", key = "server.key" }   # 可选,启用 wss

# 最大并发控制连接数(0 = 不限)
max_connections = 10

# 允许 client 请求本节点连接的 backend IP 范围(CIDR 列表,空 = 允许所有)
allow_peer_backends = ["127.0.0.1/32", "10.0.0.0/8"]

# 允许 client 请求本节点绑定的 listen IP 范围(空 = 允许所有)
allow_peer_listens = ["0.0.0.0/0", "::/0"]

[[proxies]]
name = "web"
listen = "0.0.0.0:8080"
listen_side = "local"            # "local" | "peer"
backend = "127.0.0.1:3000"
backend_side = "peer"

client.toml

server = "127.0.0.1:7000"        # 服务端地址
token = "secret"
tls = false                      # true 时使用 wss
tls_skip_verify = false          # 自签证书时设为 true

# 允许服务端请求本节点连接的 backend IP 范围(CIDR 列表,空 = 允许所有)
allow_peer_backends = ["127.0.0.1/32"]

# 允许服务端请求本节点绑定的 listen IP 范围(空 = 允许所有)
allow_peer_listens = ["127.0.0.1/32"]

[[proxies]]
name = "web"
listen = "0.0.0.0:8080"
listen_side = "peer"
backend = "127.0.0.1:3000"
backend_side = "local"

listen / backend 均为 host:port,IPv6 使用 [::1]:8080 形式。allow_peer_* 白名单中的地址必须使用 IP(不支持主机名),CIDR 掩码可省略(如 "10.0.0.1" 等同于 "10.0.0.1/32")。

传输与协议概要

  • 每对节点一条 WebSocket 长连接(client 主动连接 server),控制消息与所有数据流 在其上多路复用;每条 TCP 流分配独立 stream id。
  • 二进制帧:首字节为消息类型;控制消息为 JSON,数据帧为 stream_id(4 字节大端) + 数据块(默认 32 KiB)。
  • 支持半关闭:任一方向 EOF 只关闭对应方向,保证 HTTP/1.0 与 keep-alive 响应完整。
  • 握手时校验共享 token(失败即断开);服务端可选 wss,客户端可跳过证书校验。
  • client 断线自动重连(指数退避 1s→30s),重连后双方重新注册代理并重新绑定监听。

开发与测试

uv run pytest          # 单元 + 集成测试
uv build               # 构建发布产物

发布到 PyPI

打上 v 开头的 tag 并推送即触发 GitHub Actions 发布:

git tag v0.1.0
git push origin v0.1.0

工作流(.github/workflows/release.yml)会校验 tag 与包版本一致、运行测试、 uv build 构建后通过 trusted publishing(OIDC)发布到 PyPI。首次使用前需要在 PyPI 项目页配置 Trusted Publisher:仓库 8DE4732A/websocket-tunnel、 工作流名 Publish to PyPI。若改用 API token,删除 workflow 中 id-token: write 权限,并配置 PYPI_TOKEN secret 传给 uv publish

安全说明

连接数限制:服务端 max_connections 防止恶意客户端通过大量控制连接耗尽资源。 建议生产部署时设置一个合理上限(如 10)。

后端 / 监听白名单:默认配置下,持有 token 的对端可请求本节点连接任意 IP 或 绑定任意端口,这在可信局域网内往往是期望行为。若部署于半信任网络,应配置 allow_peer_backends 将出站连接限定为必要的内网 CIDR,并用 allow_peer_listens 约束监听 IP,以防内网探测(SSRF)与端口滥用。

传输加密:token 在握手时以明文 JSON 传输。公网部署请务必启用 wss(配置 tls.cert / tls.key);tls_skip_verify = true 仅适用于受控的自签证书环境, 生产环境应使用受信任 CA 签发的证书。

v1 暂不提供 mTLS、证书固定与配置热加载。

Release files for websocket-tunnel 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for websocket-tunnel 0.3.0
File Size Uploaded
websocket_tunnel-0.3.0.tar.gz 50.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for websocket-tunnel 0.3.0
File Interpreter ABI Platform
websocket_tunnel-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 70.3 kB

Release files / websocket_tunnel-0.3.0.tar.gz

Download URL websocket_tunnel-0.3.0.tar.gz
Size 50.8 kB
Tags Source
SHA-256 checksum
How to use checksums
b9b4b19e3344c6699d8670d9ab3bde8620ac2d87784a9f480847428c7d792fb9
BLAKE2b-256 checksum
How to use checksums
73a0282c86cb9ddbea59452ef6eacf4d93a275b5706a38d4f99a6ab75df357fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / websocket_tunnel-0.3.0-py3-none-any.whl

Download URL websocket_tunnel-0.3.0-py3-none-any.whl
Size 19.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
020799f77daaeb02ad3289a2b9cd4c1b77de42495270e18a4b9fec31f25f32af
BLAKE2b-256 checksum
How to use checksums
d3eb621d4255b0964be67b47796656f4d4dbe96eeec069b4ff3e7c0bf2129b49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.3.2

2 release files

0.3.1

2 release files

This release

0.3.0 This release

2 release files

0.2.2

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page