Info
Content

Borg

Overview

Что такое BorgBackup

BorgBackup (коротко: Borg) это программа для дедуплицирующего резервного копирования. Опционально она поддерживает сжатие и шифрование

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

Main features
  • Space efficient storage - дедупликация базируется на алгоритме content-defined chunking и используется для уменьшения кол-ва хранимых данных: каждый файл бьется на разноразмерные чанки и сохраняются только те чанки которые еще не были сохранены в репозиторий
    Чанки считаются дубликатами если их id_hash совпадают. Для вычисления id_hash используется криптостойкая хэш или MAC функция
    Дедуплицируются все чанки в рамках репозитория, не важно пришли эти чанки с разных машин, из предыдущих бэкапов, из одного бэкапа или даже из одного файла
    По сравнению с другими подходами к дедупликации, этот метод не полагается на:
    • Имена файлов / каталогов остаются прежними: таким образом, вы можете перемещать свои данные, не прерывая дедупликацию, даже между машинами, совместно использующими репозиторий
    • Полные файлы или временные метки остаются неизменными: если большой файл немного меняется, нужно сохранить только несколько новых фрагментов - это отлично подходит для виртуальных машин или необработанных дисков
    • Абсолютное положение фрагмента данных внутри файла: материал может быть сдвинут и все равно будет найден алгоритмом дедупликации
  • Speed
    • performance-critical код написан на C/Cython
    • локальное кэширование файлов/чанков
    • быстрое обнаружение неизмененных файлов
  • Data encryption - Все данные могут быть защищены с помощью 256-битного AES шифрования, целостность и подлинность данных проверяется через HMAC-SHA256. Данные шифруются на клиенте
  • Obfuscation - Опционально Borg может активно обфусцировать размер файлов/чанков чтобы сделать fingerprinting атаку более сложной
  • Compression - Все данные могут быть опционально сжаты:
    • lz4 (super fast, low compression)
    • zstd (wide range from high speed and low compression to high compression and lower speed)
    • zlib (medium speed and compression)
    • lzma (low speed, high compression)
  • Off-site backups - Borg может хранить данные на любом удаленном хосте доступном по ssh. Если Borg установлен на удаленном хосте, может быть получен большой прирост производительности в сравнении с network filesystems (sshfs, nfs, ...)
  • Backups mountable as filesystems - Бэкап архивы могут быть примонтированы как fuse для легкого интерактивного просмотра содержимого бэкапа и его восстановления

Easy to use

Инициализируй репозиторий (see borg init --help for encryption options):

root@borg-server:~# mkdir -p /var/lib/borg/my-test-backup-repo
root@borg-server:~# borg init -e none /var/lib/borg/my-test-backup-repo
root@borg-server:~# tree /var/lib/borg/my-test-backup-repo
/var/lib/borg/my-test-backup-repo
├── config
├── data
│   └── 0
│       ├── 0
│       └── 1
├── hints.1
├── index.1
├── integrity.1
└── README

2 directories, 7 files

Создай бэкап:

root@borg-server:~# borg create /var/lib/borg/my-test-backup-repo::vandud-test-backup-1 /var/log/
root@borg-server:~# borg create -v --stats /var/lib/borg/my-test-backup-repo::vandud-test-backup-2 /var/log/
Creating archive at "/var/lib/borg/my-test-backup-repo::vandud-test-backup-2"
------------------------------------------------------------------------------
Repository: /var/lib/borg/my-test-backup-repo
Archive name: vandud-test-backup-2
Archive fingerprint: 98dafada55752be228cdfc709639295b36b9161f4169152b05e707a44ecd4bb2
Time (start): Wed, 2023-12-13 16:34:54
Time (end):   Wed, 2023-12-13 16:34:54
Duration: 0.70 seconds
Number of files: 24
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
This archive:               53.54 MB              4.68 MB                511 B
All archives:              107.08 MB              9.35 MB              4.68 MB

                       Unique chunks         Total chunks
Chunk index:                      34                   66
------------------------------------------------------------------------------

Есть еще BorgWeb
Заброшенная штука, функционал сомнительной полезности

Installation

Есть три разных пути установить Borg:

  • Пакет - легко и быстро если пакет есть под твою систему
  • Бинарь - легко и быстро везде (разработчики предоставляют бинарь без зависимостей)
  • Исходники - можно через pip или git (значительно дольше)

Рассмотрим подробнее первые два

Distribution Package

Многие дистрибутивы уже имеют в репозиториях готовый к использованию пакет borgbackup который можно просто установить через пакетный менеджер

Может быть доступна далеко не последняя версия

Для Debian: apt install borgbackup

Standalone Binary

Есть готовый бинарь собранный через http://www.pyinstaller.org/
Доступен тут https://github.com/borgbackup/borg/releases

Работает очень даже хорошо

Надо держать в голове что эта штука распаковывает себя в /tmp, и если там не будет места или будет стоять опция noexec то все сломается. Можно изменить директорию для распаковки задав переменную TEMP перед запуском бинаря

Quick Start

Эта часть поможет начать работать с Borg и покрывает разные кейсы

A step by step example

  1. Перед тем как делать бэкап должен быть инициализирован репозиторий:
    $ borg init --encryption=repokey /path/to/repo
    
  2. Бэкап директорий ~/src и ~/Documents в архив с именем Monday:
    $ borg create /path/to/repo::Monday ~/src ~/Documents
    
  3. На следующий день создается архив с именем Tuesday:
    $ borg create --stats /path/to/repo::Tuesday ~/src ~/Documents
    
    Этот бэкап будет значительно быстрее и меньше, потому что будут сохранены только новые ранее не сохраненные данные. Флаг --stats выводит статистику по созданному архиву (например такая информация как занятое место и время выполнения)
  4. Список всех архивов в репозитории:
    $ borg list /path/to/repo
    
  5. Список файлов конкретного архива:
    $ borg list /path/to/repo::Monday
    
  6. Извлечь из архива файлы относительно текущей директории:
    $ borg extract /path/to/repo::Monday
    
  7. Удалить архив (это не освобождает диск):
    $ borg delete /path/to/repo::Monday
    
  8. Сжатие сегментов в репозитории:
    $ borg compact /path/to/repo
    
    Пример:
    root@borg-server:~# du -sch /var/lib/borg/my-test-backup-repo
    262M	/var/lib/borg/my-test-backup-repo
    262M	total
    root@borg-server:~# borg compact /var/lib/borg/my-test-backup-repo
    root@borg-server:~# du -sch /var/lib/borg/my-test-backup-repo
    6.0M	/var/lib/borg/my-test-backup-repo
    6.0M	total
    

По умолчанию Borg все делает молча, чтобы он давал какой-то вывод нужно использовать специальные флаги: --progress, --list, --verbose и --info

Archives and repositories

Borg-архив это результат бэкапа (результат команды borg create). Архив хранит снапшот данных файлов внутри себя. Который потом можно извлечь или примонтировать для восстановления

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

Important note about free space

Нужно следить что на сервере с репозиторием всегда достаточно свободного диска (а также в ~/.cache). Несколько гигабайтов должно быть достаточно в общем случае

Borg не использует диск зарезервированный для рута (даже когда запущен от рута). Рекомендуется зарезервировать некоторое пространство в самом Borg через опцию additional_free_space, начать можно с 2G

borg config /path/to/repo additional_free_space 2G

Если Borg запускается без свободного диска, он попытается высвободить диск (столько сколько сможет), а пока будет безопасно отвергать текущие операции, это позволит пользователю освободить больше диска с помощью удаления архивов
Если у вас реально кончится диск, то ему будет сложно или даже невозможно освободить себе диск, потому что доп место на диске нужно для всех операций, даже для операции удаления

Ты можешь использовать мониторинг или просто включить инфу о свободном месте в логи

Important note about permissions

Чтобы избежать проблем с правами (в репозитории или в кэше) всегда работай с репозиторием из под одного и того же пользователя

Если ты хочешь бэкапить файлы других пользователей или операционных систем, скорее всего потребуется запускать Borg от рута. Если бэкапите только свои файлы то запускайте Borg как обычный пользователь

Для локального репозитория просто всегда используй одного и того же пользователя для работы с Borg

Для удаленного репозитория: всегда используй напр. borg@remote_host. Вы можете использовать это и от разных локальных пользователей, удаленный пользователь запускающий Borg и работающий с репозиторием, всегда будет borg

Если нужно получить доступ к локальному репозиторию от другого пользователя, можно использовать этот же метод через ссш до borg@localhost

Important note about files changing during the backup process

Borg ничего не делает с консистентностью данных которые он бэкапит. Он просто читается и бэкапит каждый файл независимо от того в каком состоянии этот файл пребывает во время бэкапирования. На активных системах это может привести в двум видам неконсистентности:

  • Файл может измениться во время процесса бэкапа, что может привести к несогласованности архива
  • Файл может измениться во время копирования файла, что может привести к несогласованности файла

Если у вас есть набор файлов и нужно быть уверенным что они забэкапятся в конкретном или консистентном состоянии, нужно предпринять шаги для предотвращения изменения этих файлов во время бэкапа. Есть несколько общих техник для достижения этой цели

  • Убедись что не запущены программы которые могут работать с этими файлами
  • Снапшоты файлов, файловых систем, разделов контейнеров или логических разделов (LVM или ZFS могут быть полезными)
  • Сделай дамп базы данных или останови ее
  • Выключи ВМ перед тем как бэкапить ее диск
  • Выключи контейнер перед тем как бэкапить его вольюм

Для некоторых систем Borg может работать хорошо и без этих предосторожностей. Если ты просто бэкапишь файлы не не очень активной системе, то Borg отработает хорошо без дополнительной заботы о консистентности. Лог файлы и кэши могут быть в не идеальном состоянии, но это и не проблема

Для баз данных, виртуальных машин и контейнеров есть специальные техники бэкапинга, которые не просто бэкапят нижележащую ФС. Для баз данных ищи в документации техники бэкапирования которые позволят сохранять состояние данных между транзакциями. Для виртуальных машин рассмотри бэкапинг машины с нее же самой или монтаж диска выключенной ВМ. Для контейнеров поможет команда docker save

Automating backups

Ниже простой скрипт который подразумевается что будет запускаться ежедневно от рута на разных локальных машинах. Он бэкапит важные файлы машины в репозиторий ~/backup/main на удаленном сервере. Некоторые файлы исключаются из бэкапа
После бэкапирования этот скрипт также запускает borg prune для сохранения только некоторого количества последних архивов и удаления остальных
В конце он запускает borg compact для удаления уже удаленных объектов из сегментов файлов в репозитории для сохранения диска

Перед запуском убедись что репозиторий инициализирован и что скрипт имеет правильные права и может быть запущен рутом но не может быть запущен или прочитан кем либо еще (root:root 0700)

Можно использовать этот скрипт как стартовую точку и модифицировать его под себя
Не забудь протестировать свои бэкапы, убедись что prune удаляет то что нужно и что в архивах забэкаплено то что нужно

#!/bin/sh

# Setting this, so the repo does not need to be given on the commandline:
export BORG_REPO=ssh://username@example.com:2022/~/backup/main

# See the section "Passphrase notes" for more infos.
export BORG_PASSPHRASE='XYZl0ngandsecurepa_55_phrasea&&123'

# some helpers and error handling:
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM

info "Starting backup"

# Backup the most important directories into an archive named after
# the machine this script is currently running on:

borg create                         \
    --verbose                       \
    --filter AME                    \
    --list                          \
    --stats                         \
    --show-rc                       \
    --compression lz4               \
    --exclude-caches                \
    --exclude 'home/*/.cache/*'     \
    --exclude 'var/tmp/*'           \
                                    \
    ::'{hostname}-{now}'            \
    /etc                            \
    /home                           \
    /root                           \
    /var

backup_exit=$?

info "Pruning repository"

# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS machine. The '{hostname}-*' matching is very important to
# limit prune's operation to this machine's archives and not apply to
# other machines' archives also:

borg prune                          \
    --list                          \
    --glob-archives '{hostname}-*'  \
    --show-rc                       \
    --keep-daily    7               \
    --keep-weekly   4               \
    --keep-monthly  6

prune_exit=$?

# actually free repo disk space by compacting segments

info "Compacting repository"

borg compact

compact_exit=$?

# use highest exit code as global exit code
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit ))

if [ ${global_exit} -eq 0 ]; then
    info "Backup, Prune, and Compact finished successfully"
elif [ ${global_exit} -eq 1 ]; then
    info "Backup, Prune, and/or Compact finished with warnings"
else
    info "Backup, Prune, and/or Compact finished with errors"
fi

exit ${global_exit}

Pitfalls with shell variables and environment variables

Это относится ко всем переменным окружения, которые вы хотите, чтобы Borg видел, а не только к BORG_PASSPHRASE. Краткое объяснение таково: всегда экспортируйте свою переменную и используйте одинарные кавычки, если вы не уверены в деталях поведения расширения вашей оболочки. Например.:

export BORG_PASSPHRASE='complicated & long'

Это потому что экспорт дает доступ к переменным дочерним процессам одним из которых может быть Borg

Внимательнее с тем как sudo работает с экспортами
Например ты можешь удивиться что в примере ниже скрипту не будет доступна переменная и он будет запрашивать ввод пароля

export BORG_PASSPHRASE='complicated & long'
sudo ./yourborgwrapper.sh  # still prompts for password

Можно обойти это так

vandud@macbook: ~ 🚀 export MYVAR=test1
vandud@macbook: ~ 🚀 sudo -E bash -c 'echo $MYVAR'
test1
vandud@macbook: ~ 🚀 sudo bash -c 'echo $MYVAR'

Passphrase notes

Если ты используешь шифрование (или аутентификацию), Borg интерактивно спросит у тебя пароль

Подробнее тут https://borgbackup.readthedocs.io/en/stable/quickstart.html#passphrase-notes

Backup compression

По умолчанию для сжатия используется lz4 (очень быстро, но слабое сжатие), но так же доступны и другие методы сжатия
Можно использовать zstd с большим диапазоном от высокой скорости (N=1) до высокой компрессии (N=22)

zstd это современный алгоритм сжатия, который предпочтительнее zlib и lzma (исключая случаи когда нужна обратная совместимость со старыми версиями Borg)

$ borg create --compression zstd,N /path/to/repo::arch ~

Можно не использовать сжатие, например когда есть быстрый сторадж и не хочется расходовать cpu

$ borg create --compression none /path/to/repo::arch ~

Если у тебя менее быстрый сторадж под репозиторием и ты хочешь чуть большую компрессию (степень компрессии можно регулировать, у zlib это диапазон от 0 до 9)

root@borg-server:~# borg create --compression zlib,9 /var/lib/borg/my-test-backup-repo/::my-test-super-backup /var/log/

Если у тебя сильно медленный сторадж и ты хочешь сильную компрессию то можно использовать lzma
Для каждого конкретного кейса нужно искать параметры опытным путем (во время опытов держи один глаз на нагрузке на ЦПУ а второй на нагрузке на сеть)

Repository encryption

Во время создания репозитория можно сделать его шифрованным
Подробности тут https://borgbackup.readthedocs.io/en/stable/quickstart.html#repository-encryption

Remote repositories

Borg может инициализировать и работать с репозиториями на удаленных хостах если хост доступен по ssh. Быстрее и проще когда Borg установлен на удаленном хосте. В таком случае используется следующий синтаксис:

root@borg-client:~# borg init -e none root@borg-server:/var/lib/borg/remotely-initialized-repository
...
root@borg-server:/var/lib/borg# ls
my-test-backup-repo  remotely-initialized-repository

Удаленные операции через SSH могут быть автоматизированы с помощью ключей. Ты можешь ограничить использование пары ключей предварив описание публичного ключа командой (на удаленном сервере). Пример нижу запустит Borg в режиме сервера и ограничит его работу конкретным путем:

root@borg-server:~# cat .ssh/authorized_keys
command="borg serve --restrict-to-path /var/lib/borg/",restrict ssh-rsa AAAAB3N...yxHgs= root@borg-client
root@borg-client:~# borg init -e none root@borg-server:/var/tmp/remotely-initialized-repository
Repository path not allowed: /var/tmp/remotely-initialized-repository
root@borg-client:~# borg init -e none root@borg-server:/var/lib/borg/remotely-initialized-repository
root@borg-client:~#

Если нет возможности установить Borg на удаленный хост то можно использовать sshfs:

$ sshfs user@hostname:/path/to /path/to
$ borg init /path/to/repo
$ fusermount -u /path/to

Restoring a backup

Для восстановления обычно используется тот же самый хост и пользователь как когда бэкап был сделан. Такой расклад позволит избежать некоторых проблем:

  • нет проблем с путями
  • тот же маппинг user/group на userid/groupid
  • нет проблем с правами
  • у тебя уже есть рабочий и настроенный Borg на этом хосте (раз уж успешно был сделан бэкап)
    • переменные окружения с паролями от шифрованных репозиториев
    • ключи от репозиториев
    • ssh ключи уже настроены
    • уже прогретый кэш

Пользователь может быть:

  • root - если делался полный бэкап, бэкап системных штук или бэкап файлов множества пользователей
  • конкретным пользователем с правом sudo на запуск borg
  • конкретным пользователем - если делался бэкап файлов этого пользователя

Borg репозиторий может быть:

  • или локальной директорией (например локально примонтированный usb диск)
  • или удаленным сервером бэкапов доступным по ssh

Если репозиторий шифруется тебе так же потребуется ключ и контрольная фраза (которая защищает ключ)
Ключ может быть расположен:

  • в репозитории (repokey mode) - самый простой вариант
  • в хомяке пользователя который делает бэкап (keyfile mode) - сложнее:
    • если потеряешь хомяк то сперва надо восстановить ключ
    • сперва надо найти верный хост, юзер, хомяк откуда был запущен Borg при создании бэкапа

Контрольная фраза для ключа может быть:

  • введена интерактивно во время бэкапа (не удобно если бэкап автоматический)
  • предоставлена через переменную окружения в бэкапирующем скрипте

Есть два путя при восстановлении файлов из бэкапа:

  • borg mount - используй это если:
    • ты точно не знаешь какие файлы надо восстановить
    • ты не знаешь какой архив содержит нужные файлы
    • тебе нужно сперва взглянуть в файлы / директории для определения что нужно восстанавливать
    • требуется восстановить небольшой объем данных
    • тебя не беспокоит сохранность вещей которые не поддерживает FUSE (особые флаги ФС или ACL)
    • клиент имеет хорошие ресурсы (ram, cpu, disk)
    • предпочтительнее использовать какой-то файловый менеджер чем команды оболочки borg extract
  • borg extract - используй это если:
    • ты точно знаешь что тебе нужно (repo, archive, path)
    • тебе нужно восстановить большой объем данных
    • тебе нужно максимально точное воспроизведение метаданных файла (флаги ФС, ACL)
    • на клиенте мало ресурсов

Пример borg mount:

root@borg-client:~# mkdir /mnt/vandud-test-backup-dirs
root@borg-client:~# borg mount root@borg-server:/var/lib/borg/my-test-backup-repo::vandud-test-backup-dirs /mnt/vandud-test-backup-dirs
root@borg-client:~# ls /mnt/vandud-test-backup-dirs
bin  etc  sbin

root@borg-client:~# borg umount /mnt/vandud-test-backup-dirs

root@borg-client:~# borg mount root@borg-server:/var/lib/borg/my-test-backup-repo /mnt/vandud-test-backup-dirs
root@borg-client:~# ls /mnt/vandud-test-backup-dirs/
localhost-2023-12-13-16:50:28  localhost-2023-12-13-16:51:29  my-test-super-backup  vandud-test-backup-2  vandud-test-backup-dirs

Пример borg extract:

# borg extract always extracts into current directory and that directory
# should be empty (borg does not support transforming a non-empty dir to
# the state as present in your backup archive).
mkdir borg_restore
cd borg_restore

# now we find out the archive names we have in the repo:
borg list /mnt/backup/borg_repo

# we could find out the archive contents, esp. the path layout:
borg list /mnt/backup/borg_repo::myserver-system-2019-08-11

# we extract only some specific path (note: no leading / !):
borg extract /mnt/backup/borg_repo::myserver-system-2019-08-11 path/to/extract

# alternatively, we could fully extract the archive:
borg extract /mnt/backup/borg_repo::myserver-system-2019-08-11

# now move the files to the correct place...

Отличия использования удаленного сервера:
Базово все то же самое как если бы использовался локальный репозиторий, только нужно ссылаться на удаленный репозиторий по ссылке вида ssh://...


Остальные подробности начиная отсюда https://borgbackup.readthedocs.io/en/stable/usage/general.html

No Comments
Back to top