Setting up TURN/STUN
TURN and STUN are used as a component in many calling systems. Matrix uses them directly for legacy calls and indirectly for MatrixRTC via Livekit.
Continuwuity recommends using Coturn as your TURN/STUN server, which is available as a Docker image or a distro package.
Installing Coturn
Configuration
Create a configuration file called coturn.conf containing:
A common way to generate a suitable alphanumeric secret key is by using:
Port Configuration
By default, coturn uses the following ports:
3478(UDP/TCP): Standard TURN/STUN port5349(UDP/TCP): TURN/STUN over TLS49152-65535(UDP): Media relay ports
If you're also running LiveKit, you'll need to avoid port conflicts. Configure non-overlapping port ranges:
This leaves ports 50100-50200 available for LiveKit's default configuration.
Running with Docker
Run the Coturn image using:
Running with Docker Compose
Create a docker-compose.yml file and run docker compose up -d:
Coturn uses host networking mode because it needs to bind to multiple ports and work with various network protocols. Using host networking is better for performance, and reduces configuration complexity. To understand alternative configuration options, visit Coturn's Docker documentation.
Security Recommendations
For security best practices, see Synapse's Coturn documentation, which includes important firewall and access control recommendations.
Configuring Continuwuity
Once your TURN server is running, configure Continuwuity to provide credentials to clients. Add the following to your Continuwuity configuration file:
Shared Secret Authentication (Recommended)
This is the most secure method and generates time-limited credentials automatically:
The turns: URI prefix instructs clients to connect to TURN over TLS, which is highly recommended for security. Make sure you've configured TLS in your coturn server first.
Static Credentials (Alternative)
If you prefer static username/password credentials instead of shared secrets:
Static credentials are less secure than shared secrets because they don't expire and must be configured in coturn separately. It is strongly advised you use shared secret authentication.
Guest Access
By default, TURN credentials require client authentication. To allow unauthenticated access:
This is not recommended as it allows unauthenticated users to access your TURN server, potentially enabling abuse by bots. All major Matrix clients that support legacy calls also support authenticated TURN access.
Important Notes
- Replace
coturn.example.comwith your actual TURN server domain (therealmfrom coturn.conf) - The
turn_secretmust match thestatic-auth-secretin your coturn configuration - Restart or reload Continuwuity after making configuration changes
Testing Your TURN Server
Testing Credentials
Verify that Continuwuity is correctly serving TURN credentials to clients:
You should receive a response like this:
If no TURN URIs are configured (turn_uris is empty), Continuwuity will return a 404 Not Found response, as specified in MSC4166.
Testing Connectivity
Use Trickle ICE to verify that the TURN credentials actually work:
- Copy the credentials from the response above
- Paste them into the Trickle ICE testing tool
- Click "Gather candidates"
- Look for successful
relaycandidates in the results
If you see relay candidates, your TURN server is working correctly!
Troubleshooting
Clients can't connect to TURN server
- Verify firewall rules allow the necessary ports (3478, 5349, and your media port range)
- Check that DNS resolves correctly for your TURN domain
- Ensure your
turn_secretmatches coturn'sstatic-auth-secret - Test with Trickle ICE to isolate the issue
Port conflicts with LiveKit
- Make sure coturn's
min-portstarts above LiveKit'sport_range_end(default: 50200) - Or adjust LiveKit's port range to avoid coturn's default range
404 when calling turnServer endpoint
- Verify that
turn_urisis not empty in your Continuwuity config - This behavior is correct per MSC4166 if no TURN URIs are configured
Credentials expire too quickly
- Adjust the
turn_ttlvalue in your Continuwuity configuration - Default is 86400 seconds (24 hours)
Related Documentation
- MatrixRTC/LiveKit Setup - Configure group calling with LiveKit
- Coturn GitHub - Official coturn repository
- Synapse TURN Guide - Additional security recommendations