Резервная копия, которую ни разу не пробовали восстановить, пока лишь надежда. Хороший план бэкапа отвечает на три вопроса: что копируем, куда и как быстро поднимем систему обратно. В этой статье сравним три популярных инструмента (rsync, BorgBackup и restic), настроим копирование с srv-web01 и srv-linux01 на srv-backup01 (192.168.10.30, домен itpages.lab.local) и обязательно проверим восстановление.

Правило 3-2-1 остаётся актуальным: три копии данных, на двух разных носителях, одна из них вне площадки. Всё, что мы настроим на srv-backup01, закрывает лишь первый уровень. Вынос копии наружу (в облако или на другую площадку) сделаешь тем же restic или rclone уже по такому же образцу.

Подготовка: доступ по ключам

Отдельный пользователь и ключ

Не используй root для бэкапов, если можно без него. Создадим на srv-backup01 пользователя, под которым будут храниться копии, и ключ для клиентов:

# на srv-backup01
useradd -m -s /bin/bash backup
mkdir -p /srv/backups/{srv-web01,srv-linux01}
chown -R backup:backup /srv/backups

# на srv-web01
ssh-keygen -t ed25519 -f /root/.ssh/backup_ed25519 -N '' -C 'backup srv-web01'
ssh-copy-id -i /root/.ssh/backup_ed25519.pub backup@srv-backup01.itpages.lab.local

Ключ без пароля нужен для автоматических запусков, поэтому его надо ограничить. В ~backup/.ssh/authorized_keys на srv-backup01 допиши перед ключом ограничения:

from="192.168.10.20",no-pty,no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA... backup srv-web01

Теперь ключ работает только с адреса srv-web01 и не даёт интерактивной оболочки. Если ключ утечёт, им не удастся воспользоваться откуда-то ещё.

rsync: простой и прозрачный

Зеркало с инкрементальной историей

rsync копирует только изменившиеся данные и отлично подходит для файловых каталогов. Классическая схема с жёсткими ссылками даёт «снимки» по датам при минимальном расходе места: неизменённые файлы ссылаются на предыдущую копию.

#!/bin/bash
# /usr/local/sbin/rsync-backup.sh на srv-web01
set -euo pipefail
DEST=/srv/backups/srv-web01
NOW=$(date +%F_%H%M)
SSH="ssh -i /root/.ssh/backup_ed25519"

rsync -aHAX --delete --numeric-ids \
  --exclude='/proc/*' --exclude='/sys/*' --exclude='/dev/*' \
  --exclude='/run/*' --exclude='/tmp/*' --exclude='/var/cache/*' \
  --link-dest="$DEST/latest" \
  -e "$SSH" /etc /var/www /opt backup@srv-backup01.itpages.lab.local:"$DEST/$NOW/"

$SSH backup@srv-backup01.itpages.lab.local "ln -sfn $DEST/$NOW $DEST/latest"

Флаги: -a сохраняет права и время, -H жёсткие ссылки, -A ACL, -X расширенные атрибуты, --delete удаляет в копии то, чего больше нет в источнике. Сначала запускай с --dry-run и -v, чтобы увидеть, что произойдёт, особенно когда используешь --delete.

У подхода есть слабые стороны. Нет сжатия и дедупликации, шифрования на хранилище тоже нет, а если на источнике внезапно появится вредонос, он за ночь «синхронизируется» и в последнюю копию (поэтому нужны датированные снимки, а не одно зеркало). Для файлового сервера и конфигураций этого достаточно, для больших баз и виртуальных дисков уже нет.

BorgBackup: дедупликация и шифрование

Создаём репозиторий

Borg режет данные на блоки, дедуплицирует их, сжимает и шифрует. Благодаря этому сотня ежедневных копий почти не занимает места сверх первой. Установка есть в репозиториях обоих дистрибутивов (на Rocky — из EPEL):

apt install -y borgbackup          # Debian
dnf install -y epel-release borgbackup   # Rocky

# на srv-backup01 каталог для репозитория
mkdir -p /srv/borg/srv-web01 && chown backup:backup /srv/borg/srv-web01

# на srv-web01 инициализация
export BORG_RSH="ssh -i /root/.ssh/backup_ed25519"
borg init --encryption=repokey-blake2 backup@srv-backup01.itpages.lab.local:/srv/borg/srv-web01
borg key export backup@srv-backup01.itpages.lab.local:/srv/borg/srv-web01 /root/borg-key-srv-web01.txt

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

Скрипт ежедневного копирования с обслуживанием

#!/bin/bash
# /usr/local/sbin/borg-backup.sh
set -euo pipefail
export BORG_REPO="ssh://backup@srv-backup01.itpages.lab.local/srv/borg/srv-web01"
export BORG_RSH="ssh -i /root/.ssh/backup_ed25519"
export BORG_PASSCOMMAND="cat /root/.borg-pass"

borg create --stats --compression zstd,6 \
  --exclude '/var/www/*/cache' --exclude '*.tmp' \
  ::'{hostname}-{now:%Y-%m-%d_%H%M}' /etc /var/www /opt /home

borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 \
  --glob-archives '{hostname}-*'
borg compact
borg check --repository-only

Хранение «7 ежедневных, 4 еженедельных, 6 ежемесячных» — разумный старт. Команда prune удаляет лишнее, а compact фактически освобождает место на диске. Файл с парольной фразой защити: chmod 600 /root/.borg-pass.

Проверка и восстановление:

borg list
borg info ::srv-web01-2026-10-13_0300
borg mount ::srv-web01-2026-10-13_0300 /mnt/restore
ls /mnt/restore/etc/nginx; borg umount /mnt/restore
borg extract ::srv-web01-2026-10-13_0300 etc/nginx

restic: простота и облачные хранилища

Репозиторий через SFTP

restic — один бинарник, шифрование включено всегда, а поддерживаемых бэкендов много: локальный диск, SFTP, S3, Backblaze. Для srv-linux01 используем SFTP на srv-backup01:

apt install -y restic     # или dnf install -y restic
export RESTIC_REPOSITORY="sftp:backup@srv-backup01.itpages.lab.local:/srv/backups/srv-linux01/restic"
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic init
restic backup /etc /home /opt --exclude-file=/etc/restic-excludes.txt --tag daily
restic snapshots

Для нестандартного ключа добавь в ~/.ssh/config блок Host для srv-backup01 с указанием IdentityFile, и restic его подхватит. Хранение настраивается так:

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check --read-data-subset=5%
restic restore latest --target /tmp/restore --include /etc/ssh

Проверка --read-data-subset=5% читает случайные пять процентов данных и сверяет их контрольные суммы: за 20 запусков ты прочитаешь практически всё, но не нагружаешь диск каждый день.

Что выбрать

  • rsync — когда нужны обычные файлы, которые можно открыть руками, и минимум зависимостей.
  • Borg — лучшая дедупликация и степень сжатия на своих серверах, хороший выбор для SSH-хранилища.
  • restic — когда бэкенд может быть облачным или нужен один бинарник на разных платформах.

Автоматизация и защита

Таймер systemd с проверкой результата

cat > /etc/systemd/system/borg-backup.service <<'EOF'
[Unit]
Description=Borg backup srv-web01
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/borg-backup.sh
Nice=10
IOSchedulingClass=idle
EOF
cat > /etc/systemd/system/borg-backup.timer <<'EOF'
[Unit]
Description=Daily borg backup

[Timer]
OnCalendar=*-*-* 02:30
RandomizedDelaySec=15min
Persistent=true

[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now borg-backup.timer
systemctl list-timers borg-backup.timer

Приоритеты Nice и IOSchedulingClass=idle не дадут копированию задушить рабочие сервисы. Если задание упадёт, увидишь это командой systemctl --failed и в журнале.

Копия баз данных и защита от шифровальщиков

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

mysqldump --single-transaction --routines --all-databases | zstd > /var/backups/db/all-$(date +%F).sql.zst
sudo -u postgres pg_dumpall | zstd > /var/backups/db/pg-$(date +%F).sql.zst

Чтобы взломанный клиент не смог уничтожить собственные копии, ограничь Borg на сервере режимом «только добавление»: в authorized_keys укажи command="borg serve --append-only --restrict-to-path /srv/borg/srv-web01". Удалять и сжимать старые архивы тогда можно только с самого srv-backup01 вручную или по отдельному ключу.

Проверка восстановления

Раз в месяц делай учебное восстановление. Минимум: развернуть копию в тестовый каталог, сравнить с оригиналом и записать, сколько это заняло времени.

mkdir -p /tmp/restore-test
borg extract --dry-run --list ::LATEST_ARCHIVE | head
cd /tmp/restore-test && borg extract ::srv-web01-2026-10-13_0300 etc
diff -r /tmp/restore-test/etc /etc | head
zstd -dc /var/backups/db/pg-2026-10-13.sql.zst | head -20

Фиксируй результат: время восстановления нужного набора и реальный объём. Эти цифры потом пригодятся при планировании ёмкости srv-backup01 и в разговорах о допустимом простое.

Планирование хранения и объёма

Сколько места нужно

Оценивать объём хранилища нужно заранее. Возьми размер защищаемых данных, умножь на коэффициент прироста за период хранения и добавь запас. Для rsync со снимками на жёстких ссылках место занимают только изменённые файлы, поэтому расход зависит от «оборота» данных: сайт с редкими правками почти не растёт, а каталог с логами или загрузками растёт быстро. Для Borg и restic дедупликация действует на уровне блоков, и ежедневный прирост обычно составляет единицы процентов. Измеряй реальные цифры: команды borg info и restic stats --mode raw-data показывают фактический размер хранилища и коэффициент дедупликации.

Окна и приоритеты

Планируй копирование на время минимальной нагрузки, но не на одно и то же время для всех хостов, иначе сетевой канал к srv-backup01 станет узким местом. Разнеси задания на полчаса друг от друга или используй RandomizedDelaySec. Для медленных каналов ограничь скорость: в rsync это --bwlimit=20m, в restic параметр --limit-upload, а в Borg — --remote-ratelimit. Не забудь про время самой проверки целостности: полное чтение репозитория по большому объёму занимает часы, поэтому запускай его реже копирования, например раз в неделю.

Контроль результата и оповещения

Самая опасная ситуация — тихий сбой, при котором копии не создаются неделями. Добавь в скрипт отправку метки об успешном завершении во внешний мониторинг: простейший вариант — запрос к сервису вроде healthchecks или собственному скрипту, который ждёт сигнала раз в сутки и поднимает тревогу при его отсутствии. Такая схема «мёртвой руки» ловит любые поломки, включая смерть самого таймера. Пример: в конце скрипта добавь строку curl -fsS -m 10 --retry 3 http://srv-backup01.itpages.lab.local:8080/ping/web01 >/dev/null, а на srv-backup01 проверяй возраст последней метки.

И ещё одно наблюдение из практики: храни не только данные, но и документацию восстановления. Короткая инструкция «с чего начать, если srv-web01 потерян» с порядком действий, адресами репозиториев и местом хранения ключей сэкономит самые дорогие минуты, когда тебе будет не до размышлений.

Восстановление после аварии на практике

Сценарий полной потери сервера

Представь, что диск srv-web01 вышел из строя. Что делать по шагам? Поставь на новую машину ту же версию ОС, настрой сеть с прежним адресом 192.168.10.20 и именем, установи борг или restic, верни ключ SSH для доступа к srv-backup01. Затем восстанови конфигурацию и данные из последнего архива: сначала /etc, затем содержимое /var/www и каталоги приложений, и последним делом базы из дампов. После восстановления сверь права и владельцев, перезапусти сервисы и проверь работу приложения. Записанная и опробованная последовательность превращает аварию в плановую работу на пару часов.

borg extract --numeric-ids ::srv-web01-2026-10-13_0300 etc var/www opt
zstd -dc /var/backups/db/pg-2026-10-13.sql.zst | sudo -u postgres psql
systemctl daemon-reload && systemctl restart nginx itpages-app.service
systemctl --failed

Точечное восстановление файла

Чаще всего восстанавливать приходится не весь сервер, а один случайно удалённый файл или конфигурацию. Для этого монтирование архива удобнее полного извлечения: смотришь содержимое как обычную папку и копируешь нужное. В restic аналогичная команда restic mount /mnt/restic, а для rsync-снимков достаточно зайти в каталог нужной даты. Это ещё один довод хранить копии в понятном виде и регулярно отрабатывать именно такие мелкие операции, чтобы в стрессовой ситуации не вспоминать ключи командной строки.

Частые ошибки и как их избежать

  • Бэкап без проверки восстановления. Копии могут быть пустыми, неполными или зашифрованными потерянным ключом. Раз в месяц восстанавливай тестовый набор, регулярно запускай borg check и restic check.
  • Потеря ключа или пароля репозитория. Шифрование надёжно ровно настолько, чтобы без ключа данные не вернуть. Храни экспорт ключа и парольную фразу отдельно от серверов, в менеджере паролей и в сейфе администратора.
  • Копирование баз «как файлов» и хранение копии на том же сервере. Файлы работающей СУБД в копии получаются несогласованными, а бэкап на том же диске гибнет вместе с источником. Делай дамп или снимок и отправляй копию на отдельный хост.

Что дальше

Администрирование Linux — это набор связанных навыков, вот соседние темы серии: