Skip to main content
Sandro Gauci

Sandro Gauci, Enable Security

Securing coturn: Configuration Guide

Published on Feb 25, 2026 · Updated on Jun 26, 2026 in , , ,

TL;DR

coturn is the most widely deployed TURN server, and also the one we’ve found the most vulnerabilities in. This guide gives you copy-paste configuration blocks to lock it down: access control rules, protocol hardening, rate limiting, authentication, and three complete templates from minimal to high-security. All examples target coturn 4.6.x and later, with version-specific notes where the configuration changed (particularly 4.7.0 which flipped TLS defaults). coturn shipped a steady run of security fixes through 4.10.0 to 4.14.0 in 2026, so run the latest release if you can: several of these CVEs lived in the management interfaces, and the newer versions also tightened the secure-by-default behavior.

About this guide

This is the coturn-specific companion to our TURN Server Security Best Practices. That guide covers the why behind each security control. This guide covers the how for coturn specifically: copy-paste configuration blocks, complete templates, and version-specific notes.

If you’re running a version older than 4.6.x, some parameters may differ or not be available.

Quick start: a minimal secure config

All configuration templates in this guide are available in our coturn-secure-config repository, which includes a Docker environment for testing them against a live coturn instance.

If you just want a working secure config to get started, save the following as /etc/turnserver.conf:

# Minimal Secure coturn Configuration (4.6.0+)
# Save as: /etc/turnserver.conf

# Listening configuration
listening-port=3478
tls-listening-port=5349

# Authentication
lt-cred-mech
use-auth-secret
static-auth-secret=CHANGE_THIS_SECRET
realm=turn.example.com

# Access control - block internal ranges
no-multicast-peers
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=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.168.0.0-192.168.255.255
denied-peer-ip=::1
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff

# Protocol hardening / amplification reduction
no-rfc5780
no-software-attribute

# coturn 4.14.0+ only: reduce UDP 401 reflection
# unauthorized-ratelimit
# unauthorized-ratelimit-rps=10

# Rate limiting - tune these to your expected usage
user-quota=100
total-quota=10000
max-allocate-lifetime=3600

# Logging
log-file=/var/log/coturn/turnserver.log
syslog

For production, set external-ip to your server’s public IP (required for NAT traversal) and listening-ip/relay-ip to bind to a specific interface.

This covers the basics. Read on for the complete access control configuration, protocol hardening, and high-security templates.

Access control: blocking internal IP ranges

Relay abuse is the #1 threat to TURN servers. Without access controls, an attacker with valid credentials can use your TURN server to reach internal networks, localhost services, and cloud metadata endpoints. For the full rationale, see the access control section of our best practices guide.

Deny-listing non-public peer addresses

# Block multicast addresses
no-multicast-peers

# IPv4: Block special-purpose address ranges
# Current network - prevents 0.0.0.0 bypass (CVE-2020-26262)
denied-peer-ip=0.0.0.0-0.255.255.255

# Private networks (RFC1918)
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.168.0.0-192.168.255.255

# Loopback - prevents localhost access
denied-peer-ip=127.0.0.0-127.255.255.255

# Link-local - prevents AWS metadata and similar services
denied-peer-ip=169.254.0.0-169.254.255.255

# Shared address space (RFC6598)
denied-peer-ip=100.64.0.0-100.127.255.255

# IETF Protocol Assignments
denied-peer-ip=192.0.0.0-192.0.0.255

# Documentation/TEST-NET ranges
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255

# IPv6 to IPv4 relay (deprecated)
denied-peer-ip=192.88.99.0-192.88.99.255

# AS112-v4 DNS infrastructure anycast (RFC7535)
denied-peer-ip=192.31.196.0-192.31.196.255

# AMT multicast tunneling anycast (RFC7450)
denied-peer-ip=192.52.193.0-192.52.193.255

# AS112 DNS infrastructure anycast (RFC7534)
denied-peer-ip=192.175.48.0-192.175.48.255

# Benchmark testing
denied-peer-ip=198.18.0.0-198.19.255.255

# Multicast (RFC5771) - also covered by no-multicast-peers above
denied-peer-ip=224.0.0.0-239.255.255.255

# Reserved/future use (includes broadcast)
denied-peer-ip=240.0.0.0-255.255.255.255

# IPv6: Block special-purpose address ranges
# Loopback
denied-peer-ip=::1

# IPv4-mapped IPv6 addresses (prevents CVE-2026-27624 bypass)
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255

# NAT64 well-known prefix (RFC6052)
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff

# Local-use NAT64 (RFC8215)
denied-peer-ip=64:ff9b:1::-64:ff9b:1:ffff:ffff:ffff:ffff:ffff

# Discard prefix (RFC6666)
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff

# Dummy IPv6 prefix (RFC9780)
denied-peer-ip=100::1:0:0:0:0-100::1:ffff:ffff:ffff:ffff

# IETF Protocol Assignments (includes Teredo)
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff

# Documentation range (RFC3849)
denied-peer-ip=2001:db8::-2001:db8:ffff:ffff:ffff:ffff:ffff:ffff

# 6to4 (deprecated)
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff

# AS112 DNS infrastructure anycast (RFC7534)
denied-peer-ip=2620:4f:8000::-2620:4f:8000:ffff:ffff:ffff:ffff:ffff

# Documentation range (RFC9637)
denied-peer-ip=3fff::-3fff:fff:ffff:ffff:ffff:ffff:ffff:ffff

# SRv6 SID block (RFC9602)
denied-peer-ip=5f00::-5f00:ffff:ffff:ffff:ffff:ffff:ffff:ffff

# Unique local addresses (ULA)
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff

# Link-local
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff

Allow-listing specific media servers

If peer-to-peer media is not needed, the most restrictive approach is to allow-list only your media server IPs. This is what Zoom did to address C2 operation abuse through their TURN servers.

# Allow relay only to specific media server IPs
allowed-peer-ip=203.0.113.10
allowed-peer-ip=203.0.113.11
allowed-peer-ip=2001:db8::1

# Deny everything else (required - allowed-peer-ip doesn't implicitly deny)
denied-peer-ip=0.0.0.0-255.255.255.255
denied-peer-ip=::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff

Protocol hardening

Disabling unnecessary features

Each protocol feature you leave enabled expands your attack surface. For the security rationale, see the protocol hardening section of our best practices guide.

# Disable STUN CHANGE_REQUEST (RFC5780 NAT behavior discovery)
# This feature is rarely needed and expands attack surface
no-rfc5780

# Disable TURN relay entirely - only serve STUN
# Use this if you don't need relay functionality at all
# stun-only

# Disable STUN, keep only TURN relay
# no-stun

# Disable DTLS if not using encrypted TURN connections
# Only disable if your deployment uses TLS or doesn't need encryption
# no-dtls

Disabling UDP listening

Disabling UDP listening forces clients to connect to the TURN server over TCP or TLS. The server still relays media over UDP to peers, so the relay leg is unaffected. However, the client-to-server leg over TCP can introduce latency under lossy network conditions due to retransmissions and head-of-line blocking. This eliminates the primary DDoS amplification vector since TCP’s three-way handshake makes source IP spoofing impractical.

# Disable UDP listening - clients must connect via TCP/TLS
# Media is still relayed over UDP between TURN server and peers
no-udp

# Listen on TCP only
listening-port=3478
tls-listening-port=5349

Disabling TCP relay

TCP relay (RFC 6062) allows establishing raw TCP connections through the TURN server. If you only support UDP media (typical for WebRTC), disabling it reduces the attack surface for relay abuse.

# Disable TCP relay functionality (RFC 6062)
# Clients can still connect to TURN server over TCP,
# but cannot relay TCP connections to peers
no-tcp-relay

Requiring authentication for STUN Binding

By default, coturn allows unauthenticated STUN Binding requests. This is needed for ICE connectivity checks in standard WebRTC, but in closed deployments where all clients use TURN allocations, you can require authentication for STUN too:

# Require authentication for STUN Binding requests
# WARNING: Breaks standard ICE connectivity checks
secure-stun

Mitigating amplification and reflection attacks

As we cover in our threats analysis, attackers abuse TURN servers for DDoS amplification by sending unauthenticated requests (Allocate Requests, STUN Binding Requests) with spoofed source IPs. The server responds with larger error messages, giving roughly 4x amplification directed at the victim.

For a long time coturn didn’t have great configuration knobs for this. You can’t tell it “don’t respond to unauthenticated requests” because ICE connectivity checks rely on unauthenticated STUN. That changed in coturn 4.14.0, which added a per-source rate limit on exactly these 401 Unauthorized responses:

# Cap UDP 401 Unauthorized responses per source IP (coturn 4.14.0+)
# An attacker spoofs the victim's source IP to bounce 401 challenges
# (which carry ERROR-CODE, REALM and NONCE, plus SOFTWARE if the
# software attribute is enabled) off your server. Past the cap, coturn
# stays silent for that source, denying both the reflection and the
# amplification.
# Off by default - you have to opt in.
unauthorized-ratelimit
unauthorized-ratelimit-rps=10

A few things worth knowing about this one. It only applies to UDP, since TCP and TLS can’t be spoofed for reflection (the handshake forces a real return path), so those are never rate-limited. It’s consume-on-401, meaning only requests that actually produce a 401 spend a token, so your legitimate authenticated clients aren’t affected. The default cap is 10 responses per source IP per second. Do keep in mind that this is a recent addition and is marked experimental, so test it in your environment before relying on it.

If you’re on an older version, the knobs are more limited. Disabling UDP listening entirely (no-udp, covered above) eliminates the vector but adds latency on the client-to-server leg (media relay to peers still uses UDP). Beyond that, what helps is trimming the size of the responses:

# Disable RFC5780 - reduces unauthenticated response surface
# This is the default since coturn 4.7.0, but set it explicitly
# if you're running an older version
no-rfc5780

# Don't advertise server version in responses
# (marginally reduces response size)
# On coturn 4.7.0+, the software attribute is already off by default.
# On 4.6.x, use no-software-attribute to disable it.
no-software-attribute

You can also reduce amplification by using a short realm value. The realm is included in every 401 Unauthorized response, so a shorter realm means smaller responses. For WebRTC use cases, the realm value doesn’t serve a functional purpose beyond credential scoping, so something short like t works fine:

# Short realm reduces 401 response size (amplification mitigation)
realm=t

The real mitigations for amplification are at the network level, not in coturn config. See the rate limiting section of our best practices guide for UDP rate limiting with iptables/nftables, BCP38, and DDoS mitigation services.

Dangerous options: never enable in production

coturn has a few configuration options that are outright dangerous for production use. If you see any of these in your config, remove them.

# DANGEROUS: Disables all authentication. Anyone can use your TURN server.
# no-auth

# DANGEROUS: Allows relay to loopback addresses (127.x.x.x, ::1).
# allow-loopback-peers

# DANGEROUS: NON-STANDARD server relay mode.
# coturn's own source code warns: "NON-STANDARD AND DANGEROUS OPTION"
# server-relay

Web admin and CLI interfaces

coturn ships with a CLI telnet interface and an HTTPS web admin panel. Both have had security issues and should be handled with care.

CLI interface

The CLI is a telnet-based management interface. We recommend disabling it entirely unless you have a specific need for it:

# Disable CLI (recommended)
no-cli

If you do need the CLI, at minimum bind it to localhost and set a strong password:

# If CLI is required, restrict access
cli-ip=127.0.0.1
cli-port=5766
cli-password=YOUR_STRONG_CLI_PASSWORD

There’s another reason to be careful here. CVE-2026-53449 (CVSS 6.5, fixed in coturn 4.13.0) showed that the CLI’s psd (print sessions dump) command passed its filename argument straight to fopen(path, "w") with no validation, so an authenticated CLI admin could overwrite any file the coturn process can write. The CLI is disabled by default, binds to localhost by default, and coturn refuses to enable it with an empty CLI password, which limits the blast radius, but it’s one more argument for no-cli unless you genuinely need it.

Web admin panel

The web admin panel has had a serious authentication bypass bug: from around 2019 until the fix in coturn 4.9.0, the password check was inverted so that any wrong password was accepted. And it didn’t stop there. Two more issues surfaced in 2026, both requiring admin access to the panel (which is disabled by default):

  • CVE-2026-43915 (CVSS 5.4, fixed in 4.11.0): a stored XSS. coturn’s is_secure_string() filter blocks quotes and spaces but not <, >, and &, so a TURN username like <script>...</script> was stored and then rendered unescaped in the session list, executing when an admin viewed it. In --no-auth deployments, an attacker doesn’t even need credentials to plant the payload.
  • CVE-2026-53448 (CVSS 7.2, fixed in 4.12.0): SQL injection in the panel’s delete-user, delete-secret, and delete-IP operations, which interpolated HTTP parameters straight into SQL. On a PostgreSQL backend this reaches stacked queries and even OS command execution via COPY ... TO PROGRAM.

The pattern here is clear: the management interfaces are where coturn’s bugs tend to live. We recommend not enabling the web admin panel at all. If you need it, make sure you’re on the latest version and bind it to a management network:

# Only enable on the latest version and bind to management network
# web-admin
# web-admin-ip=127.0.0.1
# web-admin-port=8080

Rate limiting

Rate limiting protects against resource exhaustion, log flooding, and abuse. For the full rationale, see the rate limiting section of our best practices guide.

coturn’s rate limiting parameters all default to 0 (unlimited). The right values depend entirely on your deployment: how many concurrent users you expect, what bandwidth your server has, and what your media profiles look like. There’s no universal “secure” number we can give you here.

What we can tell you is what knobs are available:

# Per-user allocation limit (default: 0 = unlimited)
# How many simultaneous TURN allocations a single user can hold
user-quota=0

# Total server-wide allocation limit (default: 0 = unlimited)
total-quota=0

# Limit allocation lifetime (default: 3600s)
# Shorter lifetimes mean abandoned allocations get cleaned up faster
max-allocate-lifetime=3600

# Per-session bandwidth limit in bytes/sec (default: 0 = unlimited)
# Prevents a single session from consuming all server bandwidth
max-bps=0

# Total server-wide bandwidth capacity in bytes/sec (default: 0 = unlimited)
bps-capacity=0

# Channel and permission lifetimes (defaults: 600s and 300s)
# These are RFC defaults. Shorter values reduce the abuse window
# for established sessions but increase refresh traffic.
# channel-lifetime=600
# permission-lifetime=300

# Enable logging for security monitoring
log-file=/var/log/coturn/turnserver.log
syslog

The important thing is to set something rather than leaving everything unlimited. Start with values that match your expected peak usage with some headroom, monitor, and tighten from there. For a small deployment with a few hundred concurrent users, user-quota=100 and total-quota=10000 are reasonable starting points, but your mileage will vary.

Authentication

We recommend time-limited credentials with a shared secret for dynamic credential generation.

# Use time-limited credentials (recommended)
lt-cred-mech
use-auth-secret
static-auth-secret=YOUR_SECRET_KEY_HERE

# Credential lifetime (matches your API token expiry)
max-allocate-lifetime=3600

Do keep in mind that authentication provides limited protection for public conferencing systems where anyone can register or join anonymous meetings. In those cases, you must rely on the other controls: network isolation, access control rules, and rate limiting.

Logging and monitoring

Monitoring helps you catch relay abuse, DoS attacks, and unusual behavior before they cause real damage.

# Enable detailed logging
verbose
log-file=/var/log/coturn/turnserver.log

# Log to syslog for centralized monitoring
syslog

# Optionally disable log colors for parsing
simple-log

What to alert on

  • Sustained high allocation rates (potential DoS)
  • Repeated access control violations from the same IP (someone is probing)
  • Unusual bandwidth spikes
  • High error rates or authentication failures

Use SIEM systems or custom scripts to parse coturn logs and alert on suspicious patterns.

Process isolation

Running coturn as a dedicated unprivileged user limits the damage if the process is compromised. This is basic defense in depth.

# Run as dedicated user/group (create with: useradd -r -s /bin/false turnserver)
proc-user=turnserver
proc-group=turnserver

Of course, if you’re running coturn in a container, the container’s user namespace handles this. But for bare-metal or VM deployments, proc-user and proc-group are essential.

Complete configuration templates

What follows are three complete templates at different security levels. Pick the one that fits your deployment and adjust from there.

Minimal secure config

This is the bare minimum for production. Use it as a starting point, then add hardening based on your requirements. (View on GitHub)

# Minimal Secure coturn Configuration (4.6.0+)
# Save as: /etc/turnserver.conf

# Listening configuration
listening-port=3478
tls-listening-port=5349
listening-ip=YOUR_PUBLIC_IP

# Relay configuration
relay-ip=YOUR_PUBLIC_IP
external-ip=YOUR_PUBLIC_IP

# Authentication
lt-cred-mech
use-auth-secret
static-auth-secret=CHANGE_THIS_SECRET
realm=turn.example.com

# Access control - block internal ranges
no-multicast-peers
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=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.168.0.0-192.168.255.255
denied-peer-ip=::1
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff

# Protocol hardening / amplification reduction
no-rfc5780
no-software-attribute

# coturn 4.14.0+ only: reduce UDP 401 reflection
# unauthorized-ratelimit
# unauthorized-ratelimit-rps=10

# Rate limiting - tune these to your expected usage
user-quota=100
total-quota=10000
max-allocate-lifetime=3600

# Logging
log-file=/var/log/coturn/turnserver.log
syslog

This is what we recommend for most production deployments. It adds TLS, comprehensive IP blocking, protocol hardening, and monitoring on top of the minimal config. (View on GitHub)

# Recommended Secure coturn Configuration (4.6.0+)
# Save as: /etc/turnserver.conf

# Listening configuration
listening-port=3478
tls-listening-port=5349
listening-ip=YOUR_PUBLIC_IP

# Relay configuration
relay-ip=YOUR_PUBLIC_IP
external-ip=YOUR_PUBLIC_IP
min-port=49152
max-port=65535

# Authentication
lt-cred-mech
use-auth-secret
static-auth-secret=CHANGE_THIS_SECRET
realm=turn.example.com

# TLS/DTLS (recommended for encrypted TURN)
cert=/etc/coturn/cert.pem
pkey=/etc/coturn/privkey.pem
cipher-list="HIGH"
# TLS 1.0 and 1.1 are disabled by default since coturn 4.7.0
# On coturn <= 4.6.x, uncomment the following two lines:
# no-tlsv1
# no-tlsv1_1

# Access control - comprehensive IP blocking (based on IANA special-purpose registries)
no-multicast-peers
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.31.196.0-192.31.196.255
denied-peer-ip=192.52.193.0-192.52.193.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=192.175.48.0-192.175.48.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=224.0.0.0-239.255.255.255
denied-peer-ip=240.0.0.0-255.255.255.255
denied-peer-ip=::1
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
denied-peer-ip=64:ff9b:1::-64:ff9b:1:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
denied-peer-ip=100::1:0:0:0:0-100::1:ffff:ffff:ffff:ffff
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2001:db8::-2001:db8:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2620:4f:8000::-2620:4f:8000:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=3fff::-3fff:fff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=5f00::-5f00:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff

# Protocol hardening
no-rfc5780
no-tcp-relay

# Amplification reduction
# coturn 4.14.0+ only: per-source rate-limit on UDP 401 responses
# unauthorized-ratelimit
# unauthorized-ratelimit-rps=10

# Rate limiting - tune these to your expected usage
user-quota=100
total-quota=10000
max-allocate-lifetime=3600
max-bps=0               # set based on your server bandwidth
bps-capacity=0          # set based on your server bandwidth

# Logging and monitoring
log-file=/var/log/coturn/turnserver.log
syslog
verbose

# Security options
no-cli
no-software-attribute
stale-nonce=600
proc-user=turnserver
proc-group=turnserver

High-security config

Maximum restrictions for sensitive deployments: government, healthcare, financial services. This uses an allow-list approach for peer IPs, disables plain (unencrypted) listeners so clients must connect via TLS/DTLS, enforces TLS 1.3 only, and applies tighter rate limits. (View on GitHub)

# High-Security coturn Configuration (4.6.0+)
# Save as: /etc/turnserver.conf

# Listening configuration
listening-port=3478
tls-listening-port=5349
listening-ip=YOUR_PUBLIC_IP

# Relay configuration
relay-ip=YOUR_PUBLIC_IP
external-ip=YOUR_PUBLIC_IP
min-port=49152
max-port=65535

# Authentication - require encrypted connections
lt-cred-mech
use-auth-secret
static-auth-secret=CHANGE_THIS_SECRET
realm=turn.example.com

# TLS/DTLS - enforce strong encryption
cert=/etc/coturn/cert.pem
pkey=/etc/coturn/privkey.pem
cipher-list="ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
# TLS 1.0 and 1.1 are disabled by default since coturn 4.7.0
# On coturn <= 4.6.x, uncomment the following two lines:
# no-tlsv1
# no-tlsv1_1
no-tlsv1_2  # TLS 1.3 only

# Access control - whitelist approach for maximum restriction
# Only allow relay to specific media server IPs
allowed-peer-ip=203.0.113.10
allowed-peer-ip=203.0.113.11
denied-peer-ip=0.0.0.0-255.255.255.255
denied-peer-ip=::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff

# Protocol hardening - disable everything optional
no-udp    # Disable plain UDP listeners (clients must use DTLS/TLS)
no-tcp    # Disable plain TCP listeners (clients must use TLS)
no-rfc5780
no-tcp-relay
no-multicast-peers
no-cli
secure-stun  # Require auth for STUN Binding (breaks standard ICE)
# unauthorized-ratelimit (UDP 401 reflection control) is not needed here:
# no-udp already removes the plain UDP listener that reflection targets

# Rate limiting - tighter values for restricted deployments
user-quota=50
total-quota=5000
max-allocate-lifetime=1800   # 30 minutes
max-bps=0                    # set based on your server bandwidth
bps-capacity=0               # set based on your server bandwidth
channel-lifetime=300         # 5 minutes (default: 600)
permission-lifetime=180      # 3 minutes (default: 300)

# Logging
log-file=/var/log/coturn/turnserver.log
syslog
verbose
log-binding

# Security hardening
no-software-attribute   # Don't advertise server version
stale-nonce=300         # Short nonce lifetime
proc-user=turnserver
proc-group=turnserver

Version-specific gotchas

Configuration parameters change between coturn versions, and some of these changes can trip you up. Here’s what to watch out for.

coturn 4.14.0

  • Adds unauthorized-ratelimit for per-source rate-limiting of UDP 401 responses, with Prometheus counters for its decisions (covered in the amplification section above). It’s marked experimental.
  • Fixes a signed-char out-of-bounds read in base64_decode and validates hmackey length in sqlite_get_user_key before hex decoding
  • Adds optional TLS transport for Redis connections

coturn 4.13.1

  • New secure defaults: link-local, ULA, and site-local relay peers are now denied by default, and coturn auto-denies its own database backend endpoints as relay peers. Nice secure-by-default moves that reduce the chance of a misconfiguration leaving these open.
  • Canonicalizes all IPv4-in-IPv6 encodings before peer-IP checks, extending ACL normalization beyond the IPv4-mapped form (::ffff:a.b.c.d) to IPv4-compatible (::a.b.c.d), 6to4 (2002::/16), and NAT64 (64:ff9b::/96) encodings, so a denied-peer-ip range can’t be dodged by re-encoding the target

coturn 4.13.0

  • Fixes CVE-2026-53450 (CVSS 7.4 High): the IPv4-mapped loopback address ::ffff:127.0.0.1 bypassed the default loopback peer guard. Explicit denied-peer-ip=127.0.0.0-127.255.255.255 ranges were never affected, since range checks already normalize mapped addresses.
  • Fixes CVE-2026-53449 (CVSS 6.5 Medium): arbitrary file write via the CLI psd command
  • Broader security hardening pass: admin brute-force throttle, credential log redaction, constant-time comparisons, OAuth bounds checks, and a permission cap

coturn 4.12.0

  • Fixes CVE-2026-53448 (CVSS 7.2 High): SQL injection in the HTTPS admin panel’s delete-user, delete-secret, and delete-IP operations

coturn 4.11.0

  • Fixes CVE-2026-43915 (CVSS 5.4 Medium): stored XSS in the web-admin interface via a crafted TURN username

coturn 4.10.0

  • Fixes CVE-2026-43994 (CVSS 8.1 High): a pre-authentication stack buffer overflow in decode_oauth_token_gcm(). Only reachable when --oauth is enabled (non-default), but the overflow happens before authentication, so no valid key material is needed.
  • Also carries a fix tracked as CVE-2026-40613 (a reported misaligned STUN attribute read on ARM64)

coturn 4.9.0

  • Fixes CVE-2026-27624: IPv4-mapped IPv6 addresses (::ffff:x.x.x.x) could bypass all denied-peer-ip rules for IPv4 ranges. This is a bypass of the earlier CVE-2020-26262 fix.
  • Fixes inverted password check in the web admin interface (any wrong password was accepted since ~2019)
  • Multiple buffer overflow and null termination fixes across DB drivers, HTTP server, and STUN message handling
  • Migrated deprecated OpenSSL APIs to modern EVP interface

coturn 4.8.x

  • Socket buffer size now configurable: sock-buf-size
  • Improved random number generation (CVE-2025-69217)
  • Default configurations are more secure out of the box

coturn 4.7.0

  • TLS version defaults flipped: no-tlsv1 and no-tlsv1_1 were removed. TLS 1.0 and 1.1 are now disabled by default (secure-by-default). To re-enable them (not recommended), use tlsv1 or tlsv1_1. The no-tlsv1_2 option still exists to force TLS 1.3 minimum.
  • Software attribute default flipped: no-software-attribute is deprecated. The software version attribute is now hidden by default. Use software-attribute to opt in (for debugging). The deprecated no-software-attribute still works but is unnecessary on 4.7.0+.
  • RFC5780 default flipped: no-rfc5780 is deprecated. RFC5780 (NAT behavior discovery) is now disabled by default, reducing the unauthenticated response surface. Use rfc5780 to opt in if needed. On older versions, set no-rfc5780 explicitly.
  • If you’re upgrading from 4.6.x, remove no-tlsv1 and no-tlsv1_1 from your config (they are removed and produce Bad configuration format warnings on 4.7.0+). You can also remove no-rfc5780 and no-software-attribute since their behavior is now the default on 4.7.0+ (these are deprecated but silently accepted).

coturn 4.6.x

  • no-rfc5780 option added (disables NAT behavior discovery, reducing unauthenticated response surface)
  • allocation-default-address-family option added (replaces deprecated keep-address-family)
  • Improved IPv6 handling
  • Better default access controls

coturn 4.5.2

  • Fixes CVE-2020-26262 (0.0.0.0 and IPv6 loopback bypass)
  • Default blocks for loopback addresses
  • This was historically the floor for production, but given everything fixed since (see above), treat it as a floor, not a target. Run the latest release.

Vulnerability history: why updating matters

Keeping coturn updated is the single most critical security control. coturn has had its share of serious vulnerabilities over the years:

  • CVE-2026-53450 (fixed in 4.13.0, CVSS 7.4 High): ::ffff:127.0.0.1 bypassed the default loopback peer guard (explicit denied-peer-ip ranges were not affected)
  • CVE-2026-53449 (fixed in 4.13.0, CVSS 6.5 Medium): arbitrary file write via the CLI psd command
  • CVE-2026-53448 (fixed in 4.12.0, CVSS 7.2 High): SQL injection in the HTTPS admin panel delete operations
  • CVE-2026-43915 (fixed in 4.11.0, CVSS 5.4 Medium): stored XSS in the web-admin interface via a crafted TURN username
  • CVE-2026-43994 (fixed in 4.10.0, CVSS 8.1 High): pre-authentication stack buffer overflow in OAuth token decoding (--oauth mode only)
  • CVE-2026-27624 (fixed in 4.9.0, CVSS 7.2 High): IPv4-mapped IPv6 bypass of denied-peer-ip ACL, a bypass of the CVE-2020-26262 fix
  • Web admin auth bypass (fixed in 4.9.0): Inverted password check let any wrong password log in
  • Multiple buffer overflows (fixed in 4.9.0): In AES decryption, MySQL driver, HTTP server, and STUN method handling
  • CVE-2025-69217 (fixed in 4.8.0): Improved random number usage
  • CVE-2020-26262 (fixed in 4.5.2): Access control bypass via 0.0.0.0 and IPv6 loopback
  • CVE-2020-4067: Information disclosure, buffer exposure
  • CVE-2018-4056 (CVSS 9.8 Critical): SQL injection allowing arbitrary SQL execution
  • Inherited OpenSSL vulnerabilities: coturn links OpenSSL for TLS/DTLS, so any OpenSSL CVEs in your distribution’s library version also affect coturn
# Check current version
turnserver --version

# Update via package manager (Debian/Ubuntu)
apt update && apt upgrade coturn

# Or Docker (check https://github.com/coturn/coturn/releases for current version)
docker pull coturn/coturn:latest

Changelog

We keep this guide current as coturn ships new releases and fixes. What’s changed here:

  • 2026-06-26: Added coverage for the coturn 4.10.0 to 4.14.0 security fixes (CVE-2026-43994, CVE-2026-53448, CVE-2026-53449, CVE-2026-53450, and others), documented the new unauthorized-ratelimit amplification control introduced in 4.14.0, and noted the 4.13.1 secure-by-default peer-ACL improvements.
  • 2026-02-25: Initial publication.

Further reading

Subscribe to Updates

Stay updated with our latest security insights and updates.

We hate spam and are committed to protecting and respecting your privacy. You can unsubscribe from our communications at any time. By subscribing, you are agreeing to the Privacy Policy.

Sandro Gauci

Sandro Gauci

CEO, Chief Mischief Officer at Enable Security

Sandro Gauci leads the operations and research at Enable Security. He is the original developer of SIPVicious OSS, the SIP security testing toolset. His role is to focus on the vision of the company, design offensive security tools and engage in security research and testing. Therefore, he is the proud owner of the title of Chief Mischief Officer at Enable Security.

He offers public office hours and is reachable here.