Nextcloud Talk lets you make audio and video calls directly within Nextcloud. Calls often work without additional setup when participants are on the same local network or can connect directly over the internet. However, restrictive firewalls, corporate networks or certain NAT configurations can prevent these direct connections. That’s where a TURN server comes in.

What is a Nextcloud TURN server?

A TURN server acts as an intermediary: relaying audio and video data between participants instead of sending it directly between them. Nextcloud Talk first tries to establish a direct peer-to-peer connection. If needed, it uses a STUN server to determine the public network address and only falls back to TURN when necessary. This means running your own TURN server is recommended to help ensure Nextcloud Talk calls work reliably, especially when participants join from outside your network.

What do you need to set up a TURN server for Nextcloud Talk?

Before you start, you’ll need a working Nextcloud installation with the Nextcloud Talk app enabled. Nextcloud Talk requires HTTPS for WebRTC, so your Nextcloud instance should already be accessible using a valid TLS certificate. Shared hosting has limitations for larger Talk installations because audio and video calls put additional load on the server. To run your own TURN server, you also need to be able to open network ports and keep the TURN service running continuously.

For this setup, you’ll need:

  • a Nextcloud installation with Nextcloud Talk enabled,
  • administrator access to Nextcloud,
  • a Linux server where you can install software,
  • SSH access with sudo or root privileges,
  • a public IPv4 address,
  • a domain or subdomain,
  • access to the domain’s DNS settings,
  • a firewall that lets you open TCP and UDP ports.

You can use Ubuntu Server 26.04 LTS, for example. Ubuntu 24.04 LTS and current versions of Debian also work. In this guide, we’ll use turn.example.com as the TURN server address. Replace it with your domain in all commands.

Should you run your TURN server on a VPS or dedicated server?

When choosing a TURN server, processing power isn’t the only thing that matters. The network connection is especially important because TURN relays audio and video data between call participants. Whenever TURN is needed, that data passes through the server.

A small or medium-sized VPS is usually a good starting point for personal Nextcloud installations, small businesses and teams where only a few people will be using Talk for calls at the same time. If the VPS is used exclusively for TURN, two virtual CPU cores and a few gigabytes of RAM are often enough. Since TURN mainly relays audio and video data, however, a stable network connection, a public IP address and sufficient data transfer allowance are more important.

If you regularly hold video conferences with many participants at once, available network bandwidth becomes increasingly important. For larger installations, a more powerful VPS, cloud server or dedicated server may be a better choice. For larger deployments, Nextcloud recommends running the TURN server on a separate machine that can be reached directly from the internet.

Use case Suitable server
Personal Nextcloud installation, family, small team, occasional Nextcloud Talk calls Small to medium-sized VPS
Businesses with regular video calls and several simultaneous conversations Powerful VPS or cloud server
Many simultaneous connections and high TURN traffic Large VPS or dedicated server
Large Nextcloud Talk installation with High Performance Backend Separate TURN server or public IP address recommended

Running TURN on its own VPS has another advantage. Nextcloud recommends using port 443 for the widest possible compatibility. If Nextcloud is already running with Apache or NGINX on the same server, TCP port 443 is usually occupied by HTTPS. On a separate TURN server, you can use this port without conflicts.

Note

A TURN server doesn’t replace the Nextcloud Talk High Performance Backend (HPB). TURN mainly solves connection problems caused by NAT and firewalls. The HPB handles signalling and media distribution, among other tasks, for larger Nextcloud Talk installations. For group calls with more than 5 to 10 participants, you may also need the High Performance Backend.

Step 1: Set up a subdomain for the TURN server

First, your TURN server needs its own hostname. Create an A record with your DNS provider, for example:

turn.example.com → 203.0.113.10
text

Here, 203.0.113.10 represents your server’s public IPv4 address. If your server also has a working public IPv6 address, you can create an AAAA record. However, only do this if IPv6 is fully configured and accessible on your TURN server.

After updating your DNS settings, it may take some time for the new record to become available worldwide. You can check the resolution, for example, with dig turn.example.com or nslookup turn.example.com. If you also created an AAAA record, check it with dig AAAA turn.example.com.

The returned IP addresses (IPv4 and IPv6, if applicable) should match your server’s public IP addresses.

Step 2: Connect to the server and update the system

Connect to your TURN server using SSH:

ssh user@turn.example.com
bash

Replace user with your SSH username.

Next, update the package lists and install any available updates:

sudo apt update
sudo apt upgrade -y
bash

This makes sure you’re starting with an up-to-date system.

Step 3: Install coturn

We’ll use coturn as the TURN server software. It’s available as a package for Ubuntu and Debian, so you can install it using the package manager:

sudo apt install coturn -y
bash

Once it’s installed, check which version you have:

dpkg -s coturn | grep Version
bash

Nextcloud’s documentation lists coturn 4.5.0.8 as the absolute minimum. For security reasons, you should use the most up-to-date coturn version available for a new installation.

Note

Installing coturn through apt gives you the package version provided by Ubuntu. On Ubuntu, coturn is provided through the Universe repository, where standard security updates are supplied on a best-effort basis by the community and Debian. However, the package may be significantly older than the latest version from the coturn project itself. That’s why it’s important to check the installed version. If you need a newer version, you can use a suitable PPA, a container image or install coturn manually from the source code. For production systems, only use trusted sources and update coturn regularly.

Also check whether systemd recognises the coturn service:

systemctl status coturn
bash

On current Debian and Ubuntu systems, coturn is managed through a systemd unit.

Step 4: Create a secure TURN secret

Nextcloud Talk and coturn need to share the same secret. They use this secret to generate temporary login credentials for the TURN server. Generate a random secret using openssl rand -hex 32. The output will look something like this:

8c6e8a2a79bd6507e7a5274bc5779ec3a5f6c1f45dbcf420c1a824cd94a25112
text

Copy the generated value and store it securely. You’ll need to enter it later in both the coturn configuration and your Nextcloud Talk settings. Treat it like a secure password and do not use a simple access code for a production server.

Step 5: Set up a TLS certificate for TURN

For the widest possible compatibility, it’s a good idea to run TURN on port 443 and support both regular TURN connections and encrypted turns: connections. This is particularly useful for people on restrictive networks that only allow connections through port 443. To support encrypted turns: connections, coturn needs a TLS certificate. You can get one for free from Let’s Encrypt, for example.

On an Ubuntu server used exclusively for TURN, you can install Certbot through Snap:

sudo snap install --classic certbot
bash

If the certbot command isn’t available afterwards, create the following link:

sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
bash

Before requesting the certificate, open TCP port 80:

sudo ufw allow 80/tcp
bash

Then request the certificate:

sudo certbot certonly --standalone -d turn.example.com
bash

Certbot’s standalone mode temporarily starts a web server to verify that you control the domain. For this verification to work, your server must be accessible from the internet on port 80. Once the certificate has been issued, the certificate and private key are typically stored at:

/etc/letsencrypt/live/turn.example.com/fullchain.pem
/etc/letsencrypt/live/turn.example.com/privkey.pem
text

Certbot normally also sets up automatic certificate renewal. You can check whether renewal works with:

sudo certbot renew --dry-run
bash

Step 6: Make port 443 available to coturn

On Linux, ports below 1024 are known as privileged ports. On current Linux distributions, coturn often runs under a user account without elevated privileges. This means it may not have permission to open port 443. You can solve this using Linux capabilities, which let you give a program specific permissions without granting it full root access. Run the following command to allow coturn to use privileged ports:

sudo setcap cap_net_bind_service=+ep /usr/bin/turnserver
bash

This allows turnserver to open ports such as 443 without giving it full root privileges. Keep in mind that a package update may remove this permission. If coturn suddenly fails to start on port 443 after an update, check whether the capability is still set:

getcap /usr/bin/turnserver
bash

Step 7: Give coturn access to the TLS certificate

For security reasons, the Let’s Encrypt private key can normally only be read by root. However, coturn also needs access to this key to establish encrypted connections. First, check whether the turnserver user exists:

getent passwd turnserver
bash

Next, create a protected directory where coturn can access copies of the certificate and private key:

sudo install -d -m 750 -o root -g turnserver /etc/coturn
bash

Copy the certificate and private key into this directory:

sudo install -m 640 -o root -g turnserver \
/etc/letsencrypt/live/turn.example.com/fullchain.pem \
/etc/coturn/fullchain.pem
sudo install -m 640 -o root -g turnserver \
/etc/letsencrypt/live/turn.example.com/privkey.pem \
/etc/coturn/privkey.pem
bash

If your Linux distribution uses a different user for coturn, replace turnserver with the appropriate username.

When Let’s Encrypt renews your certificate, it updates the original files. However, coturn uses the copies you just created, so these need to be updated too. You’ll also need to restart coturn so it uses the renewed certificate. You can automate both tasks by creating a Certbot deploy hook. First, create the following file:

sudo nano /etc/letsencrypt/renewal-hooks/deploy/coturn.sh
bash

Add this code:

#!/bin/sh

install -m 640 -o root -g turnserver \
/etc/letsencrypt/live/turn.example.com/fullchain.pem \
/etc/coturn/fullchain.pem

install -m 640 -o root -g turnserver \
/etc/letsencrypt/live/turn.example.com/privkey.pem \
/etc/coturn/privkey.pem

systemctl restart coturn
bash

Next, make the script executable:

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/coturn.sh
bash

Now, whenever Let’s Encrypt successfully renews the certificate, the script updates the copies and restarts coturn with the new certificate files.

Step 8: Configure coturn for Nextcloud Talk

On Ubuntu and Debian, the main coturn configuration file is usually located at /etc/turnserver.conf. Before making changes, back up the existing file:

sudo cp /etc/turnserver.conf /etc/turnserver.conf.bak
bash

Then open the configuration file:

sudo nano /etc/turnserver.conf
bash

For a typical Nextcloud Talk installation, you can use the following basic configuration:

listening-port=443

fingerprint
use-auth-secret
static-auth-secret=YOUR_GENERATED_SECRET
realm=turn.example.com

cert=/etc/coturn/fullchain.pem
pkey=/etc/coturn/privkey.pem

stale-nonce
no-multicast-peers

total-quota=0
bps-capacity=0

min-port=49152
max-port=65535
text

Replace YOUR_GENERATED_SECRET with the secret you created in step 4 and turn.example.com with your TURN domain. Here’s what the main settings do:

  • listening-port=443 specifies the port clients use to connect to the TURN server.
  • fingerprint adds a fingerprint to TURN messages.
  • use-auth-secret enables the shared-secret authentication used by Nextcloud Talk.
  • static-auth-secret contains the shared secret.
  • realm specifies the server’s authentication domain.
  • cert and pkey specify the TLS certificate and private key.
  • stale-nonce limits how long authentication nonces remain valid.
  • no-multicast-peers prevents the TURN server from forwarding connections to multicast addresses.
  • min-port and max-port define the range of ports used to relay audio and video data.

By default, coturn uses UDP ports 49152 to 65535 to relay data. With a standard coturn configuration, you also need to open this port range in your firewall. When TLS is enabled in the configuration, coturn can recognise TLS connections on the regular listening port. This means you can offer both turn: and turns: connections through port 443.

Step 9: Prevent access to internal networks through the TURN server

Your TURN server shouldn’t allow someone to access internal services on your server or network by routing traffic through TURN. If the TURN server can access private networks, it’s a good idea to block connections to their IP address ranges. You can do this by adding the following entries to your coturn configuration:

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=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
text

If your TURN server also uses IPv6, you should block internal IPv6 destination addresses as well. For unique local addresses (fc00::/7) and link-local addresses (fe80::/10), add:

denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
text

Also check whether your TURN server can reach any other IPv6 addresses in your own infrastructure. If it can, block those addresses individually where necessary.

Before relying on these restrictions, check your distribution’s security tracker for the installed package. Debian currently lists coturn 4.6.1 in Bookworm and Trixie as vulnerable to CVE-2026-73212, which can allow IPv4 peer restrictions to be bypassed under specific routing conditions.

Note

If your Nextcloud Talk High Performance Backend is located on a private network and needs to be accessible from the TURN server, you shouldn’t simply block its IP address. Instead, you can allow that specific address using allowed-peer-ip or adjust the network rules to suit your setup.

Step 10: Specify the public IP address when using NAT

A VPS often has a public IP address assigned directly to it. This makes coturn easier to configure. However, if the server is behind NAT, coturn needs to know which public address corresponds to its internal IP address. For a simple setup, you can add the following setting: external-ip=203.0.113.10. If you need to explicitly map the public IP address to a private one, you can use: external-ip=203.0.113.10/10.0.0.10.

The first address is the public IP address, and the second is the internal IP one. coturn uses this information to give clients the correct public address for relaying audio and video data. The NAT device must also forward the relevant ports to your TURN server without changing the port numbers. Only configure external-ip when you need it. If you enter the wrong address, the TURN server may appear accessible even though audio and video data can’t be relayed properly.

Step 11: Configure the firewall

Next, you need to open the ports that coturn uses. Before making changes, make sure SSH access is allowed so you can still connect to your server:

sudo ufw allow OpenSSH
bash

Then open port 443 for TURN connections over both TCP and UDP:

sudo ufw allow 443/tcp
sudo ufw allow 443/udp
bash

You’ll also need to open the UDP port range that coturn uses to relay audio and video data:

sudo ufw allow 49152:65535/udp
bash

If you’re using Certbot with HTTP-01 validation, keep TCP port 80 accessible so your certificate can be renewed:

sudo ufw allow 80/tcp
bash

If UFW isn’t already enabled, check its status:

sudo ufw status
bash

Only enable the firewall once you’ve confirmed that SSH access is allowed:

sudo ufw enable
bash

If your hosting provider also uses an external cloud firewall, you’ll need to open the same ports there. Opening them in UFW alone won’t be enough if the external firewall is still blocking traffic.

Step 12: Start coturn

Now restart coturn using sudo systemctl restart coturn. To make sure the service starts automatically whenever your server reboots, also run sudo systemctl enable coturn.

Next, check whether coturn is running:

sudo systemctl status coturn --no-pager
bash

If the output shows active (running) the TURN service is running. Also check whether coturn has opened port 443:

sudo ss -lntup | grep ':443'
bash

You should see entries for turnserver.

Step 13: Add the TURN server to Nextcloud Talk

Once your TURN server is running, you need to configure Nextcloud Talk to use it. Log in to your Nextcloud instance as an administrator and open Administration settings. Then go to the Talk section and enter the following TURN server address:

turn.example.com:443
text

Make sure you don’t add https://, turn: or turns: before the address. Nextcloud only expects the hostname and port in this field. You select the TURN connection type separately. In the TURN secret field, enter exactly the same secret you previously added to /etc/turnserver.conf under static-auth-secret=. Also select:

  • UDP and TCP
  • the option that supports both turn: and turns:

Step 14: Test the TURN server

Even if coturn is running, that doesn’t necessarily mean your TURN server is accessible from the internet or that Nextcloud Talk can use it. That’s why it’s important to test the setup.

If possible, run the test from another computer using a different internet connection rather than on the TURN server itself. On an Ubuntu computer, first install the coturn tools:

sudo apt install coturn
bash

You can then test your TURN server using the tool recommended in Nextcloud’s documentation:

turnutils_uclient -p 443 -W YOUR_GENERATED_SECRET -v -y turn.example.com
turnutils_uclient -t -p 443 -W YOUR_GENERATED_SECRET -v -y turn.example.com
turnutils_uclient -t -S -p 443 -W YOUR_GENERATED_SECRET -v -y turn.example.com
bash

Replace YOUR_GENERATED_SECRET with the secret you created in step 4.

A successful test confirms that your TURN server can be reached from outside your network. However, it doesn’t yet prove that Nextcloud Talk can actually use it for audio and video calls. To check this, you can force Nextcloud Talk to send all audio and video data through TURN rather than connecting participants directly. First, join a Nextcloud Talk call. Then open your browser’s developer console and run the following command:

OCA.Talk.SimpleWebRTC.webrtc.config.peerConnectionConfig.iceTransportPolicy = 'relay'
javascript

Leave the call and join again. If the audio and video still work, Nextcloud Talk can use your TURN server to relay the call. If possible, carry out this test with two devices connected to different networks.

How does a dedicated TURN server make Nextcloud Talk more reliable?

Nextcloud Talk can handle many calls without its own TURN server. However, if participants regularly join from different networks, use cellular connections or connect from behind corporate firewalls or complex NAT configurations, running your own TURN server makes calls significantly more reliable.

For small and medium-sized installations, a separate VPS is often the best choice. You can manage it independently of your Nextcloud installation and run coturn on port 443, as Nextcloud recommends. For larger installations with many calls happening at once, make sure you have enough network bandwidth. In these cases, a more powerful VPS or dedicated server may be a better option.

Go to Main Menu