UNIXAWESOME

Restic. Безопасное и эффективное резервное копирование

#restic #backup

restic

В этом посте рассказывается о моей настройке резервного копирования и как я это делаю.

Что такое бэкап?

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

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

Какие данные нужно бэкапить?

По моему мнению это должна быть подобная информация:


Restic — это современное решение для резервного копирования, написанное на Go, которое может создавать резервные копии данных в ОС Linux, macOS, Windows и BSD. Он поддерживает шифрование, различные серверные хранилища, инкрементальное бэкапирование и их проверку.



Собралось со временем много всяких серверов, VPS’ок, роутеров и прочих устройств которые необходимо бэкапить. Из самых важных устройств это: ноутбук, домашний NAS(кастомный), два домашних микросервера, две VPS-ки.

По поводу того где хранить эту кучу Гб вариантов было немного, а точнее два: или на домашнем NAS хранилище либо в облаке. При бэкапировании на домашнее хранилище главными плюсами есть то, что дисковое пространство практически не ограничено, ну и само железо моё.

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

Купил на хецнере storagebox на 1ТБ с возможностью подключения по различным протоколам, что и подкупило помимо цены в пару евро.



В моем случае резервное копирование будет на sftp, для других типов хранилищ настройка будет практически такая же. Настраиваем беспарольный доступ по ключу. Сделав предварительно отдельный ssh ключ.

Также добавляю в свой ssh config:

Host storagebox
    HostName u196521.your-storagebox.de
    Port 23
    User u196521
    IdentityFile ~/.ssh/id_rsa_b

Ну и для подключения по sftp просто ввожу:

sftp storagebox

При желании создаем директорию для бекапов.

Инициализируем хранилище бэкапов для restic и указываем пароль к нему.

restic -r sftp:storagebox:/ init

Создаем директорию /etc/restic и в ней создаем три файла:


rest.env

RESTIC_PASSWORD=secretRepoPassword
RESTIC_REPOSITORY=sftp:storagebox:/
BACKUP_INCLUDES="--files-from=/etc/restic/rest.includes"
BACKUP_EXCLUDES="--exclude-file=/etc/restic/rest.excludes"
TG_TOKEN=""
TG_CHATID=""

rest.includes

/home/username
/usr/local
/etc

rest.excludes

__pycache__
venv
.venv
.pytest_cache
postgres*
/home/username/.npm
/home/username/.cache
/home/username/.cargo
/home/username/.mozilla
/home/username/Downloads


Далее необходимо настроить systemd service и timer для автоматического запуска.

restic-backup.service

[Unit]
Description=restic
Wants=restic.timer

[Service]
Type=oneshot
User=root
Group=root

EnvironmentFile=/etc/restic/rest.env

ExecStart=/bin/bash -c '/sbin/restic $BACKUP_EXCLUDES backup $BACKUP_INCLUDES && /sbin/restic forget --prune --keep-daily 7 --keep-weekly 15 --keep-monthly 15'

[Install]
WantedBy=multi-user.target

Также в строке ExecStart указываем сколько нужно хранить бэкапов и за какое время.



restic.timer

[Unit]
Description=restic
Requires=restic-backup.service

[Timer]
Unit=restic-backup.service
OnCalendar=daily
#OnCalendar=*-*-* 20:21:00
AccuracySec=12h
Persistent=true

[Install]
WantedBy=timers.target

После создания сервиса и таймера необходимо сделать релоад:

systemctl daemon-reload

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

systemctl enable restic.timer --now

Просмотр запланированных заданий на запуск в системе можно глянуть:

systemctl list-timers


Можно также использовать скрипт для запуска с отправкой уведомлений о статусе бэкапа в телеграм.

rest.sh

#!/bin/bash

DATE="$(date '+%Y-%m-%d %H:%M')"
URL="https://api.telegram.org/bot$TG_TOKEN/sendMessage"
HOSTNAME="$(hostname)"


backup_start() {
    START="$(date '+%Y-%m-%d %H:%M:%S')"
    restic $BACKUP_EXCLUDES backup $BACKUP_INCLUDES > /tmp/rest.log 2>&1
    backup_status=$?
#    echo $backup_status >> /tmp/rest.log
    return $backup_status
}

backup_prune() {
    restic forget --prune --keep-daily 10 --keep-weekly 4 --keep-monthly 12
}

backup_status() {
    if [ "$backup_status" -eq "0" ]
    then
        STATUS="Success 🟢"
    elif [ "$backup_status" -eq "3" ]
    then
        STATUS="Warning 🟠
\`\`\`$(cat /tmp/rest.log)\`\`\`"
    else
        STATUS="Failed 🔴
\`\`\`$(cat /tmp/rest.log)\`\`\`"
    fi
}

generate_message() {
    FINISH="$(date '+%Y-%m-%d %H:%M:%S')"
    MESSAGE="💾 *BACKUP*
*Host:* ${HOSTNAME}
*Start:* ${START}
*Finish:* ${FINISH}
*Status:* ${STATUS}
"
}

send_message() {
    curl -s -X POST \
        $URL \
        -d chat_id=$TG_CHATID \
        -d "text=$MESSAGE" \
        -d parse_mode=markdown
}

start_backup() {
    backup_start
    backup_status
    backup_prune
    generate_message
    send_message
    exit 0
}


start_backup

Reply to this post by email ↪

Or share: