{"id":27631162,"url":"https://github.com/meethigher/tcp-reverse-proxy","last_synced_at":"2025-04-23T17:42:32.662Z","repository":{"id":282522729,"uuid":"871943100","full_name":"meethigher/tcp-reverse-proxy","owner":"meethigher","description":"基于Vert.x实现的HTTP反向代理与TCP反向代理、内网穿透","archived":false,"fork":false,"pushed_at":"2025-04-19T08:32:16.000Z","size":156,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-19T15:06:12.387Z","etag":null,"topics":["expose","frp","http-server","java","reverse-proxy","tcp-proxy-server","tcp-server","tunnel","vertx"],"latest_commit_sha":null,"homepage":"https://github.com/meethigher/http-proxy-boot/releases/tag/v3.0.0","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meethigher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-10-13T11:36:26.000Z","updated_at":"2025-04-19T08:31:35.000Z","dependencies_parsed_at":"2025-04-19T09:41:09.850Z","dependency_job_id":"05f678f0-5f6a-4c55-bb32-b75bec3bda0c","html_url":"https://github.com/meethigher/tcp-reverse-proxy","commit_stats":null,"previous_names":["meethigher/tcp-reverse-proxy"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meethigher%2Ftcp-reverse-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meethigher%2Ftcp-reverse-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meethigher%2Ftcp-reverse-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meethigher%2Ftcp-reverse-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meethigher","download_url":"https://codeload.github.com/meethigher/tcp-reverse-proxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250482951,"owners_count":21437969,"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","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":["expose","frp","http-server","java","reverse-proxy","tcp-proxy-server","tcp-server","tunnel","vertx"],"created_at":"2025-04-23T17:42:31.988Z","updated_at":"2025-04-23T17:42:32.647Z","avatar_url":"https://github.com/meethigher.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tcp-reverse-proxy\n基于[Vert.x](https://vertx.io/)实现的HTTP反向代理与TCP反向代理、内网穿透\n\n开发环境\n\n* jdk: 8\n* vertx: 4.5.10\n\n依赖引入，可以访问[mvnrepository.com](https://mvnrepository.com/artifact/top.meethigher/tcp-reverse-proxy)查看版本\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003etop.meethigher\u003c/groupId\u003e\n    \u003cartifactId\u003etcp-reverse-proxy\u003c/artifactId\u003e\n    \u003cversion\u003e${tcp-reverse-proxy.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.vertx\u003c/groupId\u003e\n    \u003cartifactId\u003evertx-core\u003c/artifactId\u003e\n    \u003cversion\u003e4.5.10\u003c/version\u003e\n\u003c/dependency\u003e\n\u003c!-- 若不使用http反向代理，可不加此依赖 --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.vertx\u003c/groupId\u003e\n    \u003cartifactId\u003evertx-web\u003c/artifactId\u003e\n    \u003cversion\u003e4.5.10\u003c/version\u003e\n\u003c/dependency\u003e\n\u003c!-- 若不想添加日志，可只添加slf4j-api --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ech.qos.logback\u003c/groupId\u003e\n    \u003cartifactId\u003elogback-classic\u003c/artifactId\u003e\n    \u003cversion\u003e1.2.12\u003c/version\u003e\n\u003c/dependency\u003e\n\u003c!-- 若不使用TCP内网穿透，可不加此依赖 --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.google.protobuf\u003c/groupId\u003e\n    \u003cartifactId\u003eprotobuf-javalite\u003c/artifactId\u003e\n    \u003cversion\u003e4.30.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## 一、TCP反向代理\n\n实现TCP反向代理：`0.0.0.0:22`↔️`10.0.0.1:8080`\n\n```java\nReverseTcpProxy.create(Vertx.vertx(), \"10.0.0.1\", 8080)\n        .port(22)\n        .start();\n```\n\n## 二、TCP内网穿透\n\n虚线表示进程内部通信。实线表示外部通信。\n\n一些代码上的设计思路，参考[socket.io-client-java](https://github.com/socketio/socket.io-client-java/blob/socket.io-client-2.1.0/src/main/java/io/socket/client/Socket.java)\n\n```mermaid\nsequenceDiagram\n    autonumber\n    participant u as User\n    participant dps as DataProxyServer\n    participant ts as TunnelServer\n    participant tc as TunnelClient\n    participant bs as BackendServer\n    \n    ts--\u003ets: 监听44444端口\n    tc-\u003e\u003ets: 建立控制连接、发送鉴权密钥、申请启用22端口数据服务\n    ts--\u003ets: 鉴权校验通过\n    ts--\u003e\u003edps: 你要开启22端口\n    dps--\u003edps: 监听22端口\n    dps--\u003e\u003ets: 已开启\n    ts-\u003e\u003etc: 成功\n    tc--\u003etc: 开启与控制服务的周期心跳\n    loop 控制连接保活\n      tc-\u003e\u003ets: 发送心跳\n      ts-\u003e\u003etc: 响应心跳\n    end\n    u-\u003e\u003edps: 建立数据连接\n    dps--\u003e\u003ets: 通知\n    ts-\u003e\u003etc: 你需要主动与22数据服务建立数据连接\n    tc-\u003e\u003edps: 建立数据连接\n    note left of dps: 用户连接和数据连接绑定双向生命周期、双向数据传输\n    tc-\u003e\u003ebs: 建立后端连接\n    dps-\u003e\u003etc: 成功\n    bs-\u003e\u003etc: 成功\n    note right of tc: 数据连接和后端连接绑定双向生命周期、双向数据传输\n    \n    u-\u003edps: 双向传输\n    dps-\u003etc: 双向传输\n    tc-\u003ebs: 双向传输 \n    \n\n```\n\n假如我有一个内网`SSH`服务`10.0.0.10:22`，需要通过`192.168.0.200:22`穿透出去。并且网络条件受限如下\n\n1. `10.0.0.10`可以主动连接`192.168.0.200`\n2. `192.168.0.200`无法主动连接`10.0.0.10`\n3. 只要双方建立连接，即可实现双向数据传输\n\n这就需要TCP内网穿透了。假设你内网穿透使用的控制端口为`44444`。\n\n首先，在`192.168.0.200`这台机器，使用如下代码启动`TunnelServer`\n\n```java\nReverseTcpProxyTunnelServer.create(Vertx.vertx())\n        .port(44444)\n        // 用于用户连接和数据连接的延迟判定，如果网络较差/DNS解析较慢的情况下，建议将该参数调大\n        .judgeDelay(2000)\n        .start();\n```\n\n在`10.0.0.10`这台机器，使用如下代码启动`TunnelClient`\n\n```java\nReverseTcpProxyTunnelClient.create(Vertx.vertx())\n        .backendHost(\"10.0.0.10\")\n        .backendPort(22)\n        .dataProxyName(\"ssh-proxy\")\n        .dataProxyHost(\"192.168.0.200\")\n        .dataProxyPort(22)\n        .connect(\"192.168.0.200\", 44444);\n```\n\n\n\n## 三、HTTP反向代理\n\n实现HTTP反向代理，代理路由优先级如下\n\n1. `/local/*`↔️`http://127.0.0.1:888`\n   * `http://127.0.0.1:8080/local/1`↔️`http://127.0.0.1:888/1`\n   * `http://127.0.0.1:8080/local/1/2/3`↔️`http://127.0.0.1:888/1/2/3`\n2. `/*`↔️`https://reqres.in`\n   * `http://127.0.0.1:8080/api/users?page=2`↔️`https://reqres.in/api/users?page=2`\n\nHTTP反向代理支持如下配置\n\n1. 请求头转发客户端IP: 默认值F\n2. 保留响应头Cookie: 默认值T\n3. 保留请求头Host: 默认值F\n4. 跟随跳转: 默认值T\n5. 长连接: 默认值T\n6. 日志及日志格式自定义\n7. 代理服务完全接管跨域控制: 默认值F\n\n```java\n// addRoute第二个参数表示优先级，值越小、优先级越高\nReverseHttpProxy.create(vertx).port(8080)\n        .addRoute(new ProxyRoute()\n                .setName(\"proxy\")\n                .setSourceUrl(\"/local/*\")\n                .setTargetUrl(\"http://127.0.0.1:888\"),-1)\n        .addRoute(new ProxyRoute()\n                .setName(\"proxy\")\n                .setSourceUrl(\"/*\")\n                .setTargetUrl(\"https://reqres.in\"),1)\n        .start();\n```\n\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeethigher%2Ftcp-reverse-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeethigher%2Ftcp-reverse-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeethigher%2Ftcp-reverse-proxy/lists"}