feat(turn): внешний TURN-релей и TLS через прокси
- install.sh: --tls-terminated-by-proxy (ссылки https/wss без своего 80/443), --turn-relay-host/--turn-relay-port/--turn-relay-tls-port, общий TURN_SECRET для coturn (use-auth-secret) и LiveKit - livekit.yaml.tpl: rtc.turn_servers с внешним релеем (udp + tls) - секрет вычисляется один раз и сохраняется в .env
This commit is contained in:
+57
-2
@@ -57,6 +57,10 @@ TURN_RELAY_START="${TURN_RELAY_START:-30000}"
|
||||
TURN_RELAY_END="${TURN_RELAY_END:-40000}"
|
||||
TURN_CERT_SRC="${TURN_CERT_SRC:-}"
|
||||
TURN_CERT_SRC_KEY="${TURN_CERT_SRC_KEY:-}"
|
||||
TURN_RELAY_HOST="${TURN_RELAY_HOST:-}"
|
||||
TURN_RELAY_PORT="${TURN_RELAY_PORT:-3478}"
|
||||
TURN_RELAY_TLS_PORT="${TURN_RELAY_TLS_PORT:-5349}"
|
||||
TLS_BY_PROXY="${TLS_BY_PROXY:-false}"
|
||||
TURN_TLS_PORT="${TURN_TLS_PORT:-5349}"
|
||||
PROXY_MODE="${PROXY_MODE:-embedded}"
|
||||
PROFILE="${PROFILE:-auto}"
|
||||
@@ -116,6 +120,12 @@ install.sh — установка glchat (AGENT.md 10).
|
||||
--turn-domain <domain> домен TURN/TLS (по умолчанию turn.<domain>)
|
||||
--turn-cert <файл> сертификат для TURN/TLS (нужен при включённом TURN)
|
||||
--turn-key <файл> приватный ключ сертификата TURN/TLS
|
||||
--turn-relay-host <host> внешний TURN-релей с публичным IP (например, VPS):
|
||||
клиенты получают его в списке turn_servers
|
||||
--turn-relay-port <port> UDP-порт внешнего релея (по умолчанию 3478)
|
||||
--turn-relay-tls-port <port> TLS-порт внешнего релея (по умолчанию 5349)
|
||||
--tls-terminated-by-proxy TLS терминирует внешний прокси: свои 80/443 не занимаем,
|
||||
но ссылки в API отдаются как https/wss
|
||||
--turn-tls <port> TURN TLS (по умолчанию 5349)
|
||||
--external-proxy не занимать 80/443: отдать маршруты внешнему прокси (AGENT.md 10.13)
|
||||
--no-files-subdomain не использовать files.<domain> (fallback /files/*)
|
||||
@@ -163,6 +173,10 @@ parse_args() {
|
||||
--turn-domain) TURN_DOMAIN_OVERRIDE="${2:?}"; shift 2 ;;
|
||||
--turn-cert) TURN_CERT_SRC="${2:?}"; shift 2 ;;
|
||||
--turn-key) TURN_CERT_SRC_KEY="${2:?}"; shift 2 ;;
|
||||
--turn-relay-host) TURN_RELAY_HOST="${2:?}"; shift 2 ;;
|
||||
--turn-relay-port) TURN_RELAY_PORT="${2:?}"; shift 2 ;;
|
||||
--turn-relay-tls-port) TURN_RELAY_TLS_PORT="${2:?}"; shift 2 ;;
|
||||
--tls-terminated-by-proxy) TLS_BY_PROXY="true"; shift ;;
|
||||
--turn-tls) TURN_TLS_PORT="${2:?}"; shift 2 ;;
|
||||
--profile) PROFILE="${2:?}"; shift 2 ;;
|
||||
--max-upload) MAX_UPLOAD_MB="${2:?}"; shift 2 ;;
|
||||
@@ -255,6 +269,8 @@ resolve_derived_values() {
|
||||
|
||||
TURN_DOMAIN_RESOLVED="${TURN_DOMAIN_OVERRIDE:-turn.${DOMAIN}}"
|
||||
TURN_CERT_DIR="${TARGET_DIR}/certs"
|
||||
TURN_RELAY_HOST_RESOLVED="${TURN_RELAY_HOST}"
|
||||
turn_shared_secret >/dev/null
|
||||
|
||||
disable_simulcast="true"
|
||||
if [ "${PROFILE_LIVEKIT_SIMULCAST:-0}" -gt 0 ] 2>/dev/null; then
|
||||
@@ -281,7 +297,7 @@ resolve_derived_values() {
|
||||
livekit_extra_codecs \
|
||||
PROFILE_LIVEKIT_DISABLE_SIMULCAST PROFILE_LIVEKIT_USE_EXTERNAL_IP \
|
||||
GLCHAT_DATA_DIR GLCHAT_CADDY_PROFILE GLCHAT_TURN_CERT_DIR \
|
||||
TURN_DOMAIN_RESOLVED TURN_CERT_DIR
|
||||
TURN_DOMAIN_RESOLVED TURN_CERT_DIR TURN_RELAY_HOST_RESOLVED TURN_SECRET_RESOLVED
|
||||
}
|
||||
|
||||
validate_inputs() {
|
||||
@@ -518,13 +534,24 @@ CADDY_IMAGE_TAG=${CADDY_IMAGE_TAG}
|
||||
LIVEKIT_IMAGE_TAG=${LIVEKIT_IMAGE_TAG}
|
||||
|
||||
# --- TLS ---
|
||||
TLS_ENABLED=$([ "$SKIP_TLS" = "1" ] && echo false || echo true)
|
||||
# TLS считается включённым и когда сертификаты обслуживает внешний прокси
|
||||
# (--external-proxy --tls-terminated-by-proxy): клиентские ссылки должны быть https/wss.
|
||||
if [ "$SKIP_TLS" = "1" ] && [ "$TLS_BY_PROXY" != "true" ]; then
|
||||
TLS_ENABLED=false
|
||||
else
|
||||
TLS_ENABLED=true
|
||||
fi
|
||||
SKIP_TLS=${SKIP_TLS}
|
||||
TLS_BY_PROXY=${TLS_BY_PROXY}
|
||||
|
||||
# --- интерполяция compose (пути и профиль) ---
|
||||
GLCHAT_DATA_DIR=${GLCHAT_DATA_DIR}
|
||||
GLCHAT_CADDY_PROFILE=${CADDY_PROFILE}
|
||||
GLCHAT_TURN_CERT_DIR=${GLCHAT_TURN_CERT_DIR}
|
||||
TURN_RELAY_HOST=${TURN_RELAY_HOST_RESOLVED}
|
||||
TURN_RELAY_PORT=${TURN_RELAY_PORT}
|
||||
TURN_RELAY_TLS_PORT=${TURN_RELAY_TLS_PORT}
|
||||
TURN_SECRET=${TURN_SECRET_RESOLVED}
|
||||
|
||||
# --- порты ---
|
||||
APP_PORT=${APP_PORT}
|
||||
@@ -666,6 +693,33 @@ ensure_swap() {
|
||||
|
||||
|
||||
|
||||
# render_turn_relay_servers формирует YAML-список turn_servers для LiveKit:
|
||||
# UDP и TLS-эндпоинты внешнего релея (VPS), у которого есть публичный IP.
|
||||
# Секрет уже вычислен в resolve_derived_values (TURN_SECRET_RESOLVED).
|
||||
render_turn_relay_servers() {
|
||||
[ -n "$TURN_RELAY_HOST" ] || return 0
|
||||
printf ' turn_servers:\n'
|
||||
printf ' - host: %s\n port: %s\n protocol: udp\n secret: %s\n' \
|
||||
"$TURN_RELAY_HOST" "$TURN_RELAY_PORT" "$TURN_SECRET_RESOLVED"
|
||||
printf ' - host: %s\n port: %s\n protocol: tls\n secret: %s\n' \
|
||||
"$TURN_RELAY_HOST" "$TURN_RELAY_TLS_PORT" "$TURN_SECRET_RESOLVED"
|
||||
}
|
||||
|
||||
# turn_shared_secret — общий секрет для coturn (use-auth-secret) и LiveKit.
|
||||
# При --reconfigure сохраняется из существующего .env, иначе генерируется.
|
||||
turn_shared_secret() {
|
||||
if [ -n "${TURN_SECRET_RESOLVED:-}" ]; then
|
||||
printf '%s' "$TURN_SECRET_RESOLVED"
|
||||
return
|
||||
fi
|
||||
if [ -f "$GLCHAT_ENV_FILE" ]; then
|
||||
TURN_SECRET_RESOLVED="$(env_get TURN_SECRET || true)"
|
||||
fi
|
||||
[ -n "${TURN_SECRET_RESOLVED:-}" ] || TURN_SECRET_RESOLVED="$(rand_hex 32)"
|
||||
export TURN_SECRET_RESOLVED
|
||||
printf '%s' "$TURN_SECRET_RESOLVED"
|
||||
}
|
||||
|
||||
# install_turn_certificate копирует сертификат TURN/TLS туда, где его читает
|
||||
# контейнер LiveKit. Продление выполняет glchat-cert-refresh.timer.
|
||||
install_turn_certificate() {
|
||||
@@ -746,6 +800,7 @@ render_all_templates() {
|
||||
"TURN_RELAY_END=${TURN_RELAY_END}" \
|
||||
"TURN_CERT_FILE=$([ "$TURN_ENABLED" = "true" ] && echo /etc/certs/turn.crt || echo '')" \
|
||||
"TURN_KEY_FILE=$([ "$TURN_ENABLED" = "true" ] && echo /etc/certs/turn.key || echo '')" \
|
||||
"TURN_RELAY_SERVERS=$(render_turn_relay_servers)" \
|
||||
"TURN_UDP_PORT=${TURN_UDP_PORT}" \
|
||||
"TURN_TLS_PORT=${TURN_TLS_PORT}" \
|
||||
"TURN_EXTERNAL_TLS=${turn_external_tls}" \
|
||||
|
||||
@@ -11,6 +11,9 @@ rtc:
|
||||
use_external_ip: ${LIVEKIT_USE_EXTERNAL_IP}
|
||||
# TCP-fallback, когда UDP заблокирован сетью клиента (AGENT.md 7.14).
|
||||
allow_tcp_fallback: true
|
||||
# Внешний TURN-релей с публичным IP (VPS): даёт рабочий путь клиентам за
|
||||
# NAT/CGNAT, когда у самого инстанса белого адреса нет.
|
||||
${TURN_RELAY_SERVERS}
|
||||
|
||||
keys: {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user