Back

Все залежить від того, наскільки ти хочеш автоматизації, швидкості відновлення і скільки дискового простору готовий виділити для бекапів.


1. Повний бекап системи (цілого сервера)

  • rsync + cron Класика: робиш копію всіх файлів на інший диск/сервер. Приклад:

    rsync -aAXHv --delete / /mnt/backup/

    (опції -aAXH зберігають права, ACL, посилання, пристрої). Мінус: довго і багато місця займає.

  • Снапшоти файлової системи Якщо у тебе ext4 — можна робити через LVM-снапшоти, якщо ZFS/btrfs — то там вбудовано. Дуже швидко відновлюється, але треба мати сервер на LVM або ZFS.

  • Системний імідж (Clonezilla, partimage, dd) Це прям "фотографія" диску. Добре для рідкісного бекапу, але відновлення завжди "все або нічого".


2. Бекап тільки важливого (сайти + конфіги + бази даних)

  • Файли сайтів + конфігурація Apache/Nginx/PHP Копіюєш /var/www/, /etc/apache2/, /etc/nginx/, /etc/php/, і т.д.

  • Бази даних (MySQL/MariaDB/Postgres) Для MySQL:

    mysqldump --all-databases > /mnt/backup/all.sql

    або робити дампи по базах.

  • Користувацькі дані (наприклад /home/).

Це зазвичай достатньо, щоб підняти сервер на новій машині.


3. Хмарні/зовнішні бекапи

  • BorgBackup / Restic / Duplicity / Kopia Дуже економні, бо роблять інкрементні копії + шифрування. Можна кидати в S3 (AWS, Wasabi, Backblaze, Scaleway) чи на інший сервер. Приклад з Restic:

    restic -r sftp:user@backup-server:/srv/restic-repo backup /var/www /etc /home /var/lib/mysql
  • Rsync на інший сервер Налаштував SSH-ключ — і воно автоматично синхронізує.

  • Google Drive / Dropbox / Nextcloud Через rclone можна зливати бекапи в будь-яке сховище.


4. Автоматизація

  • Скрипт, який:

    1. Робить дампи бази.

    2. Копіює файли сайтів + конфіги.

    3. Архівує (tar.gz або 7z).

    4. Відправляє на віддалений сервер чи в хмару.

  • Додати в cron або systemd timer.


5. Варіанти для швидкого відновлення

  • Docker / LXD / VM — якщо твої сайти в контейнерах, бекапити зручно просто їхні томи + конфіг.

  • Infrastructure as Code (Ansible, Terraform) — тоді бекапиш тільки дані, а сам сервер можна розгорнути заново автоматично.


як робить бекапи hestiacp?

О, з HestiaCP все простіше — там уже вбудований свій механізм бекапів, щоб не мучитися з руками та скриптами 🙂

Як працює HestiaCP Backup:

  1. Що саме бекапиться:

    • сайти користувача (/home/username/web/...),

    • бази даних (MySQL/Postgres),

    • пошта,

    • DNS-зони,

    • користувацькі налаштування,

    • крон-завдання.

    Тобто по суті — все, що потрібно, щоб "перенести" акаунт чи відновити його.

  2. Формат:

    • Створюється архів .tar у каталозі /backup/ (на кожного юзера окремо).

    • Усередині — підкаталоги типу domains/, db/, mail/, cron/, conf/.

    • Можна вручну розпакувати й дістати потрібне.

  3. Автоматизація:

    • Бекапи керуються через HestiaCP панель: можна вказати розклад (щодня, щотижня тощо) і кількість копій, які зберігати.

    • Виконує cron-джоба: v-backup-users.

  4. Відновлення:

    • Через веб-інтерфейс Hestia → "Backups" → вибираєш архів → можна відновити повністю або частинами (наприклад, тільки базу чи тільки сайт).

  5. Куди зберігати:

    • За замовчуванням бекапи лежать локально на сервері.

    • Але можна налаштувати відправку на віддалений сервер по FTP, SFTP або в Amazon S3 (це є у "Remote Backups").


Тобто Hestia робить саме користувацькі бекапи, а не повний знімок системи. Якщо в тебе зламається сама ОС (Ubuntu, пакети, ядро), то відновлювати доведеться сервер заново + потім розгортати з бекапу користувачів.


Хочеш, я розпишу покроково, як у Hestia додати віддалене сховище для бекапів (наприклад, щоб вони летіли на інший сервер по SFTP чи в хмару)?

якими засобами краще зробити бекап-архів, визначивши перелік необхідних для збереження директорій та файлів?

Ооо, отут якраз твій сценарій — коли ти сам хочеш визначати список директорій/файлів, а не тягнути все підряд. Є кілька перевірених інструментів:


1. tar (базовий варіант)

Можна скласти список файлів у текстовий файл і передати його в tar.

tar -czf backup-$(date +%F).tar.gz -T filelist.txt

де filelist.txt виглядає так:

/etc/apache2
/etc/nginx
/etc/php
/var/www
/home
/var/lib/mysql

Плюси: стандартно, просто, без додаткових пакетів. Мінуси: завжди повний бекап (немає інкрементів).


2. rsync

Можна синхронізувати тільки потрібні шляхи на інший диск/сервер.

rsync -aAXHv --files-from=filelist.txt / /mnt/backup/

(тут filelist.txt — список директорій/файлів відносно /).

Плюси:

  • Інкрементний (копіює тільки зміни).

  • Працює через SSH (можна відразу на інший сервер). Мінуси: без стиснення (якщо треба архів — то не варіант).


3. BorgBackup / Restic / Kopia (сучасні інструменти)

Ти задаєш, що саме бекапити, і воно робить:

  • інкрементні копії,

  • шифрування,

  • дедуплікацію,

  • стиснення.

Приклад із Restic:

restic -r /mnt/backup-repo init   # створення репозиторію
restic -r /mnt/backup-repo backup --files-from=filelist.txt

Той самий filelist.txt, що й вище.

Плюси: найзручніше для довгострокового зберігання, можна відновлювати по версіях. Мінуси: треба встановити окреме ПЗ.


4. Duplicity

Працює схоже на tar+rsync, але з інкрементами і підтримкою багатьох бекендів (FTP, S3, Google Drive, WebDAV).

duplicity --include-filelist filelist.txt --exclude '**' / file:///mnt/backup/

5. rclone (як доповнення)

Не робить архів, але вміє заливати вибране напряму в Google Drive, Dropbox, S3 і т.д. Можна комбінувати:

  • спочатку tar або restic,

  • потім rclone copy → в хмару.


Висновок:

  • Якщо треба просто один архівtar -T filelist.txt.

  • Якщо хочеш регулярно знімати копії → краще rsync.

  • Якщо треба серйозне рішення з інкрементами, шифруванням і версіямиrestic або borg.


Хочеш, я складу для тебе приклад готового скрипта (на bash), який бере filelist.txt, робить архів з датою в назві й відправляє його через rclone у хмару/на інший сервер?

Мені не потрібні хмари, інкрементне копіювання і прогресс в кроні. А контрольна сума і можливість докачати після обриву

Для твоїх вимог — контрольні суми + можливість докачати після обриву — краще взяти rsync по SSH, а не scp.


Чому не scp?

  • scp копіює файл заново, якщо передача обірвалась.

  • воно не перевіряє контрольні суми (лише довжину файлу).


Чому rsync?

  • Використовує SSH (так само без додаткових сервісів).

  • Може докачати недокачаний файл (--partial --append-verify).

  • Перевіряє контрольні суми, щоб переконатися, що файл однаковий.

  • Працює у будь-якому cron.


Приклад копіювання архівів на інший сервер:

rsync -avz --partial --append-verify /var/backups/ user@server:/srv/backups/

Опції:

  • -a — зберігає атрибути файлів;

  • -v — виводить, що робить (для тесту, у cron можна прибрати);

  • -z — стискає при передачі;

  • --partial — зберігає частково передані файли;

  • --append-verify — докачує файл і перевіряє контрольну суму.


Використання в cron

0 3 * * * rsync -az --partial --append-verify /var/backups/ user@server:/srv/backups/

(можна ще додати >> /var/log/rsync-backup.log 2>&1 для логів).


Тобто у твоєму випадку схема може бути така:

  1. Скрипт робить архів із потрібних файлів (tar -T filelist.txt).

  2. rsync відправляє архіви на віддалений сервер.


Хочеш, я зберу тобі єдиний готовий скрипт, який робить архів і відразу ж заливає його на інший сервер через rsync?

Без пароля, з ключами

Дивись, у мене створений користувач "bckusr" на сервері для бекапів. В директорію цього користувача будуть записуватися бекапи: "/home/bckusr/backups". І є декілька серверів, які будуть надсилати туди бекапи. Хотілося б обійтися одним спільним ключем. Чи це можливо?

Так, можливо — але є важливі нюанси. Я поясню варіанти, ризики і дам практичні команди, щоб ти міг(могла) вибрати й налаштувати безпечно. (Говорю як Еліс — проста, прямо і без зайвих слів 😉)

Варіанти та рекомендації (коротко)

  1. Краща практіка — окремий ключ для кожного сервера. Безпечніше, дає можливість відкликати один ключ, не ламаючи інші.

  2. Можна використовувати один спільний ключ для кількох серверів — технічно працює, але небезпечно, якщо приватний ключ витече.

  3. Найкращий компроміс: або окремі ключі, або один ключ + обмеження в authorized_keys (по IP та опціях), або ще краще — SSH CA (сертифікація ключів) — але це складніше.


Якщо все ж хочеш один спільний ключ (як реалізувати)

1) Згенерувати ключ (на якомусь з відправників)

ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N ""
# приватний: /root/.ssh/backup_key
# публічний: /root/.ssh/backup_key.pub

2) Роздати приватний ключ іншим відправникам (НЕ рекомендується, але можливо)

Скопіюй приватний ключ на інші сервери (в одну й ту ж локацію), і зроби права:

scp /root/.ssh/backup_key other-sender:/root/.ssh/backup_key
ssh other-sender "chmod 600 /root/.ssh/backup_key && chown root:root /root/.ssh/backup_key"

УВАГА: приватний ключ розміщений на кількох серверах — ризик компрометації зростає. Якщо хтось з відправників зламаний — всі бекaпи під загрозою.

3) Додати публічний ключ у bckusr на бек-сервері

# на бек-сервері (login як root або як адмін)
mkdir -p /home/bckusr/.ssh
cat backup_key.pub >> /home/bckusr/.ssh/authorized_keys
chown -R bckusr:bckusr /home/bckusr/.ssh
chmod 700 /home/bckusr/.ssh
chmod 600 /home/bckusr/.ssh/authorized_keys

4) Обмеження (дуже бажано) — по IP і без зайвих можливостей

В authorized_keys приписати опції перед ключем, наприклад:

from="10.0.0.2",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA...yourkey...
from="10.0.0.3",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA...yourkey...

Це дозволить використовувати той же публічний ключ тільки з вказаних IP і заборонить перенаправлення портів/агента/pty. Дуже рекомендую хоча б from="IP" + no-... опції.

Якщо хочеш ще жорсткіше — використовуй command="..." (форсована команда), або rrsync wrapper, щоб дозволити лише запис у конкретну директорію. Але це трохи складніше налаштувати — скажу як зробити, якщо треба.


Кращий підхід (рекомендований)

  • Згенеруй окремий ключ для кожного сервера-відправника:

    ssh-keygen -t ed25519 -f /root/.ssh/backup_key_srv1 -N ""
    ssh-copy-id -i /root/.ssh/backup_key_srv1.pub -p 22 bckusr@backup-server
  • На бек-сервері в authorized_keys додай для кожного ключа опції from="IP", no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty.

  • Якщо один з відправників потрібно відключити — просто видаляєш його ключ з authorized_keys.

Це дає ту саму гнучкість і безпечніше, ніж розповсюджувати приватний ключ по всім серверам.


Додаткові поради по безпеці (не пропусти)

  • Не зберігай приватний ключ у відкритих скриптах або загальних папках. Права 600 — обов’язково.

  • Використай окремого системного користувача bckusr з домашньою папкою /home/bckusr/backups і мінімальними правами.

  • На бек-сервері переконайся, що /home/bckusr/backups існує і належить bckusr:

    mkdir -p /home/bckusr/backups
    chown -R bckusr:bckusr /home/bckusr/backups
    chmod 700 /home/bckusr/backups
  • Якщо треба — додай у sshd_config обмеження (PermitRootLogin no, AllowUsers bckusr, тощо).


Якщо хочеш — дам готові приклади:

  • приклад рядка в authorized_keys з from="IP" і no-... опціями;

  • як встановити rrsync (обмежувач rsync) і використовувати його як command="..." для безпечнішого запису лише в /home/bckusr/backups/;

  • коротку інструкцію, як відкатити (видалити) ключ при втраті;

Я можу прямо зараз підготувати готові команди під твій випадок — напиши, будь ласка:

  1. хочеш один спільний ключ або по ключу на сервер?

  2. які IP відправників (хоч приблизно), щоб я підставила приклади from="..."?

Хочу зробити це точно під тебе — ти кажеш, я налаштовую.

Давай по ключу на сервер. Відправники: 103.246.146.19, 185.203.241.148, 178.159.43.44.

Супер, це найкращий і найбезпечніший варіант 👍 Розпишу покроково, як зробити окремий ключ для кожного відправника з обмеженнями по IP.


🔑 Налаштування ключів для кількох серверів-відправників

1. На кожному відправнику згенеруй свій ключ

Наприклад, на сервері з IP 103.246.146.19:

ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N ""

(дає два файли: /root/.ssh/backup_key і /root/.ssh/backup_key.pub)

Повтори на кожному з відправників.


2. Додай публічні ключі на бек-сервер у authorized_keys

На сервері з бекапами (де користувач bckusr):

mkdir -p /home/bckusr/.ssh
nano /home/bckusr/.ssh/authorized_keys

У цей файл вставляєш по рядку для кожного відправника. Наприклад:

from="103.246.146.19",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1...ключ1... backup-srv1
from="185.203.241.148",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1...ключ2... backup-srv2
from="178.159.43.44",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1...ключ3... backup-srv3

Тут:

  • from="IP" — дозволяє доступ тільки з вказаної адреси;

  • no-* опції — забороняють тунелювання та shell-доступ, лишають тільки передачу файлів;

  • ssh-ed25519 AAAA... — вміст .pub файлу з кожного відправника.


3. Дозволи на .ssh у bckusr

chown -R bckusr:bckusr /home/bckusr/.ssh
chmod 700 /home/bckusr/.ssh
chmod 600 /home/bckusr/.ssh/authorized_keys

4. Перевірка доступу

З першого відправника:

rsync -az -e "ssh -i /root/.ssh/backup_key -p 22" /etc/hostname bckusr@<IP-бекап-сервера>:/home/bckusr/backups/srv1/

(передасть файл hostname у каталог srv1). Якщо працює без пароля — значить все правильно.


5. Організація директорій

Щоб не плутати бекапи від різних серверів, роби підкаталоги:

/home/bckusr/backups/srv1/
/home/bckusr/backups/srv2/
/home/bckusr/backups/srv3/

І в скрипті кожного сервера задавай свій:

REMOTE_DIR="/home/bckusr/backups/srv1"

Таким чином:

  • у кожного відправника свій ключ;

  • доступ дозволений тільки з його IP;

  • якщо один сервер компрометований — видаляєш його рядок у authorized_keys, інші лишаються без змін.


Хочеш, я підправлю наш скрипт так, щоб він автоматично створював свій підкаталог на віддаленому сервері (srv1/srv2/srv3), якщо його ще нема?

#!/bin/bash

# Важливо зробити перший тест:
# створи /home/bckusr/backups/slava/  (bckusr:bckusr)
# rsync -az -e "ssh -i /root/.ssh/backup_key -p 2202" /etc/hostname bckusr@178.159.43.44:/home/bckusr/backups/slava/
# і для перевірки роботи ключа, і для того, що ssh запитає це:
# Are you sure you want to continue connecting (yes/no/[fingerprint])?   yes


# ===== Налаштування =====
SERVER_ID="slava"
BACKUP_DIR="/var/backups"
FILELIST="/root/adm/backup/filelist.txt"
RETENTION_DAYS=7

REMOTE_USER="bckusr"
REMOTE_HOST="178.159.43.44"
REMOTE_PORT=2202
REMOTE_DIR="/home/bckusr/backups/$SERVER_ID"

LOG_FILE="/root/adm/backup/backup.log"
DATE=$(date +"%Y%m%d-%H%M%S")
ARCHIVE="$BACKUP_DIR/backup-$SERVER_ID-$DATE.tar.gz"
RSYNC_SSH="ssh -i /root/.ssh/backup_key -p $REMOTE_PORT"

# ===== Масив виключень =====
EXCLUDE_LIST=("/root/.ssh/" "/root/.cache/" "*.tgz" "*.bak")

# Перетворюємо масив у рядок для tar
EXCLUDES=""
for pattern in "${EXCLUDE_LIST[@]}"; do
    EXCLUDES+=" --exclude='$pattern'"
done


# ===== Створення директорій =====
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"

# ===== Створення архіву =====
echo -e "\n[$(date +"%F %T")] Починаю створення архіву $ARCHIVE" >> "$LOG_FILE"
tar -czf "$ARCHIVE" $EXCLUDES -T "$FILELIST" 2>>"$LOG_FILE"

# ===== Створення директорії на віддаленому сервері =====
# echo "[$(date +"%F %T")] Перевіряю/створюю $REMOTE_DIR на $REMOTE_HOST" >> "$LOG_FILE"
# ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "mkdir -p '$REMOTE_DIR'" 2>>"$LOG_FILE"

# ===== Відправка на віддалений сервер =====
echo "[$(date +"%F %T")] Надсилаю архів на $REMOTE_HOST:$REMOTE_DIR" >> "$LOG_FILE"
# rsync -az --partial --append-verify -e "ssh -p $REMOTE_PORT" "$ARCHIVE" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" >> "$LOG_FILE" 2>&1
rsync -az --partial --append-verify -e "$RSYNC_SSH" "$ARCHIVE" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/"

# ===== Видалення старих архівів =====
# echo "[$(date +"%F %T")] Очищаю локальні архіви старші за $RETENTION_DAYS днів" >> "$LOG_FILE"
# find "$BACKUP_DIR" -type f -name "backup-$SERVER_ID-*.tar.gz" -mtime +$RETENTION_DAYS -delete

# ===== Функція для парсингу df =====
check_disk() {
    local label="$1"
    local host_cmd="$2"

    echo "[$(date +"%F %T")] $label:" >> "$LOG_FILE"

    # Отримати рядок df
    local df_line
    df_line=$(eval "$host_cmd" | tail -n 1)

    # Витягти поля: Size Used Avail Use%
    local size used avail usep
    read -r _ size used avail usep _ <<< "$df_line"

    echo "$df_line" >> "$LOG_FILE"
    echo "Free: $avail (${usep} used)" >> "$LOG_FILE"
}

# ===== Стан дисків =====
check_disk "Локальний диск (/)" "df -h /"
check_disk "Віддалений диск ($REMOTE_DIR)" "$RSYNC_SSH $REMOTE_USER@$REMOTE_HOST \"df -h $REMOTE_DIR\""

echo -e "[$(date +"%F %T")] Бекап завершено\n" >> "$LOG_FILE"

Last updated