Coturn chronicles

Stage 0
My Coturn chronicles started when I realized that coturn has a problem with Let's Encrypt certificate on Debian Buster. After some tests this issue was solved and I shared the related info on this topic

Stage 1
After a while, my friend said that some participants couldn’t connect to the conference. It seemed that these participants didn’t have permission to access to UDP/10000. but didn’t they connect through the TURN server?

Stage 2
I decided to test the TURN server again. I blocked my outgoing UDP/10000 traffic

iptables -A OUTPUT -p udp --dport 10000 -j DROP

and tried to connect to the conference using three tabs on the browser for the same room. But failed…

Stage 3
As you know, typical Jitsi installation uses TCP/443 for both jitsi-meet and coturn. Nginx checks the incomming packets and directs them to the corresponding upstream according to their types.

I opened the coturn port (TCP/5349) to the public to see if it worked alone. I changed prosody config to publish the new turns port to the clients.


{ type = "turns", host = "", port = "5349", transport = "tcp" }

This didn’t work on the first try. I had to edit the coturn config.


And finally it worked. This means that Nginx couldn’t direct the packets correctly.

Stage 4
After some research, I saw that it would be better to direct packets by host. Therefore, I needed a second host address (FQDN) and a TLS certificate for the turn server.

  • Added a DNS record for the new FQDN (let’s say
  • Added this FQDN to the Nginx config (needed for Let’s Encrypt)
listen 80;
listen [::]:80;
listen 4444 ssl http2;
listen [::]:4444 ssl http2;
  • Created the TLS certificate
certbot certonly --agree-tos --webroot -w /usr/share/jitsi-meet -d
  • Fixed the certificate parmissions as described in here

  • Enabled the new certificate on the coturn config.


Stage 5
It was time to edit the Nginx config. I commented the map block and added a new one.

    #map $ssl_preread_alpn_protocols $upstream {
    #    ~\bh2\b         web;
    #    ~\bhttp/1\.     web;
    #    default         turn;
    map $ssl_preread_server_name $upstream { turn;
        default           web;

coturn didn’t have to listen other than anymore. So I added one more line to the config too. All added/changed lines on /etc/turnserver.conf


Stage 6
Happy end