Skip to content

Deploy a STUN server at stun.httpeers.net #1

Description

@mkotelnikov

Why

Browser peers connect peer-to-peer over WebRTC. The relay only carries the signalling. To find a direct path, each browser needs a STUN server to learn its public (server-reflexive) address.

Today nothing is configured, so @libp2p/webrtc falls back to its built-in public list: Google, Twilio, Cloudflare and Mozilla. That is fine for development and tests, and tests may keep using public servers (for example from this public STUN list; comments there report that individual entries go stale). A deployment should not depend on third-party STUN, so this is a planned installation of our own at stun.httpeers.net.

Scope

  • Server: a STUN server container (for example upstream coturn/coturn, STUN-only for now) added to deploy/docker-compose.yml.
    • Unlike every other service in the stack, it must bind host ports directly: UDP 3478, plus TCP 3478. Caddy proxies no UDP, so it cannot front it.
    • TLS (stuns: on 5349) is optional and can come later.
  • DNS: the zone's wildcard A record should already resolve stun.httpeers.net; confirm this, or add an explicit record.
  • Firewall: open 3478/udp and 3478/tcp on the host.
  • Clients: add stun:stun.httpeers.net:3478 to webRTC({ rtcConfiguration }) in the browser and hub node profiles (statewalker-sandbox: apps/httpeers-stack/src/browser/node-profile.ts, src/hub/node-profile.ts). Keep one public server as a fallback.
  • Docs: add the service to deploy/README.md and to the server runbook, including how to check it is alive.

Acceptance

  • A STUN binding request to stun.httpeers.net:3478 over UDP returns the caller's public address (for example with turnutils_stunclient stun.httpeers.net).
  • In a browser page, RTCPeerConnection with only stun:stun.httpeers.net:3478 gathers a srflx candidate.
  • The deployed pages list stun.httpeers.net in their ICE servers.

Related, deliberately out of scope: TURN

The agreed direction is that no application traffic ever crosses the relay or a hub node. When a direct WebRTC connection cannot be made (symmetric NAT, some mobile carriers), ICE must fall back to a TURN server. The same coturn install can provide TURN later, but TURN needs its own decisions, so it gets a separate issue:

  • Short-lived credentials. Pages are public, so credentials must be time-limited (coturn use-auth-secret, the "TURN REST API" scheme). @libp2p/webrtc accepts rtcConfiguration as an async function evaluated on every dial, so pages can fetch fresh credentials just before each connection.
  • Who mints them? A hub running in a browser tab cannot hold the secret. The likely answer is a small credential service beside the relay, kept separate from the relay so the relay stays free of application code.
  • Who may have one? An open TURN server is a free bandwidth proxy.
  • The relay's limits. Once TURN is live, they can go back down from 1 GiB / 6 h to signalling-sized values (apps/relay/src/limits.ts), because the relayed circuit stops being a data path.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions