字节笔记本

2026年2月22日

Lite HTTP Tunnel:轻量级 HTTP/WebSocket 隧道工具

Lite HTTP Tunnel 是一个轻量级的 HTTP/WebSocket 隧道工具,可以将本地服务暴露到公网。它基于 Socket.IO 和 Express 构建,支持多客户端路由、JWT 认证和 WebSocket 双向通信,是受 Ngrok 和 node-http-proxy 启发的开源项目。

项目简介

Lite HTTP Tunnel 由 web-tunnel 组织开发维护,采用 GPL-3.0 许可证。截至目前,该项目在 GitHub 上已获得 119 stars 和 35 forks,主要使用 JavaScript 编写。项目包含服务端和客户端两部分,服务端负责接收公网请求并通过 WebSocket 隧道转发给客户端,客户端则将请求转发到本地服务。

核心特性

  • HTTP 和 WebSocket 支持:完整支持 HTTP 请求和 WebSocket 双向通信
  • 多客户端路由:支持基于域名和路径前缀的多客户端路由(最长前缀匹配)
  • 转发头保留:自动处理 x-forwarded-* 等转发头信息
  • JWT 认证保护:隧道连接采用 JWT 令牌认证,确保安全性
  • 轻量级部署:标准 Node.js/Express 应用,支持一键部署到 Heroku 或 Render

技术栈

  • Node.js:服务端运行环境
  • Express:Web 框架
  • Socket.IO:WebSocket 通信
  • JWT:身份认证
  • UUID:请求标识生成

安装指南

服务端部署

方式一:手动部署

bash
# 克隆仓库
git clone https://github.com/web-tunnel/lite-http-tunnel.git
cd lite-http-tunnel

# 安装依赖
npm install

# 启动服务
npm start

方式二:一键部署

  • Heroku:点击部署按钮直接部署到 Heroku
  • Render:点击部署按钮直接部署到 Render

环境变量配置

服务端需要配置以下环境变量:

变量名必填说明
SECRET_KEYJWT 签名密钥
VERIFY_TOKENJWT Payload 中的静态令牌值
JWT_GENERATOR_USERNAMEJWT 生成器用户名(仅初始设置)
JWT_GENERATOR_PASSWORDJWT 生成器密码(仅初始设置)

客户端安装

bash
# 全局安装客户端
npm i -g lite-http-tunnel

# 查看帮助
lite-http-tunnel -h

快速开始

1. 配置服务端地址

bash
# 设置服务端 URL
lite-http-tunnel config server https://your-public-server

2. 获取 JWT 令牌

bash
# 使用生成器凭据获取 JWT(首次设置)
lite-http-tunnel auth $JWT_GENERATOR_USERNAME $JWT_GENERATOR_PASSWORD

3. 启动隧道

bash
# 基本用法
lite-http-tunnel start <local_port>

# 覆盖 Host 头
lite-http-tunnel start <local_port> -o localhost:5000

# 覆盖本地主机名
lite-http-tunnel start <local_port> -h my-localhost

使用示例

场景一:多环境配置(Profiles)

使用命名配置保存不同的服务器和令牌:

bash
# 保存生产环境配置
lite-http-tunnel config server https://prod-server -p production
lite-http-tunnel auth $PROD_USERNAME $PROD_PASSWORD -p production

# 保存测试环境配置
lite-http-tunnel config server https://staging-server -p staging
lite-http-tunnel auth $STAGING_USERNAME $STAGING_PASSWORD -p staging

# 使用生产环境启动
lite-http-tunnel start 3000 -p production

场景二:多客户端共享域名

从 v0.2.0 开始,支持多个客户端共享同一域名,通过路径前缀区分:

客户端 1(API v1):

bash
lite-http-tunnel config path /api_v1
lite-http-tunnel start 3001

客户端 2(API v2):

bash
lite-http-tunnel config path /api_v2
lite-http-tunnel start 3002

请求匹配规则:

  • /api_v1/* → 转发到客户端 1 的 3001 端口
  • /api_v2/* → 转发到客户端 2 的 3002 端口

最长前缀优先匹配,确保路由准确性。

工作原理

  1. 连接建立:客户端通过 Socket.IO 与服务器建立持久 WebSocket 连接
  2. 请求转发:服务器收到公网请求后,通过流事件将请求头和请求体转发给客户端
  3. 本地请求:客户端向本地目标服务发起请求,并将响应流回传
  4. WebSocket 升级:WebSocket 升级请求通过双向管道处理

服务端核心代码解析

以下是 server.js 的核心逻辑:

javascript
// Socket.IO 连接认证
io.use((socket, next) => {
  const connectHost = socket.handshake.headers.host;
  const pathPrefix = socket.handshake.headers['path-prefix'];

  // 检查是否已有连接
  if (getTunnelSocket(connectHost, pathPrefix)) {
    return next(new Error(`${connectHost} has a existing connection`));
  }

  // JWT 认证
  if (!socket.handshake.auth || !socket.handshake.auth.token){
    next(new Error('Authentication error'));
  }

  jwt.verify(socket.handshake.auth.token, process.env.SECRET_KEY, function(err, decoded) {
    if (err || decoded.token !== process.env.VERIFY_TOKEN) {
      return next(new Error('Authentication error'));
    }
    next();
  });
});

// HTTP 请求代理
app.use('/', (req, res) => {
  const tunnelSocket = getAvailableTunnelSocket(req.headers.host, req.url);
  if (!tunnelSocket) {
    res.status(404).send('Not Found');
    return;
  }

  const requestId = uuidV4();
  const tunnelRequest = new TunnelRequest({
    socket: tunnelSocket,
    requestId,
    request: {
      method: req.method,
      headers: getReqHeaders(req),
      path: req.url,
    },
  });

  req.pipe(tunnelRequest);
  // ... 响应处理逻辑
});

项目链接

许可证

GPL-3.0 License

分享: