osmRouterosmRouter

HTTP tunnels

How osmRouter routes a public hostname to your local port, and everything that flows through it.

An HTTP tunnel binds a public hostname to a port on your machine. A visitor hits the hostname, the edge forwards the request down your tunnel, your local service answers, and the response travels back out — all over a connection your machine opened outbound.

osmrouter http 8080
# -> https://<random-name>.osmrouter.com  ->  http://localhost:8080

How a request flows

Your machine dials out

The agent opens an outbound connection to the relay and registers a hostname. Nothing needs to be open on your firewall, NAT, or CGNAT.

A visitor hits the hostname

DNS for *.osmrouter.com points at the edge. The edge terminates TLS with an automatic Let's Encrypt certificate.

The edge forwards down your tunnel

The request is streamed over the tunnel your agent already opened, with response flushing enabled so streaming bodies are not buffered.

Your local service answers

The agent forwards to localhost:<port> and streams the response back. The visitor sees real HTTPS on your hostname.

What passes through

TLS is terminated for you at the edge, so visitors always reach you over HTTPS regardless of how your local server listens. The following all pass through transparently:

  • Plain HTTP and HTTPS
  • WebSockets
  • Server-Sent Events (SSE)
  • Chunked and streaming responses
  • Long-running requests — there is no wall-clock timeout; only the visitor cancelling ends the request

That makes HTTP tunnels a good fit for dev servers, webhook receivers, and on-device LLM inference behind OpenAI-compatible servers such as Ollama, vLLM, or llama-server.

Random vs pinned hostnames

By default each run gets a fresh random name. Set OSM_SUBDOMAIN to request a stable hostname instead:

OSM_SUBDOMAIN=my-app osmrouter http 8080
# -> https://my-app.osmrouter.com

Without OSM_SUBDOMAIN, every run gets a new random name and the old URL goes offline. Pin the subdomain whenever you need a fixed address — for webhooks, QR codes, or anything you've shared.

Host headers and the origin

The request reaches your local service with the original Host and the standard forwarding headers set, so framework host checks and absolute-URL generation work as expected:

  • X-Forwarded-For — the visitor's IP.
  • X-Forwarded-Protohttps.
  • X-Forwarded-Host — the public hostname the visitor used.

If your dev server rejects requests for an unknown host, allow the tunnel hostname (or disable the host check in development).

Limits

A connection refused on localhost surfaces as a 502 at the edge — start your local service before tunneling. Concurrent tunnels and monthly bandwidth are bounded by your plan.

Next steps