Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

183 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

expose

expose logo

expose is a self-hosted HTTP tunnel. Run your own server, then expose local HTTP ports from any machine - no third-party tunnel service required.

expose client

Features

  • HTTPS-only public traffic with automatic TLS (ACME) or static wildcard certificates
  • Built-in WAF blocks SQL injection, XSS, path traversal, and other attacks before they reach your app, including bounded JSON/form/text body inspection
  • Static site publishing via expose static for quick docs, SPAs, and local folders
  • Multi-route configs via expose.yml - expose multiple services under one subdomain with path-based routing
  • Real-time client dashboard with request log, latency percentiles, WAF counters, and connection stats
  • Auto-update - server and client can self-update in the background with automatic restart and client reconnection
  • Password-protected tunnels with a built-in access form and edge session cookie (per-tunnel or per-config)
  • Env-first configuration - minimal CLI flags, .env support, and interactive setup wizards
  • Rate limiting on tunnel registration plus optional public traffic throttling per hostname+client IP
  • Persistent login - authenticate once with expose login, credentials are saved locally
  • Automatic reconnection with exponential backoff and keepalive pings
  • HTTP/3 over QUIC support - clients can use --transport=quic for compatibility or negotiated multi-stream mode

How It Works

expose architecture

  1. The server terminates TLS, runs WAF inspection, and routes requests by hostname to the correct tunnel
  2. The client registers via API key, then opens a persistent WebSocket or HTTP/3 tunnel to the server
  3. Requests and responses flow over the tunnel as versioned binary frames, with raw body bytes for inline and streamed payloads

For the full request lifecycle and component breakdown, see Architecture Overview. For transport mode details (ws|quic) and QUIC requirements, see Client Configuration and UDP Deployment Topologies.

Quick Start

Prerequisites

  • A server or VPS with a public IP - or a home server with port forwarding configured
  • A domain you control (e.g. example.com)
  • A DNS wildcard A record (*.example.com) pointing to your server's public IP
  • Port mappings from public 443/tcp to internal 10443/tcp for normal HTTPS URLs, public 80/tcp to internal 10080/tcp for ACME HTTP-01, and public 443/udp to internal 10443/udp for QUIC

1. Install

Release binaries are published for macOS, Linux, and Windows on both amd64 and arm64, including Windows on Arm.

macOS and Linux:

curl -fsSL https://raw.githubusercontent.com/koltyakov/expose/main/scripts/install.sh | sh

Windows PowerShell:

irm https://raw.githubusercontent.com/koltyakov/expose/main/scripts/install.ps1 | iex

To uninstall, run the matching script:

curl -fsSL https://raw.githubusercontent.com/koltyakov/expose/main/scripts/uninstall.sh | sh
irm https://raw.githubusercontent.com/koltyakov/expose/main/scripts/uninstall.ps1 | iex

Or install from source with Go 1.26 or newer:

go install github.com/koltyakov/expose/cmd/expose@latest

2. Server - init and run

On your public-facing machine, run the interactive setup (writes a .env for you):

expose server init   # guided setup
expose server        # start the tunnel server

Then create an API key for your client(s):

expose apikey create --name default

3. Client - login and run

On any machine you want to expose:

# Login once to save credentials locally
expose login

# Expose a local HTTP port (e.g. 3000) to the internet
expose http 3000

# Or expose it with a named subdomain
expose http --domain=myapp 3000

# Or expose a static directory as a website
expose static

Open the URL shown in the terminal - that's it.

⚠️ Security notice: if your server is using per-host ACME certificates (dynamic, or auto without a matching wildcard certificate), new public hostnames are often discovered and probed by bots shortly after they are created. Protect new tunnels immediately and use --protect for anything non-public. See TLS Modes and Static Sites.

For the full walkthrough, DNS setup guides, and multi-route configs, see Quick Start.

Documentation

See the docs/ folder for all guides - server & client configuration, static sites, TLS modes, DNS setup, deployment, WAF, auto-update, troubleshooting, and more.

Development

Build and install locally:

make install

Generate coverage reports:

make cov

Acknowledgements

  • ngrok - the gold standard for HTTP tunnels and a huge inspiration. expose exists because I needed more freedom and control over infrastructure, but ngrok paved the way.
  • OpenAI and Anthropic - AI-assisted development boosted the entire build lifecycle by 10Γ—.

License

MIT

About

πŸš€ Self-hosted HTTP tunnel for exposing local apps and static sites with automatic HTTPS, built-in WAF, and a real-time terminal dashboard

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages