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. We recommend a patched release, currently 4.17.2, or your distribution’s backported fixes. If upgrading has to wait, the controls below can reduce exposure on older versions too, but they don’t replace every security fix.
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.
The configuration syntax covers 4.6.x and later, with version-specific notes for changed defaults, including DTLS becoming opt-in in 4.17.0.
Heads up
For the threat analysis and real-world attack examples that motivate these controls, see TURN Security Threats: A Hacker’s View.Note
For implementation-agnostic security principles and deployment patterns, see our TURN Server Security Best Practices.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
# 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.
Heads up
If you only setrelay-ip to an IPv4 address (e.g. relay-ip=YOUR_PUBLIC_IP), coturn will only allocate IPv4 relay addresses. This means peers using IPv6 addresses won’t be relayed, which also has a security upside: attackers cannot reach IPv6 peers through your TURN server. If you need IPv6 relay support, add a second relay-ip line with your server’s IPv6 address.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
Warning
Test this configuration in your environment before deploying to production. Verify that legitimate peer addresses (external public IPs) are not inadvertently blocked.Heads up
The::ffff:0.0.0.0-::ffff:255.255.255.255 rule blocks IPv4-mapped IPv6 peers. CVE-2026-27624 showed that this encoding could bypass IPv4 deny rules before 4.9.0. The explicit mapped-address rule is a workaround for that issue on older versions; keep it for defense in depth, not as a substitute for upgrading.Heads up
Why keep explicit rules? CVE-2026-53450 let IPv4-mapped loopback slip past the default guard before 4.13.0. The explicit loopback and mapped-address denials above protected against that issue.
CVE-2026-73212, fixed in 4.13.1, extended normalization to recognized compatible, 6to4, and NAT64 well-known-prefix encodings. But coturn can’t infer every IPv6-to-IPv4 mapping. The full list above blocks both standard NAT64 prefixes; add your deployment’s custom prefixes too, and enforce destination policy at the translator or egress firewall.
CVE-2026-73213, fixed in 4.16.0, was a separate IPv6 range-comparison bug. It under-blocked certain custom min-max intervals. The IPv6 rules in this guide are prefix-aligned ranges or exact addresses, not the affected range shape. If you can’t upgrade yet, avoid arbitrary IPv6 min-max intervals, disable TCP relay if unnecessary, and restrict relay egress independently of coturn. These measures address specific paths, not every vulnerability in an older release.
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 clients don't need it; TLS is a separate transport
# DTLS is opt-in since coturn 4.17.0
# no-dtls
Heads up
stun-only and no-stun are separate, opposite controls. stun-only disables TURN relay and keeps only STUN (useful for dedicated STUN servers). no-stun disables STUN and keeps only TURN relay. Both options coexist in current coturn versions.Disabling UDP listening
For TCP/TLS-only client connections, disable both plain UDP and DTLS. Before 4.17.0, a DTLS-capable build enabled DTLS by default when a usable certificate and private key were available. Setting up TLS could therefore enable DTLS too, and no-udp alone would leave it running. Since 4.17.0, DTLS requires opt-in with dtls.
# Clients must connect via TCP/TLS; peer media can still use UDP
no-udp
no-dtls
# TCP and TLS listening ports
listening-port=3478
tls-listening-port=5349
This removes the UDP/DTLS listener reflection surface. The trade-off is retransmissions and head-of-line blocking on the client connection under packet loss; UDP relay to peers is unaffected.
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
Warning
Only enablesecure-stun if you control all clients and know they don’t rely on unauthenticated STUN Binding. For most WebRTC deployments, this will break ICE.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. coturn 4.14.0 added a per-source rate limit on UDP 401 Unauthorized responses. It limits authentication challenges, not ordinary unauthenticated STUN Binding responses:
# Cap UDP 401 Unauthorized responses per source IP (coturn 4.14.0+)
# Past the cap, drop further 401 challenges for that source
# Off by default - you have to opt in.
unauthorized-ratelimit
unauthorized-ratelimit-rps=10
It only applies to UDP 401 responses, not TCP or TLS. The default cap is 10 responses per source IP per second; successful authenticated requests don’t spend tokens. Legitimate clients still need initial challenges, so test the limit with clients sharing a NAT address. The 4.14.0 release notes introduced it as experimental.
If you’re on an older version, the knobs are more limited. Using no-udp and no-dtls removes those listener reflection paths, with the transport trade-offs covered above. If you need UDP, trimming responses helps:
# 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-authdeployments, 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 management interfaces add attack surface on top of STUN/TURN itself. 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
Warning
If you’re running coturn < 4.9.0 withweb-admin enabled, anyone who can reach the web admin port can log in with any wrong password. Disable it immediately or upgrade.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.
Warning
These rate limits cut both ways.total-quota and bps-capacity are server-wide, so if set too low, a single attacker with valid credentials can exhaust the global quota and block allocations for everyone else (error 486). Per-user limits (user-quota, max-bps) sound better, but an attacker who can generate credentials (e.g. through an unprotected credential API) can simply create many distinct usernames, each with its own quota. coturn’s rate limiting is useful but not a substitute for protecting your credential API and using network-level rate limiting by source IP.Heads up
These are coturn’s application-level rate limits. For network-level rate limiting withiptables/nftables (which we also recommend), see the rate limiting section of our best practices guide. Both layers working together gives you much better protection than either alone.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
# Allocation lifetime, not credential expiry (set that in your credential API)
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, containers need this attention too: use a non-root container user or explicitly configured user-namespace remapping. A container alone doesn’t make the process unprivileged.
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
Use this as a starting point, then add hardening based on your requirements. Check the version-specific notes for fixes and workarounds relevant to your deployment. (View on GitHub)
# Minimal Secure coturn Configuration
# 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
Recommended secure config
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
# 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
For restricted deployments, this uses a peer allow-list, TLS 1.3-only client connections, and tighter rate limits. Plain UDP, plain TCP, and DTLS are disabled. Check client compatibility before deploying. (View on GitHub)
# High-Security coturn Configuration
# 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 - 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
no-dtls # Disable DTLS too; no-udp alone does not do this
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 is not needed here: no plain UDP listener
# 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.
Warning
Never usedenied-peer-ip=::0. The ::0 address (IPv6 unspecified) is treated as a wildcard by coturn’s addr_any() check, causing it to match all peers (IPv4 and IPv6) and blocking all TURN relay. This affects all coturn versions.coturn 4.17.x
- DTLS is now opt-in with
dtls. For TCP/TLS-only service, keep bothno-udpandno-dtls; the latter is deprecated but still accepted with a warning. - Stateless nonces are on by default, avoiding session allocation for unauthenticated UDP challenges. Nonces grow from 16 to 24 characters; clients must treat them as opaque. A shared
stateless-nonce-secretavoids extra re-authentication across restarts or load-balanced instances. - 4.17.0 fixes mobility quota bypass (CVE-2026-73216) and EVEN-PORT reservation exhaustion (CVE-2026-73215), and performs DTLS cookie verification statelessly. Log timestamps and formatting also changed; check your log parsers.
- 4.17.2 fixes an outgoing UDP TTL regression. Prefer it over 4.17.0/4.17.1.
coturn 4.16.0
- Fixes the IPv6 min-max ACL bug (CVE-2026-73213) described above and chained mobility-resume memory exhaustion (CVE-2026-68555).
- Bounds DTLS pre-cookie resource use (CVE-2026-73214); 4.17.0 adds stateless cookie handling. Also caps multiplex-peer table growth.
coturn 4.15.0
- Fixes processing of attributes after MESSAGE-INTEGRITY (CVE-2026-68554), cross-user mobility takeover (CVE-2026-65981), ACME redirect memory disclosure (CVE-2026-62959), and STUN stream-length truncation (CVE-2026-68552).
coturn 4.14.0
- Adds
unauthorized-ratelimitfor per-source rate-limiting of UDP 401 responses, with Prometheus counters for its decisions (covered in the amplification section above). Introduced as experimental. - Fixes a signed-char out-of-bounds read in
base64_decodeand validateshmackeylength insqlite_get_user_keybefore 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.
- Fixes CVE-2026-73212 by applying IPv4 peer policy to recognized mapped, compatible, 6to4, and NAT64 well-known-prefix encodings. Custom translation prefixes still need explicit policy; see the ACL section above.
coturn 4.13.0
- Fixes CVE-2026-53450 (CVSS 7.4 High): the IPv4-mapped loopback address
::ffff:127.0.0.1bypassed the default loopback peer guard. Explicitdenied-peer-ip=127.0.0.0-127.255.255.255ranges were never affected, since range checks already normalize mapped addresses. - Fixes CVE-2026-53449 (CVSS 6.5 Medium): arbitrary file write via the CLI
psdcommand - 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--oauthis 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 alldenied-peer-iprules 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-tlsv1andno-tlsv1_1were removed. TLS 1.0 and 1.1 are now disabled by default (secure-by-default). To re-enable them (not recommended), usetlsv1ortlsv1_1. Theno-tlsv1_2option still exists to force TLS 1.3 minimum. - Software attribute default flipped:
no-software-attributeis deprecated. The software version attribute is now hidden by default. Usesoftware-attributeto opt in (for debugging). The deprecatedno-software-attributestill works but is unnecessary on 4.7.0+. - RFC5780 default flipped:
no-rfc5780is deprecated. RFC5780 (NAT behavior discovery) is now disabled by default, reducing the unauthenticated response surface. Userfc5780to opt in if needed. On older versions, setno-rfc5780explicitly. - If you’re upgrading from 4.6.x, remove
no-tlsv1andno-tlsv1_1from your config (they are removed and produceBad configuration formatwarnings on 4.7.0+). You can also removeno-rfc5780andno-software-attributesince their behavior is now the default on 4.7.0+ (these are deprecated but silently accepted).
coturn 4.6.x
no-rfc5780option added (disables NAT behavior discovery, reducing unauthenticated response surface)allocation-default-address-familyoption added (replaces deprecatedkeep-address-family)- Improved IPv6 handling
- Better default access controls
coturn 4.5.2
- Fixes CVE-2020-26262 (
0.0.0.0and 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.
Heads up
Always consult the changelog when upgrading. Parameters get renamed, deprecated, or changed in subtle ways.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.1bypassed the default loopback peer guard (explicitdenied-peer-ipranges were not affected) - CVE-2026-53449 (fixed in 4.13.0, CVSS 6.5 Medium): arbitrary file write via the CLI
psdcommand - 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 (
--oauthmode only) - CVE-2026-27624 (fixed in 4.9.0, CVSS 7.2 High): IPv4-mapped IPv6 bypass of
denied-peer-ipACL, 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.0and IPv6 loopback - CVE-2020-4067: Information disclosure, buffer exposure
- CVE-2018-4056 (CVSS 9.8 Critical): SQL injection allowing arbitrary SQL execution
- OpenSSL vulnerabilities: keep the linked library patched too. Whether a particular CVE affects coturn depends on its build, configuration, and use of the affected feature.
# 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
Important
TURN implementations have had their share of serious vulnerabilities. Subscribe to security announcements for your TURN server and apply patches immediately when released.Changelog
We keep this guide current as coturn ships new releases and fixes. What’s changed here:
- 2026-09-07: Updated through 4.17.2, clarified the limits of the ACL fixes, and corrected TCP/TLS-only examples to disable DTLS as well as plain UDP.
- 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-ratelimitamplification 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
- TURN Server Security Best Practices - Implementation-agnostic security principles
- TURN Security Threats: A Hacker’s View - Threat analysis and real-world attacks
- How we abused Slack’s TURN servers - $3,500 bug bounty writeup
- CVE-2020-26262: coturn access control bypass
- coturn-secure-config - All templates from this guide with Docker test environment
- coturn GitHub
- coturn Releases
Note
Configuration is one thing, validation is another. We provide penetration testing and DoS testing for TURN deployments, and we’ve reported several of the coturn CVEs listed above. Get in touch.