How to setup coturn with letsencrypt

Giving this setup: A Nginx is providing a .well-known folder listening on port 80/443 on the server to exchange the chellange for Letsencrypt. The certificate is created properly and can be used e.g. in mentioned Nginx.

When trying to make usage of the certificate by coturn:

listening-port=3478
tls-listening-port=5349
alt-listening-port=3479
alt-tls-listening-port=5350
…
cert=/path/to/fullchain.pem
pkey=/path/to/privkey.pem

When now trying to start coturn, it appears it doesn't find/is unable to load the certs as from logs:

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

Now I'm wondering what is the correct way to setup coturn using a letsencrypt SSL chain.


Thanks for the question. Letsencrypt supports post deploy hooks. I used it with the following.

I am using a Debian 10 buster with coturn 4.5.1.1-1.1 and letsencrypt certbot 0.31.0 . Assuming:

  • coturn user: turnserver
  • coturn group: turnserver
  • letsencrypt configuration folder: /etc/letsencrypt/
  • domain name: example.com
  • coturn service can be restarted with this command: service coturn restart
  • coturn configuration file: /etc/turnserver.conf

Please adapt accordingly if your configuration differs from the above assumptions.

mkdir -p /etc/coturn/certs
chown -R turnserver:turnserver /etc/coturn/
chmod -R 700 /etc/coturn/
nano /etc/letsencrypt/renewal-hooks/deploy/coturn-certbot-deploy.sh
chmod 700 /etc/letsencrypt/renewal-hooks/deploy/coturn-certbot-deploy.sh

Adapted coturn-certbot-deploy.sh for coturn from the linked letsencrypt page example:

#!/bin/sh

set -e

for domain in $RENEWED_DOMAINS; do
        case $domain in
        example.com)
                daemon_cert_root=/etc/coturn/certs

                # Make sure the certificate and private key files are
                # never world readable, even just for an instant while
                # we're copying them into daemon_cert_root.
                umask 077

                cp "$RENEWED_LINEAGE/fullchain.pem" "$daemon_cert_root/$domain.cert"
                cp "$RENEWED_LINEAGE/privkey.pem" "$daemon_cert_root/$domain.key"

                # Apply the proper file ownership and permissions for
                # the daemon to read its certificate and key.
                chown turnserver "$daemon_cert_root/$domain.cert" \
                        "$daemon_cert_root/$domain.key"
                chmod 400 "$daemon_cert_root/$domain.cert" \
                        "$daemon_cert_root/$domain.key"

                service coturn restart >/dev/null
                ;;
        esac
done

You need to change example.com to your domain name in the above file.

Edit the certificate files locations in the coturn configuration file:

nano /etc/turnserver.conf

With those lines for example.com domain:

...
cert=/etc/coturn/certs/example.com.cert
...
pkey=/etc/coturn/certs/example.com.key
...

I was able to test the renewal through this command for all the certificates:

certbot renew --force-renewal

Or this command only for a given domain:

certbot certonly --force-renewal -d example.com

My coturn logs no longer show the following lines:

0: WARNING: cannot find certificate file: /etc/letsencrypt/live/example.com/fullchain.pem (1)
0: WARNING: cannot start TLS and DTLS listeners because certificate file is not set properly
0: WARNING: cannot find private key file: /etc/letsencrypt/live/example.com/privkey.pem (1)
0: WARNING: cannot start TLS and DTLS listeners because private key file is not set properly

Instead, I get the nice following ones:

...
0: ...: Certificate file found: /etc/coturn/certs/example.com.cert
0: ...: Private key file found: /etc/coturn/certs/example.com.key
...