Skip to content

[19.0][New] Appliance Proposal: CoTURN (Shared TURN/STUN Server) #2095

@marcos-mendez

Description

@marcos-mendez

Summary

We have built a TurnKey Linux appliance for [CoTURN](https://github.com/coturn/coturn),
the most widely deployed open-source TURN/STUN server. This appliance fills a
gap in the TurnKey ecosystem: several existing appliances (Jitsi, ejabberd,
Nextcloud Talk, BigBlueButton) depend on a TURN server for WebRTC NAT traversal,
but none provides one. Users are currently forced to configure TURN ad-hoc or
rely on third-party relay services.


Motivation

WebRTC-based applications fail for users behind symmetric NAT, carrier-grade
NAT, or restrictive firewalls unless a TURN relay is available. This affects:

  • Jitsi Meet — requires a TURN server for peers behind NAT
  • ejabberd / Prosody — XMPP video/audio calls (XEP-0215)
  • Nextcloud Talk — peer-to-peer calls in enterprise networks
  • BigBlueButton — video conferencing relay
  • Matrix/Synapse — Element video calls
  • Odoo Discuss — WebRTC calls (Odoo 17+)

A dedicated, shared CoTURN appliance lets a single instance serve all of the
above simultaneously. Each application receives the same shared secret and
generates ephemeral HMAC-SHA1 credentials independently — no coordination
required between services.


What the Appliance Does

  • Installs and configures coturn from Debian repos
  • Firstboot prompts for realm (FQDN) and external IPv4 (for NAT scenarios)
  • Auto-generates a cryptographically random shared secret on first boot
  • Produces a clean, security-hardened /etc/turnserver.conf with:
    • HMAC ephemeral credentials (use-auth-secret)
    • Private IP ranges blocked as relay targets (denied-peer-ip)
    • Nonce expiry, fingerprinting, multicast protection
    • Configurable external-ip mapping for IPv4 NAT deployments
  • Provides turnkey-coturn-credentials helper — generates JSON ICE server
    config ready to paste into any WebRTC application
  • Integrates with TurnKey's standard webmin/shellinabox/confconsole stack

Design Decisions

IPv6-first, NAT-optional. The appliance is designed to run with a real
public IPv6 address (via macvlan LXC on Proxmox or direct assignment on a VPS),
eliminating the need for external-ip on IPv6 paths. For IPv4, the
external-ip=PUBLIC/PRIVATE mapping is configured at firstboot.

Shared secret model. Uses CoTURN's use-auth-secret mode (TURN REST API,
[draft-uberti-behave-turn-rest](https://datatracker.ietf.org/doc/html/draft-uberti-behave-turn-rest-00)).
One secret, many applications. No database required.

Security defaults. All RFC 1918 and loopback ranges are blocked as relay
targets out of the box, preventing the relay from being used as a pivot into
private networks.


Repository

The appliance is available at:

https://git.pop.coop/turnkeylinux/coturn

It follows standard TurnKey appliance structure:

turnkey-coturn/
├── plan/main
├── conf.d/main
├── overlay/
│   ├── etc/turnserver.conf.template
│   └── usr/bin/turnkey-coturn-credentials
├── inithooks/
│   ├── bin/coturn.py          (firstboot configurator)
│   └── firstboot.d/
│       └── 20regen-coturn-secrets
├── changelog
└── README.md

Tested On

  • TurnKey Linux v19 (Debian 13 / Trixie)
  • LXC container on Proxmox VE 8.x (macvlan bridge, public IPv6)
  • Clients tested: Jitsi Meet, ejabberd (mod_stun_disco), Nextcloud Talk,
    Matrix/Synapse, generic WebRTC (trickle-ice test page)

Notes for Reviewers

  • Port 3478 (UDP+TCP), 5349 (TCP), and 10000–20000 (UDP) must be open and
    forwarded to the container. The README includes a full deployment checklist
    and per-application configuration examples for all major TurnKey appliances.
  • TLS (TURNS on 5349) requires a valid certificate — the firstboot optionally
    runs certbot if a public FQDN is provided.
  • The turnkey-coturn-credentials helper outputs JSON compatible with the
    WebRTC RTCPeerConnection iceServers format, making integration testing
    straightforward.

We would be happy to submit this as a PR to turnkeylinux-apps if the
maintainers are interested in including it upstream.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions