docs(turn): Add proxy protocol example for TURNS SNI routing

This commit is contained in:
stratself authored and Ellis Git committed 2026-08-04 18:18:54 +00:00
1 parent 486b50f328
commit 0d7c82cf5f
1 file changed
+76 -6
+76 -6
View File
@@ -224,16 +224,20 @@ If you instead prefer to use [eturnal][eturnal], you can refer to the guides bel
In very restrictive networks where UDP traffic and non-standard ports are disallowed, normal TURN servers are not reachable. To establish connectivity in these scenarios, a common solution is to host a TURN-over-TLS server on port 443, and allow clients to connect to it like any other web traffic.
However, port 443 is usually utilized by other HTTPS services. Therefore, one would need to **multiplex** both the TURN and the HTTPS services, and filter packets to them via **SNI routing**. A layer-4 load balancer, such as [caddy-l4][caddy-l4], can serve this function.
However, port 443 is usually utilized by other HTTPS services. Therefore, one would need to **multiplex** both the TURN and the HTTPS services, and filter packets to them via **SNI routing**. A layer-4 load balancer such as caddy-l4 can serve this function.
Below is an example of using Caddy-l4 on the host to:
Below are Caddyfile examples to multiplex both the TURNS service and LiveKit on port 443. It requires the [caddy-l4][caddy-l4] plugin to be compiled with your Caddy binary.
<details>
<summary>Caddyfile with TLS passthrough</summary>
This Caddyfile:
- Route `turn.example.com` to the TURNS port for Coturn without TLS termination, and
- Route `livekit.example.com` to the [LiveKit services](./livekit.mdx) with TLS termination by Caddy
<details>
<summary>Caddyfile</summary>
Please note that all traffic from Coturn's perspective will be coming from caddy-l4's IP now.
```
{
@@ -270,7 +274,73 @@ https://livekit.example.com {
</details>
You can now advertise `turns:turn.example.com:443?transport=tcp` as an address in your `turn_uris` as well as LiveKit. Please note that all traffic from Coturn's perspective will be coming from caddy-l4's IP now.
<details>
<summary>Caddyfile with TLS termination and PROXY protocol forwarding</summary>
This setup:
- Terminates TLS for `turn.example.com`,
- Tag the decrypted packets with PROXY protocol, and route it to coturn's `tcp-proxy-port`
- Route `livekit.example.com` to the [LiveKit services](./livekit.mdx) with TLS termination by Caddy
It allows coturn to see real client IPs, but the TLS handling is done on Caddy's side.
First, enable coturn's PROXY-protocol accepting port by adding this:
```ini
# in coturn.conf
tcp-proxy-port=5555
```
Then, in the Caddyfile:
```
{
servers {
listener_wrappers {
# intercept packets meant for the TURN domain first
# before forwarding other packets to "normal" HTTP listeners
layer4 {
@turn {
tls {
sni turn.example.com
}
}
route @turn {
tls # terminate TLS for the turn.example.com packets
proxy {
# then, proxy them to tcp-proxy-port and enable PROXY protocol version 2
upstream 127.0.0.1:5555
proxy_protocol v2
}
}
}
tls
}
}
}
# livekit stuff
https://livekit.example.com {
@lk-jwt-service path /healthz /get_token /sfu/get
route @lk-jwt-service {
reverse_proxy 127.0.0.1:8081
}
reverse_proxy http://127.0.0.1:7880
}
# placeholder server block to obtain certs for turn.example.com
https://turn.example.com {
respond "OK" 200
}
```
</details>
After configuration and spin-up, the destination `turns:turn.example.com:443?transport=tcp` should work with Trickle ICE tests. You can now advertise it as an address in your `turn_uris` as well as LiveKit.
[caddy-l4]: https://github.com/mholt/caddy-l4