So after a very long journey with 0 experience setting up STUN/TURN server and a great success I decided to write this guide to shorten the path for those who need this solution.
How does it work
Background (as far as I got it)
Corporate networks block any type of communications other than ports 80 and 443 unless they trust your app and whitelist it.
Since you can’t expect every corporation IT to whitelist your app this solution was created.
A relay server called TURN server to connect to the firewalled endpoint via 443 (or another per your configuration) TCP and to the JVB (in this case) via port 10000 UDP.
On this guide I’ll be explaining how to set-up an external TURN server using CoTURN (open source) in an Ubuntu environment. I used 20.04.
What you’ll need:
- Ubuntu server (I used 20.04) - get a good hardware for your installation, you’ll need it if you have many firewalled corporate users.
- Your server’s internet-facing public IP
- A domain for SSL connection
- SSL certificate buy one or use Let’s Encrypt free 3 months one.
Let’s begin.
STEP A - set up your server and install CoTURN
Get an Ubuntu server and set it’s connectivity and OS. get a good hardware for your installation, you’ll need it if you have many firewalled corporate users. To my impression you can configure just one TURN server per Jicofo//Prosody instance. Meaning 1 TURN server per Jitsi Shard.
I might be wrong on this - I never tried configuring more than one per shard.
Make sure it’s up-to-date using the command:
sudo apt-get -y update
Install the CoTURN package
sudo apt-get install coturn
Then you’ll need to verify CoTURN isn’t running. Type
systemctl stop coturn
Enable your CoTURN server
nano /etc/default/coturn
Be sure that the content of the file has the properly uncommented, like this
TURNSERVER_ENABLED=1
Save changes and exit the nano editor.
Next stop - STEP B - Configuration of your CoTURN server
First… we always play safe. Backup your out-of-the-box config file
mv /etc/turnserver.conf /etc/turnserver.conf.original
Now, simply jump right in to business
nano /etc/turnserver.conf
Copy and paste to following config
# /etc/turnserver.conf
# STUN server port is 3478 for UDP and TCP, and 5349 for TLS.
# Allow connection on the UDP port 3478
#listening-port=3478
# and 5349 for TLS (secure)
tls-listening-port=443
no-multicast-peers
no-cli
no-loopback-peers
no-tcp-relay
no-tcp
no-tlsv1
no-tlsv1_1
no-tlsv1_2
no-sslv3
keep-address-family
# Require authentication
fingerprint
lt-cred-mech
# We will use the longterm authentication mechanism, but if
# you want to use the auth-secret mechanism, comment lt-cred-mech and
# uncomment use-auth-secret
# Check: https://github.com/coturn/coturn/issues/180#issuecomment-364363272
#The static auth secret needs to be changed, in this tutorial
# we'll generate a token using OpenSSL
# use-auth-secret
# static-auth-secret=replace-this-secret
# ----
# If you decide to use use-auth-secret, After saving the changes, change the auth-secret using the following command:
# sed -i "s/replace-this-secret/$(openssl rand -hex 32)/" /etc/turnserver.conf
# This will replace the replace-this-secret text on the file with the generated token using openssl.
# Specify the server name and the realm that will be used
# if is your first time configuring, just use the domain as name
server-name=yourdomain.com
realm=yourdomain.com
# Important:
# Create a test user if you want
# You can remove this user after testing
user=user:whateverpassword
total-quota=100
stale-nonce=600
# Path to the SSL certificate and private key. In this example we will use
# the letsencrypt generated certificate files.
cert=/usr/local/psa/var/modules/letsencrypt/etc/live/domain.com/fullchain.pem
pkey=/usr/local/psa/var/modules/letsencrypt/etc/live/domain.com/privkey.pem
# Specify the allowed OpenSSL cipher list for TLS/DTLS connections
cipher-list="ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384"
# Specify the process user and group
proc-user=turnserver
proc-group=turnserver
no-sslv3
no-tlsv1
no-tlsv1_1
no-tlsv1_2
# jitsi-meet coturn relay disable config. Do not modify this line
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
denied-peer-ip=::1
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
syslog
STEP C - Set up your domain
For the SSL certificate you must have an A record on your domain that points to your server’s IP.
You’ll also have to set-up SRV records.
Buy your domain and set-up the DNS with an A record that points to the server’s public IP address.
Set up your A record to point to your server IP.
turn.yourdomain.com
Set up your SRV records like shown in the images below. I’m attaching images from Godaddy’s console for clarity. It was my first time setting up SRV records manually.
STUN SRV record
TURN SRV record
TURNS SRV record
STEP D - Get your domain SSL certificate
Get a SSL certificate from let’s encrypt // Zero SSL // or a company of your choice.
Once you have your certificate and private key copy and paste them into the cert.pem and privkey.pem you have in your config. Make sure to get the certificate with the full chain.
In this example
/usr/local/psa/var/modules/letsencrypt/etc/live/ourcodeworld.com/fullchain.pem
/usr/local/psa/var/modules/letsencrypt/etc/live/ourcodeworld.com/privkey.pem
STEP E - Turn your CoTURN server on and test
Turn your server on
systemctl start coturn
Check the process to verify it’s active
systemctl status coturn
You should get this output
There’s an awesome online tool that allows you to check the functionality of STUN/TURN servers. This tool is Trickle ICE, a WebRTC page project that tests the trickle ICE functionality in a regular WebRTC implementation. It creates a PeerConnection with the specified ICEServers (which will contain the information of our recently implemented server), and then starts candidate gathering for a session with a single audio stream. As candidates are gathered, they are displayed in the text box below, along with an indication when candidate gathering is complete.
To get started open the tool website in a new browser tab and start filling the ICE servers form. In the form you will need to provide the STUN or TURN URI respectively with the credentials (only for the TURN server) like this:
We need to verify the connection on port 443.
Go to Trickle ICE and fill the fields similar to this:
Important
If you’re getting an error with binding port 443 run the following commands
sudo rm /lib/systemd/system/coturn.service
sudo systemctl daemon-reload
service coturn restart
STEP F - Configuring Prosody - the fun begins
Open Prosody configuration
nano /etc/prosody/conf.d/yourdomain.com.cfg.lua
In the first few lines you’ll find the following
external_service_secret = "SECRET";
external_services = {
{ type = "stun", host = "turn.yourdomain.com", port = 3478 },
{ type = "turn", host = "turn.yourdomain.com", port = 3478, transport = "udp", secret = true, ttl = 86400, algorithm = "turn" },
{ type = "turns", host = "turn.yourdomain.com", port = 443, transport = "tcp", secret = true, ttl = 86400, algorithm = "turn" }
};
First, you’ll need to set up a auth-secret on the CoTURN server and configure it on prosody to enable the connection.
Go back to your CoTURN server and edit the config file
nano /etc/turnserver.conf
Remove the # sign before the line
# static-auth-secret=replace-this-secret
Set up a secret key as you see fit. Make it complex.
The line should look like this
static-auth-secret=some-complicated-secret
Restart CoTURN
service coturn restart
Now go to the prosody configuration and replace SECRET with your some-complicated-secret
external_service_secret = "some-complicated-secret";
Next, you’ll need to configure the “turns” line and set the the port to 443 and TCP. You can remove the turn line as we want to connection to be secured using “turns”
external_service_secret = "SECRET";
external_services = {
{ type = "stun", host = "turn.yourdomain.com", port = 3478 },
{ type = "turns", host = "turn.yourdomain.com", port = 443, transport = "tcp", secret = true, ttl = 86400, algorithm = "turn" }
};
Now save and exit the file and Restart prosody.
service prosody restart
This is it. to view CoTURN logs type
tail -n 500 -f /var/log/syslog
You’re all set. You can test the connection by blocking port 10,000 UDP on your local machine firewall and try join a meeting. You should see the logs populate on the CoTURN logs.