Commit Graph

3 Commits

Author SHA1 Message Date
e018837a1d fix(livekit): анонсировать клиентам внешний TURN — relay не работал совсем
coturn поднимался, был healthy и слушал 3478 — но клиенты о нём никогда не
узнавали: встроенный TURN выключен (`turn.enabled: false`), внешний в
конфигурации не объявлен, фронтенд `iceServers` не задаёт. За всё время
работы сервера в логах coturn нет ни одной аллокации.

Следствие: у участников из сетей, где прямое UDP-соединение не проходит,
не было relay-фолбэка вообще — только прямой UDP и TCP 7881. На
нагрузочном тесте 28.07 все разрывы `PEER_CONNECTION_DISCONNECTED`
пришлись на внешних участников и ни одного — на офисных.

Добавлена секция `rtc.turn_servers` (UDP и TCP на 3478). Эти серверы
только анонсируются клиенту в списке ICE — сам SFU через них не ходит
(см. iceServersForParticipant в LiveKit). Credentials генерируются по
механизму TURN REST API из общего `TURN_STATIC_AUTH_SECRET`, поэтому
`render-templates.sh` теперь подставляет его и `TURN_EXTERNAL_IP` также в
конфигурацию LiveKit.

TLS (5349/443) намеренно не анонсируется: сертификаты в coturn не
смонтированы, а неработающий `turns:` заставил бы клиента ждать таймаута
перед переходом к рабочему кандидату. Что нужно для его включения —
описано в разделе 8 руководства.

Там же исправлено умолчание в правилах ufw: помимо 3478 нужен диапазон
relay-аллокаций `49160:49200/udp`. Без него TURN отвечает на запросы, но
релей не работает, причём в логах coturn при этом тишина.
2026-07-29 00:17:19 +03:00
5e42f6d11b deploy: require redis auth (--requirepass) across all consumers
Redis without a password was the root cause of the security incident
(cron miner via unauthenticated replication RCE, see
.forcc/deploy/SESSION2-FINDINGS.md). Loopback binding alone doesn't
protect against a compromised container inside the same compose
network, so wire REDIS_PASSWORD as a required secret everywhere redis
is used: backend/worker/worker-transcriber(-gpu), redis-exporter,
livekit and egress (via rendered templates). docker compose now
refuses to start without it instead of silently running unauthenticated.
2026-07-25 22:59:34 +03:00
79003eb56c deploy: harden nginx/coturn/livekit configs (TLS on 443, templates, required secrets)
Переносит рабочие правки продакшен-сервера в репозиторий воспроизводимо:

- nginx: HTTPS-блок на 443 (TLS1.2/1.3, http->https redirect, ACME
  webroot, X-Forwarded-Proto) добавлен в nginx.conf.template. Список
  доменов и имя каталога сертификата — параметры (NGINX_SERVER_NAMES,
  NGINX_CERT_NAME), не хардкод. Рендерится штатным entrypoint'ом образа
  nginx (envsubst-on-templates).
- Самоподписанный dev-сертификат генерируется на старте контейнера
  (docker-entrypoint-certs.sh), если реальный Let's Encrypt не смонтирован
  — иначе `docker compose up` без профиля ломался бы локально без
  реальных сертификатов.
- healthcheck nginx переключён на /healthz (без TLS-редиректа), иначе
  http://127.0.0.1:80/ после добавления 443-редиректа всегда unhealthy.
- coturn/turnserver.conf и livekit/livekit.yaml переведены в *.template —
  оба образа не читают env для статических полей (static-auth-secret,
  use_external_ip/node_ip, webhook.api_key), поэтому реальные файлы
  генерируются перед стартом стека скриптом deploy/render-templates.sh
  (вызывается install.sh). Секреты/IP — только в .env, не в git.
- docker-compose.yml: LIVEKIT_API_KEY/SECRET везде (backend, livekit,
  egress) через ${VAR:?} без небезопасных дефолтов; порт 443 + монтирование
  /etc/letsencrypt (ro) и certbot-webroot у nginx; build-args
  VITE_LIVEKIT_URL/NEXT_PUBLIC_LIVEKIT_URL для frontend (сейчас не
  используются кодом, оставлены про запас).
2026-07-25 21:57:46 +03:00