Nextcloud Talk lets you make audio and video calls directly within Nextcloud. Calls often work without ad­di­tion­al setup when par­tic­i­pants are on the same local network or can connect directly over the internet. However, re­stric­tive firewalls, corporate networks or certain NAT con­fig­u­ra­tions can prevent these direct con­nec­tions. That’s where a TURN server comes in.

What is a Nextcloud TURN server?

A TURN server acts as an in­ter­me­di­ary: relaying audio and video data between par­tic­i­pants instead of sending it directly between them. Nextcloud Talk first tries to establish a direct peer-to-peer con­nec­tion. 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 rec­om­mend­ed to help ensure Nextcloud Talk calls work reliably, es­pe­cial­ly when par­tic­i­pants 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 in­stal­la­tion with the Nextcloud Talk app enabled. Nextcloud Talk requires HTTPS for WebRTC, so your Nextcloud instance should already be ac­ces­si­ble using a valid TLS cer­tifi­cate. Shared hosting has lim­i­ta­tions for larger Talk in­stal­la­tions because audio and video calls put ad­di­tion­al 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 con­tin­u­ous­ly.

For this setup, you’ll need:

  • a Nextcloud in­stal­la­tion with Nextcloud Talk enabled,
  • ad­min­is­tra­tor access to Nextcloud,
  • a Linux server where you can install software,
  • SSH access with sudo or root priv­i­leges,
  • 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.

VPS Hosting (Virtual Private Servers)
More scale, same world-class pricing — with the new VPS+
  • NEW: VM cloning, load balancing, block storage, and more
  • Ideal for agentic AI, LLMs, and au­toma­tion at scale
  • Free 24/7 expert support and 99.99%+ uptime
  • Unlimited traffic and no setup fees

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

When choosing a TURN server, pro­cess­ing power isn’t the only thing that matters. The network con­nec­tion is es­pe­cial­ly important because TURN relays audio and video data between call par­tic­i­pants. 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 in­stal­la­tions, small busi­ness­es and teams where only a few people will be using Talk for calls at the same time. If the VPS is used ex­clu­sive­ly 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 con­nec­tion, a public IP address and suf­fi­cient data transfer allowance are more important.

If you regularly hold video con­fer­ences with many par­tic­i­pants at once, available network bandwidth becomes in­creas­ing­ly important. For larger in­stal­la­tions, a more powerful VPS, cloud server or dedicated server may be a better choice. For larger de­ploy­ments, Nextcloud rec­om­mends running the TURN server on a separate machine that can be reached directly from the internet.

Use case Suitable server
Personal Nextcloud in­stal­la­tion, family, small team, oc­ca­sion­al Nextcloud Talk calls Small to medium-sized VPS
Busi­ness­es with regular video calls and several si­mul­ta­ne­ous con­ver­sa­tions Powerful VPS or cloud server
Many si­mul­ta­ne­ous con­nec­tions and high TURN traffic Large VPS or dedicated server
Large Nextcloud Talk in­stal­la­tion with High Per­for­mance Backend Separate TURN server or public IP address rec­om­mend­ed

Running TURN on its own VPS has another advantage. Nextcloud rec­om­mends using port 443 for the widest possible com­pat­i­bil­i­ty. 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 Per­for­mance Backend (HPB). TURN mainly solves con­nec­tion problems caused by NAT and firewalls. The HPB handles signaling and media dis­tri­b­u­tion, among other tasks, for larger Nextcloud Talk in­stal­la­tions. For group calls with more than 5 to 10 par­tic­i­pants, you may also need the High Per­for­mance 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 rep­re­sents 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 con­fig­ured and ac­ces­si­ble 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 res­o­lu­tion, 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 ap­plic­a­ble) 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 doc­u­men­ta­tion 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 in­stal­la­tion.

Note

In­stalling coturn through apt gives you the package version provided by Ubuntu. On Ubuntu, coturn is provided through the Universe repos­i­to­ry, where standard security updates are supplied on a best-effort basis by the community and Debian. However, the package may be sig­nif­i­cant­ly 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 pro­duc­tion systems, only use trusted sources and update coturn regularly.

Also check whether systemd rec­og­nizes 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 cre­den­tials 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 con­fig­u­ra­tion and your Nextcloud Talk settings. Treat it like a secure password and do not use a simple access code for a pro­duc­tion server.

Step 5: Set up a TLS cer­tifi­cate for TURN

For the widest possible com­pat­i­bil­i­ty, it’s a good idea to run TURN on port 443 and support both regular TURN con­nec­tions and encrypted turns: con­nec­tions. This is par­tic­u­lar­ly useful for people on re­stric­tive networks that only allow con­nec­tions through port 443. To support encrypted turns: con­nec­tions, coturn needs a TLS cer­tifi­cate. You can get one for free from Let’s Encrypt, for example.

On an Ubuntu server used ex­clu­sive­ly for TURN, you can install Certbot through Snap:

sudo snap install --classic certbot
bash

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

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

Before re­quest­ing the cer­tifi­cate, open TCP port 80:

sudo ufw allow 80/tcp
bash

Then request the cer­tifi­cate:

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

Certbot’s stand­alone mode tem­porar­i­ly starts a web server to verify that you control the domain. For this ver­i­fi­ca­tion to work, your server must be ac­ces­si­ble from the internet on port 80. Once the cer­tifi­cate has been issued, the cer­tifi­cate 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 cer­tifi­cate 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 priv­i­leged ports. On current Linux dis­tri­b­u­tions, coturn often runs under a user account without elevated priv­i­leges. This means it may not have per­mis­sion to open port 443. You can solve this using Linux ca­pa­bil­i­ties, which let you give a program specific per­mis­sions without granting it full root access. Run the following command to allow coturn to use priv­i­leged 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 priv­i­leges. Keep in mind that a package update may remove this per­mis­sion. If coturn suddenly fails to start on port 443 after an update, check whether the ca­pa­bil­i­ty is still set:

getcap /usr/bin/turnserver
bash

Step 7: Give coturn access to the TLS cer­tifi­cate

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 con­nec­tions. First, check whether the turnserver user exists:

getent passwd turnserver
bash

Next, create a protected directory where coturn can access copies of the cer­tifi­cate and private key:

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

Copy the cer­tifi­cate 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 dis­tri­b­u­tion uses a different user for coturn, replace turnserver with the ap­pro­pri­ate username.

When Let’s Encrypt renews your cer­tifi­cate, 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 cer­tifi­cate. 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 ex­e­cutable:

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

Now, whenever Let’s Encrypt suc­cess­ful­ly renews the cer­tifi­cate, the script updates the copies and restarts coturn with the new cer­tifi­cate files.

Step 8: Configure coturn for Nextcloud Talk

On Ubuntu and Debian, the main coturn con­fig­u­ra­tion 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 con­fig­u­ra­tion file:

sudo nano /etc/turnserver.conf
bash

For a typical Nextcloud Talk in­stal­la­tion, you can use the following basic con­fig­u­ra­tion:

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 fin­ger­print to TURN messages.
  • use-auth-secret enables the shared-secret au­then­ti­ca­tion used by Nextcloud Talk.
  • static-auth-secret contains the shared secret.
  • realm specifies the server’s au­then­ti­ca­tion domain.
  • cert and pkey specify the TLS cer­tifi­cate and private key.
  • stale-nonce limits how long au­then­ti­ca­tion nonces remain valid.
  • no-multicast-peers prevents the TURN server from for­ward­ing con­nec­tions 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 con­fig­u­ra­tion, you also need to open this port range in your firewall. When TLS is enabled in the con­fig­u­ra­tion, coturn can recognize TLS con­nec­tions on the regular listening port. This means you can offer both turn: and turns: con­nec­tions 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 con­nec­tions to their IP address ranges. You can do this by adding the following entries to your coturn con­fig­u­ra­tion:

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 des­ti­na­tion 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 in­fra­struc­ture. If it can, block those addresses in­di­vid­u­al­ly where necessary.

Before relying on these re­stric­tions, check your dis­tri­b­u­tion’s security tracker for the installed package. Debian currently lists coturn 4.6.1 in Bookworm and Trixie as vul­ner­a­ble to CVE-2026-73212, which can allow IPv4 peer re­stric­tions to be bypassed under specific routing con­di­tions.

Note

If your Nextcloud Talk High Per­for­mance Backend is located on a private network and needs to be ac­ces­si­ble 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 cor­re­sponds 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 ex­plic­it­ly 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 in­for­ma­tion 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 ac­ces­si­ble 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 con­nec­tions 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 val­i­da­tion, keep TCP port 80 ac­ces­si­ble so your cer­tifi­cate 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 au­to­mat­i­cal­ly 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 ad­min­is­tra­tor and open Ad­min­is­tra­tion 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 con­nec­tion type sep­a­rate­ly. In the TURN secret field, enter exactly the same secret you pre­vi­ous­ly 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 nec­es­sar­i­ly mean your TURN server is ac­ces­si­ble 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 con­nec­tion 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 rec­om­mend­ed in Nextcloud’s doc­u­men­ta­tion:

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 suc­cess­ful 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 con­nect­ing par­tic­i­pants 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 par­tic­i­pants regularly join from different networks, use cellular con­nec­tions or connect from behind corporate firewalls or complex NAT con­fig­u­ra­tions, running your own TURN server makes calls sig­nif­i­cant­ly more reliable.

For small and medium-sized in­stal­la­tions, a separate VPS is often the best choice. You can manage it in­de­pen­dent­ly of your Nextcloud in­stal­la­tion and run coturn on port 443, as Nextcloud rec­om­mends. For larger in­stal­la­tions 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.

Reviewer

Go to Main Menu