Backup. Файловое резервное копирование бюджетного VPS

aadc68f2ab49ed8d17e3d69b049f5e5c.jpg

Предыстория. В своё время, когда мне надо было найти решение этого вопроса на Хабре, казалось, что все статьи состоят из установки и настройки Veeam Backup, Proxmox Backup и прочих коммерческих решений для блочных устройств. У меня запросы поскромнее. SLA и 3–2–1 не требуются. Достаточно восстановить работоспособность за пару часов или хотя бы пару дней. В общем, в поиске нужной статьи мне не особо повезло. Зато в комментах оказались интересные находки. Попробовав некоторые из них, в итоге остановился на описанном ниже варианте. Настроил и забыл. В качестве облачного хранилища ранее был выбран Storj. Но недавно они превратили бесплатные аккаунты в триальные. Пришлось отказаться, пересесть на Mega и освежить в памяти настройки. Заодно и выложить сюда. Надеюсь, кому-то тоже пригодятся.

TL; DR Статья состоит из настройки rsnapshot, rclone и небольшого скрипта автоматизации.

Установка

Утилита rsnapshot легко доступна из репозитория. В моём случае на Ubuntu устанавливается так:

sudo apt install rsnapshot

На других системах используются соответствующие менеджеры пакетов, как описано в https://rsnapshot.org/download.html

А вот rclone лучше установить скриптом с сайта программы.

sudo curl https://rclone.org/install.sh | sudo bash

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

Настройка rsnapshot

У меня потребности и возможности такие — 6 ежедневных, 2 недельные копии на хосте, из них 3 последних ежедневных сохраняются в облаке. Локальное хранилище организовано в /var/cache/rsnapshot, сохранять нужно только /srv и /etc. Там compose для docker, данные и разные общие настройки вроде fail2ban, iptables и прочего. Остальное неважно. В случае каких-то больших изменений можно поднять новый VPS на другом тарифе или вообще у другого хостера. В общем, пожелания в файле /etc/rsnapshot.conf выглядят так:

snapshot_root	/var/cache/rsnapshot/
retain	daily	6
retain	weekly	2
backup	/etc/		localhost/
backup	/srv/		localhost/

Мне не нравятся все эти альфа-бета-гаммы, которые там были по умолчанию. Потому закомментировал их и добавил daily и weekly взамен. Но это просто слова. Главное — очерёдность расположения в файле. Сначала 6 снимков группы daily, затем 2 снимка группы weekly. Соответственно пришлось изменить и файл /etc/cron.d/rnapshot

30 1    * * *           root    /usr/bin/rsnapshot daily
0 1     * * 1           root    /usr/bin/rsnapshot weekly

Напомню формат времени в файле cron.


# ┌───────────── minute (0–59)
# │ ┌───────────── hour (0–23)
# │ │ ┌───────────── day of the month (1–31)
# │ │ │ ┌───────────── month (1–12)
# │ │ │ │ ┌───────────── day of the week (0–6) (Sunday to Saturday;
# │ │ │ │ │                                   7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * 

Хозяйке на заметку. Как rsnapshot ротирует снимки. Самый старый в младшей группе (daily) удаляется. Промежуточные переименовываются в x+1. Создаётся новый daily.0 и в него прописываются жёсткие ссылки из daily.1, затем поверх инкрементно накатываются копии из сохраняемых директорий. В старшей группе weekly.0 получается из последнего daily. Если сначала выполнять ротацию младшей группы, то пришлось бы хранить все 7 снимков, причём daily.6 и weekly.0 были бы близнецами. Но если первым выполнить задание старшей группы, то память о daily.5 останется в сердце weekly.0 перед тем как навсегда исчезнуть.

Настройка rclone

У меня tar архивы получаются по полгигабайта. Некоторое время назад были по 1.5 Гб. Поэтому желание пользоваться самым большим облачным хранилищем выглядит уместно. Бесплатные 20 Гб от Mega вполне устраивают. На всякий случай настроил также Google Drive (15 Гб). И немного поигрался с pCloud (9 Гб). Не смог пройти квест с мобильным приложением, http error 500 вместо логина. Так что минус 1 Гб из 10, доступных на pCloud.
Собственно настройка. В случае Mega достаточно логина и пароля, с которыми авторизуешься на сайте.

rclone config

Открывается пошаговый мастер настройки. Начать нужно с (N) для нового соединения, далее назвать соединение (например, mega), на шаге хранилищ ввести 30, чтобы выбрать именно Mega, указать емейл, затем сообщить, что пароль имеется (y) и следом ввести его. Возможно, когда статья устареет, Mega будет уже под другим номером, проверяйте самостоятельно.

  • При создании соединения с Google Drive (17) важно сделать свой собственный client ID в Google API. Иначе придётся пользоваться общим от авторов rclone, а его лимиты давно исчерпаны. Инструкция доступна на сайте rclone;

  • OAuth Client Secret находится там же в Credential;

  • Область, доступная для подключения (scope). Только файлы, созданные rclone выглядит разумно (3) ;

  • Service Account пустой;

  • Advanced настраивать не надо (там бездна);

  • А далее финт ушами. Программе требуется токен, получить его можно только браузером. Браузера в обычном смысле (не lynx) на VPS нет. Тупик? Нет! Нужно всего лишь скачать rclone на свой компьютер, повторить мастер настройки до этого шага и выбрать (Y), то есть браузер в системе имеется. Откроется браузер, где нужно нажать правильную кнопку. В консоли уже написано «Got code», его будет видно позже.

  • Shared Drive пустой;

  • Завершить мастер коротким однократным нажатием на клавишу Enter.

  • Получившийся токен вместе с фигурными скобками скопировать в окно VPS, где был выбран ответ (N) на этапе наличия браузера. Конфиг сохранён, выход через (Q). Хранятся настройки в ~/.config/rclone. Хорошо, соединение настроено. А есть ли жизнь на Марсе?

rclone mkdir mega:/test
rclone lsd mega:
rclone about mega:
rclone --help

Ошибок нет, можно продолжать.

Отправка в облако

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

sudo pwgen -cnys 32 1 >/root/.config/rclone/pwe

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

sudo mkdir /srv/scripts
sudo touch /srv/scripts/mega.sh
sudo chmod +x /srv/scripts/mega.sh
sudo nano /srv/scripts/mega.sh

Содержимое файла

#!/bin/bash

TIME_VAR=$(TIMEFORMAT="%lR"
time (
    # Stop some services
	# ...
    mkdir /tmp/backup

    tar -I 'xz -9' --warning=no-file-ignored -cvpf /tmp/backup/daily.0.tar.xz -C /var/cache/rsnapshot/ daily.0
    openssl aes-256-cbc -e -salt -pbkdf2 -in /tmp/backup/daily.0.tar.xz -out /tmp/backup/daily.0.tar.xz.aes256cbc -kfile /root/.config/rclone/pwe
    rclone delete mega:backup/daily.0.tar.xz.aes256cbc --mega-hard-delete
    rclone copyto /tmp/backup/daily.0.tar.xz.aes256cbc mega:backup/daily.0.tar.xz.aes256cbc
    rm -f /tmp/backup/daily.*

    tar -I 'xz -9' --warning=no-file-ignored -cvpf /tmp/backup/daily.1.tar.xz -C /var/cache/rsnapshot/ daily.1
    openssl aes-256-cbc -e -salt -pbkdf2 -in /tmp/backup/daily.1.tar.xz -out /tmp/backup/daily.1.tar.xz.aes256cbc -kfile /root/.config/rclone/pwe
    rclone delete mega:backup//daily.1.tar.xz.aes256cbc --mega-hard-delete
    rclone copyto /tmp/backup/daily.1.tar.xz.aes256cbc mega:backup/daily.1.tar.xz.aes256cbc
    rm -f /tmp/backup/daily.*

    tar -I 'xz -9' --warning=no-file-ignored -cvpf /tmp/backup/daily.2.tar.xz -C /var/cache/rsnapshot/ daily.2
    openssl aes-256-cbc -e -salt -pbkdf2 -in /tmp/backup/daily.2.tar.xz -out /tmp/backup/daily.2.tar.xz.aes256cbc -kfile /root/.config/rclone/pwe
    rclone delete mega:backup/daily.2.tar.xz.aes256cbc --mega-hard-delete
    rclone copyto /tmp/backup/daily.2.tar.xz.aes256cbc mega:backup/daily.2.tar.xz.aes256cbc
    rm -rf /tmp/backup
    
	# Start some services
	# ...
    ) 2>&1 1>/dev/null)

logger -t backup "backup completed in ${TIME_VAR}"
# decrypt
#openssl aes-256-cbc -d -pbkdf2 -in /tmp/backup/daily.0.tar.xz.aes256cbc -out /tmp/backup/xdaily.0.tar.xz.7z -kfile /root/.config/rclone/pwe

Как указано в заголовке статьи, сервер довольно бюджетный. Памяти в нём маловато, поэтому приходится останавливать некоторые прожорливые сервисы ради очень прожорливой программы сжатия xz. Кстати, я протестировал все эти bzip2, gzip, Izma и остановился на xz для себя. Устроило соотношение времени и размера сжатия. Так же сжатие -9 показалось более предпочтительным, чем -9e по тем же соображениям.

Опцию --warning=no-file-ignored пришлось указать потому что tar комментировал найденные сокеты.

Шифрование openssl проходит довольно быстро с использованием того самого файла /root/.config/rclone/pwe.

Удалять файл перед копированием был вынужден из-за особенности Mega. Когда копируется файл с одинаковым именем, но отличающимся содержимым, Mega перемещает предыдущий в корзину, разделяющую общую квоту 20 Гб. А доступа к корзине у rclone нет. Если не обращать внимание, лимит хранилища вскоре закончится. Возможно, позже доступ появится. Ведь пишут же, что в MEGAcmd можно обратиться к //bin. Но на данный момент приходится удалять в обход корзины. За это отвечает ключ --mega-hard-delete.

На VPS не только память ограничена, но и дисковое пространство. Сейчас бэкап перестал угрожать забить остаток свободного места, но очистка временной директории перед новой запаковкой осталась. Пусть будет.

В конце сервисы снова запускаются.

По завершении в журнале остаётся запись с тегом backup. Просмотреть можно командой:

sudo journalctl -t backup

Осталось назначить выполнение в cron.

sudo nano /etc/cron.d/sendbackup

Содержимое sendbackup

0 2 * * * root /srv/scripts/mega.sh # rclone to mega.nz

Спасибо за ваше внимание. Надеюсь увидеть в комментах какие-то другие решения, простые и сложные.

© Habrahabr.ru