diff --git a/docs/calls.mdx b/docs/calls.mdx index bf5b65fcd..46bfaa4eb 100644 --- a/docs/calls.mdx +++ b/docs/calls.mdx @@ -3,11 +3,11 @@ # Calls Matrix supports two types of calls: - Element Call powered by [MatrixRTC](https://half-shot.github.io/msc-crafter/#msc/4143) and [LiveKit](https://github.com/livekit/livekit) -- Legacy calls, sometimes using Jitsi +- Legacy calls, supported by a STUN/TURN server. Both types of calls are supported by different sets of clients, but most clients are moving towards MatrixRTC / Element Call. -For either one to work correctly, you have to do some additional setup. +For either one to work correctly, you have to do some additional setup: - For legacy calls to work, you need to set up a TURN/STUN server. [Read the TURN guide for tips on how to set up coturn](./calls/turn.mdx) -- For MatrixRTC / Element Call to work, you have to set up the LiveKit backend (foci). LiveKit also uses TURN/STUN to increase reliability - you can set up its built-in TURN server, or integrate with an existing one. [Read the LiveKit guide](./calls/livekit.mdx) +- For MatrixRTC / Element Call to work, you have to set up the LiveKit backend. LiveKit also uses TURN/STUN to increase reliability - you can set up its built-in TURN server, or integrate with an existing one. [Read the LiveKit guide](./calls/livekit.mdx) diff --git a/docs/calls/livekit.mdx b/docs/calls/livekit.mdx index 1f8d5fc9e..d6bcdc0d7 100644 --- a/docs/calls/livekit.mdx +++ b/docs/calls/livekit.mdx @@ -1,8 +1,6 @@ # Matrix RTC/Element Call Setup -:::info This guide assumes that you are using docker compose for deployment. LiveKit only provides Docker images. -::: :::tip You can find help setting up MatrixRTC in our dedicated room - [#matrixrtc:continuwuity.org](https://matrix.to/#/%23matrixrtc%3Acontinuwuity.org) @@ -104,6 +102,12 @@ ### 3. Telling clients where to find LiveKit ] ``` +If you configure Continuwuity via environment variables, use the following: + +```bash +CONTINUWUITY_MATRIX_RTC__FOCI=[{ type = "livekit", livekit_service_url = "https://livekit.example.com" }] +``` + This will expose LiveKit information on the following endpoints for clients to discover: - `/_matrix/client/unstable/org.matrix.msc4143/rtc/transports` (MSC4143 unstable, behind auth) @@ -441,7 +445,7 @@ ## Appendix ### Additional TURNS-over-443 configuration -In most situations, LiveKit [does not need TURN][sspaeth-matrix-voip-turn] to function. However, when clients are in very restrictive networks where UDP traffic and non-standard ports are disallowed, a TURN-over-TLS server on port `:443` could be employed to relay traffic. +Most of the time, LiveKit [**does not need TURN**][sspaeth-matrix-voip-turn] to function. However, there are situations where clients are in very restrictive networks that disallows non-standard ports and UDP. In these cases, a TURN-over-TLS server on port :443 could be employed to relay traffic for them. [sspaeth-matrix-voip-turn]: https://sspaeth.de/2026/04/matrix-voip-and-livekit/#turn @@ -457,43 +461,48 @@ ### Additional TURNS-over-443 configuration ## add this to `livekit.yaml` ## turn: enabled: true + + # note: the TLS port will always be advertised as :443 tls_port: 5349 + + # optional: configure an extra UDP port on :3478 + # udp_port: 3478 + relay_range_start: 50300 relay_range_end: 50400 + domain: livekit-turn.example.com + # replace these with your actual cert/key files cert_file: /path/to/livekit-turn.example.com.crt key_file: /path/to/livekit-turn.example.com.key ``` ```yaml -### add these to livekit's docker-compose ### +### add these ports to livekit's docker-compose ### +### if you're using `network_mode: host`, you can skip this part ports: - "127.0.0.1:5349:5349/tcp" - "50300-50400:50300-50400/udp" -### if you're using `network_mode: host`, you can skip this part + # "3478:3478/udp" # (optional UDP port) ``` Recreate the LiveKit container (with `docker-compose up -d livekit`) to apply these changes. Remember to allow the new `50300:50400/udp` ports through your firewall. -Then, we will configure a route from port 443 of the host back to our `livekit-turn.example.com` service on port 5349. To both **multiplex** this and LiveKit's websocket on the same port, we will use a layer-4 reverse proxy with **SNI routing** capabilities, such as [caddy-l4][caddy-l4]. +Then, we will configure a route from port 443 of the host back to our `livekit-turn.example.com` service on port 5349. To both **multiplex** this and LiveKit's websocket on the same port, we will use a layer-4 reverse proxy with **SNI routing** capabilities, such as [caddy-l4][caddy-l4] on the host system. ``` ## in your Caddyfile ## { servers { listener_wrappers { + # intercept packets meant for the TURN domain first # before forwarding other packets to "normal" HTTP listeners layer4 { - @turn { - tls { - sni livekit-turn.example.com - } - } + @turn tls sni livekit-turn.example.com route @turn { - proxy { - upstream 127.0.0.1:5349 # forward to normal TURNS port + proxy 127.0.0.1:5349 # forward to normal TURNS port } } } @@ -517,7 +526,7 @@ # livekit stuff
-Using an external TURN server +Using an external TURN server (coturn) Before continuing, make sure coturn's `min-port` and `max-port` do not overlap with LiveKit's port range: diff --git a/docs/calls/turn.mdx b/docs/calls/turn.mdx index 16430e17a..fae75b9fb 100644 --- a/docs/calls/turn.mdx +++ b/docs/calls/turn.mdx @@ -2,7 +2,11 @@ # Setting up TURN/STUN [TURN][turn] and [STUN][stun] are used as a component in many calling systems. Matrix uses them directly for legacy calls and indirectly for MatrixRTC via Livekit. -Continuwuity recommends using [Coturn][coturn] as your TURN/STUN server, which is available as a Docker image or a distro package. +Continuwuity recommends using [Coturn][coturn] as your TURN/STUN server, which is available as a Docker image or a distro package. This guide assumes that you are using docker compose for deployment. + +:::tip +You can find help setting up TURN/STUN in our MatrixRTC room - [#matrixrtc:continuwuity.org](https://matrix.to/#/%23matrixrtc%3Acontinuwuity.org) +::: [turn]: https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT [stun]: https://en.wikipedia.org/wiki/STUN @@ -50,8 +54,6 @@ ### 3. Running the coturn container [coturn-image]: https://hub.docker.com/r/coturn/coturn [coturn-docker-docs]: https://github.com/coturn/coturn/blob/master/docker/coturn/README.md#why-so-many-ports-opened -#### With Docker Compose (recommended) - Create a `docker-compose.yml` file as follows and run `docker compose up -d`: ```yaml @@ -68,15 +70,6 @@ #### With Docker Compose (recommended) - /path/to/certs:/etc/letsencrypt ``` -#### With Docker - -```bash -docker run -d --network=host \ - -v $(pwd)/coturn.conf:/etc/coturn/turnserver.conf \ - -v /path/to/certs:/etc/letsencrypt # replace this with actual paths to your certificates - coturn/coturn -``` - ### 4. Opening ports By default, coturn uses the following ports: @@ -165,9 +158,9 @@ ### Testing Credentials "username": "1752792167:@jade:example.com", "password": "KjlDlawdPbU9mvP4bhdV/2c/h65=", "uris": [ - "turns:coturn.example.com?transport=tcp", - "turn:coturn.example.com?transport=udp", - "turn:coturn.example.com?transport=tcp" + "turns:coturn.example.com:3478?transport=tcp", + "turn:coturn.example.com:3478?transport=udp", + "turn:coturn.example.com:5349?transport=tcp" ], "ttl": 86400 } @@ -187,10 +180,13 @@ ### Testing Connectivity ## Troubleshooting +To gather debug logs while troubleshooting Coturn, add `verbose` to your `coturn.conf`. You can then view these logs with `docker-compose logs --follow coturn`. + ### Errors with Trickle ICE - `code=701` - the TURN server is not reachable - Verify firewall rules allow the necessary ports (3478, 5349, and your media port range) + - Verify via logs that coturn is exposed on the correct addresses and interfaces - Check that DNS resolves correctly for your TURN domain - `code=401` - unauthorized credentials - Ensure your `turn_secret` matches coturn's `static-auth-secret` @@ -227,11 +223,11 @@ ### Using Eturnal ### TURNS-over-443 -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. +Normally, TURN would work on their default setups. However, there are situations where clients are in very restrictive networks that disallows non-standard ports and UDP. In these cases, a TURN-over-TLS server on port :443 could be employed to relay traffic for them. -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. +However, port 443 is usually utilized by other HTTPS services. Therefore, one would need to **multiplex** both TURN HTTPS on these ports, and filter packets to them via **SNI routing**. -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. +Below are examples to multiplex Coturn and [LiveKit](./livekit.mdx) on port 443, using [caddy-l4][caddy-l4] on the host system.
@@ -248,20 +244,16 @@ ### TURNS-over-443 { 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 - } - } + @turn tls sni turn.example.com route @turn { - proxy { - upstream 127.0.0.1:5349 # forward to normal TURNS port - } + proxy 127.0.0.1:5349 # forward to normal TURNS port } } + tls } } @@ -296,7 +288,6 @@ # livekit stuff ```ini # in coturn.conf tcp-proxy-port=5555 - ``` Then, in the Caddyfile: @@ -305,14 +296,12 @@ # in coturn.conf { 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 - } - } + @turn tlssni turn.example.com + route @turn { tls # terminate TLS for the turn.example.com packets proxy { @@ -320,7 +309,6 @@ # in coturn.conf upstream 127.0.0.1:5555 proxy_protocol v2 } - } } tls @@ -337,27 +325,30 @@ # livekit stuff reverse_proxy http://127.0.0.1:7880 } - -# placeholder server block to obtain certs for turn.example.com +# placeholder block to obtain certs for turn.example.com https://turn.example.com { respond "OK" 200 } ``` +**Note**: the setup will disable TURN-over-TLS functionality on port 5349/tcp. +
-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. +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](./livekit#additional-turns-over-443-configuration). [caddy-l4]: https://github.com/mholt/caddy-l4 ### Unsafe TURN setups (not recommended) -These TURN setups are available, but **not recommended** due to security issues. They are only included for completeness. -
Using static credentials +:::caution +Static credentials are less secure than shared secrets because they don't expire and must be configured in coturn separately. It is strongly advised you use [shared secret authentication](#2-configuration). +::: + If you prefer static username/password credentials instead of shared secrets: ```ini @@ -382,8 +373,4 @@ # In continuwuity.toml turn_password = "your_password" ``` -:::caution -Static credentials are less secure than shared secrets because they don't expire and must be configured in coturn separately. It is strongly advised you use shared secret authentication. -::: -