Fediversity/matrix/coturn
2024-12-04 12:07:59 +01:00
..
README.md Updated and added some nginx configuration. 2024-12-04 12:07:59 +01:00
turnserver.conf Added configuration file for coturn. 2024-12-02 15:40:44 +01:00

Table of Contents

TURN server

You need an 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, 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).

Installation

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=
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.

DNS and certificate

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 turn.example.com here.

Make sure this entry only has an A record, no AAAA.

Get a certificate for this name:

certbot certonly --nginx -d turn.example.com

This assumes you've already setup and started nginx (see nginx).

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.

Configuration

Synapse's documentation gives a reasonable default config.

We'll need a shared secret that Synapse can use to control coturn, so let's create that first:

pwgen -s 64 1

Now that we have this, we can configure our configuration file under /etc/coturn/turnserver.conf.

# We don't need more than 10000 connections:
min-port=50000
max-port=60000

use-auth-secret
static-auth-secret=<previously created secret>

realm=turn.example.com
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.

Make sure you've opened the correct ports in the firewall.