Встановлення та налаштування BorgBackup

Цей гайд описує повний цикл роботи з BorgBackup: встановлення, підготовку SSH-доступу, ініціалізацію репозиторію, створення бекапів, налаштування розкладу через bash-скрипт і cron та відновлення даних. Основний сценарій — без шифрування. Монтування архівів і робота з шифруванням винесені в кінець як додаткові розділи.

1. Встановлення borg

Debian / Ubuntu та похідні:

sudo apt update
sudo apt install -y borgbackup

Fedora / RHEL / CentOS / AlmaLinux / Rocky Linux:

sudo dnf install -y borgbackup

openSUSE:

sudo zypper install -y borgbackup

Arch Linux:

sudo pacman -S borgbackup

Перевірте встановлення:

borg --version

2. Підготовка SSH-доступу

Створіть SSH-ключ:

ssh-keygen

Скопіюйте ключ на сервер бекапу:

ssh-copy-id backup-test-s3@backup-test-s3.backup.colocall.com

Перевірте, чи працює підключення за ключем:

ssh 'backup-test-s3@backup-test-s3.backup.colocall.com' 'echo "ok"'

Якщо команда повернула ok — з'єднання працює.

3. Ініціалізація borg-репозиторію (без шифрування)

borg init --encryption=none backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1

У режимі none дані не шифруються й парольна фраза не використовується — жодна borg-команда не питатиме пароль. Це найпростіший варіант для довіреного середовища.

Якщо потрібні шифрування та цілісність даних — див. Додаток B. Шифрування та парольна фраза в кінці документа.

4. Створення бекапу

Створіть перший архів (назвемо його Monday) із каталогів ~/src і ~/Documents:

borg create --compression zstd \
  backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1::Monday \
  ~/src ~/Documents

Наступного дня створіть новий архів Tuesday:

borg create --stats --compression zstd \
  backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1::Tuesday \
  ~/src ~/Documents

Цей бекап буде значно швидшим і меншим, бо зберігаються лише нові, раніше не бачені дані (дедуплікація). Параметр –stats виводить статистику новоствореного архіву, зокрема обсяг унікальних даних (не спільних з іншими архівами):

------------------------------------------------------------------------------
Archive name: Tuesday
Archive fingerprint: bd31004d58f51ea06ff735d2e5ac49376901b21d58035f8fb05dbf866566e3c2
Time (start): Tue, 2016-02-16 18:15:11
Time (end):   Tue, 2016-02-16 18:15:11

Duration: 0.19 seconds
Number of files: 127
------------------------------------------------------------------------------
                      Original size      Compressed size    Deduplicated size
This archive:                4.16 MB              4.17 MB             26.78 kB
All archives:                8.33 MB              8.34 MB              4.19 MB

                      Unique chunks         Total chunks
Chunk index:                     132                  261
------------------------------------------------------------------------------

Переглянути всі архіви в репозиторії:

borg list backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1
Monday                               Mon, 2016-02-15 19:14:44
Tuesday                              Tue, 2016-02-16 19:15:11

У не тестовому використанні замість ~/src ~/Documents вкажіть реальні дані, напр. /etc/httpd /var/data /home/user1 /home/user2.

5. Налаштування розкладу бекапів через bash-скрипт і cron

Регулярне резервне копіювання реалізуємо bash-скриптом, який запускає cron. Скрипт виконує borg create, потім borg prune (чистить старі архіви за політикою) і borg compact (звільняє місце). Оскільки репозиторій без шифрування, парольна фраза не потрібна.

Передумови

  • Встановлений borg (перевірте шлях командою which borg).
  • Ініціалізований віддалений репозиторій (borg init –encryption=none).
  • SSH-ключ для безпарольного доступу, розміщений у /root/.ssh/id_rsa.

Крок 1. Скрипт бекапу

Створіть файл /usr/local/bin/borg-backup.sh:

#!/bin/sh
 
# cron має урізаний PATH — задаємо явно, щоб знаходився borg:
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 
# Щоб не вказувати репозиторій у кожній команді:
export BORG_REPO=ssh://backup-test-s3@backup-test-s3.backup.colocall.com/backup/borg-repo-1
 
# SSH-ключ і перевірка host key (скрипт запускається від root через cron):
export BORG_RSH="ssh -i /root/.ssh/id_rsa -o StrictHostKeyChecking=accept-new"
 
# Репозиторій без шифрування — парольна фраза не потрібна.
# Для зашифрованого репозиторію див. Додаток B.
 
# хелпери та обробка помилок:
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
 
info "Starting backup"
 
# Бекап найважливіших директорій в архів, названий за іменем хоста:
borg create                         \
    --verbose                       \
    --filter AME                    \
    --list                          \
    --stats                         \
    --show-rc                       \
    --compression zstd              \
    --exclude-caches                \
    --exclude 'home/*/.cache/*'     \
    --exclude 'var/tmp/*'           \
                                    \
    ::'{hostname}-{now}'            \
    /etc                            \
    /home                           \
    /root                           \
    /var
 
backup_exit=$?
 
info "Pruning repository"
 
# Зберігати 7 денних, 4 тижневі та 6 місячних архівів САМЕ цієї машини.
# Збіг за '{hostname}-*' критичний: prune не зачепить архіви інших машин.
borg prune                          \
    --list                          \
    --glob-archives '{hostname}-*'  \
    --show-rc                       \
    --keep-daily    7               \
    --keep-weekly   4               \
    --keep-monthly  6
 
prune_exit=$?
 
# Фактично звільнити місце ущільненням сегментів:
info "Compacting repository"
 
borg compact
 
compact_exit=$?
 
# глобальний код виходу — найбільший із трьох:
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}

Зробіть скрипт виконуваним і доступним лише для root:

sudo chown root:root /usr/local/bin/borg-backup.sh
sudo chmod 700 /usr/local/bin/borg-backup.sh

Пояснення ключових моментів

  • {hostname}-{now} — borg сам підставляє ім'я хоста й поточний час у назву архіву (на відміну від systemd, екранувати % тут не потрібно).
  • –filter AME разом із –list виводить у журнал лише додані (A), змінені (M) та проблемні (E) файли; без –list фільтр нічого не показує.
  • –exclude-caches пропускає теки, позначені файлом CACHEDIR.TAG.
  • borg prune з –glob-archives '{hostname}-*' чистить старі архіви лише цієї машини за політикою 7 днів / 4 тижні / 6 місяців.
  • borg compact фактично звільняє місце: у Borg 1.2+ prune лише позначає архіви на видалення.

Крок 2. Розклад через cron

Створіть файл /etc/cron.d/borg-backup (запуск щодня о 02:00 від root, з логуванням):

# хв год день міс д.тижня користувач команда
0 2 * * * root /usr/local/bin/borg-backup.sh >> /var/log/borg-backup.log 2>&1

Інші варіанти розкладу

0 2 * * *        # щодня о 02:00
30 23 * * 1-5    # по буднях о 23:30
0 6,18 * * *     # двічі на день: 06:00 та 18:00
0 3 * * 1        # щопонеділка о 03:00
0 4 1 * *        # першого числа місяця о 04:00

Крок 3. Перевірка

# Запустити бекап вручну, не чекаючи розкладу (для перевірки)
sudo /usr/local/bin/borg-backup.sh
 
# Переконатися, що cron-завдання на місці
cat /etc/cron.d/borg-backup
 
# Переглянути лог останнього запуску
tail -n 50 /var/log/borg-backup.log

Безпека (SSH)

StrictHostKeyChecking=accept-new довіряє лише новому ключу при першому підключенні. Значення no вимикає перевірку повністю й відкриває ризик MITM-атаки, тож його краще уникати; за можливості наперед заповніть ~/.ssh/known_hosts.

6. Відновлення з бекапу

Спершу перегляньте список архівів і оберіть потрібний:

borg list backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1
Monday                               Mon, 2016-02-15 19:14:44
Tuesday                              Tue, 2016-02-16 19:15:11

Перегляньте вміст конкретного архіву:

borg list backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1::Monday
drwxr-xr-x user   group          0 Mon, 2016-02-15 18:22:30 home/user/Documents
-rw-r--r-- user   group       7961 Mon, 2016-02-15 18:22:30 home/user/Documents/Important.doc
...

Borg відновлює файли відносно поточної директорії, тож перейдіть у безпечне місце, щоб не перезаписати наявні дані:

mkdir /tmp/borg-restore
cd /tmp/borg-restore

Відновіть увесь архів Monday:

borg extract backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1::Monday

Щоб відновити лише окремий файл чи теку, додайте шлях усередині архіву:

borg extract backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1::Monday \
  home/user/Documents/Important.doc

Додаток A. Монтування бекапів (додатковий спосіб)

Замість borg extract архіви можна примонтувати через FUSE й працювати з ними як зі звичайними директоріями. Це зручно для перегляду й вибіркового копіювання окремих файлів.

Встановлення FUSE

Для систем на базі .deb:

sudo apt-get install -y -q fuse libfuse2

Для систем на базі .rpm:

sudo dnf install -y fuse fuse-libs

Змонтувати весь репозиторій (усі архіви як директорії)

mkdir -p /mnt/borg-repo
borg mount backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1 /mnt/borg-repo
ls -la /mnt/borg-repo/
total 4
drwxr-xr-x 1 root root    0 чер  1 15:40 .
drwxr-xr-x 5 root root 4096 чер  1 15:40 ..
drwxr-xr-x 1 root root    0 чер  1 15:21 Monday

Змонтувати конкретний архів

mkdir -p /mnt/borg-archive
 
# Переглянути список архівів
borg list backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1
 
borg mount backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo-1::Monday /mnt/borg-archive
ls -al /mnt/borg-archive

Розмонтування

Після завершення роботи примонтовані бекапи потрібно розмонтувати:

umount /mnt/borg-archive
umount /mnt/borg-repo

Додаток B. Шифрування та парольна фраза (додаткова інформація)

Якщо потрібні конфіденційність і цілісність даних, репозиторій ініціалізують у режимі з шифруванням. Це окремий, складніший сценарій порівняно з основним (none).

Ініціалізація з шифруванням

Режим repokey (ключ зберігається в репозиторії):

borg init --encryption=repokey backup-test-s3@backup-test-s3.backup.colocall.com:/backup/borg-repo

Borg запропонує ввести парольну фразу. Вводьте її безпосередньо в термінал — на екрані вона не відображається.

Важливо: для доступу до зашифрованого репозиторію потрібні і КЛЮЧ, і ПАРОЛЬНА ФРАЗА.

Місце зберігання ключа залежить від режиму:

  • repokey — ключ зберігається в каталозі репозиторію.
  • keyfile — ключ зберігається в домашньому каталозі користувача.

Резервне копіювання ключа

Обов'язково експортуйте ключ і збережіть його в безпечному місці:

borg key export           REPOSITORY encrypted-key-backup
borg key export --paper   REPOSITORY encrypted-key-backup.txt
borg key export --qr-html REPOSITORY encrypted-key-backup.html

Парольну фразу зберігайте окремо в захищеному місці (менеджер секретів, сейф тощо).

Парольна фраза у скрипті бекапу

Для зашифрованого репозиторію скрипт має передавати парольну фразу borg. Не вписуйте її прямо в скрипт — винесіть у захищений файл.

Створіть /etc/borg/borg.env:

BORG_PASSPHRASE=parol_repozytoriyu

Обмежте доступ:

sudo install -d -m 700 /etc/borg
sudo chmod 600 /etc/borg/borg.env

На початку скрипта /usr/local/bin/borg-backup.sh підвантажте цей файл (одразу після рядків export):

# підвантажити парольну фразу із захищеного файлу
. /etc/borg/borg.env
export BORG_PASSPHRASE

Решта скрипта лишається без змін.

Безпека парольної фрази

Зберігання пароля в окремому файлі (права 600) надійніше за рядок export BORG_PASSPHRASE='…' прямо в скрипті. Альтернатива — BORG_PASSCOMMAND із читанням пароля з захищеного джерела.

Узгодженість даних під час бекапу

Borg читає кожен файл у тому стані, в якому застає його, і не гарантує внутрішньої узгодженості активних даних. Файл може змінитися між початком бекапу й моментом, коли borg до нього дійде, або просто під час читання. Для довільного набору файлів, які мають потрапити в бекап у консистентному стані, вживайте заходів:

  • не запускайте програми, що змінюють ці файли під час бекапу;
  • робіть знімки (snapshot) файлів, ФС або томів — напр. через LVM чи ZFS;
  • дампте бази даних або зупиняйте СУБД;
  • вимикайте віртуальні машини перед бекапом їхніх образів;
  • зупиняйте контейнери перед бекапом їхніх томів.

Для типової домашньої теки на малоактивній системі borg зазвичай працює добре й без цих заходів. Для баз даних, ВМ і контейнерів використовуйте спеціальні методи (дамп БД між транзакціями, монтування ФС вимкненої ВМ, docker save тощо).