Серверы
Резервные копии и восстановление: от правила 3-2-1 до теста восстановления
Резервная копия полезна, только если из неё можно восстановиться. Правило 3-2-1, шифрование, офлайн-копия, pg_dump/mysqldump и регулярный тест восстановления.
· 10 мин. чтения

Во многих командах резервная копия считается «существующей»: в панели включён автоматический бэкап, каждую ночь появляется какой-то архив. Но вопрос нужно ставить иначе: если сегодня сервер полностью выйдет из строя или файлы окажутся зашифрованы, за какое время и до какого состояния вы сможете восстановить систему? Если на этот вопрос нет точного ответа, безопаснее считать, что резервной копии на самом деле нет.
В этой статье разберём, как построить стратегию резервного копирования, правильно делать дамп базы данных, шифровать копии и, главное, регулярно проверять восстановление.
В чём проблема
Типичные ошибки с резервными копиями не технические, а организационные:
- Копия хранится на том же сервере. Если откажет диск или сервер будет взломан, исчезнут и исходные данные, и копия.
- Копия всегда подключена. Злоумышленник или программа-шифровальщик (ransomware), попавшие на сервер, видят и подключённый сетевой диск, и облачную папку — и удаляют или шифруют их тоже.
- Копия не зашифрована. В архиве база данных, файл
.env, персональные данные пользователей. Утечка архива равна полной утечке данных. - Восстановление ни разу не проверялось. Архив повреждён, дамп записан наполовину или порядок восстановления никто не знает — обычно это выясняется в самый неудобный момент.
- Копируются только файлы, а база нет (или наоборот). Простое копирование файлов работающей базы часто даёт несогласованное состояние.
Почему это важно для экспертизы
Официальная экспертиза кибербезопасности в основном ищет уязвимости, но рассматриваются и конфигурация сервера, и меры обеспечения информационной безопасности. Находки, связанные с резервными копиями, бывают двух видов:
- Раскрытие информации. Оставленные в веб-каталоге файлы вроде
backup.zip,db.sql,site.tar.gzможно скачать через браузер. Сканеры проверяют типичные имена, поэтому это обнаруживается быстро. - Восстанавливаемость. Возврат системы в строй после инцидента — часть безопасности. Там, где под угрозой целостность и доступность данных, ожидается задокументированный порядок резервного копирования и восстановления.
Главное правило: резервная копия — это не архив, а возможность восстановления. Непроверенная копия — это предположение.
Правило 3-2-1
Распространённый и простой принцип:
- 3 копии данных: исходные данные и две резервные;
- на 2 разных носителях (например, диск сервера и объектное хранилище);
- 1 копия в другом месте (другой дата-центр, другой провайдер или офлайн-диск в офисе).
Сегодня к нему добавляется ещё одно требование: как минимум одна копия должна быть офлайн или неизменяемой (immutable). Это основная защита от шифровальщиков: даже злоумышленник с полным доступом к серверу не должен иметь возможности удалить эту копию.
На практике неизменяемую копию получают так:
- функция «object lock» или версионирование со сроком хранения в объектном хранилище;
- резервный сервер сам «забирает» копию (pull), а основной сервер не имеет права записи на резервный;
- режим «только добавление» (append-only) — например, так настроенный репозиторий restic или borg;
- внешний диск, который периодически отключается.
Что нужно копировать
Запишите список заранее, иначе потом обнаружится, что «это тоже было нужно»:
- база данных (в виде дампа);
- загруженные пользователями файлы (
storage/app,uploadsи т. д.); - конфигурация: nginx, PHP-FPM, cron, юниты systemd, правила firewall;
.envи секреты — отдельно, с надёжным шифрованием;- код приложения обычно есть в git, но нужно фиксировать, какая именно версия работает.
Кэш, файлы сессий, каталоги vendor и node_modules копировать не обязательно — они восстанавливаются.
Проверьте сами
Сначала убедитесь, что в веб-каталоге не осталось файлов резервных копий:
find /var/www -type f \( -name "*.sql" -o -name "*.sql.gz" -o -name "*.zip" \
-o -name "*.tar.gz" -o -name "*.bak" -o -name "*.dump" \) 2>/dev/null
Проверьте и снаружи (только на своём сайте):
for f in backup.zip backup.sql db.sql site.tar.gz dump.sql .env; do
printf "%s " "$f"; curl -s -o /dev/null -w "%{http_code}\n" "https://example.uz/$f"
done
Ответ 200 означает, что файл открыт. Затем письменно ответьте на вопросы: когда сделана последняя копия, где она хранится, кто может её удалить, когда последний раз из неё восстанавливались.
Правильный дамп базы данных
PostgreSQL
pg_dump делает согласованную копию работающей базы. Пользовательский формат (-Fc) сжат и позволяет выборочное восстановление:
pg_dump -h 127.0.0.1 -U app_backup -Fc -f /backup/app_$(date +%F).dump appdb
Роли и глобальные настройки сохраняются отдельно:
pg_dumpall -h 127.0.0.1 -U postgres --globals-only > /backup/globals_$(date +%F).sql
Не пишите пароль в командной строке — используйте файл ~/.pgpass (chmod 600).
MySQL / MariaDB
Для таблиц InnoDB --single-transaction даёт согласованную копию без блокировки таблиц:
mysqldump --single-transaction --routines --triggers --events \
-u app_backup appdb | gzip > /backup/appdb_$(date +%F).sql.gz
Учётные данные храните в секции [mysqldump] файла ~/.my.cnf. Для резервного копирования создайте отдельного пользователя только с правами, нужными для чтения и дампа.
Для больших баз дампа может быть недостаточно: восстановление на момент времени (PITR) даёт архивирование WAL в PostgreSQL и binlog в MySQL. Для небольших и средних проектов ежедневный дамп и правильное хранение — обычно достаточная отправная точка.
Шифрование
Резервная копия должна быть зашифрована до того, как покинет сервер. Два распространённых способа:
restic — сам выполняет шифрование, поддерживает дедупликацию и политику хранения:
export RESTIC_REPOSITORY=s3:https://s3.example.com/backups/app
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic backup /backup /var/www/app/storage/app /etc/nginx
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check
age или gpg — шифрование обычного архива открытым ключом. В этом случае на сервере лежит только открытый ключ, а закрытый хранится в другом месте — даже при взломе сервера старые копии расшифровать нельзя:
tar -czf - /backup | age -r age1...publickey > /offsite/app_$(date +%F).tar.gz.age
Не храните ключ или пароль шифрования вместе с копией и не теряйте его: копия без ключа бесполезна. Храните ключ в надёжном месте (менеджер паролей, сейф), известном двум ответственным лицам.
Автоматизация
Ручные копии со временем забываются. Достаточно простого cron или таймера systemd:
# /etc/cron.d/app-backup
30 2 * * * backup /usr/local/bin/app-backup.sh >> /var/log/app-backup.log 2>&1
Если скрипт завершился неудачно, должно прийти уведомление. Самый простой способ — мониторинг «сердцебиения» (heartbeat): скрипт в конце отправляет сигнал, а если сигнал не пришёл, срабатывает оповещение. В проектах на Laravel пакет spatie/laravel-backup в одном месте управляет копированием базы и файлов, очисткой старых копий и уведомлениями.
Тест восстановления
Это самый часто пропускаемый и самый важный шаг. Как минимум раз в месяц:
- Подготовьте отдельный тестовый сервер или контейнер (не трогайте рабочую систему).
- Скачайте последнюю копию и расшифруйте её.
- Восстановите базу:
createdb -h 127.0.0.1 -U postgres restore_test
pg_restore -h 127.0.0.1 -U postgres -d restore_test --no-owner app_2026-10-24.dump
psql -h 127.0.0.1 -U postgres -d restore_test -c "SELECT count(*) FROM users;"
Для MySQL:
gunzip -c appdb_2026-10-24.sql.gz | mysql -u root restore_test
- Запустите приложение с этой базой и выполните основные действия: вход, открытие документа, скачивание файла.
- Запишите результат: сколько заняло времени, что мешало, какого шага не было в документации.
Из этого теста получаются два важных показателя: RPO — сколько данных вы готовы потерять (при ежедневной копии — до одних суток), и RTO — за какое время вы можете вернуть систему в строй. Согласуйте эти цифры с руководством.
С точки зрения шифровальщиков
При атаке шифровальщика злоумышленник обычно сначала пытается найти и уничтожить резервные копии. Поэтому:
- у основного сервера не должно быть права удалять копии из хранилища;
- ключи доступа к хранилищу не должны совпадать с
.envосновного сервера; - как минимум одна копия должна быть неизменяемой или офлайн;
- при восстановлении выбирайте копию, сделанную до момента инцидента, чтобы не вернуть заражённое состояние, и сначала закройте уязвимость в восстановленной системе.
Смена всех паролей и ключей после восстановления тоже должна быть частью процедуры.
Короткий чек-лист
- В веб-каталоге нет файлов
.sql,.zip,.tar.gz,.bak, и они не открываются снаружи - Записан список того, что копируется (база, загруженные файлы, конфигурация, секреты)
- База дампится согласованно через
pg_dump/mysqldump --single-transaction - 3-2-1: как минимум одна копия в другом месте, одна неизменяемая или офлайн
- Копии шифруются до выхода с сервера, ключ хранится отдельно
- Резервное копирование автоматизировано, о сбоях приходит уведомление
- Есть политика хранения (ежедневные, еженедельные, ежемесячные)
- Тест восстановления проводится регулярно, результат записывается
- RPO и RTO согласованы
Итог
Хорошая система резервного копирования не обязана быть сложной: ежедневный согласованный дамп, шифрование, неизменяемая копия в другом месте и тест восстановления раз в месяц выполнимы и для небольшой команды. В нашем процессе Claude AI агент просматривает настройки сервера, задачи cron и веб-каталог, находит открытые архивы и недостающие шаги, а специалист настраивает порядок резервного копирования и восстановления и проверяет его на практике.
Если хотите узнать, готов ли ваш порядок резервного копирования к экспертизе, оставьте заявку на сканирование. Мы поможем закрыть уязвимости до официальной проверки.


