Дисклеймер: Этот материал написан для тех, кто предпочитает полный контроль удобным кнопкам. Если вы ищете решение «в один клик», вам не сюда. Мы будем работать с консолью, ключами шифрования и системной архитектурой Linux.
Введение. Почему мы строим велосипед?
В комментариях наверняка появятся эксперты, которые спросят: «Зачем этот колхоз? Есть же BorgBackup, Restic, Bacula, Veeam, есть снапшоты файловой системы ZFS/LVM!».
Отвечаю сразу всем. Да, эти инструменты прекрасны. Но у них есть недостатки для нашей задачи:
- Зависимости: Чтобы восстановиться из Borg, вам нужен Borg. Чтобы восстановиться из Veeam, вам нужен Veeam.
- Сложность: Вы пробовали дебажить упавший инкремент Bacula в 3 часа ночи?
- Формат данных: Проприетарные или специфичные форматы контейнеров.
Наш метод — PROTOCOL IMMORTALITY — использует утилиту tar. Она есть в каждом дистрибутиве Linux с 1970-х годов. Если через 20 лет я найду свой архив на старом жестком диске, я смогу его открыть. Это стратегия максимальной выживаемости.
Критическое условие: Совместимость ОС
ВНИМАНИЕ! ЧИТАТЬ ОБЯЗАТЕЛЬНО.
Этот метод подразумевает «пересадку души» (конфигов и файлов) из одного сервера в другой. Чтобы трансплантация прошла успешно, донор и реципиент должны быть биологически совместимы.
Правило: Операционная система на новом сервере должна совпадать с ОС на старом сервере.
- Если у вас был Debian 12 — восстанавливаться нужно на чистый Debian 12.
- Если была Ubuntu 24.04 LTS — восстанавливаемся на Ubuntu 24.04 LTS.
Почему?
Потому что мы бэкапим /etc. Там лежат конфиги системных служб (Systemd, Nginx, PHP, SSH). Версии софта в разных дистрибутивах разные. Конфиг от Apache 2.4.41 может вызвать ошибку в Apache 2.4.58. Пути к библиотекам могут отличаться.
Если вы попытаетесь развернуть архив CentOS на Ubuntu, вы получите «Франкенштейна», который никогда не загрузится.
Исключение: Если вы восстанавливаете только базу данных (SQL) и файлы сайта (/var/www), версия ОС не важна. Но наш скрипт делает полный системный слепок. Учитывайте это.
Глава 1. Архитектура
Мы строим схему Master -> Slave (Источник -> Склад).
- PROD (Источник): Генерирует контент. Быстрый диск (SSD). Здесь работают скрипты архивации.
- STORAGE (Склад): Хранит контент. Медленный диск (HDD), но большой объем. Здесь мы ничего не запускаем, только храним.
- Туннель: Передача данных строго по протоколу SSH (порт 22 или ваш кастомный).
Глава 2. Настройка доступа без паролей
Автоматика требует отсутствия ввода паролей. Мы используем ключи Ed25519.
На сервере PROD:
ssh-keygen -t ed25519 -f /root/.ssh/id_backup -N ""
Мы создаем отдельный ключ id_backup. Не используйте дефолтный id_rsa, чтобы разграничить доступы. Парольная фраза (-N "") должна быть пустой.
Важно: Права доступа
SSH не будет работать, если права на приватный ключ слишком открыты. Это защита от дурака.
chmod 600 /root/.ssh/id_backup
chmod 644 /root/.ssh/id_backup.pub
Отправка ключа на STORAGE:
Теперь нужно внедрить наш публичный ключ на сервер хранения.
ssh-copy-id -p 22 -i /root/.ssh/id_backup.pub root@IP_ВАШЕГО_СКЛАДА
(Замените 22 на ваш порт SSH, если он изменен).
Глава 3. Скрипт архивации (backup.sh)
Это мозг системы. Скрипт решает несколько инженерных задач, которые часто игнорируют новички.
Задача 1: Атомарность Базы Данных
Критики скажут: «Копировать файлы работающей MySQL нельзя, они будут битыми!». И они правы. Если tar начнет читать файл базы данных в момент записи транзакции, вы получите мусор.
Решение: Мы делаем mysqldump перед архивацией. Мы создаем текстовый SQL-файл, который гарантированно целостен.
Задача 2: Инкрементальность
Каждый день гонять полные копии по 100 ГБ — безумие. Мы используем встроенную функцию gnu tar incremental. Скрипт создает файл-метаданных (.snar), в котором хранит время изменения файлов.
Код скрипта
Создайте файл /root/backup2/backup.sh:
#!/bin/bash
# === НАСТРОЙКИ ===
BDIR="/root/backup2"
REMOTE_IP="111.222.333.444" # IP Склада
REMOTE_PORT="22" # Порт SSH Склада
REMOTE_USER="root"
REMOTE_DIR="/root/backups" # Папка на Складе
SSH_KEY="/root/.ssh/id_backup"
# Имена файлов
BNAME="backup-prod"
SNAP="$BDIR/backup.snar" # Файл памяти инкремента
BLIST="$BDIR/backuplist.txt" # Список включений
BEXCL="$BDIR/backupexclude.txt" # Список исключений
DATE=$(date +%Y-%m-%d_%H%M)
DOW=$(date +%u) # День недели (1-7)
if [[ ! -d "$BDIR" ]]; then mkdir -p "$BDIR"; fi
echo "=== Старт: $(date) ==="
# 1. ДАМП БАЗЫ
# Используем --single-transaction для InnoDB, чтобы не блокировать сайт
echo "--> Дамп БД..."
mysqldump --all-databases --single-transaction --quick --lock-tables=false > "$BDIR/all-databases.sql"
# 2. СБРОС ЦЕПОЧКИ (ПОЛНЫЙ БЕКАП)
# В воскресенье (7) удаляем файл памяти, чтобы tar сделал полный архив
if [[ $DOW -eq 7 ]]; then
echo "Воскресенье. Сброс цепочки (Full Backup)."
rm -f "$SNAP"
fi
# 3. АРХИВАЦИЯ
if [[ -s $SNAP ]]; then
TYPE="inc"
cp "$SNAP" "$SNAP-1"
ARCHIVE_NAME="${BNAME}-${TYPE}-${DATE}.tar.gz"
tar -zcpf "$BDIR/$ARCHIVE_NAME" \
--exclude-from="$BEXCL" \
--listed-incremental="$SNAP" \
--files-from="$BLIST"
mv "$SNAP-1" "$SNAP"
else
TYPE="full"
ARCHIVE_NAME="${BNAME}-${TYPE}-${DATE}.tar.gz"
tar -zcpf "$BDIR/$ARCHIVE_NAME" \
--exclude-from="$BEXCL" \
--listed-incremental="$SNAP" \
--files-from="$BLIST"
fi
# 4. ОТПРАВКА (SCP)
# StrictHostKeyChecking=no нужен, чтобы скрипт не завис при смене железа на складе
if [[ -f "$BDIR/$ARCHIVE_NAME" ]]; then
echo "Отправка..."
scp -P "$REMOTE_PORT" -i "$SSH_KEY" -o StrictHostKeyChecking=no "$BDIR/$ARCHIVE_NAME" "$REMOTE_USER@$REMOTE_IP:$REMOTE_DIR/"
else
echo "ОШИБКА: Архив не создан."
exit 1
fi
# 5. ЛОКАЛЬНАЯ ЧИСТКА
# Удаляем с боевого сервера файлы старше 7 дней
find "$BDIR" -name "${BNAME}-*.tar.gz" -type f -mtime +7 -delete
echo "=== Готово ==="
Глава 4. Философия Исключений (Exclusions)
Самый важный файл: /root/backup2/backupexclude.txt.
Почему мы не бекапим всё подряд? Потому что есть файлы, привязанные к «железу». Если вы перенесете их на новый сервер, он не загрузится.
Список исключений:
/proc
/sys
/dev
/run
/tmp
/mnt
/media
/lost+found
/home/*/.wine
*.log
*.tar.gz
*.sql
/boot
/etc/fstab
/etc/network
/etc/netplan
/etc/udev
/etc/hostname
/etc/hosts
/etc/resolv.conf
Почему это важно:
/etc/fstab: Таблица разделов. На новом сервере UUID дисков будут другими. Старый fstab убьет загрузку./etc/network: На новом сервере будет другой IP-адрес. Старый конфиг убьет сеть./sys, /proc: Это виртуальные файлы ядра. Их нельзя архивировать.
Список включений (backuplist.txt):
/
Глава 5. Ротация на складе (clean.sh)
Склад не резиновый. Нам нужен скрипт, который будет удалять архивы старше 30 дней.
Файл /root/backup2/clean.sh:
#!/bin/bash
REMOTE_IP="111.222.333.444"
REMOTE_PORT="22"
SSH_KEY="/root/.ssh/id_backup"
RETENTION_DAYS=30
# Выполняем команду find удаленно через SSH
ssh -p "$REMOTE_PORT" -i "$SSH_KEY" root@$REMOTE_IP \
"find /root/backups -name '*.tar.gz' -type f -mtime +$RETENTION_DAYS -delete"
Глава 6. Протокол восстановления (Phoenix)
Представим, что ваш сервер сгорел. Вы арендовали новый. ОС та же самая (это важно!). Как воскреснуть?
Шаг 1. Скачать данные
mkdir /restore && cd /restore
scp -r root@IP_СКЛАДА:/root/backups/ .
Шаг 2. Распаковка
Важен порядок. Сначала распаковываем Полный (Full) архив, затем по очереди накатываем Инкременты. Иначе вы получите мешанину файлов.
# Гасим сервисы
service mysql stop
service nginx stop
# Распаковка в корень (-C /)
# ls | sort гарантирует правильный порядок файлов по дате
for f in $(ls backup-*.tar.gz | sort); do
echo "Restoring: $f"
tar -xpf "$f" -C /
done
# Обновляем конфиги
systemctl daemon-reload
Шаг 3. База данных
Пробуем запустить MySQL. Если не стартует (конфликт версий), у нас есть спасательный круг — текстовый дамп.
mysql < /root/backup2/all-databases.sql
Шаг 4. Reboot
После перезагрузки система поднимется со старыми конфигами, пользователями и сайтами, но на новом ядре и сетевых настройках.
Итог
Эта система работает бесплатно. Она не зависит от прихотей облачных провайдеров. Она масштабируется (просто купите еще один дешевый диск и настройте синхронизацию).
Это и есть настоящий инженерный контроль.

Дополню материал честно и по делу. Метод работает, но у него есть ограничения: жёсткая привязка к версии ОС, отсутствие встроенной проверки целостности архивов, использование scp вместо rsync и отсутствие мониторинга успешности бэкапа. Это не баги, а осознанные компромиссы ради простоты. Тем не менее, улучшить систему можно: добавить контрольные суммы (sha256sum), вести логи и проверку восстановления на тестовом сервере, заменить scp на rsync для больших объёмов, интегрировать мониторинг через Prometheus или Zabbix. Философия выбора tar проста — минимальные зависимости и максимальная совместимость. Архив, созданный сегодня, можно будет открыть через десятилетия без проприетарных инструментов. Это стратегия выживания и инженерного контроля. Система не идеальна, но её сила в прозрачности: всё видно, всё управляемо, всё можно починить руками.