mirror of
https://github.com/anten-ka/gotelegram_pro.git
synced 2026-05-19 12:16:01 +00:00
342 lines
12 KiB
Bash
342 lines
12 KiB
Bash
#!/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"
|
|
}
|