Setup STUN and TURN server on Ubuntu

Working on WebRTC? You developed a real-time audio-video app within some hours. You tested lots on your devices, test with roommates. Everything is going as expected. But out of nowhere, it did not work with your friend in distance, nor you can talk with your family back home. How can the perfect working app for local development stop working on the production? We are missing something on the equation. Let's get started.

What is WebRTC?

WebRTC is an open standard for real-time, plugin-free video, audio, and data communication. WebRTC enables peer-to-peer communication, it allows communication among browsers and devices. All the modern browser supports WebRTC.


WebRTC allows access to devices. You can access the microphone of your device, the camera that you have on your phone or laptop. It captures the data in real-time and can be streamed to the remote peer.

An RTCPeerConnection instance allows an application to establish peer-to-peer communications with another RTCPeerConnection instance in another browser, or to another endpoint implementing the required protocols.

 Even WebRTC is a peer-to-peer connection, it required servers, to pass signalling information (to establish a connection). WebRTC has not defined any signalling protocol on itself, users can use a service of their choice.

WebRTC tries to find the best path for connection using the host address obtained from a device's operating system. If not possible it tries to find an external address using a STUN server and, if that fails, traffic is routed through a TURN relay server. This is why your app works on the local network and not on the internet.

What is NATs?

We don't have enough of IPv4 to cover every device around the globe. Network address translation (NAT) is a method of mapping an IP address space into another by modifying network address information in the IP header of packets while they are in transit across a traffic routing device.

Image by Michel Bakni - license CC BY-SA 4.0


Simply, the router converts the source IP address of the packet while sending it out of the network, when the response came back, it converts the destination IP address back to that IP address thus forwarding it inside the network.

STUN

There is no use of the address provided by the NATs for WebRTC peers to peers communications. For that WebRTC depends on STUN.

STUN is on the public internet, the apps can use STUN server to discover its IP:port from a public perspective. STUN server simply check the IP:Port of the incoming request and response it back, there is not much work there is so not much powerful server is required.

TURN

If WebRTC cannot establish a connection with the above methods, TURN servers can be used as a fallback, relaying data between endpoints.

Setup STUN and TURN server on Ubuntu

Finally, here we are.

We will be using coturn, free open-source implementation of TURN and STUN Server, evolved from rfc5766-turn-server project with additional new advanced features.

Prerequisites:

  • Domain with DNS management access
  • A Ubuntu Server 
First let's install coturn. If you are on freshly installed server, let's update the repository. and reboot the server as well.

> sudo apt-get -y update
> sudo apt-get upgrade
> sudo reboot

Let's install. coturn starts automatically once installed, so let's stop it as well.

> sudo apt-get install coturn
> sudo systemctl stop coturn

SSL certificates

We need SSL certificate to configure out TURN server, so let's generate the SSL certificate using Let's Encrypt.

> sudo apt install certbot python3-certbot-nginx

Now, let's obtain the SSL certificate. Remember before this step, you should point your domain to this server. To do so find the IP address of this server and create A record on your DNS server for name stun and turn.

Remember to Enable port 80 and 443 on inbound security rules.

eg.
Name: stun.bloggernepal.com
Record Type: A,
Pointing to: (IP address)

> sudo certbot --nginx -d stun.bloggernepal.com -d turn.bloggernepal.com
> sudo certbot renew --dry-run

The first command obtain the certificate for the domains and place them on 

cert=/etc/letsencrypt/live/stun.bloggernepal.com/cert.pem
pkey=/etc/letsencrypt/live/stun.bloggernepal.com/privkey.pem

coturn configurations


Let's get back to coturn, we have installed and stoped the coturn, Let's enable TURN server in the configuration file of coturn.

> sudo nano /etc/default/coturn

and remove the # before TURNSERVER_ENABLED and press Ctl+O (write).

Let's work on etc/turnserver.config

First, let's save the current configuration, in case we want to look through the structure later.

> sudo  mv /etc/turnserver.config /etc/turnserver.config.save

Now paste the following to /etc/turnserver.conf

> sudo nano /etc/turnserver.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# /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=5349

# 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=bloggernepal.com
realm=bloggernepal.com

# Important:
# Create a test user if you want
# You can remove this user after testing
user=guest:somepassword

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=/etc/letsencrypt/live/stun.bloggernepal.com/cert.pem
pkey=/etc/letsencrypt/live/stun.bloggernepal.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
the above conf is taken from https://ourcodeworld.com/.

Everything is set by Now, let's start the coturn

> sudo systemctl start coturn

Remember to Enable port 3478 and 5349 for TCP and UDP incoming connection.

Testing STUN and TURN server

We can test our STUN and TURN server from the tool on Trickle ICE


If you test a STUN server, it works if you can gather a candidate with type "srflx". If you test a TURN server, it works if you can gather a candidate with type "relay".

Conclusion

In this post, we learn about WebRTC, how it works on simple terms, How the testing environment differs from the production environment on the WebRTC world. Then we learn about NATs, STUN and TURN server. Then we deploy our own STUN and TURN server using coturn. Any suggestions please do comment. Enjoy Peer-to-Peer connection.

Posted by Sagar Devkota

4 Comments