Embedded STUN Responder
AuthProxy ships with a built-in STUN responder for WebRTC NAT traversal. Instead of depending on stun.l.google.com:19302 (which is blocked in some networks) every customer deployment can list its own AuthProxy as a STUN server in WebRTC iceServers and the call flow keeps working without an extra service.
The responder is the absolute minimum needed for STUN binding requests: parse the request, return the reflexive transport address, increment counters. It is not a full coturn replacement (no TURN allocation, no long-term credentials).
Bind topology
The responder binds UDP on the same port AuthProxy uses for HTTP/HTTPS — the rationale is that WebRTC clients often have outbound UDP allowed on :443 even when arbitrary high ports are blocked.
+------------------------+
| AuthProxy process |
| TCP :8081 HTTPS web | <-- Razor pages, /auth/v1/*, /payorders/v1/*, ...
| UDP :8081 STUN bind | <-- STUN binding requests
+------------------------+
The actual port is resolved from same_web_port in config. IPv4 only in V1 — IPv6 binding is best-effort and is silently skipped if it fails.
API surface
Authenticated diagnostics
| Method | Path | Purpose |
|---|---|---|
POST | /auth/v1/stun/report | Store the current client's WebRTC diagnostics (ClientStunDiagnosticReport: stage, connection / ICE / signaling states, local & remote candidate types, selected-pair RTT, bytes sent/received) and return a merged server snapshot. |
GET | /auth/v1/stun/current?callId=... | Return the merged client-side and server-side diagnostics for the active session. |
Both endpoints require a valid session cookie (or X-Crm header in Local / Development / Test environments). The merged response includes server counters (packetsReceived, responsesSent, invalidPackets, lastSuccessAtUtc, etc.) so operators can correlate browser-side issues with server-side traffic without enabling debug logs.
The ProxyAdmin panel at /ProxyAdmin/StunMonitor exposes the same snapshot to operators.
Public STUN traffic
The STUN protocol itself is served on UDP — there is no HTTP endpoint. WebRTC clients add the responder to their iceServers array:
const pc = new RTCPeerConnection({
iceServers: [
{ urls: ['stun:authproxy.example.com:8081'] },
// optional fallbacks:
{ urls: ['stun:stun.l.google.com:19302'] },
],
});
When to use it
| Scenario | Recommended setup |
|---|---|
| Production with reliable Google STUN reachability | Keep Google STUN as primary, embedded as fallback. |
| Networks that block public STUN (corporate, certain countries) | Embedded STUN as primary, customer-owned coturn / Google STUN as fallback. |
| Dev / staging | Use only embedded STUN to avoid dependence on external services. |
The Chat module already lists embedded STUN among the fallback servers in its WebRTC config; see the platform CHAT-OVERVIEW.md for the full call-side flow.
Operational signals
- Process startup: log line
STUN responder bound on udp/<port>(orSTUN responder soft-failed on udp/<port>when binding is impossible — the rest of AuthProxy continues to start). - Per-packet counters: snapshot is updated on every binding request and is observable through
GET /auth/v1/stun/currentand/ProxyAdmin/StunMonitor. - Tracing: relevant Activity is emitted under
stun.bind.requestso spans can be correlated with the originating call fromchat.pwa.
Security
The current model is permissive — any UDP source can hit the responder. A more restrictive access model (recent-auth IP allowlist / active-call window / internal Chat→AuthProxy registration) is on the roadmap and will not break browser ICE semantics. Until then, treat the responder as public infrastructure.
Configuration
"Stun": {
// Master switch. Setting to false disables both the responder and diagnostics endpoints.
"Enabled": true,
// Override the auto-resolved web port if your deployment terminates HTTPS on a different
// socket from the listen port (for example behind an edge NAT or reverse proxy).
"WebPortOverride": null
}
Restart of AuthProxy is required for changes to take effect — the responder is a singleton service.
Out of scope
- TURN allocation (
Allocate/CreatePermission/ChannelBind). Use coturn for relay flows. - STUN over TLS / DTLS.
- Long-term credentials (
USERNAME/MESSAGE-INTEGRITYwith HMAC). - IPv6 dual binding when IPv4 binding fails.
Related
- Reverse Proxy — same-port HTTP server.
- Authentication API —
/auth/v1/stun/*endpoint contract. - Monitoring — operator-side dashboards.