Changed TURN documentation so we can use both legacy and Element Call. Fixed a few broken internal links.

This commit is contained in:
Hans van Zijst 2025-01-08 14:51:11 +01:00
parent d85dcefbb9
commit d0c32f1ac6
Signed by: hans
GPG key ID: 43DBCC37BFDEFD72
6 changed files with 100 additions and 64 deletions

View file

@ -95,7 +95,7 @@ how to [setup and configure it](element-call).
# Element Web
This is the fully-fledged web client, which is very [easy to set
up](element-call).
up](element-web).
# TURN
@ -104,8 +104,8 @@ We may need a TURN server, and we'll use
[coturn](coturn) for that.
It's apparently also possible to use the built-in TURN server in Livekit,
which we'll use if we use [Element Call](call). It's either/or, so make sure
you pick the right approach.
which we'll use if we use [Element Call](element-call). It's either/or, so make
sure you pick the right approach.
You could possibly use both coturn and LiveKit, if you insist on being able to
use both legacy and Element Call functionality. This is not documented here

View file

@ -5,16 +5,22 @@ include_toc: true
# TURN server
You need an TURN server to connect participants that are behind a NAT firewall.
You need a TURN server to connect participants that are behind a NAT firewall.
Because IPv6 doesn't really need TURN, and Chrome can get confused if it has
to use TURN over IPv6, we'll stick to a strict IPv4-only configuration.
Also, because VoIP traffic is only UDP, we won't do TCP.
IMPORTANT! TURN can also be offered by [LiveKit](../element-call#livekit), in
which case you should probably not run coturn (unless you don't use LiveKit's
built-in TURN server, or want to run both to support legacy calls too).
TURN-functionality can be offered by coturn and LiveKit alike: coturn is used
for legacy calls (only one-on-one, supported in Element Android), whereas
Element Call (supported by ElementX, Desktop and Web) uses LiveKit.
In our documentation we'll enable both, which is probably not the optimal
solution, but at least it results in a system that supports old and new
clients.
Here we'll describe coturn, the dedicated ICE/STUN/TURN server that needs to
be configured in Synapse, [LiveKit](../element-call#livekit) has its own page.
# Installation
@ -73,24 +79,23 @@ certbot certonly --nginx -d turn.example.com
This assumes you've already setup and started nginx (see [nginx](../nginx)).
{#fixssl}
The certificate files reside under `/etc/letsencrypt/live`, but coturn
doesn't run as root, and can't read them. Therefore we create the directory
The certificate files reside under `/etc/letsencrypt/live`, but coturn and
LiveKit don't run as root, and can't read them. Therefore we create the directory
`/etc/coturn/ssl` where we copy the files to. This script should be run after
each certificate renewal:
```
#!/bin/bash
# This script is hooked after a renewal of the certificate, so
# that it's copied and chowned and made readable by coturn:
# This script is hooked after a renewal of the certificate, so that the
# certificate files are copied and chowned, and made readable by coturn:
cd /etc/coturn/ssl
cp /etc/letsencrypt/live/turn.example.com/{fullchain,privkey}.pem .
chown turnserver:turnserver *.pem
# We should restart either coturn or LiveKit, they cannot run both!
systemctl restart coturn
#systemctl restart livekit-server
# Make sure you only start/restart the servers that you need!
systemctl try-reload-or-restart coturn livekit-server
```
@ -102,7 +107,8 @@ renew_hook = /etc/coturn/fixssl
```
Yes, it's a bit primitive and could (should?) be polished. But for now: it
works.
works. This will copy and chown the certificate files and restart coturn
and/or LiveKit, depending on if they're running or not.
# Configuration {#configuration}
@ -121,9 +127,13 @@ Now that we have this, we can configure our configuration file under
`/etc/coturn/turnserver.conf`.
```
# We don't use the default ports, because LiveKit uses those
listening-port=3480
tls-listening-port=5351
# We don't need more than 10000 connections:
min-port=50000
max-port=60000
min-port=40000
max-port=49999
use-auth-secret
static-auth-secret=<previously created secret>
@ -133,7 +143,7 @@ user-quota=12
total-quota=1200
# Of course: substitute correct IPv4 address:
listening-ip=185.206.232.60
listening-ip=111.222.111.222
# VoIP traffic is only UDP
no-tcp-relay

View file

@ -3,11 +3,17 @@
# Only IPv4, IPv6 can confuse some software
listening-ip=111.222.111.222
# Listening port for TURN (UDP and TCP):
listening-port=3480
# Listening port for TURN TLS (UDP and TCP):
tls-listening-port=5351
# Lower and upper bounds of the UDP relay endpoints:
# (default values are 49152 and 65535)
#
min-port=50000
max-port=60000
min-port=40000
max-port=49999
use-auth-secret
static-auth-secret=<very secure password>

View file

@ -11,7 +11,7 @@ here's what you need.
* **lk-jwt**. This authenticates Synapse users to LiveKit.
* **LiveKit**. This is the "SFU", which actually handles the audio and video, and does TURN.
* **Element Call widget**. This is basically the webapplication, the part you see.
* **Element Call widget**. This is basically the webapplication, the user interface.
As mentioned in the [checklist](../checklist.md) you need to define these
three entries in DNS and get certificates for them:
@ -20,6 +20,9 @@ three entries in DNS and get certificates for them:
* `livekit.example.com`
* `call.example.com`
You may already have DNS and TLS for `turn.example.com`, as it is also used
for [coturn](../coturn).
For more inspiraten, check https://sspaeth.de/2024/11/sfu/
@ -97,8 +100,7 @@ turn:
udp_port: 3478
external_tls: true
keys:
# KEY: SECRET were autogenerated by livekit/generate
# in the lk-jwt-service environment variables
# KEY: SECRET were generated by "livekit-server generate-keys"
<KEY>: <SECRET>
```
@ -109,6 +111,15 @@ chown root:turnserver /etc/livekit/livekit.yaml
chmod 640 /etc/livekit/livekit.yaml
```
Port `7880` is forwarded by nginx: authentication is also done there, and that
bit has to be forwarded to `lk-jwt-service` on port `8080`. Therefore, we
listen only on localhost.
The TURN ports are the normal, default ones. If you also use coturn, make sure
it doesn't use the same ports as LiveKit. Also, make sure you open the correct
ports in the [firewall](../firewall).
## TLS certificate
The TLS-certificate files are not in the usual place under
@ -124,7 +135,7 @@ read them there too.
If you don't have coturn installed, you should create a directory under
`/etc/livekit` and copy the files to there. Modify the `livekit.yaml` file and
the [script to copy the files](../coturn/README.md#fixssl) to use that
directory. Don't forget to update the `renew_hook` in Letsencrypt.
directory. Don't forget to update the `renew_hook` in Letsencrypt if you do.
The LiveKit API listens on localhost, IPv6, port 7880. Traffic to this port is
forwarded from port 443 by nginx, which handles TLS, so it shouldn't be reachable
@ -158,14 +169,6 @@ WantedBy=multi-user.target
Enable and start it.
<<<<<
IMPORTANT!
LiveKit is configured to use its built-in TURN server, using the same ports as
[coturn](../coturn). Obviously, LiveKit and coturn are mutually exclusive in
this setup. Shutdown and disable coturn if you use LiveKit's TURN server.
>>>>>
Clients don't know about LiveKit yet, you'll have to give them the information
via the `.well-known/matrix/client`: add this bit to it to point them at the
SFU:
@ -183,26 +186,13 @@ Make sure it is served as `application/json`, just like the other .well-known
files.
lk-jwt-service is a small Go program that handles authorization tokens. You'll need a
Go compiler, so install that:
```
apt install golang
```
# lk-jwt-service {#lkjwt}
Get the latest source code and comile it (preferably *NOT* as root):
```
git clone https://github.com/element-hq/lk-jwt-service.git
cd lk-jwt-service
go build -o lk-jwt-service
```
You'll then notice that you need a newer compiler, so we'll download that and add it to
our PATH (again not as root):
lk-jwt-service is a small Go program that handles authorization tokens for use with LiveKit.
You'll need a Go compiler, but the one Debian provides is too old (at the time
of writing this, at least), so we'll install the latest one manually. Check
[the Go website](https://go.dev/dl/) to see which version is the latest, at
the time of writing it's 1.23.3, so we'll install that:
```
wget https://go.dev/dl/go1.23.3.linux-amd64.tar.gz
@ -212,6 +202,18 @@ export PATH=`pwd`:$PATH
cd
```
This means you now have the latest Go compiler in your path, but it's not
installed system-wide. If you want that, copy the whole `go` directory to
`/usr/local` and add `/usr/local/go/bin` to everybody's $PATH.
Get the latest lk-jwt-service source code and comile it (preferably *NOT* as root):
```
git clone https://github.com/element-hq/lk-jwt-service.git
cd lk-jwt-service
go build -o lk-jwt-service
```
Now, compile:
```
@ -226,6 +228,7 @@ cp ~user/lk-jwt-service/lk-jwt-service /usr/local/sbin
chown root:root /usr/local/sbin/lk-jwt-service
```
## Systemd
Create a service file for systemd, something like this:
@ -258,8 +261,8 @@ else.
```
mkdir /etc/lk-jwt-service
vi /etc/lk-jwt-service/config
chgrp -R www-data /etc/lk-jwt-service
chmod -R o-rwx /etc/lk-jwt-service
chgrp -R root:www-data /etc/lk-jwt-service
chmod 750 /etc/lk-jwt-service
```
This is what you should put into that config file,
@ -273,12 +276,20 @@ LIVEKIT_KEY=xxx
LK_JWT_PORT=8080
```
Change the permission accordingly:
```
chown root:www-data /etc/lk-jwt-service/config
chmod 640 /etc/lk-jwt-service/config
```
Now enable and start this thing:
```
systemctl enable --now lk-jwt-service
```
# Element Call widget {#widget}
This is a Node.js thingy, so start by installing yarn. Unfortunately both npm
@ -305,6 +316,9 @@ sudo apt install yarnpkg
/usr/share/nodejs/yarn/bin/yarn install
```
Yes, this whole Node.js, yarn and npm thing is a mess. Better documentation
could be written, but for now this will have to do.
Now clone the Element Call repository and "compile" stuff (again: not as
root):
@ -315,8 +329,10 @@ cd element-call
/usr/share/nodejs/yarn/bin/yarn build
```
After that, you can find the whole shebang under "dist". Copy that to
`/var/www/element-call` and point nginx to it ([see nginx](../nginx#callwidget)).
If it successfully compiles (warnings are more or less ok, errors aren't), you will
find the whole shebang under "dist". Copy that to `/var/www/element-call` and point
nginx to it ([see nginx](../nginx#callwidget)).
## Configuring

View file

@ -1,21 +1,25 @@
# Firewall
This page is mostly a placeholder for now, but configuration of the firewall
is -of course- very important.
Several ports need to be opened in the firewall, this is a list of all ports
that are needed by the components we describe in this document.
First idea: the ports that need to be opened are:
Those for nginx are necessary for Synapse to work, the ones for coturn and
LiveKit only need to be opened if you run those servers.
| Port(s) / range | IP version | Protocol | Application |
| :-------------: | :--------: | :------: | :--------------------- |
| 80, 443 | IPv4/IPv6 | TCP | nginx, reverse proxy |
| 8443 | IPv4/IPv6 | TCP | nginx, federation |
| 7881 | IPv4/IPv6 | TCP/UDP | coturn/LiveKit TURN |
| 3478 | IPv4 | UDP | coturn/LiveKit TURN |
| 5349 | IPv4 | TCP | coturn/LiveKit TURN |
| 50000-60000 | IPv4 | TCP/UDP | coturn/LiveKit TURN |
| 3478 | IPv4 | UDP | LiveKit TURN |
| 5349 | IPv4 | TCP | LiveKit TURN TLS |
| 7881 | IPv4/IPv6 | TCP | LiveKit RTC |
| 50000-60000 | IPv4/IPv6 | TCP/UDP | LiveKit RTC |
| 3480 | IPv4 | TCP/UDP | coturn TURN |
| 5351 | IPv4 | TCP/UDP | coturn TURN TLS |
| 40000-49999 | IPv4 | TCP/UDP | coturn RTC |
The ports necessary for TURN depend very much on the specific configuration
[coturn](../coturn#configuration) or [LiveKit](../element-call#livekit).
The ports necessary for TURN depend very much on the specific configuration of
[coturn](../coturn#configuration) and/or [LiveKit](../element-call#livekit).

View file

@ -49,7 +49,7 @@ list-timers` lists `certbot.timer`.
However, renewing the certificate means you'll have to restart the software
that's using it. We have 2 or 3 pieces of software that use certificates:
[coturn](../cotorun) and/or [LiveKit](../livekit), and [nginx](../nginx).
[coturn](../coturn) and/or [LiveKit](../element-call#livekit), and [nginx](../nginx).
Coturn/LiveKit are special with regards to the certificate, see their
respective pages. For nginx it's pretty easy: tell Letsencrypt to restart it