HowTo: Setup Nextcloud Talk with TURN server


Part 3:
A pointer to this function is used in a call to init_turn_server which is defined here where it’s assigned to a function pointer var named allocate_bps_func. This function is used in handle_turn_allocate.
handle_turn_allocate will fail here if allocate_bps_func, i.e. it cannot allocate bandwidth.


Thanks for digging into this :+1:. I am too tired to exactly follow it in the code (will try tomorrow), but still wondering, why my TURN server works well then, even that bps-capacity=0 is set :thinking:.

It does not make any sense to allow limit the bandwidth to zero and effectively deactivate functioning of the TURN server. And how to disable the limit completely then? Totally common to use zero values to disable in such cases.

But again, if you can verify that switching between bps-capacity=0 and commenting it, also switches functioning of your TURN server, then we should open an GitHub issue, as this is definitely not how it should be and how everyone expects, even with the explanation in example conf.


Hm. You are right. I re-tested with uncommented bps-capacity, restarted coturn, and still could use the TURN-server.
(My testcase is a make-shift corporate-like firewall - I allow one PC to only access the Internet via a Proxy on tcp port 443, no udp).
I think the error in my short code analysis above might be that this line in the allocate_bps function will not distinguish between bps_capacity not being set, or it being 0. So 0 is probably OK (?).
Now I wonder what else I have changed that made my setup work, when it did not before…
Thanks for your persistence in pushing me to re-test!


Guess so. But I am no c coder :wink:.
But seems that disabled limit is default then, so commenting works as well.


Found the TURN server settings within database:
mysql -uroot -p -e "select * from nextcloud.oc_appconfig where appid='spreed'"
Replace “nextcloud” by your actual database name of course.


| appid  | configkey         | configvalue                                                                                                                            |
| spreed | enabled           | yes                                                                                                                                    |
| spreed | installed_version | 4.0.0                                                                                                                                  |
| spreed | stun_servers      | [""]                                                                                                              |
| spreed | turn_servers      | [{"server":"","secret":"<my_secret_string>","protocols":"udp,tcp"}] |
| spreed | types             | prevent_group_restriction                                                                                                              |

So to update settings via script e.g.:

mysql -uroot -p<password> -e "update <nextcloud_db_name>.oc_appconfig set configvalue='[\"\"]' where configkey='stun_servers'"
mysql -uroot -p<password> -e "update <nextcloud_db_name>.oc_appconfig set configvalue='[{\"server\":\"\",\"secret\":\"<your_secret_string>\",\"protocols\":\"udp,tcp\"}]' where configkey='turn_servers'"

But didn’t test syntax in this case with all the quotations :wink:. Testing pending…


To not risk messing with MySQL tables, occ can be also used to apply settings:

sudo -u www-data php /path/to/nextcloud/occ config:app:set spreed stun_servers --value='[""]'
sudo -u www-data php /path/to/nextcloud/occ config:app:set spreed turn_servers --value='[{"server":"","secret":"XXXX","protocols":"udp,tcp"}]'


One idea for this warning message:

Dec 19 09:08:17 srvr turnserver: 0: WARNING: cannot find private key file: /etc/ssl/acme/private/ (1)
Dec 19 09:08:17 srvr turnserver: 0: WARNING: cannot start TLS and DTLS listeners because private key file is not set properly

Cert generated by Letsencrypt on OpenBSD 6.4!
Right on private key is 0400, only for root and group wheel.

The turnserver start with _turnserver user.

how can i resolve _turnserver user read this file?


Ah okay on Raspbian/Debian certbot APT install, it runs as root user, to allow bind to restricted ports as well.

Somehow makes sense to run it as separate user on a permitted port.

There are two ways to grant access to private key files:

  • Copy the key + certs somewhere to a turnserver related dir and chown _turnserver:_turnserver && chmod 400. But this then needs to be done on every certificate renewal, e.g. via cron job or by adding these steps to the renewal job.
  • Create an “ssl” group, add _turnserver to this group and chown the key to this group with 440 permissions then. Then you can add any other user that requires cert+key access for TLS to this group. But this as well most likely needs to be redone on certificate renewal, depending on how (with which user) the renewal is done. Perhaps you can run the related renewal process/service with “ssl” group as well to have this done automatically.


@MichaIng: ty! :smiley:

OK, i resolve by creating an other directory, copy the private key, and chown only for _turnserver user…
with another group as “ssl”, and chmod 0440, that’s not run. :wink:

it’s weird because there is no need to change the server certificate!

another question: how i can block SSL23 usage… i want only TLS1.2!
i uncommented:


But, i’ve on start message:

Dec 19 17:30:21 srvr turnserver: 0: SSL23: Certificate file found: /etc/ssl/acme/
Dec 19 17:30:21 srvr turnserver: 0: SSL23: Private key file found: /etc/ssl/acme/turnserver/
Dec 19 17:30:21 srvr turnserver: 0: TLS1.2: Certificate file found: /etc/ssl/acme/
Dec 19 17:30:21 srvr turnserver: 0: TLS1.2: Private key file found: /etc/ssl/acme/turnserver/
Dec 19 17:30:21 srvr turnserver: 0: TLS cipher suite: ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5
Dec 19 17:30:21 srvr turnserver: 0: DTLS: Certificate file found: /etc/ssl/acme/
Dec 19 17:30:21 srvr turnserver: 0: DTLS: Private key file found: /etc/ssl/acme/turnserver/
Dec 19 17:30:21 srvr turnserver: 0: DTLS cipher suite: ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5


:+1: Actually the way to copy cert+key and chown for only the particular user is the most recommended way for security reasons. Only if you have several different services that require access, the shared group solution is handier.

Indeed, down to SSLv3 everything is supported according to the comments in turnserver.conf:
But no option to disable SSLv3.


  • So it seems that SSLv3 is disabled by default on current version, but somehow it still shows up in the log.
  • Perhaps you can look further into the logs to verify, only TLSv1.2 is used?


I understand…
But as I wrote on the previous message, I had only to deal the private key file, without any changes for another.

Thank for all! :stuck_out_tongue:


Ah jep, strict permissions are most important for your private key of course, while the certificates are public anyway and by default have weaker permissions :wink:.


Can I generate a new certificate for my turnserver, or do I need to use the certificate for my nextcloud’s apache config?


Of course you can use a different one.


:~# sudo systemctl enable --now turnserver
Failed to enable unit: File turnserver.service: No such file or directory



The service name is coturn, at least on Debian/Raspbian, if you installed via APT, so: systemctl enable coturn
And don’t forget: sed -i '/TURNSERVER_ENABLED/c\TURNSERVER_ENABLED=1' /etc/default/coturn
Otherwise the service will immediately stop.


An even easier approach is to run the script from the Nextcloud VM.

Two steps:

  1. Open port 5349 (or whichever you want)
  2. wget the RAW script and run it.


IF you run the Nextcloud VM :wink:!

Otherwise it might partly work on other Debian-based distros/systems, but leaves the config left with some wrong estimated variables => coturn settings, based on environment expectations, SSL via LetsEncrypt and others.


Can the TURN server be on the same server as Nextcloud itself? If so, I imagine we cannot refer to the TURN server by the IP address (within Nextcloud configs) as


Both can be on the same machine, but within Nextcloud settings, you still need to set the public/external IP. This is used by the end user WebRTC clients (browser, Android app), not by Nextcloud.


What if we installed our Nextcloud from a snap? That would introduce some complications, I think, to get coturn working on the same server as the snap. I made a post asking deeper questions about this here.