2024-11-15 19:35:35 +01:00
|
|
|
---
|
|
|
|
gitea: none
|
|
|
|
include_toc: true
|
|
|
|
---
|
|
|
|
|
|
|
|
# TURN server
|
|
|
|
|
|
|
|
You need an TURN server to connect participants that are behind a NAT firewall.
|
2024-11-15 21:38:05 +01:00
|
|
|
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.
|
|
|
|
|
2024-11-25 15:45:23 +01:00
|
|
|
IMPORTANT! TURN can also be offered by [LiveKit](../element-call#livekit), in
|
|
|
|
which case you should not run coturn (unless you don't use LiveKit's built-in
|
|
|
|
TURN server).
|
|
|
|
|
2024-11-15 21:38:05 +01:00
|
|
|
|
|
|
|
# Installation
|
2024-11-15 19:35:35 +01:00
|
|
|
|
|
|
|
Installation is short:
|
|
|
|
|
|
|
|
```
|
|
|
|
apt install coturn
|
|
|
|
```
|
|
|
|
|
|
|
|
For sake of maintainability we'll move the only configuration file into its
|
|
|
|
own directoy:
|
|
|
|
|
|
|
|
```
|
|
|
|
mkdir /etc/coturn
|
|
|
|
mv /etc/turnserver.conf /etc/coturn
|
|
|
|
```
|
|
|
|
|
|
|
|
We need to tell systemd to start it with the configuration file on the new
|
|
|
|
place. Edit the service file with:
|
|
|
|
|
|
|
|
```
|
|
|
|
systemctl edit coturn
|
|
|
|
```
|
|
|
|
|
|
|
|
Contrary to what the comment suggests, only the parts you add will override
|
|
|
|
the content that's already there. We have to "clean" the `ExecStart` first,
|
|
|
|
before we assign a new line to it, so this is the bit we add:
|
|
|
|
|
|
|
|
```
|
|
|
|
[Service]
|
|
|
|
ExecStart=
|
2024-11-15 21:38:05 +01:00
|
|
|
ExecStart=/usr/bin/turnserver -c /etc/coturn/turnserver.conf --pidfile=/etc/coturn/run/turnserver.pid
|
|
|
|
```
|
|
|
|
|
|
|
|
Create the directory `/etc/coturn/run` and chgrp it to `turnserver`, so that
|
|
|
|
coturn can write its pid there: `/run/turnserver.pid` can't be written because
|
|
|
|
coturn doesn't run as root.
|
|
|
|
|
|
|
|
This prepares us for the next step: configuring the whole thing.
|
|
|
|
|
|
|
|
|
2024-12-04 11:09:44 +01:00
|
|
|
# DNS and certificate {#dnscert}
|
2024-11-15 21:38:05 +01:00
|
|
|
|
|
|
|
As stated before, we only use IPv4, so a CNAME to our machine that also does
|
|
|
|
IPv6 is a bad idea. Fix a new entry in DNS for TURN only, we'll use
|
2024-11-28 14:16:46 +01:00
|
|
|
`turn.example.com` here.
|
2024-11-15 21:38:05 +01:00
|
|
|
|
|
|
|
Make sure this entry only has an A record, no AAAA.
|
|
|
|
|
|
|
|
Get a certificate for this name:
|
|
|
|
|
|
|
|
```
|
2024-11-28 14:16:46 +01:00
|
|
|
certbot certonly --nginx -d turn.example.com
|
2024-11-15 21:38:05 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
This assumes you've already setup and started nginx (see [nginx](../nginx)).
|
|
|
|
|
2024-12-04 11:09:44 +01:00
|
|
|
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
|
|
|
|
`/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:
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
Run this automatically after every renewal by adding this line to
|
|
|
|
`/etc/letsencrypt/renewal/turn.example.com.conf`:
|
|
|
|
|
|
|
|
```
|
|
|
|
renew_hook = /etc/coturn/fixssl
|
|
|
|
```
|
|
|
|
|
|
|
|
Yes, it's a bit primitive and could (should?) be polished. But for now: it
|
|
|
|
works.
|
2024-11-15 21:38:05 +01:00
|
|
|
|
|
|
|
|
2024-11-15 21:48:52 +01:00
|
|
|
# Configuration {#configuration}
|
2024-11-15 21:38:05 +01:00
|
|
|
|
|
|
|
Synapse's documentation gives a reasonable [default
|
|
|
|
config](https://element-hq.github.io/synapse/latest/setup/turn/coturn.html).
|
|
|
|
|
|
|
|
We'll need a shared secret that Synapse can use to control coturn, so let's
|
|
|
|
create that first:
|
|
|
|
|
|
|
|
```
|
|
|
|
pwgen -s 64 1
|
2024-11-15 19:35:35 +01:00
|
|
|
```
|
|
|
|
|
2024-11-15 21:38:05 +01:00
|
|
|
Now that we have this, we can configure our configuration file under
|
|
|
|
`/etc/coturn/turnserver.conf`.
|
2024-11-15 19:35:35 +01:00
|
|
|
|
2024-11-15 21:38:05 +01:00
|
|
|
```
|
|
|
|
# We don't need more than 10000 connections:
|
|
|
|
min-port=50000
|
|
|
|
max-port=60000
|
|
|
|
|
|
|
|
use-auth-secret
|
|
|
|
static-auth-secret=<previously created secret>
|
|
|
|
|
2024-11-28 14:16:46 +01:00
|
|
|
realm=turn.example.com
|
2024-11-15 21:38:05 +01:00
|
|
|
user-quota=12
|
|
|
|
total-quota=1200
|
|
|
|
|
|
|
|
# Of course: substitute correct IPv4 address:
|
|
|
|
listening-ip=185.206.232.60
|
|
|
|
|
|
|
|
# VoIP traffic is only UDP
|
|
|
|
no-tcp-relay
|
|
|
|
|
|
|
|
# coturn doesn't run as root, so the certificate has
|
|
|
|
# to be copied/chowned here.
|
|
|
|
cert=/etc/coturn/ssl/fullchain.pem
|
|
|
|
pkey=/etc/coturn/ssl/privkey.pem
|
|
|
|
|
|
|
|
denied-peer-ip=0.0.0.0-255.255.255.255
|
|
|
|
denied-peer-ip=127.0.0.0-0.255.255.255
|
|
|
|
denied-peer-ip=10.0.0.0-10.255.255.255
|
|
|
|
denied-peer-ip=172.16.0.0-172.31.255.255
|
|
|
|
denied-peer-ip=192.168.0.0-192.168.255.255
|
|
|
|
denied-peer-ip=100.64.0.0-100.127.255.255
|
|
|
|
denied-peer-ip=192.0.0.0-192.0.0.255
|
|
|
|
denied-peer-ip=169.254.0.0-169.254.255.255
|
|
|
|
denied-peer-ip=192.88.99.0-192.88.99.255
|
|
|
|
denied-peer-ip=198.18.0.0-198.19.255.255
|
|
|
|
denied-peer-ip=192.0.2.0-192.0.2.255
|
|
|
|
denied-peer-ip=198.51.100.0-198.51.100.255
|
|
|
|
denied-peer-ip=203.0.113.0-203.0.113.255
|
|
|
|
|
|
|
|
# We do only IPv4
|
|
|
|
allocation-default-address-family="ipv4"
|
|
|
|
|
|
|
|
# No weak TLS
|
|
|
|
no-tlsv1
|
|
|
|
no-tlsv1_1
|
|
|
|
```
|
|
|
|
|
|
|
|
All other options in the configuration file are either commented out, or
|
|
|
|
defaults.
|
|
|
|
|
2024-12-04 11:09:44 +01:00
|
|
|
Make sure you've opened the correct ports in the [firewall](../firewall).
|