Setting Up a Coturn TURN Server: Complete Installation Guide

Coturn is the most popular open-source implementation of STUN and TURN servers, used by countless WebRTC applications worldwide. In this guide, we'll walk through installing, configuring, and securing a Coturn server for production use.

Why Coturn?

Coturn listening ports and firewall requirements A WebRTC client reaches coturn on 3478 (UDP and TCP) for STUN and TURN, and on 5349 (TCP) for TURN over TLS. Coturn allocates relay ports in the 49152 to 65535 UDP range. Every one of these must be open in the firewall. WebRTC client browser / app coturn server 3478 /udp,tcp — STUN & TURN 5349 /tcp — TURN over TLS 49152–65535 /udp — relay all must be open in the firewall
Figure 1 — The ports coturn listens on. The wide relay range (49152–65535/UDP) is the one most often forgotten in firewall rules — and the reason TURN "authenticates but never relays".

Coturn stands out as the preferred TURN/STUN server implementation for several reasons:

  • Feature Complete: Supports TURN, STUN, STUN over TLS (STUNS), and TURN over TLS (TURNS), providing comprehensive NAT traversal capabilities.
  • High Performance: Efficiently handles thousands of concurrent connections with minimal resource usage.
  • Active Development: Regularly updated with security patches and feature improvements.
  • Production Ready: Trusted by major organizations and used in countless production deployments.
  • Extensive Documentation: Well-documented with clear configuration examples and troubleshooting guides.

Prerequisites

Before installing Coturn, ensure you have:

  • A Linux server (Ubuntu 20.04+ or similar) with root access.
  • A public IP address.
  • Open ports: 3478 (STUN/TURN), 5349 (TURNS), 49152-65535 (relay ports).
  • An SSL certificate for TURNS (Let's Encrypt recommended).
  • At least 2GB RAM and 2 CPU cores for moderate usage.

Installation Methods

Method 1: Package Manager Installation (Recommended)

On Ubuntu/Debian:

sudo apt update
sudo apt install coturn

On CentOS/RHEL:

sudo yum install coturn

Method 2: Building from Source

For the latest features or custom configurations:

# Install dependencies
sudo apt install build-essential git libssl-dev libevent-dev

# Clone repository
git clone https://github.com/coturn/coturn.git
cd coturn

# Build and install
./configure
make
sudo make install

Basic Configuration

Coturn's main configuration file is typically located at /etc/turnserver.conf. Here's a basic configuration to get started:

# Basic TURN server configuration

# Listening port for TURN/STUN
listening-port=3478

# TLS listening port for TURNS
tls-listening-port=5349

# External IP address (your server's public IP)
external-ip=YOUR_PUBLIC_IP

# Internal IP (usually same as external unless behind NAT)
# relay-ip=YOUR_INTERNAL_IP

# Realm (usually your domain)
realm=yourdomain.com

# Path to SSL certificate for TURNS
cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem

# Enable long-term credential mechanism
lt-cred-mech

# Create a user account
user=username:password

# Relay port range
min-port=49152
max-port=65535

# Enable verbose logging (disable in production)
verbose

# Log file location
log-file=/var/log/turnserver.log

# Disable TLS 1.0 and 1.1 (security)
no-tlsv1
no-tlsv1_1

Generating SSL Certificates

For TURNS functionality, you need SSL certificates. Let's Encrypt provides free certificates:

# Install certbot
sudo apt install certbot

# Generate certificate
sudo certbot certonly --standalone -d turn.yourdomain.com

# Certificates will be in:
# /etc/letsencrypt/live/turn.yourdomain.com/

Set up automatic renewal:

# Add to crontab
sudo crontab -e

# Add this line to renew certificates monthly
0 0 1 * * certbot renew --quiet

Authentication Configuration

Coturn supports multiple authentication methods:

Static Long-term Credentials

Simple but less secure, suitable for testing:

lt-cred-mech
user=testuser:testpassword

Database-backed Authentication

For larger deployments, store credentials in a database:

# PostgreSQL example
lt-cred-mech
psql-userdb="host=localhost dbname=turndb user=turn password=turnpass"

REST API Authentication

For dynamic credential generation:

use-auth-secret
static-auth-secret=your-secret-key

Generate credentials in your application:

const crypto = require('crypto');

function getTurnCredentials(name, secret) {
  const unixTimeStamp = Math.floor(Date.now() / 1000) + 24 * 3600; // 24 hours validity
  const username = `${unixTimeStamp}:${name}`;
  const hmac = crypto.createHmac('sha1', secret);
  hmac.setEncoding('base64');
  hmac.write(username);
  hmac.end();
  const password = hmac.read();

  return {
    username: username,
    password: password,
    ttl: 86400
  };
}

Security Hardening

Secure your Coturn server with these configurations:

Restrict Access

# Only allow specific IP ranges
allowed-peer-ip=10.0.0.0-10.255.255.255
allowed-peer-ip=192.168.0.0-192.168.255.255

# Deny specific IPs
denied-peer-ip=0.0.0.0-0.255.255.255

Enable Authentication

# Require authentication for all TURN requests
lt-cred-mech

# Disable anonymous access
no-auth

Rate Limiting

# Limit maximum number of sessions per user
max-bps=1000000

# Total allocation quota
user-quota=12

# Per-user quota
total-quota=1200

Firewall Configuration

# UFW example
sudo ufw allow 3478/tcp
sudo ufw allow 3478/udp
sudo ufw allow 5349/tcp
sudo ufw allow 49152:65535/udp
sudo ufw enable

Starting the Server

Enable and Start Coturn

# Enable Coturn to start on boot
sudo systemctl enable coturn

# Start the service
sudo systemctl start coturn

# Check status
sudo systemctl status coturn

Verify It's Running

# Check if port is listening
sudo netstat -tuln | grep 3478

# Check logs
sudo tail -f /var/log/turnserver.log

Testing Your Server

Using turnutils_uclient

Coturn includes testing utilities:

# Test TURN functionality
turnutils_uclient -v -t -u username -w password turn_server_ip

# Test STUN functionality
turnutils_stunclient turn_server_ip

Using WebRTC Test Pages

Test from a browser using online tools such as our free ICE Server Tester.

Configure your test with:

{
  urls: 'turn:turn.yourdomain.com:3478',
  username: 'username',
  credential: 'password'
}

Monitoring and Maintenance

Log Management

# Rotate logs to prevent disk space issues
# Add to /etc/logrotate.d/coturn

/var/log/turnserver.log {
    daily
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 root root
    sharedscripts
    postrotate
        systemctl reload coturn
    endscript
}

Performance Monitoring

Monitor key metrics:

  • Active allocations
  • Bandwidth usage
  • CPU and memory utilization
  • Failed authentication attempts
# View active sessions
sudo turnutils_uclient -L turn_server_ip

# Check resource usage
sudo top -p $(pgrep turnserver)

Database Maintenance

If using database authentication:

# Regular cleanup of expired sessions
# Add to crontab
0 2 * * * psql -d turndb -c "DELETE FROM turnusers_lt WHERE expiration < NOW();"

Advanced Configuration

Load Balancing

For high-traffic deployments, use multiple Coturn servers:

// Client configuration
const config = {
  iceServers: [
    {
      urls: [
        'turn:turn1.yourdomain.com:3478',
        'turn:turn2.yourdomain.com:3478',
        'turn:turn3.yourdomain.com:3478'
      ],
      username: 'user',
      credential: 'pass'
    }
  ]
};

Geographic Distribution

Deploy Coturn servers in multiple regions:

// Route users to nearest server
function getNearestTurnServer(userLocation) {
  const servers = {
    'us-east': 'turn:us-east.yourdomain.com',
    'eu-west': 'turn:eu-west.yourdomain.com',
    'ap-south': 'turn:ap-south.yourdomain.com'
  };

  return servers[userLocation] || servers['us-east'];
}

Bandwidth Optimization

# Limit bandwidth per user
max-bps=1000000  # 1 Mbps

# Set different limits for video/audio
bps-capacity=0

Common Issues and Solutions

Port Already in Use

# Check what's using the port
sudo lsof -i :3478

# Kill the process if necessary
sudo kill -9 <PID>

Certificate Errors

# Verify certificate paths
ls -l /etc/letsencrypt/live/yourdomain.com/

# Check certificate expiration
openssl x509 -in /path/to/cert.pem -text -noout

Connection Failures

# Check firewall
sudo ufw status

# Verify external IP configuration
curl ifconfig.me

High CPU Usage

# Limit concurrent allocations
total-quota=1000

# Adjust relay port range
min-port=49152
max-port=50152  # Smaller range

Performance Tuning

Kernel Parameters

Optimize the Linux kernel for high connection counts:

# Add to /etc/sysctl.conf
net.core.rmem_max=26214400
net.core.rmem_default=26214400
net.ipv4.udp_rmem_min=8192
net.ipv4.udp_wmem_min=8192
fs.file-max=2097152

# Apply changes
sudo sysctl -p

Coturn Tuning

# Increase worker threads
max-allocate-lifetime=3600

# Optimize for UDP
no-tcp-relay

# Disable unnecessary features if not needed
no-cli
no-dtls

Backup and Recovery

# Backup configuration
sudo cp /etc/turnserver.conf /backup/turnserver.conf.backup

# Backup certificates
sudo tar -czf /backup/certs-backup.tar.gz /etc/letsencrypt/

# Document your server settings

Conclusion

Setting up a Coturn server provides essential infrastructure for WebRTC applications, ensuring connectivity even in restrictive network environments. While the initial setup requires careful configuration, properly deployed Coturn servers are reliable and require minimal maintenance.

Follow the security best practices outlined here, monitor your server regularly, and test thoroughly before deploying to production. With a well-configured Coturn server, you'll ensure your WebRTC applications can establish connections reliably for all users.

Check Your Own Servers

Once your turnserver.conf is live, confirm it actually relays traffic and hands back relay candidates. Point the tester at your turn: and turns: URLs with your credentials to verify the deployment end to end.

Open the Free ICE Server Tester →