Lightweight, self‑hosted HTTP reverse tunnel to expose
localhostto the public internet using a Node.js relay and a Python client.
publicRelay (formerly HTTP Tunnel / Http Proxy) is an open‑source tunneling system that lets you publish a local web service without port‑forwarding or ISP NAT configuration. A public Node.js relay server accepts HTTP traffic and forwards it over a persistent WebSocket connection to a Python client running beside your local app. Responses are streamed back through the tunnel to the original requester.
This project is built for developers who want a simple, inspectable alternative to commercial tunnels ideal for local development, demos, webhook testing, or temporary sharing.
⚠️ This project is experimental and actively evolving. If you hit issues or have improvements, please open an issue or PR.
- Zero port forwarding - Works behind NAT / CGNAT.
- Bi‑directional streaming - Full request/response relay over WebSocket.
- Binary-safe - Handles JSON, text, and media via base64 for non‑text payloads.
- Header preservation - Forwards request headers end‑to‑end.
- Real client IP - Injects
X-Forwarded-Forwith the original remote address. - Self‑hosted - Run on your own VPS (AWS/Linode/DO/etc.).
- Hackable - Simple codebase, easy to extend.
[ Internet Client ]
│
▼
[ Node.js Relay (Public IP) ]
│ WebSocket (JSON / Base64)
▼
[ Python Client (Private) ] ──► [ Local App (127.0.0.1:PORT) ]
- Public Relay (Node.js) listens for HTTP requests and an incoming WebSocket connection.
- When a request arrives, the relay serializes the request (method, path, headers, body).
- The serialized request is sent over WebSocket to the Python client.
- The client replays the request locally using
requests. - The response is sent back over WebSocket.
- The relay converts it into a real HTTP response for the original requester.
The original visitor never talks directly to your private network.
- Public VPS with a reachable port
- Node.js ≥ 16
- Python ≥ 3.8
ws,requests,websocket-client
git clone https://github.com/bashified/publicRelay
cd publicRelaycd server
npm installEdit server/proxyconfig.json to point to the open port
{
"port": 8080
}Run the relay:
node proxy.jscd client
pip install -r requirements.txtEdit client/clientconfig.json:
{
"proxy-ip": "YOUR_VPS_IP",
"proxy-port": 8080,
"localApplicationIP": "127.0.0.1",
"localApplicationPort": 5000
}Run the client:
python client.pyor in background:
nohup python client.py > client.log &Make sure your local app is listening on localhost:5000 or the address that u configured on the proxy.
In command prompt
curl http://YOUR_VPS_IP:8080/
If correctly connected:
Tunnel is alive
Try forwarding requests to your local server:
http://YOUR_VPS_IP:8080/api
The server sends the initiator ip under the "X-Forwarded-For" header and this can be like this :
# python
request.headers.get("X-Forwarded-For")This should be used instead of req.ip to avoid getting "localhost"
-
No authentication is currently implemented.
-
Anyone hitting your relay can reach your local app.
-
Recommended protections:
- IP filtering
- Auth tokens
- Rate limiting
- Getting an SSL cert to allow traffic and responses in HTTP/S
Do NOT use this for banking, auth flows, or sensitive production workloads.
- Single active client connection
- Not suitable for WebRTC or long‑lived streams
- Adds latency due to request relay
[ * ] Forward initiator IP
[ * ] Binary payload support
[ * ] Header passthrough
[ ? ] Implementing a configurable firewall
[ ? ] Blacklist feature for potential DDoS detection
[ ? ] Multi‑tunnel support
[ ? ] Authentication layer
[ ? ] Access logging dashboard
[ ? ] Traffic statistics
Pull requests welcome.
If you add a feature, document it.
If you break it — fix it. If you improve it — PR it. If you love it — star it.