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.
59 lines
3.5 KiB
Bash
Executable File
59 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Рендерит статические конфиги coturn/LiveKit из шаблонов (deploy/**/*.template)
|
||
# в реальные файлы, которые монтирует docker-compose. Оба образа (coturn,
|
||
# livekit-server) НЕ поддерживают подстановку переменных окружения в файле
|
||
# конфигурации (см. комментарии в *.template) — единственный способ вынести
|
||
# секреты/IP в .env и не хранить их в git — сгенерировать файл перед стартом.
|
||
#
|
||
# Вызывается автоматически из install.sh. При ручном запуске (без install.sh)
|
||
# запускайте ПЕРЕД `docker compose up` (и после каждого изменения .env,
|
||
# влияющего на эти конфиги) — из корня репозитория:
|
||
# ./deploy/render-templates.sh
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
ENV_FILE="$SCRIPT_DIR/../.env"
|
||
|
||
if [ ! -f "$ENV_FILE" ]; then
|
||
echo "render-templates.sh: не найден $ENV_FILE — сначала запустите ./install.sh или скопируйте .env.example в .env" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# Читаем только нужные ключи через grep/cut (НЕ `source .env`) — .env содержит
|
||
# значения вроде `SMTP_FROM=VidConf <no-reply@vidconf.example>`, где `<` —
|
||
# валидный литерал для docker-compose/pydantic, но невалидный bash-синтаксис
|
||
# (интерпретируется как редирект) при попытке `source` файла целиком.
|
||
env_var() {
|
||
grep -E "^${1}=" "$ENV_FILE" 2>/dev/null | tail -1 | cut -d= -f2-
|
||
}
|
||
|
||
TURN_STATIC_AUTH_SECRET="$(env_var TURN_STATIC_AUTH_SECRET)"
|
||
TURN_REALM="$(env_var TURN_REALM)"
|
||
TURN_EXTERNAL_IP="$(env_var TURN_EXTERNAL_IP)"
|
||
LIVEKIT_API_KEY="$(env_var LIVEKIT_API_KEY)"
|
||
LIVEKIT_NODE_IP="$(env_var LIVEKIT_NODE_IP)"
|
||
LIVEKIT_USE_EXTERNAL_IP="$(env_var LIVEKIT_USE_EXTERNAL_IP)"
|
||
REDIS_PASSWORD="$(env_var REDIS_PASSWORD)"
|
||
|
||
: "${TURN_STATIC_AUTH_SECRET:?TURN_STATIC_AUTH_SECRET не задан в .env}"
|
||
: "${TURN_REALM:?TURN_REALM не задан в .env}"
|
||
: "${TURN_EXTERNAL_IP:?TURN_EXTERNAL_IP не задан в .env (внешний IP/домен сервера для TURN-релея)}"
|
||
: "${LIVEKIT_API_KEY:?LIVEKIT_API_KEY не задан в .env}"
|
||
: "${LIVEKIT_NODE_IP:?LIVEKIT_NODE_IP не задан в .env (внешний IP/домен для ICE)}"
|
||
: "${LIVEKIT_USE_EXTERNAL_IP:?LIVEKIT_USE_EXTERNAL_IP не задан в .env (true/false)}"
|
||
: "${REDIS_PASSWORD:?REDIS_PASSWORD не задан в .env (redis запускается с --requirepass, см. docker-compose.yml)}"
|
||
|
||
export TURN_STATIC_AUTH_SECRET TURN_REALM TURN_EXTERNAL_IP LIVEKIT_API_KEY LIVEKIT_NODE_IP LIVEKIT_USE_EXTERNAL_IP REDIS_PASSWORD
|
||
|
||
envsubst '${TURN_STATIC_AUTH_SECRET} ${TURN_REALM} ${TURN_EXTERNAL_IP}' \
|
||
< "$SCRIPT_DIR/coturn/turnserver.conf.template" > "$SCRIPT_DIR/coturn/turnserver.conf"
|
||
echo "[render] deploy/coturn/turnserver.conf готов"
|
||
|
||
envsubst '${LIVEKIT_USE_EXTERNAL_IP} ${LIVEKIT_NODE_IP} ${LIVEKIT_API_KEY} ${REDIS_PASSWORD}' \
|
||
< "$SCRIPT_DIR/livekit/livekit.yaml.template" > "$SCRIPT_DIR/livekit/livekit.yaml"
|
||
echo "[render] deploy/livekit/livekit.yaml готов"
|
||
|
||
envsubst '${REDIS_PASSWORD}' \
|
||
< "$SCRIPT_DIR/egress/egress.yaml.template" > "$SCRIPT_DIR/egress/egress.yaml"
|
||
echo "[render] deploy/egress/egress.yaml готов"
|