|
1 | | -# Lite HTTP Tunnel |
| 1 | +# Lite HTTP Tunnel (Server) |
2 | 2 |
|
3 | | -A tunnel tool to help you expose local web (HTTP/WebSocket) server behind a NAT or firewall to the internet. Inspired by [Ngrok](https://github.com/inconshreveable/ngrok) and [node-http-proxy](https://github.com/http-party/node-http-proxy). |
| 3 | +Expose any local HTTP or WebSocket service to the internet through a lightweight tunnel. The server multiplexes inbound traffic and streams it to connected clients over a persistent WebSocket. Inspired by [Ngrok](https://github.com/inconshreveable/ngrok) and [node-http-proxy](https://github.com/http-party/node-http-proxy). |
4 | 4 |
|
5 | 5 |  |
6 | 6 |
|
7 | | -## How it work |
| 7 | +## How it works |
8 | 8 |
|
9 | | -The tunnel is based on `WebSocket`. We have a `WebSocket` connection between the client and server to stream HTTP/WebSocket requests from public server to your local server. |
| 9 | +1. The client opens a Socket.IO WebSocket to the server and stays connected. |
| 10 | +2. For each incoming public request, the server forwards headers and body to the client via stream events. |
| 11 | +3. The client makes a request to the local target and streams the response back. WebSocket upgrades are handled bidirectionally. |
10 | 12 |
|
11 | | -## Usage |
| 13 | +Key features: |
| 14 | +- HTTP and WebSocket support |
| 15 | +- Multi-client routing by host and path prefix (longest-prefix wins) |
| 16 | +- Forwarded headers preserved (x-forwarded-*) |
| 17 | +- JWT-protected tunnel connection |
12 | 18 |
|
13 | | -### Deploy at public server |
| 19 | +## Deploy the server |
14 | 20 |
|
15 | | -Firstly please deploy this project to your own web host with public internet access. The project is just a `Node.js` web server based on `Express.js`. So just deploy as what you do for [deploying Node.js web server](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/deployment). |
| 21 | +This is a standard Node.js/Express server. |
16 | 22 |
|
17 | | -#### Deploy to Heroku with following button |
| 23 | +- Run locally |
| 24 | + ```sh |
| 25 | + npm install |
| 26 | + npm start |
| 27 | + ``` |
18 | 28 |
|
19 | | -[](https://heroku.com/deploy) |
| 29 | +- One‑click deploy |
| 30 | + - Heroku: [](https://heroku.com/deploy) |
| 31 | + - Render: [](https://render.com/deploy) |
20 | 32 |
|
21 | | -#### Deploy to Render with following button |
| 33 | +### Required environment variables |
22 | 34 |
|
23 | | -[](https://render.com/deploy) |
| 35 | +- `SECRET_KEY`: Secret used to sign/verify JWTs |
| 36 | +- `VERIFY_TOKEN`: Static token value expected inside the JWT payload |
| 37 | +- `JWT_GENERATOR_USERNAME`, `JWT_GENERATOR_PASSWORD` (optional, bootstrap only): |
| 38 | + Used by `/tunnel_jwt_generator` to issue a JWT during initial setup. Remove them after obtaining the client token. |
24 | 39 |
|
25 | | -#### JWT Token generator environment variables |
| 40 | +## Use the client |
26 | 41 |
|
27 | | -In first deployment, you need to provide `JWT_GENERATOR_USERNAME` and `JWT_GENERATOR_PASSWORD` environment variables. We will use those values to auth and get JWT token at client side. After you get `JWT Token`, you can remove `JWT_GENERATOR_USERNAME` and `JWT_GENERATOR_PASSWORD` environment variables to keep safe. |
| 42 | +Install the client on the machine that can reach your local service: |
28 | 43 |
|
29 | | -### Setup Client |
30 | | - |
31 | | -#### Install client |
32 | | - |
33 | | -Please install `lite-http-tunnel` client in your local computer where it can access your local HTTP server. |
34 | | - |
35 | | -```shell |
36 | | -$ npm i -g lite-http-tunnel |
37 | | -$ lite-http-tunnel -h |
38 | | -``` |
39 | | - |
40 | | -#### Config remote public server address: |
41 | | - |
42 | | -```shell |
43 | | -$ lite-http-tunnel config server https://your_web_host_domain |
| 44 | +```sh |
| 45 | +npm i -g lite-http-tunnel |
| 46 | +lite-http-tunnel -h |
44 | 47 | ``` |
45 | 48 |
|
46 | | -#### Auth with server: |
47 | | - |
48 | | -```shell |
49 | | -$ lite-http-tunnel auth $JWT_GENERATOR_USERNAME $JWT_GENERATOR_PASSWORD |
50 | | -``` |
51 | | - |
52 | | - > Replace `$JWT_GENERATOR_USERNAME` and `$JWT_GENERATOR_PASSWORD` with values that you provide at tunnel server |
53 | | -
|
54 | | -#### Or With specified profile |
55 | | - |
56 | | -```shell |
57 | | -$ lite-http-tunnel config server https://your_web_host_domain -p profile1 |
58 | | -$ lite-http-tunnel auth $JWT_GENERATOR_USERNAME $JWT_GENERATOR_PASSWORD -p profile1 |
59 | | -``` |
| 49 | +Point the client to your server and authenticate: |
60 | 50 |
|
61 | | -#### Start client |
| 51 | +```sh |
| 52 | +# Set server URL (optionally with a profile) |
| 53 | +lite-http-tunnel config server https://your-public-server |
62 | 54 |
|
63 | | -```shell |
64 | | -$ lite-http-tunnel start your_local_server_port |
| 55 | +# Get a JWT from the server using generator credentials (bootstrap) |
| 56 | +lite-http-tunnel auth $JWT_GENERATOR_USERNAME $JWT_GENERATOR_PASSWORD |
65 | 57 | ``` |
66 | 58 |
|
67 | | -Please replace your_local_server_port with your local HTTP server port, eg: `8080`. |
68 | | - |
69 | | -After that you can access your local HTTP server by access `your_public_server_domain`. |
70 | | - |
71 | | -#### Start with specified profile: |
| 59 | +Start the tunnel: |
72 | 60 |
|
73 | | -```shell |
74 | | -$ lite-http-tunnel start your_local_server_port -p profile1 |
75 | | -``` |
76 | | - |
77 | | -#### Change origin to local server: |
| 61 | +```sh |
| 62 | +# Basic |
| 63 | +lite-http-tunnel start <local_port> |
78 | 64 |
|
79 | | -```shell |
80 | | -$ lite-http-tunnel start your_local_server_port -o localhost:5000 |
81 | | -``` |
| 65 | +# With a specific profile |
| 66 | +lite-http-tunnel start <local_port> -p profile1 |
82 | 67 |
|
83 | | -#### Change local server host: |
| 68 | +# Override Host header (origin) for the local target |
| 69 | +lite-http-tunnel start <local_port> -o localhost:5000 |
84 | 70 |
|
85 | | -```shell |
86 | | -$ lite-http-tunnel start your_local_server_port -h localhost1 |
| 71 | +# Override local hostname used for target resolution (default: localhost) |
| 72 | +lite-http-tunnel start <local_port> -h my-localhost |
87 | 73 | ``` |
88 | 74 |
|
89 | | -## Multiple Clients |
| 75 | +Once running, requests to your public server will be forwarded to your local service. |
90 | 76 |
|
91 | | -### Use different domains for public server |
| 77 | +### Profiles (multiple saved configs) |
92 | 78 |
|
93 | | -The server steams web request to WebSocket connection which has same host value in request headers. |
| 79 | +The CLI supports named profiles so you can save different servers/tokens locally. By default it uses the `default` profile and stores configs in `~/.lite-http-tunnel/<profile>.json`. |
94 | 80 |
|
95 | | -So if you have multiple domains for the proxy server, you can have multiple clients based on different domain. |
| 81 | +Common examples: |
96 | 82 |
|
97 | | -For example, you have `https://app1.test.com` and `https://app2.test.com` for this proxy server. |
| 83 | +```sh |
| 84 | +# Save server under a named profile |
| 85 | +lite-http-tunnel config server https://your-public-server -p profile1 |
98 | 86 |
|
99 | | -In client 1: |
| 87 | +# Authenticate and save JWT to that profile |
| 88 | +lite-http-tunnel auth $JWT_GENERATOR_USERNAME $JWT_GENERATOR_PASSWORD -p profile1 |
100 | 89 |
|
101 | | -``` |
102 | | -$ lite-http-tunnel config server https://app1.test.com -p profile1 |
103 | | -$ lite-http-tunnel start your_local_server_port -p profile1 |
| 90 | +# Start the client using that profile |
| 91 | +lite-http-tunnel start <local_port> -p profile1 |
104 | 92 | ``` |
105 | 93 |
|
106 | | -In client 2: |
| 94 | +Use different profiles to switch between environments (e.g., staging vs prod) or to run multiple clients with distinct settings. |
107 | 95 |
|
108 | | -``` |
109 | | -$ lite-http-tunnel config server https://app2.test.com -p profile2 |
110 | | -$ lite-http-tunnel start your_local_server_port -p profile2 |
111 | | -``` |
| 96 | +## Multiple clients |
112 | 97 |
|
113 | | -### Use path prefix |
| 98 | +### By domain |
| 99 | +Each tunnel is keyed by request `Host`. If you run the server under multiple domains, connect one client per domain. |
114 | 100 |
|
115 | | -From `0.2.0`, it supports to have multiple clients with different path prefix. |
116 | | - |
117 | | -In client 1: |
| 101 | +### By path prefix |
| 102 | +From `0.2.0`, multiple clients can share the same host using different path prefixes. |
118 | 103 |
|
| 104 | +Client 1: |
119 | 105 | ``` |
120 | | -$ lite-http-tunnel config path /api_v1 |
121 | | -$ lite-http-tunnel start your_local_server_port |
| 106 | +lite-http-tunnel config path /api_v1 |
| 107 | +lite-http-tunnel start <local_port> |
122 | 108 | ``` |
123 | 109 |
|
124 | | -In client 2: |
125 | | - |
| 110 | +Client 2: |
126 | 111 | ``` |
127 | | -$ lite-http-tunnel config path /api_v2 |
128 | | -$ lite-http-tunnel start your_local_server_port |
| 112 | +lite-http-tunnel config path /api_v2 |
| 113 | +lite-http-tunnel start <local_port> |
129 | 114 | ``` |
130 | 115 |
|
131 | | -With that, requests with path prefix `/api_v1` will be streamed to client 1, requests with path prefix `/api_v2` will be streamed to client 2 |
| 116 | +Requests matching `/api_v1` route to client 1; `/api_v2` route to client 2. Longest prefix always wins. |
132 | 117 |
|
133 | 118 | ## Related |
134 | 119 |
|
135 | | -A introduce article: [Building a HTTP Tunnel with WebSocket and Node.JS](https://medium.com/@embbnux/building-a-http-tunnel-with-websocket-and-node-js-98068b0225d3?source=friends_link&sk=985d90ec9f512928b34ed38b7ddcb378) |
| 120 | +Intro article: [Building a HTTP Tunnel with WebSocket and Node.JS](https://medium.com/@embbnux/building-a-http-tunnel-with-websocket-and-node-js-98068b0225d3?source=friends_link&sk=985d90ec9f512928b34ed38b7ddcb378) |
0 commit comments