wormhole

module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 10, 2026 License: Apache-2.0

README ΒΆ

πŸ•³οΈ Wormhole

Zero-config tunnel tool to expose local services to the internet.

Wormhole folds network space like a wormhole, allowing developers to expose local services to the internet with a single command.

CI Go Report Card Go Reference codecov Release Go Version License Docker Pulls GitHub Downloads

δΈ­ζ–‡ζ–‡ζ‘£

Features

  • πŸš€ Zero Config β€” Just one command to expose your local service
  • πŸ”’ Secure β€” TLS encryption with Let's Encrypt auto-certificates
  • 🌐 HTTP/HTTPS β€” Full HTTP support with Host-based routing
  • πŸ”Œ TCP Tunnels β€” Support for any TCP protocol (gRPC, WebSocket, etc.)
  • πŸ“Š Inspector β€” Built-in traffic inspection UI with real-time WebSocket streaming
  • 🀝 P2P β€” NAT traversal and direct peer-to-peer connections with end-to-end encryption (X25519 + AES-256-GCM)
  • πŸ”‘ Auth & RBAC β€” HMAC-SHA256 team tokens with role-based access control
  • 🐳 Docker Ready β€” Easy deployment with Docker and systemd

Quick Start

Installation

Homebrew (macOS/Linux)

brew install lucientong/tap/wormhole

Docker

# Run client
docker run --rm -it lucientong/wormhole client --server tunnel.example.com:7000 --local 8080

# Run server
docker run -d -p 7000:7000 -p 80:80 lucientong/wormhole server --domain tunnel.example.com

Go Install

go install github.com/lucientong/wormhole/cmd/wormhole@latest

Pre-built Binaries

Download from GitHub Releases.

Build from Source

git clone https://github.com/lucientong/wormhole.git
cd wormhole && make build
Usage
# Expose local port 8080
wormhole 8080

# Or with explicit client command
wormhole client --local 8080

# Connect to a specific server
wormhole client --server tunnel.example.com:7000 --local 8080

# Request a specific subdomain
wormhole client --local 8080 --subdomain myapp

# Enable traffic inspector
wormhole client --local 8080 --inspector 4040

# Disable P2P mode (use relay only)
wormhole client --local 8080 --p2p=false

That's it! Your local service is now accessible from the internet.

Architecture

πŸ“– For detailed protocol design and system architecture, see Architecture Guide.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Your Users    β”‚   HTTP  β”‚  Wormhole       β”‚  Tunnel β”‚  Your Local     β”‚
β”‚   (Internet)    β”‚ ──────► β”‚  Server (VPS)   β”‚ ──────► β”‚  Service :8080  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                            β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”
                            β”‚ TLS + Routing β”‚
                            β”‚ + Port Alloc  β”‚
                            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Key Design
  • Multiplexed Tunnel: A single TCP connection carries multiple logical streams (control, HTTP requests, heartbeats) via a custom binary frame protocol
  • Host-based Routing: Server routes incoming HTTP requests to the correct client based on Host header and subdomain
  • Inspector: Client-side HTTP traffic capture with a real-time web UI (WebSocket push + REST API)
  • P2P: STUN-based NAT discovery (IPv4/IPv6 dual-stack) + UDP hole punching for direct connections, with automatic relay fallback
  • Auth: HMAC-SHA256 token signing with role-based access control (admin/member/viewer), pre-shared token mode for quick setup
Components
  • wormhole-server: Runs on a VPS with public IP, handles routing and TLS
  • wormhole-client: Runs locally, connects to server and forwards traffic

Server Deployment

# Using Docker Compose
docker-compose -f deployments/docker/docker-compose.yml up -d

# Or directly
docker run -d \
  -p 7000:7000 \
  -p 80:80 \
  -p 443:443 \
  -e WORMHOLE_DOMAIN=tunnel.example.com \
  lucientong/wormhole server
Systemd
# Install binary
sudo cp wormhole /usr/local/bin/

# Create user
sudo useradd -r -s /bin/false wormhole

# Install service file
sudo cp deployments/systemd/wormhole-server.service /etc/systemd/system/

# Start service
sudo systemctl daemon-reload
sudo systemctl enable wormhole-server
sudo systemctl start wormhole-server
Manual
wormhole server \
  --port 7000 \
  --domain tunnel.example.com \
  --tls

Configuration

Client Options
Flag Description Default
--server Server address localhost:7000
--local Local port to expose Required
--local-host Local host to forward to 127.0.0.1
--subdomain Request specific subdomain Auto-generated
--token Team token for auth None
--inspector Inspector UI port 0 (disabled)
--p2p Enable P2P direct connection true
Server Options
Flag Description Default
--port Tunnel listen port 7000
--host Host to bind to 0.0.0.0
--http-port HTTP traffic port 80
--admin-port Admin API port 7001
--domain Domain for tunnel URLs (env: WORMHOLE_DOMAIN) localhost
--tls Enable TLS (auto-cert if domain is set) false
--cert Path to TLS certificate file None
--key Path to TLS private key file None
--require-auth Require authentication for connections false
--auth-tokens Comma-separated pre-shared tokens None
--auth-secret HMAC secret for signed tokens (min 16 chars) None
--admin-token Token to protect admin API None
--persistence Storage backend: memory (default) or sqlite memory
--persistence-path Path to SQLite database ~/.wormhole/wormhole.db

API

Admin API (Server)
# Health check (always public)
curl http://localhost:7001/health

# Statistics (requires --admin-token if configured)
curl -H "Authorization: Bearer <admin-token>" http://localhost:7001/stats

# Connected clients
curl -H "Authorization: Bearer <admin-token>" http://localhost:7001/clients
Authentication

Wormhole supports two authentication modes:

# Simple pre-shared tokens
wormhole server --require-auth --auth-tokens token1,token2
wormhole client --server example.com:7000 --local 8080 --token token1

# HMAC-SHA256 signed tokens (for team management)
wormhole server --require-auth --auth-secret "my-secret-at-least-16-chars"

# Protect admin API with a separate token
wormhole server --admin-token my-admin-secret
Persistent Storage

By default, Wormhole uses in-memory storage, which is lost on restart. To persist team data and token revocations, enable SQLite storage:

# Enable SQLite persistence (default path: ~/.wormhole/wormhole.db)
wormhole server --require-auth --auth-secret "my-secret" --persistence sqlite

# Specify custom database path
wormhole server --require-auth --auth-secret "my-secret" \
  --persistence sqlite \
  --persistence-path /var/lib/wormhole/data.db

Persistent storage saves:

  • Team information
  • Revoked token blacklist
Inspector API (Client)
# List captured requests
curl http://localhost:4040/api/requests

# Get request details
curl http://localhost:4040/api/requests/:id

# Clear all records
curl -X DELETE http://localhost:4040/api/requests

# Real-time stream (WebSocket)
wscat -c ws://localhost:4040/api/ws

Development

Building from Source
# Clone repository
git clone https://github.com/lucientong/wormhole.git
cd wormhole

# Build
make build

# Run tests
make test

# Run with coverage
make test-coverage

# Lint (requires golangci-lint)
golangci-lint run ./...
Project Structure
wormhole/
β”œβ”€β”€ cmd/
β”‚   β”œβ”€β”€ wormhole/     # CLI entry point (Cobra)
β”‚   β”œβ”€β”€ server/       # Standalone server entry (thin wrapper)
β”‚   └── client/       # Standalone client entry (thin wrapper)
β”œβ”€β”€ pkg/
β”‚   β”œβ”€β”€ client/       # Client core (config, connection, persistence)
β”‚   β”œβ”€β”€ server/       # Server core (config, routing, handler, TLS, admin)
β”‚   β”œβ”€β”€ tunnel/       # Core tunneling (mux, frame, stream, pool)
β”‚   β”œβ”€β”€ inspector/    # Traffic inspection (capture, storage, websocket)
β”‚   β”œβ”€β”€ p2p/          # P2P direct connection (STUN, hole punch, predictor)
β”‚   β”œβ”€β”€ proto/        # Control protocol (JSON messages)
β”‚   β”œβ”€β”€ auth/         # Authentication & RBAC (HMAC tokens, roles, permissions)
β”‚   β”œβ”€β”€ version/      # Build version info
β”‚   └── web/          # Embedded web UI
β”œβ”€β”€ web/              # Frontend source (SolidJS)
β”œβ”€β”€ docs/             # Architecture documentation
β”œβ”€β”€ deployments/      # Docker, systemd configs
└── scripts/          # Build and install scripts

Security

Wormhole is designed with security in mind, but as a tunneling tool that exposes local services to the internet, proper configuration is essential.

Security Features
Feature Description
TLS Encryption All HTTP traffic encrypted via TLS 1.2+ with Let's Encrypt auto-certificates
P2P E2E Encryption X25519 ECDH key exchange + AES-256-GCM for direct P2P connections
HMAC-SHA256 Tokens Signed team tokens with expiration and revocation support
RBAC Role-based access control (admin / member / viewer)
Rate Limiting Automatic IP blocking after repeated authentication failures
Token Revocation Individual token blacklist + team-level bulk revocation (version-based) with persistent storage
Constant-time Auth Admin token comparison uses crypto/subtle to prevent timing attacks
Request Limits MaxHeaderBytes and request body size limits to mitigate DoS
Production Deployment Checklist

⚠️ Do not use default settings in production. Follow this checklist to harden your deployment.

wormhole server \
  --domain tunnel.example.com \
  --tls \
  --require-auth \
  --auth-secret "$(openssl rand -base64 32)" \
  --admin-token "$(openssl rand -hex 16)" \
  --persistence sqlite \
  --persistence-path /var/lib/wormhole/wormhole.db
  • Enable TLS (--tls): Without TLS, all traffic (including auth tokens) is transmitted in plaintext. Always enable TLS in production.
  • Enable Authentication (--require-auth): Without auth, anyone can create tunnels on your server.
  • Set a strong auth secret (--auth-secret): Use at least 32 random characters. This secret signs all team tokens.
  • Protect the Admin API (--admin-token): Without this, anyone with network access to the admin port can manage your server.
  • Use persistent storage (--persistence sqlite): Ensures token revocations survive server restarts.
  • Restrict admin port access: Bind the admin port to localhost or use firewall rules (e.g., --admin-port 127.0.0.1:7001).
Security Considerations
P2P Mode

P2P direct connections feature end-to-end encryption using X25519 ECDH key exchange and AES-256-GCM authenticated encryption. The key exchange happens via the server's signaling channel, but the server never sees the shared secret β€” only public keys are relayed. This provides:

  • X25519 ECDH key agreement for perfect forward secrecy per session
  • AES-256-GCM authenticated encryption for all data packets
  • HMAC-SHA256 authentication of hole-punch probes to prevent injection
  • HKDF-SHA256 key derivation with separate keys for encryption and probe authentication

If P2P hole punching fails, the client automatically falls back to the encrypted relay channel:

# Disable P2P to force all traffic through the encrypted relay
wormhole client --local 8080 --p2p=false
Inspector

The traffic inspector captures and displays HTTP request/response data. In production:

  • Do not enable the inspector on public-facing deployments
  • The inspector API binds to localhost by default, but be cautious if your network allows local access
Admin API Without Token

If --admin-token is not configured, the Admin API is completely open with no authentication. This allows anyone with network access to:

  • View all connected clients and tunnels
  • Generate and revoke tokens
  • Manage teams

Always configure --admin-token in production.

Subdomain Randomness

Auto-generated subdomains use 64-bit cryptographic randomness (crypto/rand), producing 16-character hex strings. This makes brute-force subdomain guessing infeasible.

Roadmap

  • Phase 1: Basic TCP tunnel with multiplexing
  • Phase 2: HTTP routing + TLS + Admin API
  • Phase 3: Traffic inspector UI
  • Phase 4: P2P direct connection β€” primitives (STUN, hole punch, predictor, signaling)
  • Phase 4.5: P2P end-to-end integration (peer matching, data transfer, relayβ†’P2P switch)
  • Phase 5: Team collaboration (auth, HMAC tokens, RBAC, admin API protection)
  • Phase 6: P2P end-to-end encryption (X25519 ECDH, AES-256-GCM, HMAC-authenticated hole punch)

Contributing

Contributions are welcome! Please read our Contributing Guide for details.

License

Apache License β€” see LICENSE for details.

Directories ΒΆ

Path Synopsis
cmd
client command
Package main provides the standalone client entry point.
Package main provides the standalone client entry point.
server command
Package main provides the standalone server entry point.
Package main provides the standalone server entry point.
wormhole command
Package main is the entry point for the Wormhole CLI.
Package main is the entry point for the Wormhole CLI.
wormhole/cmd
Package cmd provides the CLI commands for Wormhole.
Package cmd provides the CLI commands for Wormhole.
internal
testutil
Package testutil provides testing utilities for Wormhole.
Package testutil provides testing utilities for Wormhole.
pkg
auth
Package auth provides authentication and authorization for Wormhole.
Package auth provides authentication and authorization for Wormhole.
inspector
Package inspector provides HTTP traffic inspection and recording capabilities.
Package inspector provides HTTP traffic inspection and recording capabilities.
p2p
Package p2p provides peer-to-peer direct connection capabilities.
Package p2p provides peer-to-peer direct connection capabilities.
proto
Package proto provides control protocol definitions for Wormhole.
Package proto provides control protocol definitions for Wormhole.
tunnel
Package tunnel provides the core tunneling functionality for Wormhole.
Package tunnel provides the core tunneling functionality for Wormhole.
version
Package version provides build version information.
Package version provides build version information.
web
Package web provides embedded static resources for the Inspector Web UI.
Package web provides embedded static resources for the Inspector Web UI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL