Evan Reichard 9efc2b0494
All checks were successful
continuous-integration/drone/push Build is passing
fix(tunnel): stabilize concurrent stream handling
2026-05-03 23:13:22 -04:00
2025-10-05 17:50:37 -04:00
2025-10-12 14:55:27 -04:00
2025-10-12 14:55:27 -04:00
2025-09-23 09:24:09 -04:00
2025-10-12 14:55:27 -04:00
2025-09-20 18:40:26 -04:00
2025-10-05 17:50:37 -04:00
2025-09-20 18:15:38 -04:00
2025-10-12 15:11:11 -04:00
2025-09-20 18:29:27 -04:00
2025-10-12 14:55:27 -04:00
2025-10-12 14:55:27 -04:00
2025-09-20 18:15:38 -04:00

Conduit

A lightweight tunneling service that exposes local services to the internet through a public server — similar to ngrok, but self-hosted.

Deploy Conduit on a public server (e.g., https://conduit.example.com), then create tunnels from your local machine. Point a tunnel at a local endpoint (e.g., localhost:8000) and it becomes accessible at a subdomain like https://black-fox-123.conduit.example.com.

Example

Features

  • HTTP & TCP tunneling — automatically detected based on the target scheme
  • Subdomain routing — each tunnel gets a unique subdomain on the server
  • Auto-generated tunnel names — random color-animal-number names when none is provided
  • Local tunnel monitor — web UI on :8181 with SSE-based live request/response inspection
  • API key authentication — simple shared-key auth between client and server
  • Minimal footprint — single binary, no external dependencies

Architecture

┌──────────────┐         WebSocket          ┌──────────────────┐
│ conduit      │◄──────────────────────────► │ conduit          │
│ tunnel       │    (control + streams)      │ serve            │
│ (client)     │                             │ (public server)  │
├──────────────┤                             ├──────────────────┤
│ HTTP Fwd  or │                             │ http.Server      │
│ TCP Fwd      │                             │ Subdomain router │
├──────────────┤                             │ WS upgrade       │
│ Tunnel       │                             └──────────────────┘
│ Monitor :8181│
└──────────────┘

The server uses net/http.Server to accept connections and inspects the HTTP Host header for routing. Requests to the base domain hit the control API; requests to subdomains are hijacked and forwarded over WebSocket to the matching tunnel client. The client then forwards traffic to the local target via either a reverse-proxy (HTTP) or direct TCP dial.

Quick Start

Prerequisites

  • Go 1.25+ (or Docker)

Build

# Local build (all platforms)
make build_local

# Docker
make docker_build_local

Server

Run the server on a publicly accessible host:

conduit serve \
  --server https://conduit.example.com \
  --bind 0.0.0.0:8080 \
  --api_key your-secret-key

Or with Docker:

docker run -p 8080:8080 \
  -e CONDUIT_SERVER=https://conduit.example.com \
  -e CONDUIT_API_KEY=your-secret-key \
  conduit:latest

Client

Create a tunnel to expose a local service:

# HTTP tunnel (auto-generates name)
conduit tunnel \
  --server https://conduit.example.com \
  --api_key your-secret-key \
  --target http://localhost:8000

# Named TCP tunnel
conduit tunnel \
  --server https://conduit.example.com \
  --api_key your-secret-key \
  --name my-service \
  --target localhost:5432

The local tunnel monitor is available at http://localhost:8181 for HTTP tunnels.

Configuration

All options can be set via CLI flags or environment variables (CONDUIT_ prefix):

Server (conduit serve)

Flag Env Var Default Description
--server CONDUIT_SERVER http://localhost:8080 Public server address
--api_key CONDUIT_API_KEY API key (required)
--bind CONDUIT_BIND 0.0.0.0:8080 Listen address
--log_level CONDUIT_LOG_LEVEL info Log level
--log_format CONDUIT_LOG_FORMAT text Log format (text or json)

Client (conduit tunnel)

Flag Env Var Default Description
--server CONDUIT_SERVER http://localhost:8080 Conduit server address
--api_key CONDUIT_API_KEY API key (required)
--name CONDUIT_NAME (auto-generated) Tunnel subdomain name
--target CONDUIT_TARGET Local target address (required)
--log_level CONDUIT_LOG_LEVEL info Log level
--log_format CONDUIT_LOG_FORMAT text Log format (text or json)

Server API

Endpoint Description
/_conduit/tunnel?tunnelName=<name>&apiKey=<key> WebSocket tunnel registration
/_conduit/info?apiKey=<key> JSON list of active tunnels

Project Structure

├── cmd/             # Cobra CLI commands (root, serve, tunnel)
├── config/          # Configuration parsing & logging setup
├── server/          # HTTP server, subdomain routing, hijack + WebSocket upgrade
├── tunnel/          # Tunnel, Stream, and Forwarder abstractions
├── store/           # In-memory request/response recording for the monitor
├── web/             # Local tunnel monitor HTTP server & SSE streaming
├── types/           # Shared message types
├── pkg/maps/        # Generic concurrent map
├── build/           # Compiled binaries (gitignored in practice)
├── Dockerfile       # Single-stage Docker build
└── Makefile         # Build & release targets

License

See repository for license details.

Description
No description provided
Readme 44 MiB
Languages
Go 78.3%
JavaScript 18.3%
Makefile 1.5%
Dockerfile 0.7%
Nix 0.7%
Other 0.5%