{"id":15014244,"url":"https://github.com/codingmiao/hppt","last_synced_at":"2025-04-07T10:24:21.843Z","repository":{"id":213712204,"uuid":"734751925","full_name":"codingmiao/hppt","owner":"codingmiao","description":"一款可通过任意协议转发tcp端口的工具  A tool to forward tcp ports over any protocol","archived":false,"fork":false,"pushed_at":"2024-12-12T10:55:52.000Z","size":1300,"stargazers_count":76,"open_issues_count":0,"forks_count":27,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-31T08:12:03.409Z","etag":null,"topics":["java","nat","netty","proxy"],"latest_commit_sha":null,"homepage":"","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/codingmiao.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}},"created_at":"2023-12-22T14:14:27.000Z","updated_at":"2024-12-12T10:55:37.000Z","dependencies_parsed_at":"2023-12-22T16:02:40.596Z","dependency_job_id":"426f41fd-ac26-4450-95fa-50ff8ebffcca","html_url":"https://github.com/codingmiao/hppt","commit_stats":{"total_commits":46,"total_committers":2,"mean_commits":23.0,"dds":"0.021739130434782594","last_synced_commit":"57058b9a8d402f7750cf3dc3389ca034bf5d5d91"},"previous_names":["codingmiao/hppt"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingmiao%2Fhppt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingmiao%2Fhppt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingmiao%2Fhppt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingmiao%2Fhppt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codingmiao","download_url":"https://codeload.github.com/codingmiao/hppt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247633023,"owners_count":20970251,"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":["java","nat","netty","proxy"],"created_at":"2024-09-24T19:45:21.981Z","updated_at":"2025-04-07T10:24:21.815Z","avatar_url":"https://github.com/codingmiao.png","language":"Java","readme":"![hppt](_doc/img/hppt.png)\n\nhppt，一款可通过任意协议转发tcp端口的工具。\n\n[中文](./readme.md)\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[English](./readme_en.md)\n\n[github](https://github.com/codingmiao/hppt)\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[gitee](https://gitee.com/wowtools/hppt)\n\n\n# 简介\n日常工作中，我们常常因为无法访问某些远程端口而带来很多麻烦，例如下面的场景，服务器的防火墙只留了80/443端口用以web访问，\n如果你希望访问到服务器上的数据库、SSH等端口，可以借助本工具把需要的端口映射出来：\n\n![hppt](_doc/img/1.jpg)\n\n# 快速开始\n在[releases](https://github.com/codingmiao/hppt/releases)\n页面下载最新版本编译好的hppt。\n\n或自行下载源码编译：\n```shell\n#jar\nmvn clean package -DskipTests\n\n#可选操作 打native包\nsu graalvm\ncd run\nmvn org.graalvm.buildtools:native-maven-plugin:build\n```\n\n本项目编译成了可执行文件及jar包。\n\n可执行文件无环境依赖、内存占用较少，但因为没有jit支持，性能略逊于jar包执行；\n\njar包执行性能更好，但多消耗一些内存，如需jar包执行，请先前往[jdk官网](https://jdk.java.net/archive/)下载对应你操作系统版本的jdk21。\n\n## 示例1 通过http端口，反向代理访问内部服务器SSH端口\n\n假设你有一个服务器集群，仅有一个nginx提供了80/443端口对外访问(111.222.33.44:80)，你想要访问集群中的应用服务器(192.168.0.2)的22端口，则可以按如下结构部署\n\n![示例1](_doc/img/3.jpg)\n\n1、在集群中任一服务器上新建一个hppt目录，并上传hppt.jar（也可用可执行文件 hppt.exe 或 hppt）、ss.yml、logback.xml文件到此目录下:\n\n```\nhppt\n    - hppt.jar (or hppt.exe or hppt_linux_file)\n    - ss.yml\n    - logback.xml\n```\n\n并调整ss.yml的配置信息:\n\n```yaml\n#使用http post协议传输数据，此协议最为简单，但性能略差，如有需要请查看websocket协议或hppt协议或自定义协议\ntype: post\n#服务http端口\nport: 20871\n# 允许的客户端账号和密码\nclients:\n  - user: user1\n    password: 12345\n  - user: user2\n    password: 112233\n\n```\n（注1：作为快速演示，这里的type选择了最简单的post类型，此场景下可按[这篇文档](_doc/demo/websocket.md)配置websocket以获得更高性能，或是有独立端口的话可以按[这篇文档](_doc/demo/hppt.md)配置hppt协议）\n\n（注2：实际应用中，为了确保安全，建议把密码设置得更复杂一些）\n\n执行如下命令运行服务端的hppt（3选1）\n\njar包运行\n```shell\ncd hppt\n\u003cjdk21_path\u003e/bin/java -jar hppt.jar ss ss.yml\n```\n\nwindows下可执行文件运行\n```shell\ncd hppt\nchcp 65001\nhppt.exe ss ss.yml\n```\n\nlinux下可执行文件运行\n```shell\ncd hppt\n./hppt ss ss.yml\n#后台运行用命令  nohup ./hppt ss ss.yml \u003e/dev/null \u0026\n```\n\n\n在nginx上增加一段配置指向hppt\n\n```\nserver {\n    # 用https也ok的，对应修改nginx https配置即可\n    listen       80;\n    ...\n    location /xxx/ {\n        proxy_pass http://localhost:20871/;\n    }\n    ...\n```\n\n随后，访问`http://111.222.33.44:80/xxx/` 能看到“error 404”字样即证明服务端部署成功。\n\n2、自己笔记本上，新建一个hppt目录，拷贝hppt.jar (or hppt.exe or hppt_linux_file)、sc.yml、logback.xml文件到此目录下:\n\n```\nhppt\n    - hppt.jar (or hppt.exe or hppt_linux_file)\n    - sc.yml\n    - logback.xml\n```\n\n并调整sc.yml的配置信息:\n\n```yaml\n# 和服务端的type保持一致\ntype: post\n# 客户端用户名，每个sc进程用一个，不要重复\nclientUser: user1\n# 客户端密码\nclientPassword: 12345\n\npost:\n  # 服务端http地址，如无法直连，用nginx代理几次填nginx的地址也ok\n  serverUrl: \"http://111.222.33.44:80/xxx\"\n  # 这个示例中，不用nginx的话直接配原始的服务端端口\n  #serverUrl: \"http://111.222.33.44:20871\"\n  # 人为设置的延迟（毫秒），一般填0即可，如果传文件等数据量大、延迟要求低的场景，可以设一个几百毫秒的延迟来降低post请求发送频率\n  sendSleepTime: 0\nforwards:\n    # 把192.168.0.2的22端口代理到本机的10022端口\n  - localPort: 10022\n    remoteHost: \"192.168.0.2\"\n    remotePort: 22\n    # 同理也可以代理数据库等任意TCP端口，只要服务端的hppt所在服务器能访问到的端口都行\n  - localPort: 10023\n    remoteHost: \"192.168.0.3\"\n    remotePort: 3306\n\n\n```\n\n执行如下命令启动客户端的hppt（3选1）\n\njar包运行\n```shell\ncd hppt\n\u003cjdk21_path\u003e/bin/java -jar hppt.jar sc sc.yml\n```\n\nwindows下可执行文件运行\n```shell\ncd hppt\nchcp 65001\nhppt.exe sc sc.yml\n```\n\nlinux下可执行文件运行\n```shell\ncd hppt\n./hppt sc sc.yml\n#后台运行用命令  nohup ./hppt ss ss.yml \u003e/dev/null \u0026\n```\n\n随后，你就可以在公司用linux连接工具访问localhost的10022端口，来登录应用服务器了\n\n\n## 示例2 内网穿透，通过公网转发，访问无公网IP的服务器\n\n假设你家里有一台台式机(ssh端口为22)，并且有一台公网VPS服务器(ip 111.222.33.44)，你想在公司用笔记本登录家里的台式机，可按如下结构部署：\n\n![示例2](_doc/img/4.jpg)\n\n1、公网服务器上，新建一个hppt目录，拷贝hppt.jar（也可用可执行文件 hppt.exe 或 hppt）、sc.yml、logback.xml文件到此目录下:\n\n```\nhppt\n    - hppt.jar (or hppt.exe or hppt_linux_file)\n    - sc.yml\n    - logback.xml\n```\n\n并调整sc.yml的配置信息:\n\n```yaml\n# 通讯协议 本示例使用了性能最好的hppt协议，加r前缀表示客户端和服务端角色互换。这里也可以配http post或websocket\ntype: rhppt\n# 客户端用户名，每个sc进程用一个，不要重复\nclientUser: user1\n# 客户端密码\nclientPassword: 12345\n\n# 服务端口\nrhppt:\n  port: 20871\n\nforwards:\n    # 把192.168.0.2的22端口代理到本机的10022端口\n  - localPort: 10022\n    remoteHost: \"192.168.0.2\"\n    remotePort: 22\n    # 同理也可以代理数据库等任意TCP端口，只要服务端的hppt所在服务器能访问到的端口都行\n  - localPort: 10023\n    remoteHost: \"192.168.0.3\"\n    remotePort: 3306\n\n```\n\n执行如下命令启动公网服务器上的hppt（3选1）\n\njar包运行\n```shell\ncd hppt\n\u003cjdk21_path\u003e/bin/java -jar hppt.jar sc sc.yml\n```\n\nwindows下可执行文件运行\n```shell\ncd hppt\nchcp 65001\ntitle \"hppt\"\nhppt.exe sc sc.yml\npause\n```\n\nlinux下可执行文件运行\n```shell\ncd hppt\n./hppt sc sc.yml\n#后台运行用命令  nohup ./hppt ss ss.yml \u003e/dev/null \u0026\n```\n\n2、家里的台式机上，新建一个hppt目录，拷贝hppt.jar (or hppt.exe or hppt_linux_file)、ss.yml、logback.xml文件到此目录下：\n\n```\nhppt\n    - hppt.jar (or hppt.exe or hppt_linux_file)\n    - ss.yml\n    - logback.xml\n```\n\n修改ss.yml\n\n```yaml\n# 通讯协议 客户端与服务端保持一致\ntype: rhppt\n#服务http端口\nport: 20871\n\n# 指向上一步启动的服务的ip和端口\nrhppt:\n  host: \"111.222.33.44\"\n  port: 20871\n\n# 允许的客户端账号和密码\nclients:\n  - user: user1\n    password: 12345\n  - user: user2\n    password: 112233\n\n```\n\n\n执行如下命令启动家里台式机上的hppt（3选1）\n\njar包运行\n```shell\ncd hppt\n\u003cjdk21_path\u003e/bin/java -jar hppt.jar ss ss.yml\n```\n\nwindows下可执行文件运行\n```shell\ncd hppt\nchcp 65001\ntitle \"hppt\"\nhppt.exe ss ss.yml\npause\n```\n\nlinux下可执行文件运行\n```shell\ncd hppt\n./hppt ss ss.yml\n#后台运行用命令  nohup ./hppt ss ss.yml \u003e/dev/null \u0026\n```\n\n随后，你就可以在公司用linux连接工具访问111.222.33.44的10022端口，来登录家里的台式机了\n\n\n## 示例3 编写自定义协议\n如下图所示，A、B两台机器间无法进行通信，但他们都可以访问到机器C上的kafka，本示例演示如何通过编写自定义协议，使得A能够以C上的kafka作为桥梁访问到B上的SSH端口：\n\n![kafkademo](_doc/img/kafkademo.jpg)\n\n首先clone本项目到本地，然后`mvn clean install`把本项目安装到maven。\n\n然后新建一个java工程，引入hppt-run以及kafka等maven依赖\n```xml\n        \u003cdependency\u003e\n            \u003cgroupId\u003eorg.wowtools.hppt\u003c/groupId\u003e\n            \u003cartifactId\u003erun\u003c/artifactId\u003e\n            \u003cversion\u003e1.0-SNAPSHOT\u003c/version\u003e\n        \u003c/dependency\u003e\n        \u003c!--继续添加其他依赖--\u003e\n```\n然后就可以编写代码了：\n\n编写一个服务端实现并在机器B上运行，你需要实现如下方法:\n```java\npublic class ServerDemo extends ServerSessionService\u003cT\u003e {\n\n    public ServerDemo(SsConfig ssConfig) {\n        super(ssConfig);\n    }\n\n    //初始化时需要做什么\n    public void init(SsConfig ssConfig) throws Exception {\n    }\n\n    //怎样发送字节到客户端\n    protected void sendBytesToClient(T ctx, byte[] bytes) {\n    }\n\n    //收到客户端的字节时，主动去调用receiveClientBytes(CTX ctx, byte[] bytes)\n\n    //当客户端断开时需要做什么\n    protected void closeCtx(T ctx) throws Exception {\n    }\n\n    //当本服务端关闭后，在此释放掉连接池等资源\n    protected void doClose() throws Exception {\n    }\n}\n```\n完整的示例实现请参考[这里](kafkademo/src/main/java/org/wowtools/hppt/kafkademo/ServerDemo.java)\n\n\n编写一个客户端实现并在机器B上运行，你需要实现如下方法:\n```java\npublic class ClientDemo extends ClientSessionService {\n    public ClientDemo(ScConfig config) throws Exception {\n        super(config);\n    }\n\n    //怎样连接到服务端\n    protected void connectToServer(ScConfig config, Cb cb) throws Exception {\n    }\n\n    //怎样发送字节到服务端\n    protected void sendBytesToServer(byte[] bytes) {\n    }\n\n    //收到服务端的字节时，主动去调用receiveServerBytes(byte[] bytes)\n}\n```\n完整的示例实现请参考[这里](kafkademo/src/main/java/org/wowtools/hppt/kafkademo/ClientDemo.java)\n\n随后，你就可以通过访问A的10022端口，来连接B上的SSH 22端口了。\n\n# Q\u0026A\n\n## 性能如何？\n\n使用hppt或websocket等长连接协议的话，本项目只是做了个转发和加解密等操作，性能损耗在5%以内，以下是示例2中scp命令拷贝一个186m的文件，连接原始端口和代理端口的耗时对比：\n\n```shell\n# 直连\nscp -P 22 jdk-21_linux-aarch64_bin.tar.gz   root@xxx:/xxx                                                                                                                          \n100%  186MB   7.5MB/s   00:25\n# 代理\nscp -P 10022 jdk-21_linux-aarch64_bin.tar.gz   root@xxx:/xxx                                                                                                                          \n100%  186MB   7.2MB/s   00:26\n\n```\n\n但如果是用http post作为传输协议的话，由于http本身短连接、带了很多请求头等无用信息之类的原因，损耗就比较大了，笔者在应用环境中测试甚至会达到30%左右的损耗。\n所以在性能敏感的场景，建议使用长连接协议，短连接协议仅在不关注性能或是环境不允许的情况下再使用。\n\n## 安全性如何？\n\n必须使用指定的用户才能连接，数据传输过程中对字节进行了加密以防监听，如果你还需要更多的个性化验证，比如用户登录，可以发邮件到[liuyu@wowtools.org](liuyu@wowtools.org)\n进行定制化开发。\n\n# 后续计划\n\n完成rwebsocket协议，优化rpost协议的性能开销\n\n中继模式开发\n\n完善文档和demo\n\n...(还有什么好玩的想法给我提issue或者发邮件哈)\n","funding_links":[],"categories":["网络编程"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodingmiao%2Fhppt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodingmiao%2Fhppt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodingmiao%2Fhppt/lists"}