diff --git a/openvidu-server/deployments/external-turn/.env b/openvidu-server/deployments/external-turn/.env new file mode 100644 index 00000000..121ef548 --- /dev/null +++ b/openvidu-server/deployments/external-turn/.env @@ -0,0 +1,12 @@ +# The domain which is pointing to the public ip of the machine. +TURN_DOMAIN_NAME= + +# If CERTIFICATE_TYPE=letsencrypt, you need to configure a valid email for notifications +LETSENCRYPT_EMAIL= + +# TURN fixed credentials. This parameter purpose is to support "TURN Server REST API". +# See: +# - https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00 +# - https://www.ietf.org/proceedings/87/slides/slides-87-behave-10.pdf +# IMPORTANT: USE ALPHANUMERIC VALUES TO AVOID ISSUES IN .env +TURN_STATIC_AUTH_SECRET= \ No newline at end of file diff --git a/openvidu-server/deployments/external-turn/certbot.sh b/openvidu-server/deployments/external-turn/certbot.sh new file mode 100755 index 00000000..86593264 --- /dev/null +++ b/openvidu-server/deployments/external-turn/certbot.sh @@ -0,0 +1,36 @@ +#!/bin/sh -x + +# Trap exit signal +exit_func() { + exit 1 +} +trap exit_func TERM INT + +export CRONTIME="${CRONTIME:-12h}" +export COTURN_CONTAINER_NAME="${COTURN_CONTAINER_NAME:-coturn}" + +while :; do + CERTIFICATES_FOUND=false + if [ -f "/etc/letsencrypt/live/${TURN_DOMAIN_NAME}/cert.pem" ] && + [ -f "/etc/letsencrypt/live/${TURN_DOMAIN_NAME}/privkey.pem" ]; then + CERTIFICATES_FOUND=true + fi + certbot "$@"; + chmod 777 -R /etc/letsencrypt; + TURN_PID=$(pgrep -n '^turnserver$') + if [ -n "${TURN_PID}" ]; then + if [ "${CERTIFICATES_FOUND}" = "false" ]; then + # If certificates not found on startup, restart coturn + kill -KILL "${TURN_PID}" + else + # Send SIGUSR2 signal to coturn to restart process with new certificates + # As certbot is running in the same namespace as coturn (#pid:container:coturn), + # it will send the signal to the coturn process to reload the certificates + kill -USR2 "${TURN_PID}" + fi + fi + # Sleep CRONTIME seconds for next check + sleep "${CRONTIME}" & + # Wait for sleep without blocking signals + wait $! +done; \ No newline at end of file diff --git a/openvidu-server/deployments/external-turn/docker-compose.yml b/openvidu-server/deployments/external-turn/docker-compose.yml new file mode 100644 index 00000000..f6c89e6e --- /dev/null +++ b/openvidu-server/deployments/external-turn/docker-compose.yml @@ -0,0 +1,57 @@ +version: '3' + +services: + coturn: + container_name: coturn + image: coturn/coturn:4.5.2 + restart: always + network_mode: host + volumes: + - ./certbot/etc/letsencrypt:/etc/letsencrypt + command: + - --cert=/etc/letsencrypt/live/${TURN_DOMAIN_NAME}/cert.pem + - --pkey=/etc/letsencrypt/live/${TURN_DOMAIN_NAME}/privkey.pem + - --realm=${TURN_DOMAIN_NAME} + - --fingerprint + - --listening-ip=0.0.0.0 + - --external-ip=$$(detect-external-ip) + - --listening-port=443 + - --tls-listening-port=443 + - --min-port=${MIN_PORT:-40000} + - --max-port=${MAX_PORT:-65535} + - --log-file=stdout + - --verbose + - --use-auth-secret + - --static-auth-secret=${TURN_STATIC_AUTH_SECRET} + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" + + certbot: + image: certbot/certbot + container_name: certbot + restart: always + pid: host + entrypoint: /wrapper/certbot.sh + ports: + - 80:80 + environment: + - CRONTIME=12h + - COTURN_CONTAINER_NAME=coturn + - TURN_DOMAIN_NAME=${TURN_DOMAIN_NAME} + volumes: + - ./certbot-wrapper/certbot.sh:/wrapper/certbot.sh + - ./certbot/etc/letsencrypt:/etc/letsencrypt + - ./certbot/letsencrypt:/var/lib/letsencrypt + - ./certbot/www-certbot:/var/www/certbot + command: + - certonly + - --non-interactive + - --standalone + - --preferred-challenges=http + - --email=${LETSENCRYPT_EMAIL} + - --agree-tos + - --domain=${TURN_DOMAIN_NAME} + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" \ No newline at end of file diff --git a/openvidu-server/deployments/external-turn/install_openvidu_external_coturn.sh b/openvidu-server/deployments/external-turn/install_openvidu_external_coturn.sh new file mode 100755 index 00000000..a7569331 --- /dev/null +++ b/openvidu-server/deployments/external-turn/install_openvidu_external_coturn.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash + +COTURN_FOLDER="coturn" +CERTBOT_WRAPPER="${COTURN_FOLDER}/certbot-wrapper" +COTURN_VERSION=master +DOWNLOAD_URL="https://raw.githubusercontent.com/OpenVidu/openvidu/master/openvidu-server/deployments/external-turn/${COTURN_VERSION}" +#COTURN_VERSION=4.5.2 +#DOWNLOAD_URL="https://s3.eu-west-1.amazonaws.com/aws.openvidu.io/external-turn/${COTURN_VERSION}" +fatal_error() { + printf "\n =======¡ERROR!=======" + printf "\n %s" "$1" + printf "\n" + exit 0 +} + +new_coturn_installation() { + printf '\n' + printf '\n =======================================' + printf '\n Install OpenVidu External Coturn %s' "${COTURN_VERSION}" + printf '\n =======================================' + printf '\n' + + # Create coturn directory + printf '\n => Creating folder '%s'...' "${COTURN_FOLDER}" + mkdir "${COTURN_FOLDER}" || fatal_error "Error while creating the folder '${COTURN_FOLDER}'" + + # Create coturn directory + printf '\n => Creating folder '%s'...' "${CERTBOT_WRAPPER}" + mkdir "${CERTBOT_WRAPPER}" || fatal_error "Error while creating the folder '${CERTBOT_WRAPPER}'" + + # Download necessary files + printf '\n => Downloading OpenVidu Pro files:' + + curl --silent ${DOWNLOAD_URL}/.env \ + --output "${COTURN_FOLDER}/.env" || fatal_error "Error when downloading the file '.env'" + printf '\n - .env' + + curl --silent ${DOWNLOAD_URL}/docker-compose.yml \ + --output "${COTURN_FOLDER}/docker-compose.yml" || fatal_error "Error when downloading the file 'docker-compose.yml'" + printf '\n - docker-compose.yml' + + curl --silent ${DOWNLOAD_URL}/certbot.sh \ + --output "${CERTBOT_WRAPPER}/certbot.sh" || fatal_error "Error when downloading the file 'certbot.sh'" + printf '\n - certbot.sh' + + + + # Add execution permissions + printf "\n => Adding permission:" + + chmod +x "${CERTBOT_WRAPPER}/certbot.sh" || fatal_error "Error while adding permission to 'certbot.sh'" + printf '\n - certbot.sh' + + # Ready to use + printf '\n' + printf '\n' + printf '\n =======================================' + printf '\n External OpenVidu Coturn installed. %s' "${COTURN_VERSION}" + printf '\n =======================================' + printf '\n' + printf '\n 1. Go to coturn folder:' + printf '\n $ cd coturn' + printf '\n' + printf '\n 2. Configure all parameters specified at the .env file ' + printf '\n $ nano .env' + printf '\n' + printf '\n 3. Start Coturn' + printf '\n $ docker-compose up -d' + printf '\n' + printf '\n' + exit 0 + +} + +# Check docker and docker-compose installation +if ! command -v docker > /dev/null; then + echo "You don't have docker installed, please install it and re-run the command" + exit 0 +fi + +if ! command -v docker-compose > /dev/null; then + echo "You don't have docker-compose installed, please install it and re-run the command" + exit 0 +else + COMPOSE_VERSION=$(docker-compose version --short | sed "s/-rc[0-9]*//") + if ! printf '%s\n%s\n' "1.24" "$COMPOSE_VERSION" | sort -V -C; then + echo "You need a docker-compose version equal or higher than 1.24, please update your docker-compose and re-run the command"; \ + exit 0 + fi +fi + +new_coturn_installation