restic: зашифрованные резервные копии, ротация и проверка целостности

0
25
Обложка статьи: restic: зашифрованные резервные копии, ротация и проверка целостности

Резервная копия, которую нельзя восстановить или которая лежит открытой, не защищает, а создаёт ещё одну точку утечки. restic решает три задачи сразу: шифрует данные, хранит их без дублирования и умеет проверять целостность. Правило 3-2-1 и ручное шифрование через GPG описаны отдельно; здесь практика restic с проверкой на тестовом репозитории.

Статья опирается на логику направления «Безопасность данных» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Проверка выполнена с restic 0.19.1 в контейнере на тестовых данных, после неё всё удалено.

Что должно получиться

Уровень Что это значит на практике
2. Гигиенический Резервные копии делаются по расписанию, хранятся в зашифрованном виде, проверяются на целостность, восстановление отработано

Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.

Репозиторий и пароль

Репозиторий создаётся один раз. Пароль храните в файле с правами 600 (не в командной строке и не в истории оболочки), а его копию — отдельно от самих копий, например в менеджере паролей: без пароля данные не восстановить.

export RESTIC_REPOSITORY=/backup/repo
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic init

Репозиторий может находиться и на удалённом хранилище (sftp, S3-совместимое): шифрование выполняется до отправки, поэтому хранилищу данные не видны. В тесте в каталоге репозитория лежат только служебные файлы config, keys, index, snapshots и блоки данных data; строки из исходных файлов в них не читаются.

Копии и восстановление

Команда restic backup КАТАЛОГ --tag nightly создаёт снимок (snapshot). Первая копия двух файлов (около 295 КиБ) добавила в репозиторий около 295 КиБ. Повторная копия после добавления одной строки в файл добавила около 4 КиБ: хранятся только новые блоки. Восстановление последнего снимка:

restic restore latest --target /tmp/restore-test
diff -r /srv/data /tmp/restore-test/srv/data

В тесте восстановленные файлы совпали с исходными. Ошибка пароля: с неверным паролем команда snapshots завершилась сообщением Fatal: wrong password or no key found.

Скрипт с ротацией и проверкой

#!/usr/bin/env bash
# Резервная копия каталога в зашифрованный репозиторий restic + проверка + ротация.
# Переменные: RESTIC_REPOSITORY (путь или адрес), RESTIC_PASSWORD_FILE (файл с паролем, права 600), SRC (что копировать)
set -euo pipefail
: "${RESTIC_REPOSITORY:?}" "${RESTIC_PASSWORD_FILE:?}" "${SRC:?}"
[ "$(stat -c %a "$RESTIC_PASSWORD_FILE")" = "600" ] || { echo "файл пароля должен иметь права 600" >&2; exit 2; }

restic backup "$SRC" --tag nightly --exclude-caches
# хранить: 7 дневных, 4 недельных, 6 месячных копий; остальное удалить
restic forget --tag nightly --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
# целостность структуры каждый раз, чтение 1/10 данных при каждом запуске (полное чтение раз в месяц: --read-data)
restic check --read-data-subset=1/10
echo "restic: копия, ротация и проверка выполнены"

Что делает скрипт: отказывается работать, если у файла пароля не те права (в тесте при правах 644 вернул код 2 и сообщение об этом); создаёт копию; удаляет старые снимки по правилам и освобождает место (--prune); проверяет структуру и читает десятую часть данных. Проверка ротации: в репозитории было 40 ежедневных снимков за 40 дней, после запуска остались 11 (удалено 30), затем check завершился без ошибок. Запускайте скрипт из cron или таймера systemd: изоляция служб systemd.

Проверка целостности

Команда Что проверяет Результат в тесте
restic check Структуру репозитория, снимки и индекс. Содержимое блоков данных не читает После порчи байта в файле данных ошибок не нашла
restic check --read-data-subset=1/10 Читает и расшифровывает часть данных (в скрипте каждый раз десятую) Не запускалась на повреждённом репозитории
restic check --read-data Читает все данные целиком Нашла повреждённый пакет: «contains 2 errors», расшифровка блока не удалась

Вывод: обычный check повреждение данных не видит. Только чтение данных обнаруживает битые файлы, поэтому запускайте --read-data регулярно (например, раз в месяц) или используйте подмножество с разными частями, например 1/10 в одну ночь, 2/10 в другую. Найдя повреждённые пакеты, не ремонтируйте на месте: сначала сделайте новую копию в другой репозиторий и только потом следуйте инструкции restic по восстановлению.

Порядок внедрения

  1. Определите, что копировать: базы (дамп, а не файлы работающей базы), конфигурации, каталоги с данными; исключите кэши и временные файлы.
  2. Создайте репозиторий вне копируемого сервера и сохраните пароль отдельно.
  3. Настройте расписание и срок хранения под ваши требования к потере данных и глубине истории.
  4. Добавьте мониторинг: сообщение об ошибке при ненулевом коде возврата и контроль возраста последнего снимка.
  5. Отрабатывайте восстановление по расписанию: restore на отдельную машину и сверка.
  6. Закройте доступ: у сервера, делающего копии, не должно быть возможности удалять их на хранилище (отдельные права или режим «только добавление»).
  7. Если в копиях персональные данные, учтите сроки хранения и удаление по запросу: самопроверка по ПДн.

Диагностика

Симптом Причина и что делать
wrong password or no key found Неверный пароль или другой репозиторий. Проверьте файл пароля и значение RESTIC_REPOSITORY
Каждая копия читает все файлы заново («no parent snapshot found») Изменилось имя хоста (так бывает при запуске в контейнере с новым именем при каждом запуске). Задайте постоянное значение через --host
check без ошибок, а восстановление не работает Обычный check не читает данные. Запустите check --read-data и восстановите тестовую копию
Репозиторий не освобождает место Не выполнен forget --prune: одного forget недостаточно
Скрипт отказывается запускаться У файла пароля права шире 600. Выполните chmod 600
Копия базы данных не восстанавливается Скопированы файлы работающей базы. Делайте дамп средствами СУБД и копируйте его

Где это в модели зрелости

Материал относится к направлению «Безопасность данных» (материалы направления, карта зрелости). Уровень 2 требует, чтобы данные были защищены, а меры подтверждались проверкой: шифрование копий, контроль целостности и отработанное восстановление дают такое подтверждение.

Как проверить

  1. Расписание копий работает, возраст последнего снимка контролируется мониторингом.
  2. Репозиторий зашифрован, пароль хранится отдельно и доступен ответственным.
  3. Последнее восстановление на отдельной машине проведено и задокументировано, файлы сверены.
  4. Регулярно выполняется чтение данных (--read-data целиком или по частям).
  5. Сервер, создающий копии, не может удалить их на хранилище.

Источники

Комментарии закрыты.