feat(turn): TURN/TLS с сертификатом, порты релея и автообновление сертификата
- install.sh: --turn-domain/--turn-cert/--turn-key, проверка наличия сертификата, копирование в /opt/glchat/certs, UFW открывает диапазон релея - livekit.yaml.tpl: relay_range_start/end, cert_file/key_file - compose: сертификаты монтируются в LiveKit read-only - systemd timer glchat-cert-refresh: ежедневно копирует обновлённый сертификат из внешнего ACME-хранилища и перезапускает LiveKit при изменении - smoke.sh: TURN-порты обязательны при включённом TURN + проверка CN сертификата
This commit is contained in:
@@ -67,6 +67,7 @@ services:
|
|||||||
ports: []
|
ports: []
|
||||||
volumes:
|
volumes:
|
||||||
- ./livekit/livekit.yaml:/etc/livekit.yaml:ro
|
- ./livekit/livekit.yaml:/etc/livekit.yaml:ro
|
||||||
|
- ${GLCHAT_TURN_CERT_DIR}:/etc/certs:ro
|
||||||
logging: *default-logging
|
logging: *default-logging
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ services:
|
|||||||
- "${LIVEKIT_UDP_PORT}:7882/udp"
|
- "${LIVEKIT_UDP_PORT}:7882/udp"
|
||||||
volumes:
|
volumes:
|
||||||
- ./livekit/livekit.yaml:/etc/livekit.yaml:ro
|
- ./livekit/livekit.yaml:/etc/livekit.yaml:ro
|
||||||
|
- ${GLCHAT_TURN_CERT_DIR}:/etc/certs:ro
|
||||||
logging: *default-logging
|
logging: *default-logging
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
+113
-3
@@ -52,6 +52,11 @@ LIVEKIT_WS_PORT="${LIVEKIT_WS_PORT:-7880}"
|
|||||||
LIVEKIT_TCP_PORT="${LIVEKIT_TCP_PORT:-7881}"
|
LIVEKIT_TCP_PORT="${LIVEKIT_TCP_PORT:-7881}"
|
||||||
LIVEKIT_UDP_PORT="${LIVEKIT_UDP_PORT:-7882}"
|
LIVEKIT_UDP_PORT="${LIVEKIT_UDP_PORT:-7882}"
|
||||||
TURN_UDP_PORT="${TURN_UDP_PORT:-3478}"
|
TURN_UDP_PORT="${TURN_UDP_PORT:-3478}"
|
||||||
|
TURN_DOMAIN_OVERRIDE="${TURN_DOMAIN_OVERRIDE:-}"
|
||||||
|
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_TLS_PORT="${TURN_TLS_PORT:-5349}"
|
TURN_TLS_PORT="${TURN_TLS_PORT:-5349}"
|
||||||
PROXY_MODE="${PROXY_MODE:-embedded}"
|
PROXY_MODE="${PROXY_MODE:-embedded}"
|
||||||
PROFILE="${PROFILE:-auto}"
|
PROFILE="${PROFILE:-auto}"
|
||||||
@@ -108,6 +113,9 @@ install.sh — установка glchat (AGENT.md 10).
|
|||||||
--livekit-tcp <port> LiveKit TCP (по умолчанию 7881)
|
--livekit-tcp <port> LiveKit TCP (по умолчанию 7881)
|
||||||
--livekit-udp <port> LiveKit UDP (по умолчанию 7882)
|
--livekit-udp <port> LiveKit UDP (по умолчанию 7882)
|
||||||
--turn-udp <port> TURN UDP (по умолчанию 3478)
|
--turn-udp <port> TURN UDP (по умолчанию 3478)
|
||||||
|
--turn-domain <domain> домен TURN/TLS (по умолчанию turn.<domain>)
|
||||||
|
--turn-cert <файл> сертификат для TURN/TLS (нужен при включённом TURN)
|
||||||
|
--turn-key <файл> приватный ключ сертификата TURN/TLS
|
||||||
--turn-tls <port> TURN TLS (по умолчанию 5349)
|
--turn-tls <port> TURN TLS (по умолчанию 5349)
|
||||||
--external-proxy не занимать 80/443: отдать маршруты внешнему прокси (AGENT.md 10.13)
|
--external-proxy не занимать 80/443: отдать маршруты внешнему прокси (AGENT.md 10.13)
|
||||||
--no-files-subdomain не использовать files.<domain> (fallback /files/*)
|
--no-files-subdomain не использовать files.<domain> (fallback /files/*)
|
||||||
@@ -152,6 +160,9 @@ parse_args() {
|
|||||||
--livekit-tcp) LIVEKIT_TCP_PORT="${2:?}"; shift 2 ;;
|
--livekit-tcp) LIVEKIT_TCP_PORT="${2:?}"; shift 2 ;;
|
||||||
--livekit-udp) LIVEKIT_UDP_PORT="${2:?}"; shift 2 ;;
|
--livekit-udp) LIVEKIT_UDP_PORT="${2:?}"; shift 2 ;;
|
||||||
--turn-udp) TURN_UDP_PORT="${2:?}"; shift 2 ;;
|
--turn-udp) TURN_UDP_PORT="${2:?}"; shift 2 ;;
|
||||||
|
--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-tls) TURN_TLS_PORT="${2:?}"; shift 2 ;;
|
--turn-tls) TURN_TLS_PORT="${2:?}"; shift 2 ;;
|
||||||
--profile) PROFILE="${2:?}"; shift 2 ;;
|
--profile) PROFILE="${2:?}"; shift 2 ;;
|
||||||
--max-upload) MAX_UPLOAD_MB="${2:?}"; shift 2 ;;
|
--max-upload) MAX_UPLOAD_MB="${2:?}"; shift 2 ;;
|
||||||
@@ -242,6 +253,9 @@ resolve_derived_values() {
|
|||||||
[ "$PROXY_MODE" = "external" ] && turn_external_tls="true"
|
[ "$PROXY_MODE" = "external" ] && turn_external_tls="true"
|
||||||
TURN_EXTERNAL_TLS="$turn_external_tls"
|
TURN_EXTERNAL_TLS="$turn_external_tls"
|
||||||
|
|
||||||
|
TURN_DOMAIN_RESOLVED="${TURN_DOMAIN_OVERRIDE:-turn.${DOMAIN}}"
|
||||||
|
TURN_CERT_DIR="${TARGET_DIR}/certs"
|
||||||
|
|
||||||
disable_simulcast="true"
|
disable_simulcast="true"
|
||||||
if [ "${PROFILE_LIVEKIT_SIMULCAST:-0}" -gt 0 ] 2>/dev/null; then
|
if [ "${PROFILE_LIVEKIT_SIMULCAST:-0}" -gt 0 ] 2>/dev/null; then
|
||||||
disable_simulcast="false"
|
disable_simulcast="false"
|
||||||
@@ -262,10 +276,12 @@ resolve_derived_values() {
|
|||||||
|
|
||||||
GLCHAT_DATA_DIR="${GLCHAT_DATA_DIR}"
|
GLCHAT_DATA_DIR="${GLCHAT_DATA_DIR}"
|
||||||
GLCHAT_CADDY_PROFILE="${CADDY_PROFILE}"
|
GLCHAT_CADDY_PROFILE="${CADDY_PROFILE}"
|
||||||
|
GLCHAT_TURN_CERT_DIR="${TURN_CERT_DIR}"
|
||||||
export FILES_DOMAIN_RESOLVED CADDY_PROFILE LIVEKIT_PUBLISH TURN_EXTERNAL_TLS \
|
export FILES_DOMAIN_RESOLVED CADDY_PROFILE LIVEKIT_PUBLISH TURN_EXTERNAL_TLS \
|
||||||
livekit_extra_codecs \
|
livekit_extra_codecs \
|
||||||
PROFILE_LIVEKIT_DISABLE_SIMULCAST PROFILE_LIVEKIT_USE_EXTERNAL_IP \
|
PROFILE_LIVEKIT_DISABLE_SIMULCAST PROFILE_LIVEKIT_USE_EXTERNAL_IP \
|
||||||
GLCHAT_DATA_DIR GLCHAT_CADDY_PROFILE
|
GLCHAT_DATA_DIR GLCHAT_CADDY_PROFILE GLCHAT_TURN_CERT_DIR \
|
||||||
|
TURN_DOMAIN_RESOLVED TURN_CERT_DIR
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_inputs() {
|
validate_inputs() {
|
||||||
@@ -283,6 +299,11 @@ validate_inputs() {
|
|||||||
if [ -n "$ADMIN_PASSWORD" ] && [ "${#ADMIN_PASSWORD}" -lt 8 ]; then
|
if [ -n "$ADMIN_PASSWORD" ] && [ "${#ADMIN_PASSWORD}" -lt 8 ]; then
|
||||||
die "пароль администратора короче 8 символов"
|
die "пароль администратора короче 8 символов"
|
||||||
fi
|
fi
|
||||||
|
# LiveKit требует сертификат для TURN/TLS (проверено на v1.9.7: без него
|
||||||
|
# сервер не стартует). Либо передаём файлы, либо отключаем TURN.
|
||||||
|
if [ "$TURN_ENABLED" = "true" ] && [ "$DRY_RUN" != "1" ] && [ -z "$TURN_CERT_SRC" ]; then
|
||||||
|
die "TURN включён, но не задан сертификат: передайте --turn-cert/--turn-key или запустите с --no-turn"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
check_ports_free() {
|
check_ports_free() {
|
||||||
@@ -503,6 +524,7 @@ SKIP_TLS=${SKIP_TLS}
|
|||||||
# --- интерполяция compose (пути и профиль) ---
|
# --- интерполяция compose (пути и профиль) ---
|
||||||
GLCHAT_DATA_DIR=${GLCHAT_DATA_DIR}
|
GLCHAT_DATA_DIR=${GLCHAT_DATA_DIR}
|
||||||
GLCHAT_CADDY_PROFILE=${CADDY_PROFILE}
|
GLCHAT_CADDY_PROFILE=${CADDY_PROFILE}
|
||||||
|
GLCHAT_TURN_CERT_DIR=${GLCHAT_TURN_CERT_DIR}
|
||||||
|
|
||||||
# --- порты ---
|
# --- порты ---
|
||||||
APP_PORT=${APP_PORT}
|
APP_PORT=${APP_PORT}
|
||||||
@@ -627,6 +649,27 @@ ensure_swap() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# install_turn_certificate копирует сертификат TURN/TLS туда, где его читает
|
||||||
|
# контейнер LiveKit. Продление выполняет glchat-cert-refresh.timer.
|
||||||
|
install_turn_certificate() {
|
||||||
|
[ "$TURN_ENABLED" = "true" ] || return 0
|
||||||
|
if [ "$DRY_RUN" = "1" ]; then
|
||||||
|
log_file_only "DRY-RUN: копирование сертификата TURN/TLS в ${TURN_CERT_DIR}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
mkdir -p "$TURN_CERT_DIR"
|
||||||
|
chmod 750 "$TURN_CERT_DIR"
|
||||||
|
if [ -n "$TURN_CERT_SRC" ]; then
|
||||||
|
install -m 640 "$TURN_CERT_SRC" "${TURN_CERT_DIR}/turn.crt"
|
||||||
|
install -m 640 "${TURN_CERT_SRC_KEY:?нужен --turn-key}" "${TURN_CERT_DIR}/turn.key"
|
||||||
|
ok "сертификат TURN/TLS установлен: ${TURN_CERT_DIR}/turn.crt"
|
||||||
|
elif [ -f "${TURN_CERT_DIR}/turn.crt" ]; then
|
||||||
|
ok "используем ранее установленный сертификат TURN/TLS"
|
||||||
|
else
|
||||||
|
warn "сертификат TURN/TLS не найден: TURN не запустится (см. --turn-cert)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
render_all_templates() {
|
render_all_templates() {
|
||||||
info "генерируем конфиги в ${TARGET_DIR}"
|
info "генерируем конфиги в ${TARGET_DIR}"
|
||||||
mkdir -p "${TARGET_DIR}"/{caddy/logs,caddy/data,caddy/config,livekit,fail2ban,nftables}
|
mkdir -p "${TARGET_DIR}"/{caddy/logs,caddy/data,caddy/config,livekit,fail2ban,nftables}
|
||||||
@@ -661,6 +704,7 @@ render_all_templates() {
|
|||||||
"CADDY_CPUS=1.0" "CADDY_MEMORY_LIMIT=256m" \
|
"CADDY_CPUS=1.0" "CADDY_MEMORY_LIMIT=256m" \
|
||||||
"CADDY_IMAGE_TAG=${CADDY_IMAGE_TAG}" "LIVEKIT_IMAGE_TAG=${LIVEKIT_IMAGE_TAG}" \
|
"CADDY_IMAGE_TAG=${CADDY_IMAGE_TAG}" "LIVEKIT_IMAGE_TAG=${LIVEKIT_IMAGE_TAG}" \
|
||||||
"GLCHAT_CADDY_PROFILE=${CADDY_PROFILE}" \
|
"GLCHAT_CADDY_PROFILE=${CADDY_PROFILE}" \
|
||||||
|
"GLCHAT_TURN_CERT_DIR=${TURN_CERT_DIR}" \
|
||||||
"LIVEKIT_API_KEY=${LIVEKIT_API_KEY}" "LIVEKIT_API_SECRET=${LIVEKIT_API_SECRET}" \
|
"LIVEKIT_API_KEY=${LIVEKIT_API_KEY}" "LIVEKIT_API_SECRET=${LIVEKIT_API_SECRET}" \
|
||||||
"HTTP_PORT=${HTTP_PORT}" "HTTPS_PORT=${HTTPS_PORT}"
|
"HTTP_PORT=${HTTP_PORT}" "HTTPS_PORT=${HTTPS_PORT}"
|
||||||
|
|
||||||
@@ -680,7 +724,11 @@ render_all_templates() {
|
|||||||
"LIVEKIT_UDP_PORT=${LIVEKIT_UDP_PORT}" \
|
"LIVEKIT_UDP_PORT=${LIVEKIT_UDP_PORT}" \
|
||||||
"LIVEKIT_USE_EXTERNAL_IP=${use_external_ip}" \
|
"LIVEKIT_USE_EXTERNAL_IP=${use_external_ip}" \
|
||||||
"TURN_ENABLED=${TURN_ENABLED}" \
|
"TURN_ENABLED=${TURN_ENABLED}" \
|
||||||
"TURN_DOMAIN=turn.${DOMAIN}" \
|
"TURN_DOMAIN=${TURN_DOMAIN_RESOLVED}" \
|
||||||
|
"TURN_RELAY_START=${TURN_RELAY_START}" \
|
||||||
|
"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_UDP_PORT=${TURN_UDP_PORT}" \
|
"TURN_UDP_PORT=${TURN_UDP_PORT}" \
|
||||||
"TURN_TLS_PORT=${TURN_TLS_PORT}" \
|
"TURN_TLS_PORT=${TURN_TLS_PORT}" \
|
||||||
"TURN_EXTERNAL_TLS=${turn_external_tls}" \
|
"TURN_EXTERNAL_TLS=${turn_external_tls}" \
|
||||||
@@ -710,6 +758,64 @@ render_all_templates() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# install_cert_refresh копирует обновлённый сертификат TURN и перезапускает LiveKit.
|
||||||
|
install_cert_refresh() {
|
||||||
|
[ "$TURN_ENABLED" = "true" ] || return 0
|
||||||
|
[ -n "$TURN_CERT_SRC" ] || return 0
|
||||||
|
[ "$DRY_RUN" = "1" ] && return 0
|
||||||
|
|
||||||
|
cat >/usr/local/sbin/glchat-cert-refresh <<EOF
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Сгенерировано deploy/install.sh: копирует свежий сертификат TURN/TLS
|
||||||
|
# из внешнего ACME-хранилища и перезапускает LiveKit при изменении.
|
||||||
|
set -eu
|
||||||
|
SRC_CRT="${TURN_CERT_SRC}"
|
||||||
|
SRC_KEY="${TURN_CERT_SRC_KEY}"
|
||||||
|
DST_DIR="${TURN_CERT_DIR}"
|
||||||
|
if [ ! -r "\$SRC_CRT" ] || [ ! -r "\$SRC_KEY" ]; then
|
||||||
|
echo "glchat-cert-refresh: исходный сертификат недоступен" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
before="\$(sha256sum "\$DST_DIR/turn.crt" 2>/dev/null | cut -d' ' -f1 || true)"
|
||||||
|
install -m 640 "\$SRC_CRT" "\$DST_DIR/turn.crt"
|
||||||
|
install -m 640 "\$SRC_KEY" "\$DST_DIR/turn.key"
|
||||||
|
after="\$(sha256sum "\$DST_DIR/turn.crt" | cut -d' ' -f1)"
|
||||||
|
if [ "\$before" != "\$after" ]; then
|
||||||
|
docker restart glchat-livekit >/dev/null
|
||||||
|
echo "glchat-cert-refresh: сертификат обновлён, LiveKit перезапущен"
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
chmod 0755 /usr/local/sbin/glchat-cert-refresh
|
||||||
|
|
||||||
|
cat >/etc/systemd/system/glchat-cert-refresh.service <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=glchat: обновление сертификата TURN/TLS
|
||||||
|
After=docker.service
|
||||||
|
Requires=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/sbin/glchat-cert-refresh
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat >/etc/systemd/system/glchat-cert-refresh.timer <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=glchat: ежедневная проверка сертификата TURN/TLS
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=daily
|
||||||
|
Persistent=true
|
||||||
|
RandomizedDelaySec=1h
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now glchat-cert-refresh.timer >/dev/null 2>&1 ||
|
||||||
|
warn "не удалось включить glchat-cert-refresh.timer"
|
||||||
|
ok "автообновление сертификата TURN настроено (systemd timer, ежедневно)"
|
||||||
|
}
|
||||||
|
|
||||||
install_cli_and_units() {
|
install_cli_and_units() {
|
||||||
info "устанавливаем glchat CLI и systemd-юнит"
|
info "устанавливаем glchat CLI и systemd-юнит"
|
||||||
if [ "$DRY_RUN" = "1" ]; then
|
if [ "$DRY_RUN" = "1" ]; then
|
||||||
@@ -732,7 +838,7 @@ configure_ufw() {
|
|||||||
}
|
}
|
||||||
info "настраиваем UFW"
|
info "настраиваем UFW"
|
||||||
if [ "$DRY_RUN" = "1" ]; then
|
if [ "$DRY_RUN" = "1" ]; then
|
||||||
log_file_only "DRY-RUN: ufw default deny incoming; allow ${SSH_PORT}, ${LIVEKIT_TCP_PORT}/tcp, ${LIVEKIT_UDP_PORT}/udp, TURN"
|
log_file_only "DRY-RUN: ufw default deny incoming; allow ${SSH_PORT}, ${LIVEKIT_TCP_PORT}/tcp, ${LIVEKIT_UDP_PORT}/udp, TURN ${TURN_UDP_PORT}/udp, ${TURN_TLS_PORT}/tcp, relay ${TURN_RELAY_START}-${TURN_RELAY_END}/udp"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
ufw --force reset >/dev/null 2>&1 || true
|
ufw --force reset >/dev/null 2>&1 || true
|
||||||
@@ -748,6 +854,8 @@ configure_ufw() {
|
|||||||
if [ "$TURN_ENABLED" = "true" ]; then
|
if [ "$TURN_ENABLED" = "true" ]; then
|
||||||
ufw allow "${TURN_UDP_PORT}/udp" comment 'turn' >/dev/null
|
ufw allow "${TURN_UDP_PORT}/udp" comment 'turn' >/dev/null
|
||||||
ufw allow "${TURN_TLS_PORT}/tcp" comment 'turn-tls' >/dev/null
|
ufw allow "${TURN_TLS_PORT}/tcp" comment 'turn-tls' >/dev/null
|
||||||
|
# Relay-диапазон: через эти порты TURN отдаёт медиа (AGENT.md 4.2).
|
||||||
|
ufw allow "${TURN_RELAY_START}:${TURN_RELAY_END}/udp" comment 'turn-relay' >/dev/null
|
||||||
fi
|
fi
|
||||||
ufw --force enable >/dev/null
|
ufw --force enable >/dev/null
|
||||||
ok "UFW активен: $(ufw status | head -1)"
|
ok "UFW активен: $(ufw status | head -1)"
|
||||||
@@ -1075,6 +1183,7 @@ main() {
|
|||||||
install_packages
|
install_packages
|
||||||
install_docker
|
install_docker
|
||||||
generate_secrets
|
generate_secrets
|
||||||
|
install_turn_certificate
|
||||||
write_env_file
|
write_env_file
|
||||||
render_all_templates
|
render_all_templates
|
||||||
apply_profile
|
apply_profile
|
||||||
@@ -1084,6 +1193,7 @@ main() {
|
|||||||
configure_fail2ban
|
configure_fail2ban
|
||||||
configure_ssh_hardening
|
configure_ssh_hardening
|
||||||
install_cli_and_units
|
install_cli_and_units
|
||||||
|
install_cert_refresh
|
||||||
build_or_pull_image
|
build_or_pull_image
|
||||||
start_stack
|
start_stack
|
||||||
bootstrap_admin
|
bootstrap_admin
|
||||||
|
|||||||
@@ -41,3 +41,9 @@ turn:
|
|||||||
udp_port: ${TURN_UDP_PORT}
|
udp_port: ${TURN_UDP_PORT}
|
||||||
tls_port: ${TURN_TLS_PORT}
|
tls_port: ${TURN_TLS_PORT}
|
||||||
external_tls: ${TURN_EXTERNAL_TLS}
|
external_tls: ${TURN_EXTERNAL_TLS}
|
||||||
|
# Диапазон портов релея должен быть открыт в firewall (§4.2).
|
||||||
|
relay_range_start: ${TURN_RELAY_START}
|
||||||
|
relay_range_end: ${TURN_RELAY_END}
|
||||||
|
# LiveKit требует сертификат для TURN/TLS; файлы готовит установщик.
|
||||||
|
cert_file: ${TURN_CERT_FILE}
|
||||||
|
key_file: ${TURN_KEY_FILE}
|
||||||
|
|||||||
+14
-1
@@ -121,9 +121,22 @@ else
|
|||||||
if ss -tulnH 2>/dev/null | grep -q ":${port} "; then
|
if ss -tulnH 2>/dev/null | grep -q ":${port} "; then
|
||||||
pass "слушает ${spec}"
|
pass "слушает ${spec}"
|
||||||
else
|
else
|
||||||
skip "не слушает ${spec} (проверьте конфиг LiveKit/TURN)"
|
fail "не слушает ${spec} (TURN не запустился: проверьте cert_file в livekit.yaml)"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
# TURN/TLS должен отдавать валидный сертификат на своём домене.
|
||||||
|
turn_domain="$(grep -A3 '^turn:' "${GLCHAT_ETC_DIR}/livekit/livekit.yaml" 2>/dev/null |
|
||||||
|
awk '/domain:/ {print $2; exit}')"
|
||||||
|
if [ -n "$turn_domain" ] && command -v openssl >/dev/null 2>&1; then
|
||||||
|
cert_cn="$(echo | timeout 8 openssl s_client -connect "127.0.0.1:${TURN_TLS_PORT}" \
|
||||||
|
-servername "$turn_domain" 2>/dev/null |
|
||||||
|
openssl x509 -noout -subject 2>/dev/null | sed 's/.*CN *= *//')"
|
||||||
|
if [ "$cert_cn" = "$turn_domain" ]; then
|
||||||
|
pass "TURN/TLS отдаёт сертификат для ${turn_domain}"
|
||||||
|
else
|
||||||
|
fail "TURN/TLS: сертификат не для ${turn_domain} (CN=${cert_cn:-нет})"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user