{"id":34502693,"url":"https://github.com/kzw200015/kt-tunnel","last_synced_at":"2026-04-22T06:04:28.659Z","repository":{"id":329595341,"uuid":"1119970364","full_name":"kzw200015/kt-tunnel","owner":"kzw200015","description":"Reverse tunneling tool based on Kotlin, Netty, and WebSocket","archived":false,"fork":false,"pushed_at":"2025-12-20T17:04:40.000Z","size":139,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-22T18:05:18.437Z","etag":null,"topics":["kotlin","netty","tunneling","websocket"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kzw200015.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-12-20T07:56:02.000Z","updated_at":"2025-12-20T17:04:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kzw200015/kt-tunnel","commit_stats":null,"previous_names":["kzw200015/kt-tunnel"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/kzw200015/kt-tunnel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzw200015%2Fkt-tunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzw200015%2Fkt-tunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzw200015%2Fkt-tunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzw200015%2Fkt-tunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kzw200015","download_url":"https://codeload.github.com/kzw200015/kt-tunnel/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kzw200015%2Fkt-tunnel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27992999,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","netty","tunneling","websocket"],"created_at":"2025-12-24T02:19:29.630Z","updated_at":"2026-04-22T06:04:28.653Z","avatar_url":"https://github.com/kzw200015.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kt-tunnel\n\n一个基于 **Kotlin/JVM + Netty** 实现的 WS/WSS 三端隧道（`server / agent / client`），用于在公网 `server` 与内网 `agent` 之间建立 TCP 访问通道。\n\n支持：\n- 本地端口转发（`--forward`）：`listenHost:listenPort -\u003e targetHost:targetPort`（由 agent 侧去连接 target）\n- 本地 SOCKS5 代理（`--socks5`）：仅支持 `NO_AUTH` + `CONNECT`\n- `ws` / `wss`（server 可配置证书或一键自签）\n\n## 技术选型\n\n- **Kotlin/JVM**：单一可执行 JAR 交付；代码表达力强，适合快速实现网络协议与状态机。\n- **Netty 4.2**：事件驱动 + pipeline 模型，适合构建高并发长连接服务端/客户端；内置 HTTP/WebSocket/SOCKS5 codec。\n- **WebSocket（ws/wss）**：统一承载控制面与数据面，部署时可复用 80/443，穿透网络环境更友好。\n- **picocli**：以子命令组织 `server/agent/client`，参数声明清晰、帮助信息自动生成。\n- **kotlinx.serialization**：控制面消息使用 JSON（TextWebSocketFrame）序列化/反序列化。\n- **logback**：统一日志输出，便于排障。\n- **Gradle + Shadow 插件**：构建 `standalone` fat-jar（包含全部依赖），便于分发运行。\n\n## 架构设计与思路（简要）\n\n### 1) 三端职责\n- **server（公网）**\n  - 同端口提供 3 个 WebSocket endpoint：`/ws/agent/control`、`/ws/agent/data`、`/ws/client/tunnel`\n  - 维护 `agentId -\u003e control channel` 在线表\n  - 维护隧道状态：`pending`（等待 agent 绑定）/ `active`（已配对转发）\n  - 在 `clientTunnelWS` 与 `agentDataWS` 之间**透明转发二进制帧**\n- **agent（内网）**\n  - 与 server 保持一条 control WS 长连接（注册、接收建隧道指令）\n  - 每条隧道：先拨号连接 `targetHost:targetPort`（TCP），再建立 data WS（首包 `AGENT_DATA_BIND` 绑定 tunnelId）\n  - 在 `target TCP ↔ data WS` 之间转发\n- **client（本地）**\n  - 按 `--forward` / `--socks5` 在本地启动 listener\n  - 每接入一条本地连接就创建一条 client tunnel WS（首包 `CLIENT_TUNNEL_OPEN`）\n  - **收到 server 的 `CLIENT_TUNNEL_OK` 后才开始读取/转发本地数据**，避免半连接与乱序\n\n### 2) 连接与时序（无多路复用）\n\n每条隧道（tunnelId）独占连接：\n- `client -\u003e server`：`/ws/client/tunnel`（1 条）\n- `agent  -\u003e server`：`/ws/agent/data`（1 条）\n此外 agent 还有一条长期 `control` 连接：`/ws/agent/control`。\n\n典型时序：\n1. agent 连接 control 并发送 `AGENT_REGISTER`\n2. client 建立 tunnel WS 并发送 `CLIENT_TUNNEL_OPEN`（携带 agentId/target/token）\n3. server 校验 token + agent 在线后将 tunnel 置为 `pending`，并向 agent 下发 `TUNNEL_CREATE`\n4. agent 连接 target TCP 成功后建立 data WS，发送 `AGENT_DATA_BIND`\n5. server 绑定两端后返回 `CLIENT_TUNNEL_OK`，随后开始双向透传 BinaryWebSocketFrame\n\n数据路径：\n`local TCP ↔ clientTunnelWS ↔ server ↔ agentDataWS ↔ agent ↔ target TCP`\n\n## 使用方法\n\n### 1) 构建\n\n需要 JDK 8+。\n\n```bash\n./gradlew shadowJar\n```\n\n产物：`build/libs/kt-tunnel-*-standalone.jar`\n\n### 2) 启动 server（公网）\n\n不启用 TLS（ws）：\n```bash\njava -jar build/libs/kt-tunnel-*-standalone.jar server \\\n  --bind 0.0.0.0:8000 \\\n  --token TOKEN\n```\n\n启用 TLS（wss），方式二选一：\n- 指定证书（PEM）：\n```bash\njava -jar build/libs/kt-tunnel-*-standalone.jar server \\\n  --bind 0.0.0.0:8000 \\\n  --token TOKEN \\\n  --cert server.crt --key server.key\n```\n- 一键自签（便于本地/临时验证）：\n```bash\njava -jar build/libs/kt-tunnel-*-standalone.jar server \\\n  --bind 0.0.0.0:8000 \\\n  --token TOKEN \\\n  --self-signed-tls kttunnel\n```\n\n### 3) 启动 agent（内网）\n\n```bash\njava -jar build/libs/kt-tunnel-*-standalone.jar agent \\\n  --server ws://127.0.0.1:8000 \\\n  --token TOKEN \\\n  --agent-id AGENT_ID\n```\n\n不传 `--agent-id` 会自动生成 UUID 并在控制台打印 `agentId=...`。\n\n若 server 使用 TLS（wss），`--server` 需使用 `wss://`。证书校验可选：\n- `--ca ca.crt`：指定自定义 CA\n- `--insecure`：跳过证书校验（仅开发环境）\n\n### 4) 启动 client（本地）\n\nclient 需要至少提供一个 `--forward` 或 `--socks5`（可多次传入，创建多个本地 listener）。\n\n#### 4.1 端口转发（forward）\n\n示例：把本地 `9000` 转发到 agent 可访问的 `127.0.0.1:8080`：\n```bash\njava -jar build/libs/kt-tunnel-*-standalone.jar client \\\n  --server ws://127.0.0.1:8000 \\\n  --token TOKEN --agent-id AGENT_ID \\\n  --forward 9000:127.0.0.1:8080\n```\n\n`--forward` 支持格式（可多次传入）：\n- `\u003clistenPort\u003e:\u003ctargetHost\u003e:\u003ctargetPort\u003e`（listenHost 默认 `0.0.0.0`）\n- `\u003clistenHost\u003e:\u003clistenPort\u003e:\u003ctargetHost\u003e:\u003ctargetPort\u003e`\n\n#### 4.2 SOCKS5 代理（socks5）\n\n启动本地 SOCKS5（示例：监听 `127.0.0.1:1080`）：\n```bash\njava -jar build/libs/kt-tunnel-*-standalone.jar client \\\n  --server ws://127.0.0.1:8000 \\\n  --token TOKEN --agent-id AGENT_ID \\\n  --socks5 127.0.0.1:1080\n```\n\n`--socks5` 支持格式（可多次传入）：\n- `\u003cport\u003e`（listenHost 默认 `0.0.0.0`）\n- `\u003clistenHost\u003e:\u003cport\u003e`\n\n说明：当前 SOCKS5 仅支持 `NO_AUTH` 与 `CONNECT`，不支持 UDP/鉴权等扩展。\n\n### 5) 查看帮助\n\n```bash\njava -jar build/libs/kt-tunnel-*-standalone.jar --help\njava -jar build/libs/kt-tunnel-*-standalone.jar server --help\njava -jar build/libs/kt-tunnel-*-standalone.jar agent --help\njava -jar build/libs/kt-tunnel-*-standalone.jar client --help\n```\n\n## 限制与注意事项\n\n- **无多路复用**：每条本地连接会新建一条 client tunnel WS；每条隧道在 agent 侧也会新建一条 data WS + 一条 target TCP。\n- **鉴权为共享 token（MVP）**：建议配合 TLS（wss）使用，避免明文传输。\n- **TLS 自签证书**：默认不受信任；可用 `--insecure` 临时跳过校验，或把 CA 通过 `--ca` 传给 client/agent。\n- **长连接空闲**：agent control 会定时发送心跳，避免长时间无流量时被中间网络设备回收连接。\n\n## 更多文档\n\n- 详细实现说明与协议细节：`doc/kotlin-netty-picocli-wss-tunnel.md`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkzw200015%2Fkt-tunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkzw200015%2Fkt-tunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkzw200015%2Fkt-tunnel/lists"}