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 по восстановлению.
Порядок внедрения
- Определите, что копировать: базы (дамп, а не файлы работающей базы), конфигурации, каталоги с данными; исключите кэши и временные файлы.
- Создайте репозиторий вне копируемого сервера и сохраните пароль отдельно.
- Настройте расписание и срок хранения под ваши требования к потере данных и глубине истории.
- Добавьте мониторинг: сообщение об ошибке при ненулевом коде возврата и контроль возраста последнего снимка.
- Отрабатывайте восстановление по расписанию:
restoreна отдельную машину и сверка. - Закройте доступ: у сервера, делающего копии, не должно быть возможности удалять их на хранилище (отдельные права или режим «только добавление»).
- Если в копиях персональные данные, учтите сроки хранения и удаление по запросу: самопроверка по ПДн.
Диагностика
| Симптом | Причина и что делать |
|---|---|
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 требует, чтобы данные были защищены, а меры подтверждались проверкой: шифрование копий, контроль целостности и отработанное восстановление дают такое подтверждение.
Как проверить
- Расписание копий работает, возраст последнего снимка контролируется мониторингом.
- Репозиторий зашифрован, пароль хранится отдельно и доступен ответственным.
- Последнее восстановление на отдельной машине проведено и задокументировано, файлы сверены.
- Регулярно выполняется чтение данных (
--read-dataцеликом или по частям). - Сервер, создающий копии, не может удалить их на хранилище.
Источники
- Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.
- Документация restic: restic.readthedocs.io; исходный код: github.com/restic/restic.


















