feat(coturn): TURN over TLS на 5349 — сертификаты, монтирование, анонс клиентам

coturn (nobody:nogroup, без root-фазы в entrypoint) не может сам прочитать
приватный ключ Let's Encrypt — coturn-certs-init (по образцу
recordings-init/llm-models-init) копирует fullchain/privkey в отдельный
volume под правами 644, не трогая права на ключ на хосте.

TURN_TLS_HOST в .env — единственный переключатель фичи: пусто (dev-дефолт)
вырезает TLS-блоки из turnserver.conf и rtc.turn_servers целиком (маркеры
BEGIN/END-TLS-* в *.template, render-templates.sh), непустое значение
включает оба сразу — TLS без анонса LiveKit клиентам не имеет смысла
(история 0.0.14: coturn работал healthy, но клиенты о нём не знали, и не
было ни одной аллокации). Значение обязано быть доменом сертификата, а не
IP — иначе браузер не пройдёт TLS-валидацию по имени хоста для turns:.

TLS-запись в rtc.turn_servers стоит последней в списке (фолбэк дороже
прямого UDP/TCP).
This commit is contained in:
2026-08-02 20:26:56 +03:00
parent 45c997380f
commit 9bc8d6174d
6 changed files with 134 additions and 14 deletions

View File

@@ -59,6 +59,16 @@ TURN_STATIC_AUTH_SECRET=change-me-turn-secret
# скриптом deploy/render-templates.sh (вызывается install.sh).
TURN_EXTERNAL_IP=127.0.0.1
# TURN over TLS (5349) — единственный переключатель во всём проекте: пусто =
# TLS выключен везде (dev-дефолт, как ниже), непустое значение = coturn
# слушает TLS на 5349 (сертификат смонтирован из /etc/letsencrypt через
# coturn-certs-init, docker-compose.yml) И LiveKit объявляет клиентам запись
# protocol: tls. ⚠️ Обязан быть ДОМЕНОМ сертификата (например, vidconf.ru —
# тем же, что и NGINX_CERT_NAME), а НЕ IP-адресом, в отличие от
# TURN_EXTERNAL_IP выше: браузер проверяет TLS-сертификат TURN-сервера по
# имени хоста, а Let's Encrypt выписывает сертификат на домен.
TURN_TLS_HOST=
# --- Nginx: TLS (443) + список доменов — deploy/nginx/nginx.conf.template ---
# Домены, которые обслуживает nginx (через пробел, все — в server_name).
NGINX_SERVER_NAMES=example.com www.example.com