How to Configure Coturn TURN Server with Let’s Encrypt Certificates: Permission Issues and Best Practices


3 views

When integrating Coturn with Let's Encrypt certificates, many developers encounter permission-related errors despite having valid certificate paths configured. The typical error pattern looks like:

WARNING: cannot start TLS and DTLS listeners because private key file is not set properly
WARNING: cannot find private key file: /path/to/privkey.pem
WARNING: cannot start TLS and DTLS listeners because certificate file is not set properly
WARNING: cannot find certificate file: /path/to/fullchain.pem

The issue typically stems from three potential factors:

  • Incorrect file permissions on the certificate files
  • Coturn service running under a user without read access
  • SELinux/AppArmor restrictions (on some Linux distributions)

Here's the proper way to configure Coturn with Let's Encrypt certificates:

# 1. Verify certificate paths in your coturn config (/etc/turnserver.conf)
cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem

# 2. Set proper permissions
sudo chmod 755 /etc/letsencrypt/{live,archive}
sudo chmod 640 /etc/letsencrypt/live/yourdomain.com/privkey.pem
sudo chmod 644 /etc/letsencrypt/live/yourdomain.com/fullchain.pem

# 3. Ensure the Coturn user can access the files
sudo chown -R turnserver:turnserver /etc/letsencrypt/live/yourdomain.com/

# 4. For SELinux systems (RHEL/CentOS)
sudo semanage fcontext -a -t cert_t "/etc/letsencrypt/live/yourdomain.com(/.*)?"
sudo restorecon -Rv /etc/letsencrypt/live/yourdomain.com

# 5. Restart Coturn
sudo systemctl restart coturn

For better maintainability, consider creating a dedicated certificate directory for Coturn:

sudo mkdir /etc/coturn/certs
sudo ln -s /etc/letsencrypt/live/yourdomain.com/fullchain.pem /etc/coturn/certs/
sudo ln -s /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/coturn/certs/

Then update your turnserver.conf:

cert=/etc/coturn/certs/fullchain.pem
pkey=/etc/coturn/certs/privkey.pem

Add this to your Let's Encrypt renewal hook to ensure Coturn reloads after certificate renewal:

#!/bin/bash
systemctl reload coturn

Save it as /etc/letsencrypt/renewal-hooks/deploy/reload-coturn.sh and make it executable:

chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-coturn.sh

When integrating Let's Encrypt certificates with Coturn (TURN server), many developers encounter permission and path-related errors despite having valid certificates. The typical error pattern looks like this:

WARNING: cannot start TLS and DTLS listeners because private key file is not set properly
WARNING: cannot find private key file: /path/to/privkey.pem
WARNING: cannot start TLS and DTLS listeners because certificate file is not set properly
WARNING: cannot find certificate file: /path/to/fullchain.pem

Coturn needs:

  • Read access to the certificate chain (typically fullchain.pem)
  • Read access to the private key (privkey.pem)
  • Appropriate file permissions (usually 600 or 640)
  • Correct ownership (turnserver user or group)

Here's how to properly configure the certificates:

# 1. Locate your Let's Encrypt certificates
sudo ls -l /etc/letsencrypt/live/yourdomain.com/

# 2. Set proper permissions (adjust paths accordingly)
sudo chmod 640 /etc/letsencrypt/live/yourdomain.com/privkey.pem
sudo chmod 644 /etc/letsencrypt/live/yourdomain.com/fullchain.pem

# 3. Change ownership to the turnserver user
sudo chown turnserver:turnserver /etc/letsencrypt/live/yourdomain.com/privkey.pem
sudo chown turnserver:turnserver /etc/letsencrypt/live/yourdomain.com/fullchain.pem

Your configuration should reference the absolute paths:

listening-port=3478
tls-listening-port=5349
alt-listening-port=3479
alt-tls-listening-port=5350
cert=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
pkey=/etc/letsencrypt/live/yourdomain.com/privkey.pem
# Recommended additional settings:
dh-file=/etc/ssl/certs/dhparam.pem
no-tlsv1
no-tlsv1_1

Add this to your certbot renewal hook:

#!/bin/bash
# /etc/letsencrypt/renewal-hooks/deploy/coturn-cert-renew.sh

# Set permissions again after renewal
chmod 640 /etc/letsencrypt/live/yourdomain.com/privkey.pem
chmod 644 /etc/letsencrypt/live/yourdomain.com/fullchain.pem
chown turnserver:turnserver /etc/letsencrypt/live/yourdomain.com/privkey.pem
chown turnserver:turnserver /etc/letsencrypt/live/yourdomain.com/fullchain.pem

# Reload coturn
systemctl reload coturn

Use these commands to test:

# Check if coturn is listening on TLS port
sudo netstat -tulnp | grep 5349

# Test TLS connectivity
openssl s_client -connect yourdomain.com:5349 -showcerts

# Check coturn logs
journalctl -u coturn -f

For systems where Coturn can't access /etc/letsencrypt:

sudo mkdir -p /etc/coturn/certs
sudo ln -s /etc/letsencrypt/live/yourdomain.com/fullchain.pem /etc/coturn/certs/
sudo ln -s /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/coturn/certs/
sudo chown -R turnserver:turnserver /etc/coturn/certs

Then update coturn.conf to point to these new locations.