We recently had an support inquiry from one of our Nextcloud customers at Netways Web Services. He told us that he had installed the Nextcloud Video Calls app from the Nextcloud Appstore but was not able to make any video calls. He and the person on the other end always got a black video screen when attempting to call each other.
After some research I identified the potential cause of the problem. It turned out that a TURN server was required (pardon the pun).


TURN – what is that?

The Nextcloud Video Calls app contains a WebRTC-based server called spreed. WebRTC uses the ICE (Interactive Connectivity Establishment) framework to overcome networking complexities (like NATs) where connecting the participating clients directly isn’t possible. But it will need at least a STUN server to accomplish that. STUN standing for “Session Traversal Utilities for NAT” will enable the clients to discover their public IP addresses and the NAT where they are behind. Note that this server is only used to initially establish the connection. Once the connection is set up the media will stream directly between the clients. The Nextcloud Video Calls app is preconfigured with “stun.nextcloud.com:443” as STUN server. But this doesn’t always work – just like our customer experienced it, for some clients a STUN server won’t be enough to establish the connection. That might be the case if one or multiple participants are behind a symmetric NAT where UDP hole punching does not work. And that’s where the TURN server comes in. “Traversal Using Relay NAT” (TURN) extends STUN capabilities to make media traversal possible even if the clients are behind symmetric NATs. But that means that the whole traffic will flow through the TURN server since it is acting as a relay. Therefore most TURN servers use credential or shared secret mechanisms to authenticate the clients. So after all you end up having two options: either you find a TURN server provider that you can trust and who is willing to grant you access to his service or you set up your own TURN server.


How to set up a TURN Server

We decided to set up our own TURN. Like most of the tutorials recommend we installed Coturn. Our “TURN-VM” is running Ubuntu 16.04 and has a public IP address – this is actually quite important since the TURN server needs at least one dedicated public IP address to work properly. In order to have full STUN/TURN server functionality it’s even required to have two public IP addresses.
Now let’s start – first install coturn:

apt-get install coturn

Next enable coturn as service (use the editor of your choice):

vim /etc/default/coturn

Now uncomment the last line, save and close the file:

# Uncomment it if you want to have the turnserver running as 
# an automatic system service daemon

We will have a look at the config file of Coturn. It has a lot of lines so I will only go over settings that are relevant in conjunction with Nextcloud’s spreed video calls. Open the turnserver.conf with an editor

vim /etc/turnserver.conf

and have a look at the following lines


Those are the default listening ports coturn will use. In my case I changed them to


because I don’t have a webserver running on the VM and I already had the ports open in the firewall. This is important – make sure that the server is reachable on these ports and no firewall is blocking them.
Note that the tls-listening-port is only relevant if you plan on using TLS-encrypted connections.

You’ll find the following line a couple of lines below the tls-listening-port:


If you leave it as a comment then Coturn will listen on all the IP addresses available for this host. I uncommented it and changed it to the actual public IP address of this server


Further down I did the same for the relay-ip:


Now look for “fingerprint” and “lt-cred-mech” and uncomment:


A couple of lines below you’ll find




uncomment both, then open up another shell window and generate a secret for example with

openssl rand -hex 32

copy the generated secret string and paste it into the turnserver.conf


Enabling “use-auth-secret” and setting a “static-auth-secret” will prevent unauthorized usage of your TURN server and is highly recommended!

Head further down and look for


then uncomment and change it to the FQDN of the TURN server


The next line to uncomment and change is


then uncomment


If you want to use TLS then you should get a SSL certificate and key for example via Letsencrypt and then set the following lines of the turnserver.conf to the path where those files are located, in my case:


also set cipher-list to


If you don’t plan on using this TURN server as STUN then you can uncomment


Now some last uncommenting


and you should be ready to start your coturn server. Save the file and close the editor.

Start/restart coturn for example with

service coturn restart


/etc/init.d/coturn restart

You may want to watch the logfile to see if everthing is fine

tail -f /var/log/turn_YYYY-MM-DD.log
0: log file opened: /var/log/turn_2017-08-15.log
0: pid file created: /var/run/turnserver.pid
0: IO method (main listener thread): epoll (with changelist)
0: WARNING: I cannot support STUN CHANGE_REQUEST functionality because only one IP address is provided
0: Wait for relay ports initialization...
0:   relay 185.XX.XXX.XXX initialization...
0:   relay 185.XX.XXX.XXX initialization done
0: Relay ports initialization done
0: IO method (general relay thread): epoll (with changelist)
0: IO method (general relay thread): epoll (with changelist)
0: turn server id=0 created
0: turn server id=2 created
0: IPv4. TLS/SCTP listener opened on : 185.XX.XXX.XXX:80
0: IPv4. TLS/TCP listener opened on : 185.XX.XXX.XXX:80
0: IO method (general relay thread): epoll (with changelist)
0: IPv4. TLS/SCTP listener opened on : 185.XX.XXX.XXX:443
0: IPv4. TLS/TCP listener opened on : 185.XX.XXX.XXX:443

So now we are ready to test if it is working.


How to test my TURN Server

Visit this page and see if you can get a proper response from your Coturn server.

The field for “STUN or TURN URI” should look something like this:


but you can also use the IP:


adding the part “?transport=tcp” is important as I was not able to get my TURN server to respond without TCP only.
Next click on “Gather candidates”.

What you would want as a result should look similar to this:

Time Component  Type Foundation Protocol    Address	 Port	         Priority
0.006	1	host	0	 UDP	60925	126 | 32512 | 255
0.009	1	host	1	 TCP	63376	125 | 32640 | 255
0.010	1	host	1	 TCP	9	125 | 32704 | 255
0.015	2	host	0	 UDP	47302	126 | 32512 | 254
0.016	2	host	1	 TCP	64892	125 | 32640 | 254
0.016	2	host	1	 TCP	9	125 | 32704 | 254
0.031	1	srflx	2	 TCP	XXX.XX.XX.XX	3362	 99 | 32607 | 255
0.051	2	srflx	2	 TCP	XXX.XX.XX.XX	3364	 99 | 32607 | 254
0.069	                                                                     Done

If you get a timeout with “Not reachable?” then probably a firewall is blocking the connection. Check again if the ports for the TURN server are open and if you can reach it externally via Telnet or something similar.

If everything works as expected you can continue and enter FQDN, port and shared secret in the video calls settings of your Nextcloud:

Also make sure that “TURN server protocols” is set to “TCP only”.
Finally test if video calls work with participants from different networks, through NAT’s and firewalls.

Well, that’s at least how I got it working and our NWS Nextcloud customer confirmed that he was able to make video calls without black screens as soon as he added in the TURN server details that I sent him.
Feel free to check out our Software as a Service platform NWS where you can test Nextcloud 30 days for free.

Gabriel Hartmann

Autor: Gabriel Hartmann

Gabriel freut sich nun in seiner Ausbildung zum Fachinformatiker für Systemintegration bei NETWAYS endlich sein im Informatikstudium gesammeltes Wissen artgerecht anwenden zu können. Wenn er nicht gerade an Servern, PC’s und sonstigem bastelt, vertreibt sich der gebürtige Oberfranke seine Freizeit mit Radfahren, Fotografie und Snowboarden. Vor allem reizen ihn interessante Projekte und das Arbeiten an Open Source basierten Linux-Systemen.