Self-hosted HTTP/WebSocket tunnel — exposes a local port at https://<subdomain>.yourdomain via a single Go binary on each side.
- Server accepts WebSocket client connections and routes inbound HTTP requests by subdomain
- Client dials the server, registers a subdomain, and forwards traffic to a local port
- Shared-secret auth via
TUNNEL_SECRET; subdomain reservation and capacity limits - Status pages (rendered server-side) showing active tunnels
- Cross-platform prebuilt clients in
bin/(linux/darwin/windows, amd64/arm64) and a one-lineinstall.sh
Go 1.24, gorilla/websocket. No database — state is in memory.
Build:
go build -o bin/htunnel-server ./cmd/htunnel-server
go build -o bin/htunnel ./cmd/htunnelServer (set env first, see .env.example):
./bin/htunnel-serverClient:
htunnel <local-port> -s <subdomain> -t <token>
# e.g. htunnel 3000 -s myapp -t YOUR_TOKEN- Required env on the server:
PORT,BASE_DOMAIN,TUNNEL_SECRET,REQUEST_TIMEOUT,MAX_BODY_SIZE. See.env.example. - Nginx in front of the server is recommended for TLS + wildcard subdomain routing — see
nginx.conf. - The
bin/directory contains committed release binaries; remove from.gitignoreif you don't want them shipped.