{"id":45858265,"url":"https://github.com/llongtao/http-tunnel","last_synced_at":"2026-03-02T03:07:47.773Z","repository":{"id":105212165,"uuid":"425151061","full_name":"llongtao/http-tunnel","owner":"llongtao","description":"使用http搭建隧道的形式从外网访问内网资源","archived":false,"fork":false,"pushed_at":"2026-02-27T08:22:55.000Z","size":200,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-27T10:27:40.095Z","etag":null,"topics":["go","golang","http-proxy","proxy","proxy-server","socks5","ssh","tcp","tunnel"],"latest_commit_sha":null,"homepage":"","language":"Go","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/llongtao.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,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2021-11-06T03:59:58.000Z","updated_at":"2026-02-27T08:25:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"020c3029-2678-4d28-ad96-644450628b87","html_url":"https://github.com/llongtao/http-tunnel","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/llongtao/http-tunnel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llongtao%2Fhttp-tunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llongtao%2Fhttp-tunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llongtao%2Fhttp-tunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llongtao%2Fhttp-tunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/llongtao","download_url":"https://codeload.github.com/llongtao/http-tunnel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llongtao%2Fhttp-tunnel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29991309,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T01:47:34.672Z","status":"online","status_checked_at":"2026-03-02T02:00:07.342Z","response_time":60,"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":["go","golang","http-proxy","proxy","proxy-server","socks5","ssh","tcp","tunnel"],"created_at":"2026-02-27T05:14:25.404Z","updated_at":"2026-03-02T03:07:47.768Z","avatar_url":"https://github.com/llongtao.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# http-tunnel\n\n`http-tunnel` 是一个基于 WebSocket 的 TCP 隧道系统，用于把“本地访问虚拟 IP:端口”转发到远端内网真实服务。  \n典型场景是：用户只访问固定地址（如 `10.2.2.123:30080`），由 agent 通过隧道连到服务端，再由服务端转发到内网目标地址。\n\n主要解决的痛点：\n- 研发团队常见限制：只能开通 HTTP/HTTPS 端口，不能额外开放自定义 TCP 端口\n- 内网 TCP 服务（如管理端口、私有 API、调试端口）无法被外部直接访问\n- 终端用户不希望配置复杂网络环境，只希望访问固定地址即可连通目标服务\n- 多个内网目标需要统一出口与统一认证，降低运维复杂度\n\n本项目的做法：\n- 复用已开通的 HTTP/HTTPS 端口承载 WebSocket 隧道\n- 在隧道内传输内部 TCP 流量，实现“HTTP 口复用的 TCP 代理”\n\n核心组件：\n- `go/cmd/htunnel-server`：服务端，维护 agent 连接并按 `vip_map` 转发到真实 IP\n- `go/cmd/htunnel-agent`：客户端 agent，建立隧道并承接本地流量\n- `go/cmd/htunnel-ui`：桌面端连接器（账号密码登录、自动获取 token 和路由）\n- `go/internal/protocol/tunnel.proto`：隧道消息协议定义（Protobuf）\n\n\n## 功能\n- Agent 与 Server 通过 WebSocket 长连接通信（`ws`/`wss`）\n- 使用 JWT 做 Agent 认证（HS256）\n- 服务端支持虚拟 IP 到真实内网 IP 的一对一静态映射\n- Agent 内置 SOCKS5，并可托管 `tun2socks` 进程实现虚拟网卡流量接入\n\n## 快速开始\n### 1. 部署服务端\n二选一：\n- 本机运行：\n```bash\ncd go\ngo run ./cmd/htunnel-server -config configs/server.yaml\n```\n- Docker 部署：\n```bash\ndocker build -t htunnel-server:latest .\ndocker run --rm -p 8082:8082 \\\n  -v $(pwd)/go/configs/server.yaml:/app/configs/server.yaml:ro \\\n  htunnel-server:latest\n```\n\n### 2. 配置服务端\n编辑 `go/configs/server.yaml`，至少确认三项：\n- `listen.addr`：服务监听地址（默认 `:8082`）\n- `auth.users`：客户端登录账号密码\n- `auth.users.\u003cname\u003e.route_cidrs`：该用户下发到客户端的网段（用于本地路由）\n- `network.vip_map`：虚拟 IP 到真实目标 IP 的映射  \n\n示例：\n```yaml\nauth:\n  users:\n    alice:\n      password: \"pass123\"\n      route_cidrs:\n        - \"10.2.2.123/32\"\nnetwork:\n  vip_map:\n    \"10.2.2.123\": \"172.28.52.13\"\n```\n\n说明：如果用户未配置 `route_cidrs`，服务端会默认把 `vip_map` 中的 VIP 按 `/32` 下发给客户端。\n\n### 3. 运行 Agent\n- 推荐：启动桌面端 `htunnel-ui`，填写服务地址+账号密码，点击“连接”\n- 命令行：直接运行\n```bash\ncd go\ngo run ./cmd/htunnel-agent -config configs/agent.yaml\n```\n  - 当 `auth.token` 为空时，agent 会使用 `auth.username/password` 调用 `/api/agent/login` 自动获取 token 和路由配置\n\n## 目录\n- `go/configs/server.yaml`：服务端配置样例\n- `go/configs/agent.yaml`：agent 配置样例\n\n## 本地运行\n```bash\ncd go\ngo mod tidy\ngo run ./cmd/htunnel-server -config configs/server.yaml\n```\n\n另开一个终端运行 agent：\n```bash\ncd go\ngo run ./cmd/htunnel-agent -config configs/agent.yaml\n```\n\n## 服务端 Docker 部署\n构建镜像（项目根目录）：\n```bash\ndocker build -t htunnel-server:latest .\n```\n\n运行容器：\n```bash\ndocker run --rm -p 8082:8082 \\\n  -v $(pwd)/go/configs/server.yaml:/app/configs/server.yaml:ro \\\n  htunnel-server:latest\n```\n\n## 原生界面（Wails）\n客户端支持原生桌面界面（非浏览器页面），推荐流程：\n- 填服务端地址 + 账号密码\n- 点击“连接”（自动向服务端登录并获取 token）\n- 自动把 `agent_id` 设置为用户名（或服务端返回值）\n- 自动下发 `route_cidrs` 到本地配置\n- token 未过期时，桌面端启动后会自动连接\n\n启动桌面端：\n```bash\ncd go\nsudo go run -tags \"desktop,production\" ./cmd/htunnel-ui -config configs/agent.yaml\n```\n\nmacOS 如果出现 `Undefined symbols ... _OBJC_CLASS_$_UTType`，请加上：\n```bash\ncd go\nsudo CGO_LDFLAGS='-framework UniformTypeIdentifiers' go run -tags \"desktop,production\" ./cmd/htunnel-ui -config configs/agent.yaml\n```\n\n或使用根目录命令：\n```bash\nmake run-ui\n```\n\n## 发布打包（包含 tun2socks）\n用户不需要单独下载 `tun2socks`。发布时可直接打一个自包含包：\n\n```bash\ncd go\n./scripts/release.sh\n```\nWindows 可用：\n```powershell\ncd go\n.\\scripts\\release.ps1\n```\n\n产物位于 `go/dist/`，每个平台目录都包含：\n- `bin/htunnel-agent`\n- `bin/htunnel-ui`（`INCLUDE_UI=1` 默认启用）\n- `bin/tun2socks`\n- `configs/agent.yaml`\n- `start-agent.sh` / `start-agent.ps1`\n- `start-ui.sh` / `start-ui.ps1`\n- `start.sh` / `start.ps1`（兼容入口，默认启动 agent）\n\n示例（mac）：\n```bash\ncd go/dist/htunnel-agent-darwin-arm64\n./start-ui.sh\n```\n\n示例（windows，管理员 PowerShell）：\n```powershell\ncd go\\dist\\htunnel-agent-windows-amd64\n.\\start-ui.ps1\n```\n\n注意：`tun2socks` 依赖 cgo，请在目标平台本机打包（mac 打 mac 包，windows 打 windows 包）。\n\n## 配置说明\n### 服务端映射\n`go/configs/server.yaml`:\n```yaml\nnetwork:\n  vip_map:\n    \"10.2.2.123\": \"192.168.0.25\"\n```\n含义：访问 `10.2.2.123:\u003cport\u003e` 会被转发到 `192.168.0.25:\u003cport\u003e`。\n\n### 认证\n服务端配置 JWT 参数 + 账号：\n```yaml\nauth:\n  jwt:\n    secret: \"change-me\"\n    issuer: \"htunnel\"\n    audience: \"htunnel-agent\"\n    expire_hour: 24\n  users:\n    alice:\n      password: \"pass123\"\n      route_cidrs:\n        - \"10.2.2.123/32\"\n```\n\n桌面端调用 `POST /api/agent/login`：\n- 入参：`username`、`password`\n- 出参：`token`、`agent_id`、`ws_url`、`route_cidrs`\n\nagent 仍支持直接写 token（兼容旧方式）：\n```yaml\nserver:\n  base_url: \"http://127.0.0.1:8082\"\nauth:\n  token: \"\u003cjwt-token\u003e\"\n  username: \"alice\"\n  password: \"pass123\"\n  password_enc: \"\u003cencrypted-by-ui\u003e\"\n```\n\n说明：桌面 UI 会把密码加密后写入 `password_enc`，不再持久化明文 `password`。\n当通过命令行直接启动 agent 时，若 `token` 为空，会尝试使用 `username/password` 自动登录获取 token。\n\n可用内置工具生成测试 token：\n```bash\ncd go\ngo run ./cmd/gen-jwt -secret change-me -issuer htunnel -audience htunnel-agent -agent agent-01\n```\n\n### TUN\nagent 通过启动 `tun2socks` 接入虚拟网卡流量：\n```yaml\ntun:\n  enabled: true\n  binary: \"\"\n  name: \"utun9\"\n  addr: \"10.2.2.2\"\n  gateway: \"10.2.2.1\"\n  mask: \"255.255.255.0\"\n  route_cidrs:\n    - \"10.2.2.123/32\"\n```\n开发环境可直接安装到 `go/bin`（中国网络可用镜像）：\n```bash\nmake install-tun2socks\n```\n\n或手动执行：\n```bash\ncd go\nmkdir -p bin\nGOPROXY=https://goproxy.cn,direct GOBIN=$(pwd)/bin \\\n  go install -tags socks github.com/eycorsican/go-tun2socks/cmd/tun2socks@v1.16.11\n```\n\n`binary` 为空时，agent 会按以下顺序自动查找：\n1. 可执行文件所在目录的 `bin/tun2socks`\n2. 配置文件目录下的 `bin/tun2socks`\n3. 当前目录的 `bin/tun2socks`\n4. 系统 `PATH`\n\n并通过 `auto_route_commands` 配置系统路由命令（需管理员权限）。\n建议同时配置 `auto_route_cleanup_commands`，agent 退出时自动清理临时路由，避免残留。\n\n## CI\nGitHub Actions 已切换为 Go 流水线：`.github/workflows/go.yml`。\n新增 agent 打包流水线：`.github/workflows/package-agent.yml`，目前产物包含：\n- `windows-amd64`\n- `darwin-amd64`\n- `darwin-arm64`\n\n当推送 `v*` tag（如 `v2.1.0`）时，会自动把上述产物作为附件上传到 GitHub Release。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllongtao%2Fhttp-tunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fllongtao%2Fhttp-tunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllongtao%2Fhttp-tunnel/lists"}