[2024 WIP] Project BAKAp: Резервное копирование

Дано:

несколько серверов и ПК без бэкапов.

Проблема:

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

Решение:

Для единой системы хранения и создания бэкапов будем использовать всего лишь две программы: Syncthing и Duplicacy. Они кроссплатформенные и поддерживают шифрование, что как раз подходит для наших целей.

Шаг 0. Введение.

Для начала определим список всех устройств, на которых будет развёртываться данная система, а также что и в каком объёме на них содержится.

  • Серверы (Debian)
    • [€3.2] Основной сервер baka.solutions (сайт, блог, почта, фонотека Тумбач;Радио) (19 из 23 Гб занято)
    • [€0.7] Прокси-сервер, оставшийся от Тумбача (заглушки, демо-версии Foxtan) (5 из 9.1 Гб занято)
    • [₽103] Сервер инфраструктуры и мелких сервисов (личный VPN и прокси) (4.5 из 5.9 Гб занято)
    • [free] Сервер от Oracle VM.Standard.E2.1.Micro (пустой) (3.9 из 45 Гб занято)
    • [free] Сервер от Oracle VM.Standard.E2.1.Micro (пустой) (2.4 из 45 Гб занято)
    • [free] Сервер от Oracle на ARM (пустой) (3.3 из 45 Гб занято)
  • ПК (Alpine/Debian/FreeBSD/Windows)
    • BS478 (~10 из 447 Гб занято)
    • BS1151 (~100 из 447 Гб занято)
    • BS1155 (~200 из 930 Гб занято)
    • BS1168 (~600 из 930 Гб занято)
  • Телефоны (Android)
    • Личный телефон (100+30 Гб)
  • Холодные хранилища
    • Внешний жёсткий диск на 1 Тб (копии Тумбача, фото, файлы)
  • Облачные хранилища
    • MEGA (20 Гб)
    • Dropbox (2.3 Гб)

Вполне очевидно, что больше всего свободного места находится на ПК. Но все они не находятся в сети круглосуточно, что несколько затрудняет автоматизацию в целом. ПК тяжело рассматривать в качестве постоянного и надёжного хранилища данных, поэтому будем отталкиваться от того, что место на ПК — промежуточный пункт между данными и бэкапом.

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

  • Публичное
    • фонотека радио — 13 Гб
    • картинки и аудио — 1.7 Гб
  • Защищённое
    • почта — 1 Гб
    • сайт baka.solutions с подсайтами — 150 Мб
    • сайт tumba.ch с подсайтами — 150 Мб
    • бэкап сервера baka.solutions — 6 Гб + дельта
    • бэкап сервера tumba.ch — 5 Гб + дельта
    • бэкап сервера сервисов — 4 Гб + дельта
  • Личное
    • фотографии — 32 Гб
    • файлы — ~10 Гб

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

Проблему отсутствия избыточности данных решаем с помощью Syncthing. На серверах с бэкапами устанавливаем нулевое доверие, чтобы файлы оставались зашифрованными. Храним данные как минимум в двух местах, распределённых географически и физически, без учёта оригинала. Для основного хранения можем принести в жертву один из бесплатных серверов, предварительно расширив ему дисковое пространство до лимита (Oracle устанавливает единый лимит в 200 Гб, которые делятся на все серверы; в сумме 150 уже истрачено, например, для какого-то одного сервера увеличить можно до ~100 Гб). А если с сервером что-либо случится, то останется копия в облаке или на внешнем носителе.

Для постоянно подключенных серверов устанавливаем бэкапы по расписанию.
Для ПК и телефонов есть два варианта:

  • синхронизация с одним из серверов (но данные на сервере не будут зашифрованы)
  • синхронизация с облачным хранилищем, откуда сервер будет бэкапить данные (но данные в облаке не будут зашифрованы)

Выводы: один сервер выделим под хранение личных файлов (фото, профили, файлы), другой — под файлы проектов. Так «боевые» серверы ничего не будут знать о «личных», и наоборот. Дополнительно обеспечим избыточность через синхронизацию с холодными хранилищами, но уже вручную.

Шаг 1. Настройка серверов.

Syncthing

Debian/Ubuntu: ставим Syncthing через apt по инструкции с сайта.

Создаём отдельного пользователя, у которого будет доступ к папкам для бэкапов. Например, бэкапы будут храниться в папке /home/rngnrs/BAKAps. Структура папок будет совпадать с распределением файлов выше: на одном сервере храним public и protected, на другом — private.

$ sudo adduser rngnrs
$ sudo mkdir /home/rngnrs/.ssh
$ sudo cp /home/ubuntu/.ssh/authorized_keys /home/rngnrs/.ssh/authorized_keys
$ sudo chown rngnrs:rngnrs -R /home/rngnrs/.ssh/

Теперь нужно запустить Syncthing от нашего юзера. Для этого будем использовать systemd.

$ sudo systemctl enable [email protected]
$ sudo systemctl start [email protected]

Подсказка: для следующего блока можно использовать nginx!

Из-под юзера правим конфиг, расположенный в ~/.config/syncthing/config.xml. Меняем gui.address с 127.0.0.1:8384 на [::]:8384 или внутренний IP Вашей подсети. В моём случае, веб-морда будет доступна через VPN. Сохраняем конфиг, перезапускаем сервис.

$ sudo service syncthing@rngnrs restart

Сразу же зададим пароль для подключения к панели управления (/#settings-gui). Приступим к настройке.

/#settings-connections: уберём галочку локального обнаружения, если наши серверы не в одной подсети. Если не хотим светить нашу связку Device ID — IP, то уберём глобальное обнаружение, но для этого придётся или прописывать адреса напрямую, или поднимать свой discovery-сервер, что не является целью данной заметки.

На принимающем сервере настроим устройства. Подключим их через web-интерфейс.

Вкладка добавления устройства. Просто указываем имя сервера и ID, его можно получить через конфиг или меню «Действия».
Ставим галочку на пункте «Автопринятие». Так все папки, отправленные серверами, будут сохраняться сами, без участия человека.
Зайдём в меню настроек и изменим папку для сохранения по умолчанию. Её будет использовать функция автопринятия.

Настало время расшарить папку. Для этого добавляем её сначала на отдающем сервере, после чего делимся ей с сервером бэкапа, но уделяем особое внимание настройкам.

ID папки можно присвоить самим, ровно как и путь.

Будьте аккуратны при указании ярлыка папки: он не должен пересекаться с другими именами на сервере бэкапа, так как при автопринятии используется стандартный путь (который мы настроили выше) и название папки. Я выбрал Music, потому что в моём случае другой папки с тем же именем не будет.

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

Почему здесь так много устройств? Я добавлял их ранее для теста. В дальнейшем я перенесу связи других устройств на бэкап-сервер, и каждое устройство будет подключено только к бэкап-серверу, а не друг к другу, как это сделано сейчас.

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

Вопрос: Почему не остановиться на этом? У Syncthing есть же система версионирования, которая может предотвратить потерю данных.
Ответ: Сами разработчики не рассматривают данную программу как инструмент для бэкапа. К тому же, их система не имеет функций отката/восстановления к предыдущему состоянию. Помимо этого, мы можем случайно повредить файлы, и тогда изменения улетят в наш «бэкап», после чего они будут необратимы.

Duplicacy

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

Из минусов следующей реализации:

  • использование отличного от стандартного идентификатора (bs1168 или baka-solutions вместо default)
  • единое место хранения всех бэкапов (одна папка вместо отдельных). Удивительно, но это ещё и плюс: дедупликация повторяющихся файлов между устройствами, например, файлы операционных систем, если это полные бэкапы.

Скачиваем бинарник на серверы, которые мы хотим бэкапить. Из-за того, что разраб — жадный азиат, его поделие распространяется бесплатно только через Github в виде CLI-приложения.

$ sudo wget -O /usr/local/bin/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.1.0/duplicacy_linux_x64_3.1.0
$ sudo chmod +x /usr/local/bin/duplicacy

Затем нам необходимо создать репозиторий хранилища, куда мы будем складывать бэкапы. Делается это командой duplicacy init [command options] <snapshot id> <storage url>. В нашем случае, для полного бэкапа сервера baka.solutions команда имеет вид:

# cd /
# duplicacy init -e baka-solutions sftp://[email protected]/BAKAps/full/

Папка full на бэкап-сервере должна быть уже создана, команда не создаёт структуру папок.

Опция -e шифрует конфиг-файл репозитория на сервере (но не на клиенте!). Каждое подключение к данному хранилищу потребует указание этой опции и ввода пароля. snapshot_id может состоять лишь из букв, цифр, дефиса и знака подчёркивания.
Также можно указать -storage-name, если планируем бэкапить на несколько серверов.

Также мы должны настроить доступ по ключам, чтобы не указывать пароль при каждой попытке бэкапа. Если кратко, то:

$ ssh-keygen -t rsa -b 4096 -C "[email protected]"
$ cat ~/.ssh/id_rsa.pub
$ duplicacy set -key ssh_key_file -value ~/.ssh/id_rsa
$ duplicacy set -key password -value <password>

Дальше нам потребуется указать исключения в файле /.duplicacy/filters:

-home/rngnrs/radio/music/*

# exclude system files
-swapfile
-boot/
-dev/
-proc/
-run/
-sys/

# exclude postfix
e:var/spool/postfix/.*$
# exclude sockets
e:.*\.sock$
# exclude any cache files/directories
e:.*/\.cache/.*$
e:.*/cache/.*$
# exclude npm
e:.*/\.npm/.*$
# exclude node_modules
e:.*/node_modules/.*$
# exclude opam
e:.*/\.opam/.*$

Все пути указываются без начального слэша!

Тестируем наши исключения командой:

# duplicacy -d -log backup -enum-only

Если ничего нужного не исключилось, идём дальше.

Проверим бэкап перед боевым применением. Важно, чтобы не спрашивались никакие пароли и ключи, иначе бэкап не будет работать автоматически, и весь чарующий эффект смысл пропадёт.

# duplicacy backup -dry-run -stats
...
Backup for / at revision 1 completed
Files: 63838 total, 5,432M bytes; 63838 new, 5,432M bytes
File chunks: 1974 total, 5,432M bytes; 816 new, 4,150M bytes, 2,381M bytes uploaded
Metadata chunks: 4 total, 18,043K bytes; 4 new, 18,043K bytes, 6,083K bytes uploaded
All chunks: 1978 total, 5,450M bytes; 820 new, 4,168M bytes, 2,387M bytes uploaded
Total running time: 00:04:33

Отлично, вышло всего лишь чуть больше 5 Гб, а загрузилось так вообще только 2 Гб! Это полный бэкап, дальше будет только ежедневная дельта.

Если скрипт не завершается, к примеру, выводится надпись Killed, то следует создать/увеличить swap-файл.

Добавим скрипт для очистки устаревших ревизий. Мы не будем хранить ежедневные копии вечно, только 30 дней. Возможно, перебор, но дельта будет минимальной, поэтому это допустимо.

# mkdir /.duplicacy/scripts
# nano /.duplicacy/scripts/post-backup
#!/bin/sh
# Keep no snapshots older than 365 days
# Keep 1 snapshot every 30 day(s) if older than 180 day(s)
# Keep 1 snapshot every 7 day(s) if older than 30 day(s)
# Keep 1 snapshot every 1 day(s) if older than 7 day(s)
/usr/local/bin/duplicacy prune -id baka-solutions -keep 0:365 -keep 30:180 -keep 7:30 -keep 1:7 -threads 2

# chmod +x /.duplicacy/scripts/post-backup
# crontab -e
# m h  dom mon dow   command
 24 0  *   *   *     /usr/local/bin/duplicacy backup -hash -stats -threads 2

Полный бэкап сервера настроен. Повторяем действия для остальных серверов и отдельных папок.

Шаг 2. Настройка ПК.

В данном шаге будем рассматривать ПК под управлением Windows. Для ОС на базе Linux/BSD просто выполним действия для сервера.

Перейдём на страницу скачивания Duplicacy. Скачиваем и переименовываем в duplicacy.exe, складываем в папку с бинарниками (в любую папку из значения PATH переменных среды). Если в командной строке при вводе команды duplicacy выпадает помощь по программе, то идём дальше.

> cd C:\
> duplicacy init -e bs1168 sftp://[email protected]/BAKAps/full/
Enter SSH password: ***
Enter storage password for sftp://[email protected]/BAKAps/full/: ***
The storage 'sftp://[email protected]/BAKAps/full/' has already been initialized
Compression level: 100
Average chunk size: 4194304
Maximum chunk size: 16777216
Minimum chunk size: 1048576
Chunk seed: 384901bcb3bdee59509d1643e41e08e4029f048835850390283116f0f7e35e9f
C:\ will be backed up to sftp://[email protected]/BAKAps/full/ with id bs1168
> duplicacy set -key password -value <password>
> duplicacy backup -hash -vss -dry-run -stats

-vss создаёт теневую копию, что требует права администратора.

Фильтры для бэкапа:

# exclude cache
e:.*/cache/.*$
e:.*/shader-cache/.*$

# exclude telemetry
e:.*/datareporting/.*$
e:.*/crashes/.*$
e:.*/minidumps/.*$
e:.*/gmp\-[a-z0-9]+/.*$
e:.*/.*\.lock$


# include Firefox profiles
+Users/*/AppData/Roaming/Mozilla/Firefox/Profiles/*
+Users/*/AppData/Roaming/Mozilla/Firefox/Profiles/
+Users/*/AppData/Roaming/Mozilla/Firefox/
+Users/*/AppData/Roaming/Mozilla/

# include Thunderbird profiles
+Users/*/AppData/Roaming/Thunderbird/Profiles/*
+Users/*/AppData/Roaming/Thunderbird/Profiles/
+Users/*/AppData/Roaming/Thunderbird/*.ini
-Users/*/AppData/Roaming/Thunderbird/*/
+Users/*/AppData/Roaming/Thunderbird/

+Users/*/AppData/Roaming/
+Users/*/AppData/
-Users/*/*/
+Users/*/
+Users/

# exclude others
-*

Добавим холодное хранилище (внешний жёсткий диск) в репозиторий:

> duplicacy add -repository C:\ -copy default -bit-identical -e cold bs1168 I:\BAKAps\
> duplicacy set -key password -value <password> -storage cold

Теперь можно сделать бэкап и скопировать его между хранилищами.

> duplicacy copy -id bs1168 -to cold -download-threads 8   # -from default — стандартное значение
...
Source storage set to sftp://...
Repository set to C:\
Destination storage set to I:\BAKAps\

Шаг 3. Настройка телефона.

На Android будем использовать Syncthing-Fork (оно же в F-Droid)

Преимущества форка в том, что он ест меньше энергии, чем оригинальное приложение.

В целом, выполняем все те же самые действия, что и при настройке ПК: добавляем устройства и выбираем папки для синхронизации.

// ✍️ Заметка в процессе дополнения! Оставайтесь тунцом.

Полезные ссылки: