У резервного копирования есть давняя боль: полная копия сервера весит десятки гигабайт, копировать её нужно каждую ночь, а меняется между запусками лишь малая часть файлов. Архиватор tar пишет всё заново, rsync дублирует каталог целиком, и место на накопителе тает на глазах. BorgBackup подходит к задаче иначе: содержимое нарезается на блоки, повторяющиеся блоки записываются один раз, при этом каждый архив в списке выглядит полноценной самостоятельной копией. Ниже разобрана настройка репозитория на локальном диске и на удалённой машине через SSH, создание архивов с понятными метками, просмотр копии через FUSE, правила удержания, проверка целостности и сценарии восстановления от одного файла до полного отката.

Дедупликация на уровне блоков превращает сотни архивов в компактный набор уникальных данных

Borg работает не с файлами, а с блоками. При создании архива каждый файл нарезается на куски переменной длины, границы кусков вычисляются по содержимому через скользящую хеш-функцию. Отсюда практичное следствие: если в начало документа вставили новый абзац, сдвигается лишь небольшая окрестность правки, остальные блоки остаются байт в байт прежними и второй раз на диск не пишутся. Типичный блок в стандартных настройках весит около пары мегабайт.

Каждый блок получает уникальный хеш-отпечаток, по нему Borg ищет фрагмент в индексе репозитория. Не нашёл - записал на диск, нашёл - новый архив получает ссылку на сохранённый кусок. Сотый по счёту архив занимает место, пропорциональное изменениям за сутки, а не полному объёму сервера: каталог etc с конфигурациями в первые сутки уходит в хранилище целиком, дальше добавляются доли процента.

Снаружи каждый архив выглядит полной копией: в репозитории лежит манифест со списком блоков и их порядком, при извлечении Borg собирает файлы обратно. Дедупликация действует в пределах одного репозитория: несколько серверов в общем хранилище делят одинаковые блоки, а два разных репозитория между собой не пересекаются. Borg распознаёт жёсткие ссылки, сохраняет их содержимое один раз и восстанавливает ссылки при извлечении, разрежённые файлы не раздуваются нулями.

Локальный кеш в каталоге ~/.cache/borg содержит индекс блоков, поэтому повторные запуски не перечитывают неизменённые файлы. Долгий первый запуск пишет контрольные точки: при обрыве связи повторная команда продолжит копирование с последней точки, а в списке появится временный архив с суффиксом checkpoint.

Шифрование репозитория и выбор алгоритма сжатия под конкретный тип данных

Режим шифрования выбирается один раз при инициализации. Режим repokey кладёт ключ шифрования внутрь репозитория, ключ заперт парольной фразой, для доступа достаточно помнить фразу и иметь путь к хранилищу. Режим keyfile держит ключ на клиентской машине в каталоге ~/.config/borg/keys: без этого файла репозиторий не откроется даже при верной фразе, зато копия хранилища постороннему ничего не даёт. Первая схема проще в эксплуатации, вторая строже, выбор зависит от того, что дороже потерять: файл ключа или контроль над копией репозитория.

Порядок операций фиксированный: Borg сжимает блок до шифрования, потому что зашифрованный текст почти не сжимается. Быстрый lz4 применяется по умолчанию, zlib и lzma выжимают сильнее, но заметно грузят процессор, zstd держит разумный баланс и настраивается уровнем, например zstd,15: текст конфигов сжимается в разы, нагрузка остаётся умеренной. Для уже сжатого содержимого вроде фотографий сжатие отключается значением none, иначе процессорное время тратится впустую. Режим auto пробует сжать блок и сохраняет его как есть, если выигрыша нет.

Ключ и парольная фраза не восстанавливаются автоматически, их утрата означает утрату всех копий. Ключ выгружается командой borg key export и хранится на отдельном носителе, фраза держится в менеджере паролей.

Инициализация репозитория на локальном диске и на удалённом сервере через SSH

В большинстве дистрибутивов пакет называется borgbackup: в Debian и Ubuntu достаточно apt install borgbackup. Для удалённого хранилища утилита нужна на обеих машинах: локальная сторона выступает клиентом, удалённая запускает borg serve и складывает блоки на свой диск.

Локальный репозиторий инициализируется одной командой:

borg init -e repokey /srv/backup/web01.borg

Флаг -e выбирает режим шифрования, каталог репозитория создаётся сам, хранилище разумно держать вне копируемых путей.

На удалённой машине заводится отдельный пользователь и каталог для чужих копий:

useradd -m borg
mkdir -p /srv/backup
chown -R borg:borg /srv/backup

На клиенте генерируется выделенный ключ SSH без пароля:

ssh-keygen -t ed25519 -f ~/.ssh/id_borg -N ""

Публичный ключ добавляется на сервере в файл ~/.ssh/authorized_keys пользователя borg одной строкой с жёстким ограничением, после префикса идёт сам ключ:

command="borg serve --restrict-to-path /srv/backup",restrict

Такой ключ не даёт постороннему командной оболочки на сервере: с ним доступен только запуск borg serve и только внутри разрешённого каталога. Усиленный вариант добавляет ключ --append-only: удаления фиксируются в журнале, стереть старые копии возможно только сняв ограничение на сервере.

Инициализация удалённого хранилища выполняется с клиента:

export BORG_RSH="ssh -i ~/.ssh/id_borg"
borg init -e repokey borg@backupserver:/srv/backup/web01.borg

Команда запросит парольную фразу дважды и создаст структуру репозитория.

Создание архивов с понятными метками и регулярный запуск по расписанию

Синтаксис создания прост: borg create ОПЦИИ РЕПОЗИТОРИЙ::ИМЯ ПУТИ. Имя архива удобно собирать из подстановок: {hostname} подставит имя машины, {now} - момент запуска с настраиваемым форматом даты. Пример ночной копии:

borg create --stats --compression zstd \
  --exclude "/home/*/.cache" \
  borg@backupserver:/srv/backup/web01.borg::web01-{now:%Y-%m-%d} \
  /etc /var/www /home

Флаг --stats печатает сводку: исходный объём, объём после дедупликации и реально занятое место, выгода видна уже на второй день. Флаг --one-file-system не даёт копированию выйти за границы одной файловой системы, полезно при копировании корня с отдельными разделами. Исключения пишутся шаблонами: кеши приложений и тяжёлые журналы не засоряют хранилище. Базы данных перед копированием выгружаются в дамп штатными средствами, файловая копия работающей базы рассогласована. Список копий показывает borg list, детали конкретного архива раскрывает borg info.

Для регулярности подходит cron. Сначала готовится файл фразы:

echo "длинная парольная фраза" > /root/.borg-passphrase
chmod 600 /root/.borg-passphrase

Основная команда живёт в сценарии /usr/local/bin/borg-nightly.sh, потому что символ процента в кронтабе требует экранирования:

#!/bin/bash
export BORG_REPO="borg@backupserver:/srv/backup/web01.borg"
export BORG_PASSCOMMAND="cat /root/.borg-passphrase"
export BORG_RSH="ssh -i /root/.ssh/id_borg"
borg create --stats --compression zstd --lock-wait 3600 ::web01-{now:%Y-%m-%d} /etc /var/www /home

Строки расписания приобретают вид:

BORG_REPO="borg@backupserver:/srv/backup/web01.borg"
BORG_PASSCOMMAND="cat /root/.borg-passphrase"
BORG_RSH="ssh -i /root/.ssh/id_borg"
0 2 * * * /usr/local/bin/borg-nightly.sh >> /var/log/borg-nightly.log 2>&1
30 3 * * 0 borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --glob-archives "web01-*" >> /var/log/borg-prune.log 2>&1
0 7 1 * * borg check --repository-only >> /var/log/borg-check.log 2>&1

Флаг --lock-wait 3600 заставит новый запуск дождаться освобождения блокировки: одновременная запись в хранилище не допускается. Нулевой код возврата означает успех, ненулевой - повод открыть лог.

Монтирование архива через FUSE даёт доступ к файлам без их извлечения

Для просмотра на клиенте нужен FUSE, в Debian и Ubuntu ставится пакет fuse3. Дальше весь репозиторий монтируется как обычный каталог:

mkdir /mnt/borg-arch
borg mount borg@backupserver:/srv/backup/web01.borg /mnt/borg-arch

Внутри точки монтирования появляются подкаталоги с именами архивов:

ls /mnt/borg-arch
web01-2026-04-09  web01-2026-04-10  web01-2026-04-11

Можно смонтировать и один архив целиком: borg mount borg@backupserver:/srv/backup/web01.borg::web01-2026-04-11 /mnt/borg-arch. Скопировать одну конфигурацию можно обычным cp:

cp /mnt/borg-arch/web01-2026-04-11/etc/nginx/nginx.conf /tmp/nginx.conf

Точка монтирования доступна только на чтение, испортить копию через неё не выйдет. Отмонтирование выполняется командой borg umount /mnt/borg-arch.

Один файл достаётся и без FUSE, прямым потоком:

cd /tmp
borg extract --stdout borg@backupserver:/srv/backup/web01.borg::web01-2026-04-11 etc/nginx/nginx.conf > nginx.conf

Каталог извлекается во временное место, пути внутри архива записаны без первого слэша, адресация идёт от корня распаковки:

mkdir -p /tmp/restore && cd /tmp/restore
borg extract borg@backupserver:/srv/backup/web01.borg::web01-2026-04-11 etc/nginx
rsync -a /tmp/restore/etc/nginx/ /etc/nginx/

Разницу между двумя ночами показывает borg diff с парой имён архивов.

Команда prune и правила удержания сдерживают рост репозитория

Политика удержания описывает, сколько копий оставить в каждой категории. Правила задаются набором флагов:

borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 \
  --glob-archives "web01-*" --dry-run \
  borg@backupserver:/srv/backup/web01.borg

Логика отбора прямая: Borg оставляет самый свежий архив, затем последний архив за каждые из последних семи суток, четыре недели и шесть месяцев, остальное помечается к удалению. Флаг --glob-archives ограничивает правило архивами с общим префиксом, незаменимо, когда в одном репозитории копии нескольких машин. Пробный прогон с --dry-run показывает план, повторный вызов без него исполняет план. Самый свежий архив не удаляется никогда.

Prune меняет только метаданные и проходит быстро. В свежих версиях Borg место на диске возвращает команда borg compact: она переписывает сегменты хранилища и убирает блоки, на которые больше не ссылается ни один архив. Разумный ритм: prune раз в неделю, compact раз в месяц.

Проверка целостности и полный откат сервера на тестовой машине

Команда borg check без флагов читает весь репозиторий: сверяет структуру индекса, контрольные суммы и шифрование, на больших хранилищах уходят часы. Флаг --repository-only проверяет каркас хранилища без глубокого обхода архивов, подходит для ежемесячного прогона из кронтаба. Флаг --verify-data сверяет каждый блок вплоть до криптографического хеша: самый медленный и самый основательный вариант после любых сомнений в накопителе. Грубый обрыв операции иногда оставляет блокировку, она снимается командой borg break-lock.

Один файл достаётся потоком --stdout или через точку монтирования. Каталог извлекается во временное место и переносится rsync, так перезапись рабочих конфигураций остаётся осознанным решением. Полный откат требует, чтобы в архив попадал корень целиком: сервер загружается со спасательной системы, целевой диск монтируется в /mnt/target, затем выполняется распаковка:

cd /mnt/target
borg extract borg@backupserver:/srv/backup/web01.borg::web01-2026-04-11

Разметка диска, файловая система и загрузчик живут вне архива, их готовят штатными средствами спасательной системы. После распаковки останется смонтировать псевдофайловые системы, войти в chroot и переустановить загрузчик. Borg возвращает файлы, остальное делают обычные инструменты дистрибутива.

Уверенность в схеме даёт только репетиция на тестовой машине, и она сводится к короткой последовательности шагов:
1. развернуть чистую виртуальную машину с тем же дистрибутивом и версией;
2. установить пакет borgbackup и подготовить ключ доступа к репозиторию;
3. смонтировать самый свежий архив и сверить состав файлов с контрольным списком;
4. распаковать архив в целевой каталог и запустить сервисы;
5. замерить время каждого шага и обновить памятку восстановления.

Репетиция закрывает три вопроса сразу: репозиторий доступен, фраза и ключ под рукой, порядок действий отработан. BorgBackup берёт на себя хранение и экономию места, а дисциплина расписания и привычка проверять восстановление, а не только создание копий, остаются на человеке.