#!/bin/bash # GoTelegram v2.2 — Бекап и восстановление конфигурации # ── Создание бекапа ────────────────────────────────────────────────────────── create_backup() { local password="$1" local output_dir="${2:-$BACKUP_DIR}" local timestamp timestamp=$(date +%Y%m%d_%H%M%S) local backup_name="gotelegram_backup_${timestamp}" local tmp_dir="/tmp/${backup_name}" mkdir -p "$tmp_dir" "$output_dir" # Собираем файлы log_info "Собираю конфигурацию..." # telemt конфиг if [ -f "$TELEMT_CONFIG" ]; then cp "$TELEMT_CONFIG" "$tmp_dir/config.toml" fi # GoTelegram конфиг if [ -f "$GOTELEGRAM_CONFIG" ]; then cp "$GOTELEGRAM_CONFIG" "$tmp_dir/gotelegram.json" fi # nginx конфиг (stealth mode) if [ -f "$NGINX_SITE_CONF" ]; then cp "$NGINX_SITE_CONF" "$tmp_dir/nginx.conf" fi # SSL сертификаты local domain domain=$(config_get domain 2>/dev/null) if [ -n "$domain" ] && [ -d "/etc/letsencrypt/live/$domain" ]; then mkdir -p "$tmp_dir/certs" cp "/etc/letsencrypt/live/$domain/fullchain.pem" "$tmp_dir/certs/" 2>/dev/null cp "/etc/letsencrypt/live/$domain/privkey.pem" "$tmp_dir/certs/" 2>/dev/null log_dim "SSL сертификаты включены" fi # Шаблон сайта (если есть) if [ -d "$WEBSITE_ROOT" ] && [ -f "$WEBSITE_ROOT/index.html" ]; then mkdir -p "$tmp_dir/site" cp -r "$WEBSITE_ROOT"/* "$tmp_dir/site/" log_dim "Шаблон сайта включён" fi # Метаданные local ip mode engine ip=$(get_server_ip) mode=$(config_get mode 2>/dev/null || echo "unknown") engine=$(config_get engine 2>/dev/null || echo "telemt") cat > "$tmp_dir/metadata.json" << EOMETA { "backup_version": "1.0", "gotelegram_version": "$GOTELEGRAM_VERSION", "created_at": "$(date -Iseconds)", "hostname": "$(hostname)", "ip": "$ip", "engine": "$engine", "mode": "$mode", "port": $(config_get port 2>/dev/null || echo "443"), "domain": "$(config_get domain 2>/dev/null)" } EOMETA # Архивируем local tar_file="/tmp/${backup_name}.tar.gz" if ! tar czf "$tar_file" -C /tmp "$backup_name" 2>/dev/null; then log_error "Ошибка создания архива" rm -rf "$tmp_dir" rm -f "$tar_file" return 1 fi if [ ! -f "$tar_file" ]; then log_error "Архив не создан" rm -rf "$tmp_dir" return 1 fi # Шифруем если задан пароль local final_file="" if [ -n "$password" ]; then final_file="${output_dir}/${backup_name}.tar.gz.enc" openssl enc -aes-256-cbc -salt -pbkdf2 -in "$tar_file" -out "$final_file" -pass "pass:${password}" 2>/dev/null if [ $? -ne 0 ]; then log_error "Ошибка шифрования" rm -f "$tar_file" rm -rf "$tmp_dir" return 1 fi rm -f "$tar_file" log_success "Бекап зашифрован (AES-256-CBC)" else final_file="${output_dir}/${backup_name}.tar.gz" mv "$tar_file" "$final_file" fi # SHA256 подпись sha256sum "$final_file" > "${final_file}.sha256" 2>/dev/null # Очистка rm -rf "$tmp_dir" local size size=$(du -h "$final_file" | cut -f1) log_success "Бекап создан: $final_file ($size)" echo "$final_file" return 0 } # ── Восстановление из бекапа ──────────────────────────────────────────────── restore_backup() { local backup_file="$1" local password="$2" if [ ! -f "$backup_file" ]; then log_error "Файл не найден: $backup_file" return 1 fi local tmp_dir="/tmp/gotelegram_restore_$$" mkdir -p "$tmp_dir" # Расшифровываем если нужно local tar_file="" if echo "$backup_file" | grep -q '\.enc$'; then if [ -z "$password" ]; then echo -ne " Введите пароль от бекапа: " read -rs password echo "" fi tar_file="/tmp/gotelegram_restore_$$.tar.gz" openssl enc -aes-256-cbc -d -pbkdf2 -in "$backup_file" -out "$tar_file" -pass "pass:${password}" 2>/dev/null if [ $? -ne 0 ]; then log_error "Неверный пароль или повреждённый файл" rm -rf "$tmp_dir" "$tar_file" return 1 fi else tar_file="$backup_file" fi # Распаковываем tar xzf "$tar_file" -C "$tmp_dir" 2>/dev/null if [ $? -ne 0 ]; then log_error "Ошибка распаковки архива" rm -rf "$tmp_dir" return 1 fi # Находим папку бекапа local backup_dir backup_dir=$(find "$tmp_dir" -maxdepth 1 -type d -name "gotelegram_backup_*" | head -1) [ -z "$backup_dir" ] && backup_dir="$tmp_dir" # Проверяем метаданные if [ -f "$backup_dir/metadata.json" ]; then local bk_version bk_mode bk_ip bk_version=$(jq -r '.gotelegram_version // "unknown"' "$backup_dir/metadata.json") bk_mode=$(jq -r '.mode // "unknown"' "$backup_dir/metadata.json") bk_ip=$(jq -r '.ip // "unknown"' "$backup_dir/metadata.json") echo "" echo -e " ${BOLD}${WHITE}📦 Бекап:${NC}" echo -e " Версия: $bk_version | Режим: $bk_mode | IP: $bk_ip" echo -e " Дата: $(jq -r '.created_at' "$backup_dir/metadata.json")" echo "" fi if ! confirm "Восстановить конфигурацию? Текущие настройки будут перезаписаны."; then rm -rf "$tmp_dir" return 0 fi # Останавливаем сервисы stop_telemt 2>/dev/null systemctl stop nginx 2>/dev/null # Восстанавливаем telemt конфиг if [ -f "$backup_dir/config.toml" ]; then mkdir -p /etc/telemt cp "$backup_dir/config.toml" "$TELEMT_CONFIG" chmod 600 "$TELEMT_CONFIG" log_success "telemt конфиг восстановлен" fi # Восстанавливаем GoTelegram конфиг if [ -f "$backup_dir/gotelegram.json" ]; then mkdir -p "$GOTELEGRAM_DIR" cp "$backup_dir/gotelegram.json" "$GOTELEGRAM_CONFIG" log_success "GoTelegram конфиг восстановлен" fi # Восстанавливаем nginx конфиг if [ -f "$backup_dir/nginx.conf" ]; then mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled cp "$backup_dir/nginx.conf" "$NGINX_SITE_CONF" ln -sf "$NGINX_SITE_CONF" "$NGINX_SITE_LINK" log_success "nginx конфиг восстановлен" fi # Восстанавливаем SSL if [ -d "$backup_dir/certs" ]; then local domain domain=$(config_get domain 2>/dev/null) if [ -n "$domain" ]; then local cert_dir="/etc/letsencrypt/live/$domain" mkdir -p "$cert_dir" cp "$backup_dir/certs/"* "$cert_dir/" 2>/dev/null log_success "SSL сертификаты восстановлены" fi fi # Восстанавливаем шаблон сайта if [ -d "$backup_dir/site" ]; then mkdir -p "$WEBSITE_ROOT" cp -r "$backup_dir/site"/* "$WEBSITE_ROOT/" chown -R www-data:www-data "$WEBSITE_ROOT" 2>/dev/null log_success "Шаблон сайта восстановлен" fi # Запускаем сервисы if is_telemt_installed; then start_telemt fi systemctl start nginx 2>/dev/null # Очистка rm -rf "$tmp_dir" [ "$tar_file" != "$backup_file" ] && rm -f "$tar_file" log_success "Восстановление завершено!" show_proxy_info return 0 } # ── Список бекапов ─────────────────────────────────────────────────────────── list_backups() { if [ ! -d "$BACKUP_DIR" ] || [ -z "$(ls -A "$BACKUP_DIR" 2>/dev/null)" ]; then log_info "Бекапов нет" return 1 fi echo "" echo -e " ${BOLD}${WHITE}📦 Доступные бекапы:${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..60})${NC}" local i=1 for f in "$BACKUP_DIR"/gotelegram_backup_*.tar.gz*; do [ -f "$f" ] || continue [[ "$f" == *.sha256 ]] && continue local size date_str name size=$(du -h "$f" | cut -f1) name=$(basename "$f") date_str=$(echo "$name" | grep -oE '[0-9]{8}_[0-9]{6}' | head -1) local encrypted="" [[ "$f" == *.enc ]] && encrypted=" 🔒" echo -e " ${CYAN}${i})${NC} ${name} (${size})${encrypted}" ((i++)) done echo -e " ${DIM}$(printf '─%.0s' {1..60})${NC}" } # ── Очистка старых бекапов ─────────────────────────────────────────────────── cleanup_old_backups() { local keep="${1:-5}" local count count=$(find "$BACKUP_DIR" -name "gotelegram_backup_*.tar.gz*" ! -name "*.sha256" 2>/dev/null | wc -l) if [ "$count" -gt "$keep" ]; then local to_delete=$((count - keep)) find "$BACKUP_DIR" -name "gotelegram_backup_*.tar.gz*" ! -name "*.sha256" 2>/dev/null | sort | head -n "$to_delete" | while read -r f; do rm -f "$f" "${f}.sha256" done log_dim "Удалено $to_delete старых бекапов (оставлено $keep)" fi } # ── Интерактивный бекап ────────────────────────────────────────────────────── interactive_backup() { echo "" echo -e " ${BOLD}${WHITE}💾 Создание бекапа${NC}" echo -ne " Зашифровать бекап паролем? [Y/n]: " read -r use_pass local password="" if [[ ! "$use_pass" =~ ^[Nn] ]]; then echo -ne " Введите пароль: " read -rs password echo "" echo -ne " Повторите пароль: " read -rs password2 echo "" if [ "$password" != "$password2" ]; then log_error "Пароли не совпадают" return 1 fi if [ ${#password} -lt 6 ]; then log_error "Пароль слишком короткий (минимум 6 символов)" return 1 fi fi create_backup "$password" cleanup_old_backups } # ── Интерактивное восстановление ───────────────────────────────────────────── interactive_restore() { list_backups || return 1 echo -ne " Номер бекапа (или путь к файлу): " read -r choice local backup_file="" if [[ "$choice" =~ ^[0-9]+$ ]]; then local i=1 for f in "$BACKUP_DIR"/gotelegram_backup_*.tar.gz*; do [ -f "$f" ] || continue [[ "$f" == *.sha256 ]] && continue if [ "$i" -eq "$choice" ]; then backup_file="$f" break fi ((i++)) done elif [ -f "$choice" ]; then backup_file="$choice" fi if [ -z "$backup_file" ]; then log_error "Бекап не найден" return 1 fi restore_backup "$backup_file" }