WebRTC Behind Corporate Firewalls and Proxies
By SRIFT maintainers · Published
Reviewed by SRIFT maintainers · last reviewed against the SRIFT 4.3.2 source · third-party facts checked 8 October 2026.
Short answer
WebRTC fails on corporate networks because they typically block outbound UDP, allow only ports 80 and 443, force web traffic through an HTTP proxy, and sometimes decrypt TLS for inspection. Direct peer-to-peer media and data channels need UDP, so on such a network the connection either goes through a TURN relay over TLS on port 443 or does not happen.
The reliable design is an ordered fallback: direct UDP, then TURN over UDP, then TURN over TLS on 443, then a WebSocket relay, then plain HTTPS long-polling. Each step needs less from the network and costs more in speed. Whether a browser will send TURN traffic through a configured proxy varies by browser and by policy, so the last two steps are the ones that work almost everywhere.
- Usual blocker
- Outbound UDP denied; only TCP 80/443 allowed
- Best WebRTC fallback
- TURN over TLS on port 443
- When TURN is blocked too
- A WebSocket relay, then HTTPS long-polling
- Proxy support for TURN
- Varies by browser and admin policy
This guide is about managed networks: mandatory proxies, TLS inspection and blocked UDP. For a step-by-step diagnosis on any network, see why WebRTC connections fail.
What corporate networks block, and why WebRTC notices
Enterprise egress policies are written for web browsing, email and a list of approved services. Three common rules matter for WebRTC:
- No outbound UDP except DNS to internal resolvers. STUN binding requests never leave the building, so the browser gathers no server-reflexive candidates and UDP hole punching cannot start. TURN over UDP fails for the same reason.
- Only TCP 80 and 443, sometimes only to allow-listed destinations or categories. TURN on its default port 3478 is unreachable over either transport.
- Unknown protocols dropped. Next-generation firewalls classify traffic by content, not only by port. A connection on 443 that does not look like TLS, or a TLS connection that does not carry HTTP after the handshake, may be blocked or cut.
The browser loads the web application fine, because that is HTTPS through the sanctioned path. Signaling over WebSocket may or may not work. ICE then times out with no working candidate pair, which users experience as “connecting…” forever. The NAT traversal guide explains why a direct path needs UDP in the first place.
HTTP proxies, CONNECT and what browsers do with WebRTC
In many offices, nothing reaches the internet directly; everything goes through an explicit HTTP proxy, configured by a PAC file or system settings. For HTTPS the client sends CONNECT host:443 to the proxy (RFC 9110, section 9.3.6), the proxy opens a TCP connection to the destination, and from then on relays bytes in both directions. The proxy decides per request whether to allow the tunnel, often by host name and port, and may require authentication first.
CONNECT carries TCP only. UDP cannot go through an HTTP proxy, and the WebRTC IP handling rules in RFC 8828 say that by default WebRTC traffic should not be sent through proxies at all. RFC 8828 defines a stricter “Mode 4” for environments that require it: when the application's HTTP traffic is proxied, WebRTC media must be proxied too, and if the proxy does not support UDP, TCP is used through the proxy instead.
Browser support is uneven
- Chromium-based browsers (Chrome, Edge) expose this as an enterprise policy. Microsoft's documentation for Edge's
WebRtcLocalhostIpHandlingpolicy describes thedisable_non_proxied_udpvalue as “Use TCP unless proxy server supports UDP”, and its per-site variant as UDP SOCKS proxying with a fallback to TCP proxying. With that policy, TURN over TCP or TLS through the proxy is the only way WebRTC can connect. - Firefox has had code to send TURN over TCP through an HTTP proxy for years, according to Mozilla's bug tracker, but Mozilla publishes no administrator documentation describing exactly when it applies, how it interacts with PAC files, or whether authenticated proxies work. Treat it as something to test on your own network.
- Safari: we found no Apple documentation on WebRTC and HTTP proxies, so we make no claim.
Even where a browser does tunnel TURN through the proxy, the proxy must allow CONNECT to the TURN server's host and port. Proxies that allow-list destinations by category or by host name will refuse an unknown TURN host until someone adds it. That is the realistic summary: WebRTC through a proxy is possible, but it depends on three parties (browser, proxy policy, TURN provider) lining up.
TLS inspection and WebSocket-hostile proxies
TLS inspection
An inspecting proxy or firewall terminates TLS, presents a certificate signed by a corporate root CA that managed devices trust, inspects the plaintext, and opens its own TLS connection to the real server. It is built for HTTP. TURN over TLS (turns:, RFC 7065) carries STUN and TURN messages inside TLS, not HTTP, so an inspection device may reject the connection as an unknown protocol, or the TURN client may refuse the re-signed certificate. Which of these happens depends on the device and the client. The usual fix is an inspection bypass for the TURN provider's host names.
DTLS between two WebRTC peers is a different matter: its certificate fingerprints travel in the signaling messages, so a middlebox cannot transparently re-sign it. Networks that inspect everything therefore tend to block peer-to-peer DTLS rather than decrypt it.
Command-line tools run into inspection differently. A Node.js or Python program does not read the operating system's corporate root automatically in every configuration, so its HTTPS requests fail with “self-signed certificate in chain” or a similar error. The fix is to trust the corporate root explicitly, never to disable certificate verification.
Proxies that break WebSockets
A WebSocket starts as an HTTP request with Upgrade: websocket and then becomes a long-lived, bidirectional stream (RFC 6455). Some proxies do not support the upgrade, some strip the headers, some allow it but close connections that stay idle or open too long, and some buffer data in ways that stall a stream. Through an inspecting proxy, wss:// fails when the proxy cannot handle the upgrade inside the decrypted session. The remedy is to have a transport that is nothing but ordinary HTTPS requests: long-polling, where the client keeps one request open waiting for data and sends its own data in separate POSTs. It is slower and chattier, but a proxy that lets you browse lets it through.
An ordered fallback strategy
The first three rungs are handled by ICE if you give the browser the right iceServers: STUN for server-reflexive candidates, TURN with ?transport=udp, and a turns: URL on port 443. ICE gathers all of them in parallel and prefers the cheaper candidates, so including the TLS server costs nothing on open networks. Two practical points:
- Port 443 for TURN over TLS matters. A TURN server on 5349 (the default TLS port) is no help on a network that only allows 443.
- Use short-lived TURN credentials. Fetch them from your server per session rather than shipping static credentials in the page, where anyone can copy and reuse them.
Rungs 4 and 5 are outside WebRTC entirely: the application relays data through its own server. That only makes sense if the data is encrypted end to end before it reaches the relay, otherwise the fallback quietly turns a peer-to-peer design into a server that can read everything. The STUN vs TURN comparison covers the ICE side; what a relay can see covers the privacy side.
How SRIFT behaves on locked-down networks
The behaviour below is from SRIFT's source code at version 4.3.2.
In the browser
- UDP probe. If no server-reflexive candidate appears within 1.5 seconds, the browser treats UDP as unusable. When a TURN server is available it then restricts the peer connection to relay candidates (TURN over TCP or TLS); without TURN it skips WebRTC.
- TURN over TLS on 443 first. The server mints short-lived TURN credentials per request from every configured provider and sorts each provider's URLs as
turns:on 443, otherturns:, TURN over TCP, then TURN over UDP. One of the four public STUN servers listens on 443. - Sealed WebSocket relay. A direct data channel gets 3 seconds to open. Otherwise the transfer runs over SRIFT's WebSocket relay on 443, with each chunk sealed with AES-256-GCM under a per-transfer ECDH key, so the relay forwards ciphertext.
- HTTPS stream when WebSockets fail. If the WebSocket cannot open twice, the session connection, including the sealed relay chunks, switches to HTTPS requests with a 25-second long poll. The browser tries WebSocket again every 10 minutes.
From the command line
The srift CLI and its background daemon route every outbound request through one network layer. It honours HTTPS_PROXY, HTTP_PROXY, ALL_PROXY and NO_PROXY; tunnels through http:// and https:// proxies with CONNECT (Basic credentials in the proxy URL are supported); speaks SOCKS5 for socks5:// and socks5h:// proxies; and never proxies loopback, so the local daemon stays reachable. It never disables TLS verification: on a certificate error it tells you to set NODE_EXTRA_CA_CERTS. The daemon's session connection switches to the same HTTPS stream after repeated WebSocket failures.
export HTTPS_PROXY=http://proxy.corp.example:8080
export NO_PROXY=localhost,.corp.example
export NODE_EXTRA_CA_CERTS=/path/to/corp-root-ca.pem # the proxy's root CA, PEM
# Windows: setx NODE_EXTRA_CA_CERTS "C:\path\to\corp-root-ca.pem" (then open a new terminal)
srift doctor # which transports work here, with a fix for each failure
srift doctor --deep # also creates a small encrypted link and downloads it back
srift quick-share ./report.pdf --encrypt --oncesrift doctor runs its probes in parallel: DNS resolution, an HTTPS request to the server (which also catches captive portals and a system clock more than five minutes off), the signaling WebSocket, UDP to a STUN server, the peer-discovery WebSocket, the configured proxy, local loopback and background-process permissions, the daemon, storage and temp space, and the system curl. Each check is reported as WORKS, WARN, BLOCKED or SKIPPED with a specific fix, followed by an overall verdict (ok, degraded or blocked) and whether links will be served from the background daemon or in-process. Blocked UDP is a warning, not a failure, because links and relays work over 443. --json gives the same report for scripts.
For moving files off a machine that has only outbound HTTPS, such as a CI runner or a server behind an egress proxy, srift quick-share needs nothing but outbound 443; the remote server transfer guide walks through it.
Symptoms, causes and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| No server-reflexive (srflx) candidates; ICE fails | Outbound UDP blocked | Add TURN over TLS on 443; ask IT to allow UDP to the TURN provider for better speed |
| Only relay candidates over TCP or TLS; transfers slow | UDP blocked, TURN running over TCP | Expected on this network; allowing UDP 3478 to the TURN host restores UDP relaying |
| No relay candidates either, even with TURN configured | TURN host not allow-listed, port not 443, or the browser does not send TURN through the proxy | Use a turns: URL on 443; ask for the TURN host to be allowed; fall back to an application relay |
| TURN over TLS connects then drops at once | TLS inspection treats the non-HTTP stream as unknown | Request an inspection bypass for the TURN host names |
| WebSocket upgrade fails (400, 403) or closes immediately | Proxy does not support or allow the HTTP Upgrade | Fall back to HTTPS long-polling; ask for WebSocket support for the host |
| WebSocket works but drops after a fixed idle period | Proxy idle or maximum-duration timeout | Send application keepalives; reconnect and resume transfers by byte offset |
CLI: self-signed certificate in certificate chain | TLS-inspecting proxy re-signs traffic | Point NODE_EXTRA_CA_CERTS at the proxy's root CA (PEM); never set NODE_TLS_REJECT_UNAUTHORIZED=0 |
| CLI: host not found, while the browser works | Only the proxy can resolve external names | Set HTTPS_PROXY so the proxy resolves the host (use socks5h:// for SOCKS) |
| CLI: proxy answers 407 | Proxy requires authentication | Put Basic credentials in the proxy URL; NTLM or Kerberos proxies need a local authenticating forwarder |
If none of these match, the guide to failed WebRTC connections covers causes that are not specific to corporate networks, such as browser permissions, extensions and VPN split tunnelling.
Frequently asked questions
Can I make WebRTC work behind a firewall without asking IT for anything?
Often, if the application provides TURN over TLS on port 443 and the firewall does not inspect or allow-list TLS destinations. If it does, the remaining option is an application relay over WebSocket or HTTPS, which works wherever ordinary browsing works.
Does a VPN help?
A full-tunnel corporate VPN usually applies the same egress rules as the office, so it rarely helps. A VPN that is allowed to carry UDP to the internet can make direct connections possible, but it changes which network the traffic leaves from, which your security team may not permit.
Is TURN over TCP slower than TURN over UDP?
Usually, yes. A lost packet on a TCP connection delays everything behind it until it is retransmitted, and WebRTC's own congestion control then runs on top of TCP's. For file transfer the throughput penalty is often acceptable; for real-time audio and video it is more noticeable.
References
- RFC 8656: Traversal Using Relays around NAT (TURN) (IETF)
- RFC 7065: TURN Uniform Resource Identifiers (IETF)
- RFC 8828: WebRTC IP Address Handling Requirements (IETF)
- RFC 9110: HTTP Semantics (CONNECT, section 9.3.6) (IETF)
- RFC 6455: The WebSocket Protocol (IETF)
- Microsoft Edge policy: WebRtcLocalhostIpHandling (Microsoft)
- Microsoft Edge policy: WebRtcIPHandlingUrl (Microsoft)
Use SRIFT from a terminal
One command prints a download link that streams from your machine. Needs only outbound HTTPS; --encrypt keeps the key out of the relay.
npx -y srift-transfer quick-share ./build.tar.gz --encryptRelated resources
- STUN vs TURN: How WebRTC Gets Through NATWhat STUN and TURN servers do, how ICE picks between host, server-reflexive and relay candidates, and what a TURN relay can and cannot see.Explainer
- Why WebRTC Connections Fail, and How to Fix ThemWhy two browsers sometimes cannot connect directly: ICE failures, blocked UDP, symmetric NAT and missing TURN, with a diagnosis checklist.Troubleshooting
- WebRTC vs WebSockets for File TransferDirect WebRTC data channels and server-relayed WebSockets compared for file transfer: latency, throughput, reliability, cost and privacy.Comparison
- Get Files Off a Remote Server Without Opening Inbound PortsPull logs, dumps and builds from Linux servers, cloud VMs and headless boxes when SSH is not an option: outbound-only methods and their trade-offs.How-to
