Настройка Restic для резервного копирования VPS
Узнайте, как настроить Restic на Ubuntu 24.04 для передачи зашифрованных копий по SFTP. Руководство включает создание репозитория, настройку таймеров systemd и проверку восстановления.
Почему резервная копия на том же сервере не является резервной копией
Restic — это бесплатный инструмент резервного копирования с открытым исходным кодом, который отправляет зашифрованные дедуплицированные снимки ваших файлов в удаленное хранилище: на другой VPS, домашний компьютер или S3-совместимое объектное хранилище. В этом руководстве описывается настройка Restic на Ubuntu 24.04: от установки до создания репозитория по SFTP, выполнения первого резервного копирования, настройки ночного таймера systemd, политики хранения и процедуры восстановления, подтверждающей работоспособность всей системы. Местом назначения должна быть другая машина, так как копия, хранящаяся на том же сервере, погибнет вместе с ним.
Директория backup/ на том же сервере, который подвергается резервному копированию, защищает вас только от одного: случайного удаления файла. Она не уцелеет при выходе из строя диска, так как находилась на этом же диске. Она не уцелеет при атаке злоумышленника с правами root, так как он первым делом удалит копии. Она не уцелеет при ошибке в управлении аккаунтом, которая приведет к удалению самого VPS. В статье Самый неэффективный дата-центр в мире высмеивается архив tarball с именем backup_final_v2_REAL, лежащий на том же массиве, что и данные, и эта шутка актуальна, потому что многие из нас поступали именно так. Правило гласит: данные должны находиться вне сервера, а restic — это самый простой способ следовать этому правилу.
Restic в четырех понятиях
Репозиторий. Место, куда restic записывает данные. Это каталог в собственном формате restic, заполненный зашифрованными блоками, которые может прочитать только restic. Вы никогда не редактируете его вручную; взаимодействие происходит через команды restic и адрес -r.
Снапшот. Снимок файлов в определенный момент времени. Каждый запуск резервного копирования создает снапшот, каждый снапшот можно восстановить отдельно, и каждый из них выглядит как полная копия ваших данных на тот момент.
Дедупликация. Restic разбивает файлы на фрагменты, определяемые их содержимым, и загружает только те фрагменты, которых еще нет в репозитории. Первое резервное копирование загружает всё; каждый последующий запуск загружает примерно то, что изменилось. Ночной снапшот объемом 20 GB, в котором изменилось 50 MB, занимает около 50 MB, поэтому хранение десятков снапшотов обходится дешево.
Шифрование по умолчанию. Репозиторий restic всегда зашифрован (AES-256). Restic отказывается создавать или открывать репозиторий с пустым паролем, если вы не передадите --insecure-no-password (начиная с restic 0.17.0), поэтому для репозитория, настроенного по этому руководству, пароль требуется для каждой команды. Хост резервного копирования или провайдер хранилища видят только зашифрованные блоки. Важное следствие: потеряете пароль — данные будут безвозвратно утеряны, так задумано архитектурой. Храните копию пароля где-то еще, а не на этом сервере. Это настолько важно, что ниже упоминается еще дважды.
Установка restic в Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionВ Ubuntu 24.04 устанавливается версия restic 0.16.4, в то время как актуальный upstream-релиз — 0.19.1. Этот разрыв существует, так как в LTS-релизах (long term support) версии пакетов замораживаются, однако для данного руководства это не имеет значения: версия 0.16.4 поддерживает все описанные функции. Если вам требуется новейший релиз ради повышения производительности, скачайте официальный бинарный файл со страницы релизов проекта restic на GitHub, распакуйте его с помощью bunzip2 и установите в /usr/local/bin/restic; установка restic не требует иных действий.
Создание репозитория на другом сервере по SFTP
Вам потребуется целевая машина: обычно для этого подходит второй небольшой VPS или любой сервер с запущенным SSH-сервером и свободным местом на диске. Restic поддерживает протокол SFTP (передача файлов поверх SSH), поэтому на хосте для резервных копий не нужно устанавливать дополнительное ПО. В этом руководстве хост для резервных копий имеет адрес 10.0.0.12, а пользователь — restic. Не называйте этого пользователя backup: в Ubuntu и Debian при каждой установке создается зарезервированная системная учетная запись backup (uid 34, без командной оболочки), поэтому adduser backup завершится ошибкой, а ssh backup@... попадет в nologin.
Ежедневное задание будет выполняться от имени root на сервере, с которого создается резервная копия, поэтому пользователю root необходим доступ по ключу к хосту для резервных копий. Создайте отдельный ключ без парольной фразы, так как в 3 часа ночи некому будет её вводить, и скопируйте его:
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login worksЕсли вы не знакомы с ключами, основы управления SSH-ключами объясняют модель доступа, права доступа и способы отзыва ключа в будущем.
Далее — пароль от репозитория. Сгенерируйте надежный пароль и сохраните его в файл, доступный только пользователю root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordТеперь скопируйте этот пароль в ваш менеджер паролей, прежде чем продолжать. Если этот VPS выйдет из строя, репозиторий вместе с этим паролем позволит восстановить всё; репозиторий без пароля не позволит восстановить ничего.
Инициализируйте репозиторий:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password initcreated restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1Альтернативным местом хранения является S3-совместимое объектное хранилище, что является верным выбором, если вы не хотите использовать вторую машину. Любой S3-совместимый бакет работает аналогично; меняются только адрес и две переменные с учетными данными:
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password initВсё, что идет после init, идентично для обоих вариантов хранения. В остальной части этого руководства используется адрес SFTP; подставьте свой.
Первое резервное копирование с исключениями
Выполняйте резервное копирование только тех данных, которые невозможно восстановить переустановкой, а не всей файловой системы целиком. Операционная система восстанавливается при переустановке, а ваши конфигурации и данные — нет. Для типичного VPS это означает /etc, /home и те каталоги, где ваши приложения хранят состояние, например /srv или /var/www. Исключайте кэши: они занимают много места, постоянно обновляются и пересоздаются автоматически:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'Files: 4181 new, 0 changed, 0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c savedПервый запуск загружает все данные, поэтому он занимает некоторое время. Запустите ту же команду повторно, и она завершится за несколько секунд, сообщив об изменении нескольких файлов и добавлении нескольких MiB, так как дедупликация загружает только новые блоки данных. Выведите список имеющихся копий:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsКаждый снимок содержит ID, время создания и пути, которые он включает. Именно по этим ID выполняется восстановление.
Ежедневный запуск с помощью systemd timer
Ввод адреса репозитория в каждой команде быстро утомляет, а резервное копирование, которое вы запускаете вручную, перестает выполняться уже через месяц. Обе проблемы решаются одним скриптом и одним таймером. Скрипт устанавливает две переменные окружения, которые считывает restic, RESTIC_REPOSITORY и RESTIC_PASSWORD_FILE, поэтому каждая команда внутри него остается короткой:
sudo nano /usr/local/bin/restic-backup.sh#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic checksudo chmod 700 /usr/local/bin/restic-backup.shСтроки forget и check объясняются в следующих двух разделах. Теперь расписание: сервис oneshot, который запускает скрипт, и таймер, который активирует его в 03:00 каждую ночь. Таймер здесь лучше, чем строка в cron, потому что он записывает логи в journal, а Persistent=true запускает пропущенную резервную копию сразу после того, как сервер включается после простоя.
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.targetВключите таймер, затем запустите сервис вручную один раз и проследите за его работой:
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fsystemctl list-timers показывает, когда произойдет следующий запуск. Вы также можете сгенерировать пару файлов юнитов вместо того, чтобы вводить их вручную:
Полное описание шаблона для этих двух файлов, включая синтаксис календаря и директивы безопасности, которые может содержать сервис, приведено в запуск программы как systemd-сервиса на VPS.
Резервная копия — это лишь слухи, пока вы её не восстановили
Считайте это предложение заповедью. Задача резервного копирования, которая успешно выполняется каждую ночь, доказывает лишь то, что задача была запущена; она не доказывает, что ваши данные можно вернуть. Две проверки устраняют этот пробел.
Во-первых, restic check, который скрипт уже запускает каждую ночь. Он проверяет структуру репозитория и индекс, поэтому скрытое повреждение на хосте резервного копирования будет обнаружено на следующую ночь, а не в день восстановления. Раз в месяц запускайте более глубокую версию, которая загружает и криптографически проверяет случайную десятую часть реальных данных:
sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%Поскольку подмножество выбирается случайно каждый раз, документация restic прямо указывает, что повторные запуски не гарантируют проверку каждого pack-файла, сколько бы вы их ни делали. Если вы хотите, чтобы ежемесячные запуски охватывали весь репозиторий без необходимости полной загрузки, используйте форму с фиксированной группой: --read-data-subset=1/10 в один месяц, 2/10 в следующий и так далее до 10/10. Restic делит pack-файлы на десять примерно равных групп и проверяет только группу n, поэтому полный цикл из десяти запусков считывает каждую группу по одному разу.
Во-вторых, тренировка восстановления. Находясь в root-оболочке, как описано выше, восстановите один реальный каталог из последнего снапшота во временное место и сравните его с исходными файлами:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshdiff, не выводящий ничего, означает, что каждый байт вернулся в исходном виде — это единственное доказательство, которое имеет значение. После этого удалите /srv/restore-drill. Проводите эту тренировку ежемесячно, а раз или два в год выполняйте полную версию: восстановите весь последний снапшот на временный VPS и проверьте, что ваше приложение действительно запускается из него. Если ваши данные состоят из миллионов мелких файлов, например почтовых каталогов Maildir или пользовательских загрузок, перед полным восстановлением проверьте запас инодов на целевом диске командой df -i: восстановление может упасть с ошибкой нехватки места, хотя df -h показывает свободные гигабайты, и разбор лимитов инодов в ext4 и XFS объясняет, почему так происходит и что с этим делать. В день, когда вам потребуется, чтобы это сработало под давлением, вы захотите, чтобы это была процедура, которую вы уже выполняли.
Хранение: forget и prune
Без политики снимки накапливаются бесконечно, а репозиторий постоянно растет. Строка forget в скрипте применяет политику каждую ночь: --keep-daily 7 сохраняет по одному снимку в день за последние семь дней, --keep-weekly 4 по одному в неделю за четыре недели, и --keep-monthly 6 по одному в месяц за шесть месяцев. Все, что не защищено правилами, помечается как забытое.
Команда forget сама по себе лишь удаляет записи о снимках; блоки данных остаются в репозитории, пока их что-то не удалит. Именно это делает --prune: она находит блоки, на которые не ссылается ни один из оставшихся снимков, и удаляет их — именно в этот момент освобождается место на диске. Операция prune создает реальную нагрузку на репозиторий, поэтому на больших хранилищах некоторые запускают forget каждую ночь, а --prune — раз в неделю; для типичных размеров VPS ежедневного запуска вполне достаточно.
Базы данных: сначала дамп, затем резервная копия
Restic копирует файлы по мере их чтения, а база данных постоянно записывает данные в свои файлы. Если захватить файл «живой» базы данных в момент записи, то при восстановлении она окажется поврежденной, так как копия будет содержать смесь страниц до и после записи. Решение стандартное: база данных должна создать согласованный экспорт в файл, после чего restic выполнит резервное копирование этого файла.
Для PostgreSQL добавьте строку с дампом в начало restic-backup.sh, перед командой restic backup, и включите каталог с дампом в пути для резервного копирования:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump выполняет ту же роль для MariaDB и MySQL. В качестве примера реализации этого шаблона, раздел о резервном копировании Nextcloud переводит систему в режим обслуживания, создает дамп Postgres и копирует файлы как единый согласованный набор — именно тот набор, который restic должен каждую ночь выгружать с сервера. Для SQLite используется аналогичный подход, но с меньшими усилиями: руководство по Vaultwarden останавливает контейнер на несколько секунд для создания «холодной» копии db.sqlite3, и именно этот архив restic отправляет с сервера.
FAQ
Зашифрованы ли резервные копии restic?
Да, всегда. Каждый репозиторий restic зашифрован с помощью AES-256, режима без шифрования не существует. Restic также отказывается от пустого пароля, если вы не передадите --insecure-no-password (доступно с restic 0.17.0), поэтому для репозитория, настроенного согласно этому руководству, пароль требуется для каждой команды. Машина или провайдер, хранящий репозиторий, содержит только зашифрованные блоки, поэтому скомпрометированный хост резервного копирования не раскроет ваши файлы. Компромисс абсолютен: без пароля данные не могут быть восстановлены никем, поэтому храните его копию отдельно от сервера.
Делает ли restic инкрементальные резервные копии?
Каждый снапшот restic ведет себя как полная резервная копия, при этом занимая место как инкрементальная. Restic разбивает файлы на фрагменты и загружает только те, которые еще не были сохранены в репозитории, поэтому ночной запуск передает примерно то, что изменилось за день. В отличие от традиционных схем инкрементального копирования, здесь нет цепочки для воспроизведения: любой снапшот восстанавливается напрямую, а удаление старого снапшота никогда не нарушает целостность более нового.
Как восстановить файлы из резервной копии restic?
Запустите restic snapshots, чтобы найти ID снапшота, затем restic restore <id> --target /some/empty/dir, чтобы восстановить его, добавив --include /path для восстановления только части данных. latest работает вместо ID. Restic воссоздает исходную структуру каталогов в целевой папке, поэтому восстановление /etc/ssh попадет в /some/empty/dir/etc/ssh. Потренируйтесь до того, как это понадобится, потому что непроверенная резервная копия — это лишь слухи.
Как часто нужно запускать резервное копирование restic?
Ежедневный запуск — разумный минимум для сервера, а дедупликация делает это недорогим: каждый запуск загружает только те фрагменты, которые изменились с момента последнего. Данные, которые быстро меняются или потеря которых даже за один день будет болезненной, можно копировать каждые несколько часов с тем же шаблоном таймера. Частота — это простая часть; также регулярно запускайте restic check и ежемесячно проводите тренировку восстановления, так как расписание без проверки — это ложное успокоение.
Что произойдет, если я потеряю пароль от репозитория restic?
Резервные копии невозможно восстановить. Шифрование restic не имеет «черного хода» или сброса, поэтому пароль так же важен, как и сами резервные копии. Храните копию в своем менеджере паролей и в любом другом надежном месте, которое не является резервируемым сервером. Пока у вас есть доступ, restic key add позволяет зарегистрировать второй пароль для того же репозитория, что даст вам запасной вариант.