В условиях постоянно растущих угроз кибербезопасности, хранение резервных копий в хранилище S3 становится как никогда актуальным. Сохранение бэкапов на той же виртуальной машине небезопасно, а традиционные файловые бэкапы не обеспечивают достаточной надежности.
Restic предоставляет современные решения, включая сжатие и шифрование бэкапов, исключение ненужных данных и возможность создания версионированного репозитория. Кроме того, Restic позволяет гибко настроить таймер бэкапа и количество версий, что делает его идеальным инструментом для актуальных задач защиты данных.
Установка
Шаг 1
Bitrix VM — это CentOS 7, следовательно, для начала нужно установить Restic.
yum install yum-plugin-copr
yum copr enable copart/restic
yum install restic
Шаг 2
Создаем файл `restic_backup` в /usr/local/bin/ с содержимым:
#!/usr/bin/env bash
set -o errexit # завершать скрипт при возникновении ошибок
source /etc/restic_backup/settings.sh # импортировать настройки
# Создать временную директорию для SQL-дампов
dbs_save_dir=/tmp/databases_backup
mkdir -p "$dbs_save_dir"
# Включить подробное логирование скрипта
log_file=/var/log/restic_backup.log
echo "# --------- BACKUP STARTED AT $(date -R) --------- #" >> "$log_file"
exec >> "$log_file"
exec 2>&1
export PS4='+$0:$LINENO '
set -o xtrace
Вспомогательные функции:
# ------------------------------------------------------------------------- #
# Вспомогательные функции #
# ------------------------------------------------------------------------- #
parse_uri() {
# Парсер URI
uri="$1"
schema="$(cut -d ':' -f 1 <<<"$uri")"
user="$(grep -Po '(?<=://)(.*)(?=@)' <<<"$uri" | cut -d ':' -f 1)"
password="$(passw=$(grep -Po '(?<=://)(.*)(?=@)' <<<"$uri"); \
[[ $passw =~ .+:.+ ]] && echo ${passw##*:})" || true
host="$(grep -Po '(?<=@)(.*)' <<<"$uri" |
cut -d '/' -f 1 | cut -d ':' -f 1)"
port="$(prt=$(grep -Po '(?<=@)(.*)' <<<"$uri" |
cut -d '/' -f 1); [[ $prt =~ .+:[0-9]{1,} ]] &&
echo ${prt##*:})" || true
path="$(pth=$(grep -Po '(?<=@)(.*)' <<<"$uri"); [[ $pth =~ :~ ]] &&
cut -d ':' -f 2 <<<"$pth" ||
grep -Po '(?<=(:[~/])|/)(.*)' <<<"$pth" |
xargs -I {} echo /{} | sed 's%//%/%g')" || true
# Декодинг пароля
__urldecode() {
: "${*//+/ }"; echo -e "${_//%/\\x}";
}
password="$(__urldecode "$password")" || true
}
get_name() {
# Фунция печатает на экран имя файла с временной меткой
local name="${1##*/}"
local ext="$2"
local ff="${name_prefix}${name}_%Y%m%d-%H%M"
date +"${ff}${ext}"
}
dump_mysql() {
# Выполнить дамп базы данных
parse_uri "$1"
echo "Выполняется дамп БД '${path##*/}' от ${user}@${host} ..."
dump_name="$dbs_save_dir"/"$(get_name "$path" '.sql.gz')"
[ "$port" ] || port=3306 # Устанавливаем порт MySQL по умолчанию
nice -n 10 ionice -c2 -n 7 mysqldump \
--no-tablespaces \
--quick \
--single-transaction \
--host="$host" \
--port="$port" \
"${path##*/}" \
--user="$user" \
--password="$password" \
| gzip -9c > "$dump_name"
if [ -s "$dump_name" ]; then
echo "Дамп сохранён как: $dump_name"
else
rm "$dump_name"
echo "Что-то пошло не так. Размер дампа 0 байт. Файл $dump_name удалён" >&2
exit 1
fi
}
Запуск резервного копирования:
# ------------------------------------------------------------------------- #
# Запуск резервного копирования #
# ------------------------------------------------------------------------- #
##
# Дамп баз данных
# Запускается если массив databases непустой
if [ -n "$databases" ]; then
echo "Запуск дампа баз данных ..."
for database in "${databases[@]}"; do
dump_mysql "$database"
done
fi
##
# Если репозиторий для бэкапов не инициализирован, инициализировать
# https://restic.readthedocs.io/en/stable/075_scripting.html
echo "Проверка репозитория ..."
if ! restic snapshots; then
restic init
fi
# Удаление блокировок процессов restic
restic unlock
# Переиндексация
restic rebuild-index
# Удаление старых бэкапов
echo "Удаление старых бэкапов ..."
restic forget --keep-last "$RESTIC_KEEP" --prune
#restic prune
# Дамп баз данных
# Запускается если массив databases непустой
#if [ -n "$databases" ]; then
# echo "Запуск дампа баз данных ..."
# for database in "${databases[@]}"; do
# dump_mysql "$database"
# done
#fi
# Выполнить резервное копирование в репозиторий
echo "Резервное копирование запущено ..."
restic backup --exclude='bitrix/cache' "${files[@]}" "$dbs_save_dir"
# Осторожно удаляем временную директорию для SQL-дампов
echo "Удаление директории с временными файлами"
if [[ "$dbs_save_dir" == "/" ]]; then
echo "ПОПЫТКА УДАЛИТЬ КОРНЕВУЮ ФС!" >&2; exit 1
fi
rm -rf "${dbs_save_dir:-/nonexistent}"
echo -e "\e[32mРезервное копирование завершено\e[0m"
Шаг 3
Создаем два файла: `restic_backup.service` и `restic_backup.timer` в /etc/systemd/system/ с содержимым ниже.
`restic_backup.service` — сервис, который вызывает скрипт резервного копирования:
[Unit]
Description=Service for run restic backup
After=network.target
[Service]
ExecStart=/usr/local/bin/restic_backup
SyslogIdentifier=restic_backup
Restart=no
TimeoutStopSec=30
KillMode=process
Type=oneshot
`restic_backup.timer` — таймер, который запускает резервное копирование каждую субботу в 1:00:00:
[Unit]
Description=Dayly restic backup timer
[Timer]
Unit=restic_backup.service
OnCalendar=Sat *-*-* 1:00:00
Persistent=true
[Install]
WantedBy=timers.target
Шаг 4
Далее создаем папку `restic_backup` в /etc/ и файл `settings.sh` с нашими настройками подключения до хранилища S3. Получаем такой путь /etc/restic_backup/settings.sh. Нужно заполнить данные для подключения к хранилищу S3 и данные от БД, пароль от БД можно найти в /bitrix/.settings.php.
Пароль от БД обязательно надо перевести в percent code, можно использовать сервис dencoder.
Из файлов сохраняем конфигурацию сервера /etc/ и все данные сайтов Битрикс /home/bitrix/.
# ------------------------------------------------------------------------- #
# ВНИМАНИЕ! Этот файл должен содержать валидный код на Bash #
# ------------------------------------------------------------------------- #
# --------------------------- НАСТРОЙКИ RESTIC ---------------------------- #
# Ключ доступа к бакету S3. Совпадает с логином аккаунта
export AWS_ACCESS_KEY_ID=Здесь логин
# Секретный ключ доступа к бакету. Можно скопировать из ПУА.
export AWS_SECRET_ACCESS_KEY=Ключ доступа к бакету
# Адрес репозитория, куда будут сохраняться резервные копии
export RESTIC_REPOSITORY="s3:https://s3.timeweb.com/id/папка/"
# Пароль для доcтупа к бэкапам. Все бэкапы шифруются. В случае утраты этого
# пароля получить доступ к резрвным копиям будет невозможно!
export RESTIC_PASSWORD="Пароль"
#RESTIC_PASSWORD определяет пароль, который Restic будет использовать для #шифрования ваших резервных копий. Это шифрование происходит локально, поэтому #вы можете выполнить резервное копирование на ненадежный внешний сервер, не #беспокоясь о том, что содержимое ваших файлов может быть раскрыто
# Количество бэкпов, которые нужно хранить в репозитории
RESTIC_KEEP=5
# Указываем директорию с кешем
#export XDG_CACHE_HOME /root/.cache/
Список файлов и директорий бэкапа:
# ------------------ СПИСОК ФАЙЛОВ И ДИРЕКТОРИЙ ДЛЯ БЭКАПА ---------------- #
# Пути к файлам и директориям обязательно должны быть абсолютными.
# Абсолютный путь содержит полный путь до файла/директории начиная от
# корневого каталога системы.
#
# Переменная `files` ниже содержит перечень путей. Обратите внимание, что
# пути, которые содержат пробелы должны быть обязательно включены в кавычки.
# Пример: '/home/user/some dir'
files=(
/etc
/home/bitrix
)
Список баз данных бэкапа:
# ---------------------- СПИСОК БАЗ ДАННЫХ ДЛЯ БЭКАПА --------------------- #
# Ниже необходимо указать реквизиты подключения к базам данных в формате URI
# (DSN). Запись должна иметь следующий вид:
#
# mysql://пользователь:пароль@хост:порт/имя_базы_данных
#
# Обратите внимание на разделители между частями URI: ":", "@", "/". Порт
# можно опустить, если используется стандартный 3306.
#
# Ниже дан записи для БД bitrix_db и именем пользователя bitrix_usr и
# паролем boRpBnhGn7ue.
#
# mysql://bitrix_usr:boRpBnh242Gn7121ue@localhost/bitrix_db
#
# Если пароль пользователя базы данных содержит специальные символы, то такой
# пароль обязательно надо закодировать в percent code. Это можно сделать
# следующей командой в терминале:
#
# echo 'ваш_пароль' | perl -MURI::Escape -wlne 'print uri_escape $_'
#
# или через онлайн-сервис https://meyerweb.com/eric/tools/dencoder/
#
# Ниже введите URI с реквизитами баз данных так как это показано. Обратите
# внимание, что знак равно не должен быть отделён пробелами. Формат записи
# строго такой как есть.
databases=(
mysql://bitrix0:boRpBnh242Gn7121uet@localhost/sitemanager
)
Шаг 5
Включить таймер с помощью команд:
systemctl start restic_backup.timer
systemctl enable restic_backup.timer
Команды для работы с Restic
Узнать дату следующего запланированного резервного копирования:
systemctl list-timers | grep restic
Запустить резервное копирование вручную с помощью команды:
systemctl start restic_backup
Узнать статус текущего резервного копирования:
systemctl status restic_backup
Восстановить часть файлов из бэкапа:
restic restore latest --target /home/bitrix --path "/home/bitrix"
Просмотр созданных бэкапов:
source /etc/restic_backup/settings.sh
restic snapshots
Пишите свои вопросы по решению и предлагайте новые темы в комментариях.