#!/bin/bash # Скрипт установки HPB - Nextcloud Spreed Signaling Stack # Автоматически генерирует секреты и настраивает все сервисы set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" INSTALL_DIR="/etc/f7cloud-spreed-signaling" BIN_DIR="/usr/bin" SBIN_DIR="/usr/sbin" LIB_DIR="/usr/lib/x86_64-linux-gnu/janus" CONFIG_DIR="/etc/janus" SYSTEMD_DIR="/etc/systemd/system" # Цвета для вывода RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Проверка прав root check_root() { if [[ $EUID -ne 0 ]]; then log_error "Этот скрипт должен запускаться от root" exit 1 fi } # Генерация случайных hex строк generate_hex() { local length=$1 openssl rand -hex "$length" | tr -d '\n' } # Генерация base64 строки generate_base64() { local length=$1 openssl rand -base64 "$length" | tr -d '\n' | tr -d '=' | head -c "$length" } # Генерация всех секретов generate_secrets() { log_info "Генерация секретов..." # Signaling server секреты SIGNALING_HASHKEY=$(generate_hex 32) # 32 байта = 64 hex символа SIGNALING_BLOCKKEY=$(generate_hex 16) # 16 байт = 32 hex символа SIGNALING_INTERNAL_SECRET=$(generate_hex 32) # 64 hex символа SIGNALING_BACKEND_SECRET=$(generate_hex 32) # 64 hex символа # TURN секрет (должен совпадать в signaling и turnserver) TURN_SECRET=$(generate_hex 32) # 64 hex символа TURN_API_KEY=$(generate_base64 16) # ~16 символов base64 # Janus admin secret JANUS_ADMIN_SECRET=$(generate_base64 16) # ~16 символов log_info "Секреты сгенерированы" } # Создание пользователей системы create_users() { log_info "Создание системных пользователей..." # Пользователь для signaling if ! id "_signaling" &>/dev/null; then useradd --system --no-create-home --shell /usr/sbin/nologin \ --comment "Nextcloud Talk signaling server" _signaling || true log_info "Пользователь _signaling создан" else log_warn "Пользователь _signaling уже существует" fi # Пользователь для NATS (обычно уже есть) if ! id "nats" &>/dev/null; then useradd --system --no-create-home --shell /usr/sbin/nologin \ --comment "NATS Server" nats || true log_info "Пользователь nats создан" else log_warn "Пользователь nats уже существует" fi # Пользователь для coturn (обычно уже есть) if ! id "turnserver" &>/dev/null; then useradd --system --no-create-home --shell /usr/sbin/nologin \ --comment "coTURN STUN/TURN Server" turnserver || true log_info "Пользователь turnserver создан" else log_warn "Пользователь turnserver уже существует" fi } # Копирование бинарников install_binaries() { log_info "Установка бинарников..." # Signaling if [[ -f "$SCRIPT_DIR/signaling-server/signaling" ]]; then cp "$SCRIPT_DIR/signaling-server/signaling" "$BIN_DIR/signaling" chmod 755 "$BIN_DIR/signaling" log_info "signaling установлен в $BIN_DIR/signaling" else log_error "Бинарник signaling не найден!" exit 1 fi # Janus if [[ -f "$SCRIPT_DIR/signaling-server/janus/bin/janus" ]]; then cp "$SCRIPT_DIR/signaling-server/janus/bin/janus" "$BIN_DIR/janus" chmod 755 "$BIN_DIR/janus" log_info "janus установлен в $BIN_DIR/janus" # Janus библиотеки mkdir -p "$LIB_DIR" cp -r "$SCRIPT_DIR/signaling-server/janus/lib/"* "$LIB_DIR/" log_info "Janus библиотеки установлены в $LIB_DIR" else log_error "Бинарник janus не найден!" exit 1 fi # NATS Server if [[ -f "$SCRIPT_DIR/signaling-server/nats-server" ]]; then cp "$SCRIPT_DIR/signaling-server/nats-server" "$SBIN_DIR/nats-server" chmod 755 "$SBIN_DIR/nats-server" log_info "nats-server установлен в $SBIN_DIR/nats-server" else log_error "Бинарник nats-server не найден!" exit 1 fi # coTURN if [[ -f "$SCRIPT_DIR/signaling-server/turnserver" ]]; then cp "$SCRIPT_DIR/signaling-server/turnserver" "$BIN_DIR/turnserver" chmod 755 "$BIN_DIR/turnserver" # Создаем симлинк coturn -> turnserver ln -sf turnserver "$BIN_DIR/coturn" log_info "turnserver установлен в $BIN_DIR/turnserver" else log_error "Бинарник turnserver не найден!" exit 1 fi } # Установка конфигов с подстановкой секретов install_configs() { log_info "Установка конфигурационных файлов..." # Создаем директории mkdir -p "$INSTALL_DIR" mkdir -p "$CONFIG_DIR" # Signaling server.conf if [[ -f "$SCRIPT_DIR/server.conf.example" ]]; then sed -e "s|YOUR_32_OR_64_BYTE_HEX_HASHKEY|$SIGNALING_HASHKEY|g" \ -e "s|YOUR_16_24_OR_32_BYTE_HEX_BLOCKKEY|$SIGNALING_BLOCKKEY|g" \ -e "s|YOUR_INTERNAL_CLIENT_SECRET|$SIGNALING_INTERNAL_SECRET|g" \ -e "s|YOUR_NEXTCLOUD_BACKEND_SECRET|$SIGNALING_BACKEND_SECRET|g" \ -e "s|YOUR_TURN_API_KEY|$TURN_API_KEY|g" \ -e "s|YOUR_TURN_SHARED_SECRET|$TURN_SECRET|g" \ "$SCRIPT_DIR/server.conf.example" > "$INSTALL_DIR/server.conf" chmod 600 "$INSTALL_DIR/server.conf" chown _signaling:_signaling "$INSTALL_DIR/server.conf" log_info "server.conf создан в $INSTALL_DIR/server.conf" log_warn "ВАЖНО: Отредактируйте $INSTALL_DIR/server.conf - укажите реальные URL бэкендов Nextcloud!" else log_error "server.conf.example не найден!" exit 1 fi # Janus конфиги if [[ -d "$SCRIPT_DIR/config/janus" ]]; then cp -r "$SCRIPT_DIR/config/janus/"* "$CONFIG_DIR/" # Подставляем admin_secret в janus.jcfg sed -i "s|admin_secret = \"CHANGE_ME\"|admin_secret = \"$JANUS_ADMIN_SECRET\"|g" \ "$CONFIG_DIR/janus.jcfg" chown -R root:root "$CONFIG_DIR" log_info "Janus конфиги установлены в $CONFIG_DIR" else log_error "Janus конфиги не найдены!" exit 1 fi # coTURN turnserver.conf if [[ -f "$SCRIPT_DIR/config/coturn/turnserver.conf.example" ]]; then # Получаем публичный IP (если доступен) или оставляем плейсхолдер PUBLIC_IP=$(curl -s --max-time 2 https://api.ipify.org 2>/dev/null || echo "YOUR_PUBLIC_IP") DOMAIN=$(hostname -f 2>/dev/null || echo "YOUR_DOMAIN") sed -e "s|YOUR_TURN_STATIC_AUTH_SECRET|$TURN_SECRET|g" \ -e "s|YOUR_PUBLIC_IP|$PUBLIC_IP|g" \ -e "s|YOUR_DOMAIN|$DOMAIN|g" \ "$SCRIPT_DIR/config/coturn/turnserver.conf.example" > "/etc/turnserver.conf" chmod 640 "/etc/turnserver.conf" chown turnserver:turnserver "/etc/turnserver.conf" log_info "turnserver.conf создан в /etc/turnserver.conf" log_warn "ВАЖНО: Отредактируйте /etc/turnserver.conf - укажите реальные IP адреса и пути к сертификатам!" else log_error "turnserver.conf.example не найден!" exit 1 fi # NATS конфиг if [[ -f "$SCRIPT_DIR/config/nats/nats-server.conf" ]]; then cp "$SCRIPT_DIR/config/nats/nats-server.conf" "/etc/nats-server.conf" chmod 644 "/etc/nats-server.conf" chown nats:nats "/etc/nats-server.conf" log_info "nats-server.conf установлен в /etc/nats-server.conf" else log_error "nats-server.conf не найден!" exit 1 fi } # Установка systemd unit файлов install_systemd() { log_info "Установка systemd unit файлов..." if [[ -d "$SCRIPT_DIR/systemd" ]]; then cp "$SCRIPT_DIR/systemd/"*.service "$SYSTEMD_DIR/" systemctl daemon-reload log_info "Systemd unit файлы установлены" else log_error "Systemd unit файлы не найдены!" exit 1 fi } # Сохранение секретов в файл (для справки) save_secrets() { SECRETS_FILE="$INSTALL_DIR/.secrets.txt" cat > "$SECRETS_FILE" <