The webteleport/relay system is a multi-protocol relay service that provides secure tunneling capabilities over WebSocket, WebTransport, QUIC, and TCP connections. It functions as a reverse proxy gateway that accepts connections from backend services through various protocols and exposes them to external HTTP/HTTPS clients.
This document provides a high-level introduction to the relay system's architecture, core interfaces, and operational model. For detailed information about specific components:
Sources: spec.go1-83 go.mod1-45 README.md1-7
The relay serves as a bidirectional tunnel gateway that:
The system enables backends behind NAT or firewalls to expose HTTP services without requiring inbound network access, using outbound connections to the relay server.
Sources: spec.go12-82
The relay supports four primary connection protocols for backend services:
| Protocol | Port(s) | Server Component | Use Case |
|---|---|---|---|
| WebSocket | 8080 | WSServer | Browser-compatible, HTTP-based tunneling |
| WebTransport | 8082, 8083 | WTServer | Modern HTTP/3 with multiplexing and datagrams |
| QUIC | 8081 | quic-go, net-quic upgraders | Native QUIC connections without HTTP/3 |
| TCP | 8081 | tcp.Upgrader | Raw TCP tunneling |
All protocols converge on the edge.Edge abstraction and use tunnel.Session for secure communication with backend services.
Sources: go.mod8-21 spec.go12-22
The relay architecture is built around three fundamental interfaces defined in spec.go12-82:
Diagram: Core Interface Architecture and Implementations
Relayer Interface spec.go13-22
dispatcher.Dispatcher, edge.HTTPUpgrader, and Ingress capabilitiesWSServer and WTServerIngress Interface spec.go25-43
http.Handler that processes incoming HTTP requestsedge.Subscriber to receive new backend connectionsGetRoundTripper() for host-to-session resolutionAliasHandler(), RecordsHandler()Storage Interface spec.go46-82
Allocate(), Upsert(), RemoveSession()Ping(), Scan()GetRecord(), LookupRecord()Alias(), Unalias(), Aliases()Sources: spec.go1-83
The Store component store.go implements the Storage interface and maintains two core data structures:
RecordMap: Maps session keys (TCP ports or onion IDs) to *Record instancesAliasMap: Maps user-defined aliases to session keys for human-friendly addressingEach Record represents an active backend session and contains:
tunnel.Session instance for bidirectional communicationhttp.RoundTripper for forwarding HTTP requests over the tunnelSources: spec.go46-82
WSServer wsserver.go
edge.HTTPUpgrader to convert WebSocket connections to edge.Edge instancesWTServer wtserver.go
webtransport.Upgrader for WebTransport session creationBoth servers embed an Ingress implementation and delegate request handling to it.
Sources: spec.go13-22
The following diagram illustrates the complete lifecycle from backend connection to request handling:
Diagram: High-Level System Operation Flow
1. Connection Phase
Backend services connect to the relay using one of the supported protocols. The protocol-specific server (WSServer, WTServer, or upgrader) converts the raw connection into an edge.Edge abstraction.
2. Allocation Phase
Store.Allocate() generates a unique key:
3. Registration Phase
Store.Upsert() creates a Record containing:
tunnel.Session for bidirectional communicationhttp.RoundTripper for HTTP forwarding4. Active Phase Two concurrent goroutines maintain session health:
CLOSE to terminate session)The main thread handles incoming HTTP requests.
5. Request Phase When an external client makes an HTTP request:
Dispatch() method routes to appropriate handlerGetRoundTripper() to resolve host to RecordReverseProxy forwards request via Record.RoundTripperMetricsTransport collects traffic statistics6. Termination Phase Sessions end via:
CLOSE command from backendStore.RemoveSession() removes the Record from RecordMap and cleans up associated aliases.
Sources: spec.go1-83 go.mod8-21
The relay leverages several key external modules:
| Module | Version | Purpose |
|---|---|---|
quic-go/quic-go | v0.59.0 | Native QUIC protocol implementation |
quic-go/webtransport-go | v0.10.0 | WebTransport over HTTP/3 |
gorilla/websocket | v1.5.3 | WebSocket protocol (indirect via btwiuse/wsconn) |
hashicorp/yamux | v0.1.3+ | Stream multiplexing over single connection |
btwiuse/muxr | v0.0.1 | HTTP request routing and middleware |
btwiuse/dispatcher | v0.0.0 | Request dispatch pattern |
btwiuse/proxy | v0.0.0 | Reverse proxy utilities |
webteleport/webteleport | v0.5.40-alpha.12 | Core tunnel and edge abstractions |
webteleport/utils | v0.2.19-alpha.10 | Utility functions |
For detailed dependency analysis and protocol stack details, see Module Dependencies.
Sources: go.mod8-44
The system uses Go interfaces extensively to separate concerns:
Relayer defines protocol server behaviorIngress defines HTTP handling behaviorStorage defines session management behaviorThis allows multiple implementations and easy testing.
All transport protocols (WebSocket, WebTransport, QUIC, TCP) converge on the edge.Edge abstraction from the webteleport/webteleport package. This unified interface enables protocol-agnostic session management.
The relay supports both TCP-based (WebSocket) and UDP-based (QUIC/WebTransport) transports, providing flexibility for different network conditions and client capabilities.
Each session maintains continuous health monitoring through:
All HTTP traffic flows through MetricsTransport, which tracks:
For metrics details, see Metrics and Monitoring.
Sources: spec.go1-83 go.mod8-44
The relay implements sophisticated request routing through multiple dispatch stages:
WSServer.Dispatch() or WTServer.Dispatch() determines request type/debug/* or /api/* routed to internal handlersStorage.GetRecord() or Storage.LookupRecord() resolves host to sessionReverseProxy configured with request rewriting ruleshttp.RoundTripper over tunnel.SessionFor detailed routing logic, see Request Flow.
Sources: spec.go25-43
The relay uses two types of session identifiers:
For TCP-protocol backends, Store.Allocate() assigns an available TCP port. External clients connect to relay.host:<port> to reach the backend.
For HTTP-protocol backends, Store.Allocate() derives an onion ID (e.g., abc123.relay.host) based on connection metadata. External clients use HTTP Host headers to route requests.
The relay supports user-friendly aliases that map to session keys. The AliasHandler API enables:
POST /api/aliases - Create alias mappingsGET /api/aliases - List all aliasesDELETE /api/aliases/:name - Remove aliasFor alias management details, see Alias Management.
Sources: spec.go46-82
The relay provides:
tunnel.Session from the webteleport packageThe relay itself does not implement authentication; it relies on the security model of the underlying tunnel.Session protocol.
Sources: spec.go1-83 go.mod17
This overview provides the foundation for understanding the webteleport/relay architecture. Subsequent sections dive deeper into specific components and their implementations.
Refresh this wiki