diff --git a/deploy/coturn/turnserver.conf.example b/deploy/coturn/turnserver.conf.example index cb8a9e6..b75062c 100644 --- a/deploy/coturn/turnserver.conf.example +++ b/deploy/coturn/turnserver.conf.example @@ -10,6 +10,14 @@ stun-only no-tcp no-tls +# Approved NAT survey listeners only. Keep `stun-only` enabled: these auxiliary +# endpoints are for ordinary Binding requests, not TURN media relay. Replace +# with the host address already bound by the main listener. +# They use the same public IP and therefore measure destination-port behavior; +# full RFC 5780 behavior discovery still needs a second public IPv4. +#aux-server=:3479 +#aux-server=:3480 + # Keep automatic address selection on a single-homed public host. On a # multi-homed host, bind only the intended public interface. #listening-ip= diff --git a/docs/operations/self-hosting.md b/docs/operations/self-hosting.md index b386f08..3083632 100644 --- a/docs/operations/self-hosting.md +++ b/docs/operations/self-hosting.md @@ -73,6 +73,29 @@ Coturn runs `stun-only`, `no-tcp`, and `no-tls`. It must answer STUN binding and reject TURN allocation. Avoid verbose STUN/ICE logging because infrastructure necessarily observes client IP addresses. +## Temporary NAT Survey + +Enable the auxiliary listeners only for an approved aggregate-only survey. Add +the following to the service-owned coturn configuration, using the local +address already bound by the main listener: + +```ini +aux-server=:3479 +aux-server=:3480 +``` + +Keep `stun-only`, `no-tcp`, and `no-tls` unchanged. Allow UDP 3479 and 3480 in +both the cloud security group and the existing nftables input rule, validate +the complete ruleset with `nft -c -f /etc/nftables.conf`, then restart only +`coturn.service`. Verify `ss -lunp` shows all three UDP listeners and that an +ordinary STUN Binding succeeds on each; do not add these URLs to production +`STUN_URLS` or inject predicted ICE candidates. Remove the two `aux-server` +lines and firewall ports after the survey, validate again, and restart coturn. + +These same-IP auxiliary ports measure destination-port mapping behavior. They +are not a full RFC 5780 alternate-address deployment; that requires a second +public IPv4. + ## Operational Verification - `/healthz` returns `{"status":"ok"}` locally and through the public origin. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 8949880..8e0bb0e 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -50,6 +50,7 @@ Peer IDs, SDP, ICE candidates, tokens or media credentials. | ---: | --- | --- | | TCP 80/443 | public | HTTP redirect and HTTPS/WSS reverse proxy | | UDP 3478 | public | STUN-only coturn | +| UDP 3479/3480 | temporary public during approved NAT survey | auxiliary STUN-only coturn listeners | | UDP 7882 | public when SFU enabled | LiveKit WebRTC media | | TCP 8787 | private | Screener application | | TCP 7880 | private when SFU enabled | LiveKit signaling/control | @@ -58,6 +59,15 @@ TCP 3478, TCP/TLS 5349, TURN relay ranges, LiveKit media TCP, and other media ports remain closed. HTTPS/WSS transport is independent of the UDP-only media contract. +The optional NAT survey uses `stun::3479` and `:3480` in a +diagnostic page only. It does not change `STUN_URLS`, ordinary Peer ICE, or any +media route, and it needs both cloud security-group rules and the host's +`/etc/nftables.conf` rule. Coturn must bind the auxiliary listeners to the +host's local address with `aux-server`; opening a cloud port without a listener +has no effect. No new DNS record is required. Same-IP ports measure destination +port allocation behavior; a full RFC 5780 alternate-address test requires a +second public IPv4. + ## Bounds - Site-access requests are rate-limited at the reverse proxy and use constant- diff --git a/docs/status.md b/docs/status.md index 570d8f4..59341e0 100644 --- a/docs/status.md +++ b/docs/status.md @@ -23,10 +23,11 @@ This is the current execution index. Git history owns completed timelines; - Site access uses a stateless 24-hour rolling idle cookie. An active site-authorized page renews it hourly through the existing status request; Viewer-grant admission remains independent and cannot create or renew it. -- Public media listeners remain STUN-only UDP 3478 and LiveKit UDP 7882. Web - ingress is TCP 80/443; Node 8787 and LiveKit control/signaling 7880 are - private. TURN, ICE/TCP, media TCP, TLS relay, port 5349, and relay ranges are - disabled. +- Public media listeners remain STUN-only UDP 3478 and LiveKit UDP 7882. During + the approved NAT survey, coturn also exposes auxiliary STUN-only UDP 3479 + and 3480; ordinary `STUN_URLS` and media routes remain unchanged. Web ingress + is TCP 80/443; Node 8787 and LiveKit control/signaling 7880 are private. TURN, + ICE/TCP, media TCP, TLS relay, port 5349, and relay ranges are disabled. - Browser video uses the content-independent H.264 sender gate with VP8 fallback, plus the locked pre-share `VP8 | Auto | H264` Host selector and resolved codec display. Video retains `contentHint = "motion"`; audio uses diff --git a/docs/todo.md b/docs/todo.md index d94e0d2..853a19f 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -88,8 +88,11 @@ until their stated boundary is met. into production ICE without a new accepted decision and a measured gate. See [Browser NAT traversal](./research/nat-traversal.md). The Browser preflight proves only positive mapping variation and synthetic-candidate syntax; the - next executable gate requires an isolated Linux namespace runner with two - real Browser ICE agents. + isolated Linux namespace lab now covers the controlled Browser gate. A + self-hosted same-IP two/three-port endpoint is available for an approved + aggregate-only field survey; keep observations diagnostic until stable + sequential allocation is common enough to justify a new decision. Do not + inject predicted candidates yet. 15. **Unresolved route-state ownership claims.** Reopen lower-revision reauthentication, active SFU failure during an unrelated prepare, and multi-child relay-evidence ownership only from an exact current-wire