Self-hosted service
coturn/coturn avatar
coturn/coturn

coturn: the TURN and STUN server behind NAT-bound WebRTC

coturn TURN server project

14,439 stars2,274 forksCNOASSERTION

At a glance

What is it?
coturn is a C implementation of TURN and STUN for relaying VoIP and WebRTC media through NAT. The install path is short, but the RFC coverage has real gaps worth knowing before you deploy it.
Who is it for?
Adopt coturn if you need a self-hosted TURN relay for WebRTC or SIP and you are willing to run the relay ports and a credential database yourself. Skip it if your clients depend on RFC 8489 SHA256 authentication, USERHASH, or ICMP relaying, since the README states those are absent and unreachable peers produce silence rather than a Data indication.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The NAT problem coturn exists to solve

Two peers behind symmetric NATs cannot learn each other's public address well enough to send media directly. STUN answers the simpler half of that: a client asks a server what its address looks like from the outside, and uses that answer to try a direct path. When the direct path fails, TURN takes over and relays the media through a server that both sides can reach. coturn implements both roles in one daemon, and the README describes it as "a VoIP media traffic NAT traversal server and gateway."

The audience is infrastructure teams running WebRTC, SIP, or any real-time media stack where some fraction of clients will always need a relay. That fraction is the whole point: coturn is the fallback path, and it has to exist even when most sessions never touch it. It is not a general-purpose proxy and it is not a signalling server. It moves packets for clients that already know each other's session parameters.

What the relay actually does with a packet

A client authenticates against coturn, requests an allocation, and receives a relayed transport address on the server. The peer sends to that address, and coturn forwards the payload to the client over the client-to-server transport. The README lists the client-to-server protocols as UDP, TCP, TLS (including TLS 1.3 with ECDHE), DTLS 1.0 and 1.2, and an experimental SCTP path. Relay protocols are narrower: UDP per RFC 8656 and TCP per RFC 6062.

That asymmetry matters operationally. You can accept a client over DTLS and still relay only UDP or TCP to the far side. DTLS listeners are also opt-in: the README states they are not started unless --dtls is given, so a deployment that assumes DTLS is live by default is wrong.

Authentication sits in front of allocation. coturn supports the classic long-term credentials mechanism, the TURN REST API for time-limited secret-based credentials used by WebRTC applications, and an experimental third-party oAuth option per RFC 7635. Message integrity is HMAC-SHA1 with MD5-hashed keys, which is what the STUN and TURN standards require. User records can live in SQLite, MariaDB/MySQL, PostgreSQL, Redis, or MongoDB, and Redis doubles as a status and statistics store.

Installing coturn and running a first server

The README gives two install paths. On a Linux distribution that packages coturn, the quickest start is apt, followed by running the daemon with logging to standard output so you can see what it does:

bash
apt install coturn
turnserver --log-file stdout

With no configuration file, this starts the server with defaults and prints its log lines to the terminal. The README notes that distribution packages may lag the upstream version, and it also notes that the Prometheus metrics interface is unavailable in the apt package.

The container path is the one most people reach for, because it pins the relay port range explicitly:

bash
docker run -d -p 3478:3478 -p 3478:3478/udp -p 5349:5349 -p 5349:5349/udp -p 49152-65535:49152-65535/udp coturn/coturn

Port 3478 is the STUN and TURN listener, 5349 is the TLS and DTLS listener, and 49152-65535 is the relay range. If the relay range is not reachable from the public internet, allocations succeed and media silently fails, which is the single most common misconfiguration for this class of server. The image is published on Docker Hub, GitHub Container Registry, and Quay.io, and the repository carries a docker/coturn directory with its own README.

Building from source needs libevent2 and libmicrohttpd, plus OpenSSL 3.0 or newer if you want TLS, DTLS, and authorized STUN and TURN. The README is explicit that older OpenSSL versions are not supported. The build sequence is the usual autotools shape:

bash
git clone [email protected]:coturn/coturn.git
cd coturn
./configure
make

Database backends are optional and only needed when authentication is required.

Where coturn falls short of the specs it claims

The RFC list is long, but the README annotates it honestly, and the annotations are the interesting part. RFC 8489 authentication additions are not implemented: MESSAGE-INTEGRITY-SHA256, PASSWORD-ALGORITHMS, PASSWORD-ALGORITHM, USERHASH, and the nonce cookie are all absent. An RFC 8489 client therefore falls back to that spec's MD5 key derivation with SHA-1 MESSAGE-INTEGRITY, which RFC 8489 permits. The message-processing rules are implemented, including ignoring attributes after MESSAGE-INTEGRITY, first-wins for repeated attributes, and unpadded ERROR-CODE reason phrases. So this is a partial RFC 8489 story, not a missing one.

ICMP relaying is the sharper gap. RFC 8656 Section 11.5 defines an ICMP attribute, and coturn does not implement it. The README states the consequence plainly: an unreachable peer produces silence rather than a Data indication. If your application relies on ICMP errors to detect a dead peer quickly, coturn will not give you that signal, and you need a timeout at a higher layer.

RFC 3489, the deprecated classic STUN, is opt-in via --rfc3489-compatibility and scheduled for removal in the next major release, with a deprecation note in docs/rfc3489-deprecation.md. Anyone still carrying a legacy client on that path has a migration deadline, not an indefinite option.

coturn against a managed TURN service

The alternative most teams weigh is not another self-hosted daemon but a hosted TURN provider, where the relay, TLS certificates, and geographic distribution are someone else's operational problem and you consume credentials through an API. That difference is structural rather than a feature comparison. A hosted service removes the relay port range from your firewall rules and the credential database from your infrastructure, and in exchange you pay per relayed traffic and you accept the provider's regions and uptime.

Self-hosting coturn keeps media on infrastructure you control, which matters when regulatory or latency requirements pin the relay to a specific network, and it lets you pick the credential backend: SQLite for a small deployment, PostgreSQL or MariaDB for a shared one, Redis when you also want statistics. The cost is that you now own the relay port range, the certificate lifecycle for port 5349, and the capacity planning for concurrent allocations. coturn does not remove that work; it defines the surface you have to operate.

Management, monitoring, and what upgrades involve

coturn exposes a telnet CLI and an HTTPS management interface, and it can push status and statistics into Redis or expose them through a Prometheus interface. The Prometheus endpoint is the one to check early, because the README says it is unavailable in the apt package. If metrics matter to you, the container or a source build is the path, and the repository includes examples/run_tests_prom.sh alongside a set of other run_tests scripts covering DTLS defaults, IPv6 relay, mobility quota, rate limiting, and stateless binding.

The licence is listed as NOASSERTION in the repository metadata, which means GitHub could not match the LICENSE file to a known identifier. Read LICENSE directly before you depend on the terms; that is a factual gap in the metadata, not a legal opinion, and it is worth resolving before coturn becomes load-bearing.

Upgrade cost is mostly configuration drift. Releases are frequent (4.18.0 landed on 2026-09-08, with a matching docker/4.18.0-r0 image tag the same day), and the repository carries a ChangeLog plus an INSTALL file. The rfc3489 deprecation is the concrete upgrade item to track, since it is scheduled for removal in the next major release.

Editorial conclusion

Adopt coturn if you need a self-hosted TURN relay for WebRTC or SIP and you are willing to run the relay ports and a credential database yourself. Skip it if your clients depend on RFC 8489 SHA256 authentication, USERHASH, or ICMP relaying, since the README states those are absent and unreachable peers produce silence rather than a Data indication. Before rollout, verify which RFC 8489 authentication path your clients actually negotiate, and confirm the relay port range 49152-65535 is open end to end.

Frequently asked questions

What is coturn?

coturn is a free open source implementation of a TURN and STUN server, written in C. The README describes it as a VoIP media traffic NAT traversal server and gateway.

What is a TURN server and how does it work with WebRTC?

A TURN server relays media between peers that cannot reach each other directly, and coturn implements both the STUN discovery role and the TURN relay role. coturn supports the TURN REST API, which the README describes as a time-limited secret-based authentication mechanism for WebRTC applications.

Is there any free TURN server?

coturn is free and open source, and Linux distributions may ship a packaged version installable with apt install coturn. You still supply the host, the open relay port range, and any credential database yourself.

how to install coturn

The README gives two routes: apt install coturn on Linux distributions that package it, or docker run with ports 3478, 5349, and the relay range 49152-65535 published. Building from source needs libevent2 and libmicrohttpd, and OpenSSL 3.0 or newer for TLS and DTLS.

how to setup coturn server

Run turnserver --log-file stdout for a default start, or the Docker image with the relay port range published. Authentication requires choosing a user database from SQLite, MariaDB/MySQL, PostgreSQL, Redis, or MongoDB.

coturn alternative

The realistic alternative is a hosted TURN provider, which removes the relay port range and credential database from your infrastructure in exchange for per-traffic cost and the provider's regions. coturn keeps the media on hardware you control and lets you choose the credential backend.

Official sources

  1. coturn/coturn on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/coturn-coturn.svg)](https://hysenlabs.com/projects/coturn-coturn)