Резервные копии Restic в S3: шифрование, retention, forget/prune и проверка restore | AdminWiki

Резервные копии Restic в S3: шифрование, retention, forget/prune и проверка restore

11 сентября 2026 18 мин. чтения
Содержание статьи

Что такое Restic и почему S3 подходит для бэкапов

Restic загружает в S3 только новые блоки данных. Файл, изменившийся на 1 КБ, добавит в бакет десятки килобайт вместо полной копии: утилита режет поток на блоки (в среднем 1 МиБ, минимум 512 КиБ, максимум 8 МиБ), считает хеши и пропускает всё, что уже лежит в репозитории.

Связка закрывает три задачи сразу. Шифрование идёт на клиенте до отправки байтов в сеть, поэтому провайдер хранит нечитаемый набор объектов. Хранилище масштабируется под любой объём и оплачивается по факту. Retention-политики, проверка целостности и метрики входят в тот же бинарник, сторонние агенты и демоны не нужны.

Цифры для ориентира. Сервер с 500 ГБ данных при канале 100 Мбит/с отдаёт первый бэкап примерно за 12 часов, последующие запуски с изменениями 2-5% данных укладываются в минуты. Сжатый репозиторий на 200-300 ГБ в S3 Standard обходится в несколько долларов в месяц, стоимость API-запросов при ежедневных инкрементах измеряется центами. Схему защиты копий вне основной площадки разбирает материал про удалённое резервное копирование.

Ключевые возможности Restic: шифрование, дедупликация, snapshot-модель

  • Шифрование на клиенте. AES-256 в режиме CTR для данных, Poly1305-AES для аутентификации блоков, ключ выводится из пароля через scrypt. Провайдер S3 не видит ни содержимого файлов, ни их имён.
  • Дедупликация блоков. Работает между файлами, снапшотами и разными хостами в одном репозитории. Копии виртуальных машин, дубликаты логов и одинаковые библиотеки дают экономию в разы.
  • Snapshot-модель. Каждый запуск создаёт снапшот с ID, тегами, меткой хоста и списком путей. Историю можно смотреть, сравнивать через restic diff и удалять по политике.
  • Один бинарник. Ни базы данных, ни демона, ни зависимостей. Бэкенды: AWS S3, MinIO, Wasabi, Backblaze B2, Yandex Object Storage, SFTP, rest-server, Azure, GCS.
  • Сжатие zstd. С версии 0.14 блоки сжимаются, что уменьшает объём плохо дедуплицируемых данных: логов, дампов, бинарников, архивов.

Требования и подготовка окружения

  1. Restic версии 0.17.0 или новее. Проверка: restic version. Репозиторий формата 2 создаётся флагом --repository-version 2, он снимает часть ограничений формата 1 на больших репозиториях.
  2. S3-совместимый бакет и отдельный IAM-пользователь под бэкапы, без прав на остальные бакеты аккаунта.
  3. Синхронизированное время (chrony или systemd-timesyncd). Расхождение часов ломает подпись запросов AWS Signature V4.
  4. Место под локальный кеш: по умолчанию ~/.cache/restic, для репозиториев в сотни гигабайт закладывайте 5-10 ГБ. Каталог меняется флагом --cache-dir.
  5. Файл пароля с правами 600, лежащий вне git-репозиториев и бэкапов конфигурации.
# Debian и Ubuntu
apt update && apt install -y restic

# Проверка версии
restic version

# Универсальный способ: бинарник из релизов проекта
tar -xzf restic_0.*_linux_amd64.tar.gz
install -m 755 restic /usr/local/bin/restic

Настройка Restic backup в S3: пошаговая инструкция

Создание S3-бакета и IAM-политики с минимальными правами

Бакет создавайте в нужном регионе, версионирование оставляйте выключенным. Restic сам управляет версиями через снапшоты, а включённый versioning удваивает счёт за хранение и мешает prune физически удалять блоки. Если политика компании требует версионирование, добавьте lifecycle-правило на удаление нетекущих версий через 7 дней. Шифрование на стороне хранилища (SSE-S3 или SSE-KMS) включайте как второй слой: данные уже зашифрованы Restic, но это закрывает требования аудита.

aws s3api create-bucket \
  --bucket my-backup-bucket \
  --region eu-central-1 \
  --create-bucket-configuration LocationConstraint=eu-central-1

aws s3api get-bucket-location --bucket my-backup-bucket

Пользователь для бэкапов получает минимум прав. Та же политика в JSON-виде переносится в консоль IAM, ниже YAML-представление для читаемости:

Version: '2012-10-17'
Statement:
  - Sid: ListOnly
    Effect: Allow
    Action:
      - s3:ListBucket
      - s3:GetBucketLocation
    Resource: arn:aws:s3:::my-backup-bucket
  - Sid: ObjectsOnly
    Effect: Allow
    Action:
      - s3:GetObject
      - s3:PutObject
      - s3:DeleteObject
      - s3:AbortMultipartUpload
      - s3:ListMultipartUploadParts
    Resource: arn:aws:s3:::my-backup-bucket/*

Условие aws:SourceIp в политике ограничит работу ключа подсетью серверов. Для MinIO и Wasabi права выдаются своими средствами, набор операций тот же плюс разрешение на многочастотную загрузку. Разбор политик, ACL и версионирования с примерами для AWS CLI и MinIO Client собран в статье про S3-протокол и настройку клиентов.

Инициализация репозитория Restic в S3

export RESTIC_REPOSITORY=s3:s3.amazonaws.com/my-backup-bucket
export RESTIC_PASSWORD_FILE=/etc/restic/password
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=eu-central-1

restic init --repository-version 2
restic cat config

Для MinIO, Wasabi и self-hosted хранилищ endpoint указывается целиком, вместе со схемой и портом:

export RESTIC_REPOSITORY=s3:https://minio.example.com:9000/backup
restic -o s3.region=us-east-1 -o s3.bucket-lookup=path init
restic snapshots

Что должно получиться: restic init печатает строку created restic repository с адресом бакета, restic cat config возвращает JSON с полями version, id и chunker_polynomial. Если вместо этого выводится Fatal: unable to open config file, значит репозиторий ещё не создан, недоступен endpoint или у ключа нет права s3:PutObject. Пароль сохраните в менеджере секретов до первого бэкапа: восстановить его из репозитория невозможно.

Первый бэкап и проверка снапшотов

restic backup /etc /home /srv \
  --exclude-caches \
  --exclude-file=/etc/restic/excludes.txt \
  --tag daily \
  --host web-01 \
  --verbose

restic snapshots
restic stats --mode raw-data
restic stats --mode restore-size

В файл исключений добавьте /proc, /sys, /dev, /var/cache, /var/tmp и шаблоны *.tmp, *.sock. Проверка результата: restic snapshots показывает снапшот с ID, временем, хостом и тегами, restic stats --mode raw-data считает объём уникальных блоков в репозитории, --mode restore-size оценивает данные в развёрнутом виде. Разница между двумя числами и есть эффект дедупликации и сжатия. Для медленного канала полезны флаги --limit-upload 8000 (КиБ/с) и -o s3.connections=10.

Автоматизация бэкапа: готовый скрипт, логи и уведомления

#!/usr/bin/env bash
set -euo pipefail

export RESTIC_REPOSITORY=s3:s3.amazonaws.com/my-backup-bucket
export RESTIC_PASSWORD_FILE=/etc/restic/password
export AWS_ACCESS_KEY_ID=$(cat /etc/restic/aws.key)
export AWS_SECRET_ACCESS_KEY=$(cat /etc/restic/aws.secret)
export AWS_DEFAULT_REGION=eu-central-1

LOG=/var/log/restic/backup-$(date +%F).log
mkdir -p /var/log/restic

notify() {
  curl -s -X POST "$ALERT_WEBHOOK" -d "$1" -o /dev/null || true
}

if restic backup /etc /home /srv \
     --exclude-caches \
     --tag daily \
     --host $(hostname) >> "$LOG" 2>&1; then
  notify "Backup OK on $(hostname) $(date -Is)"
else
  notify "Backup FAILED on $(hostname) $(date -Is), see $LOG"
  exit 1
fi

Коды возврата Restic стоит различать в мониторинге: 0 означает успех, 1 общую ошибку, 3 завершение с ошибками чтения части файлов, 10 отсутствие репозитория, 11 проблему с блокировкой, 12 неверный пароль. Код 3 при ежедневном запуске чаще всего означает, что приложение держит открытые файлы с изменившимся размером.

# /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic backup to S3
OnFailure=alert@%n.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Nightly restic backup

[Timer]
OnCalendar=*-*-* 02:30:00
RandomizedDelaySec=10m
Persistent=true

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now restic-backup.timer
systemctl list-timers restic-backup.timer
journalctl -u restic-backup.service -n 50

Cron-вариант выглядит как строка 30 2 * * * /usr/local/bin/restic-backup.sh >> /var/log/restic/cron.log 2>&1. У cron нет Persistent=true, поэтому пропущенный после выключения сервера запуск не повторится. Шаблоны скриптов для cron и systemd с уведомлениями собраны в руководстве про резервное копирование сервера и автотесты восстановления.

Restic шифрование резервных копий и изоляция credentials

Как работает шифрование в Restic: AES-256 и Poly1305

Restic шифрует всё: содержимое блоков, метаданные снапшотов, имена файлов, структуру каталогов и теги. Провайдер видит набор объектов с случайными именами и их размеры, но не может определить, какой файл где лежит. AES-256 в режиме CTR шифрует данные, Poly1305-AES считает код аутентификации для каждого блока. Подмена объекта в бакете ломает проверку, и Restic сообщит об ошибке вместо выдачи повреждённых файлов.

Мастер-ключ репозитория лежит в самом репозитории, в каталоге keys, зашифрованный ключом из пароля. Ключ выводится функцией scrypt с параметрами N=32768, r=8, p=1. Потеря пароля означает потерю данных: в бакете останется нерасшифровываемый мусор, оплачиваемый по тарифу хранения.

Безопасное хранение пароля и ключей S3

Пароль в командной строке виден в ps и в истории shell, поэтому флаг -p и переменной RESTIC_PASSWORD в открытом виде места нет. Рабочие варианты:

  • RESTIC_PASSWORD_FILE на файл с правами 600 и владельцем root.
  • RESTIC_PASSWORD_COMMAND на команду, которая забирает пароль из хранилища секретов: AWS Secrets Manager, HashiCorp Vault, gopass.
  • systemd LoadCredential: секрет попадает в приватный каталог процесса, доступный только этому сервису.
  • Отдельные IAM-ключи на каждый хост, чтобы компрометация одной машины не открывала бэкапы всех остальных.
install -m 600 /dev/null /etc/restic/password
printf '%s' 'длинный-пароль-из-менеджера-секретов' > /etc/restic/password

# Пароль забирается напрямую из Secrets Manager
export RESTIC_PASSWORD_COMMAND="aws secretsmanager get-secret-value --secret-id restic/password --query SecretString --output text"
# Фрагмент unit-файла
[Service]
LoadCredential=restic-password:/etc/restic/password
Environment=RESTIC_PASSWORD_FILE=%d/restic-password

В shell-скрипте секрет доступен как $CREDENTIALS_DIRECTORY/restic-password. Проверка изоляции: команда systemctl show restic-backup.service -p Environment не должна выводить пароль, а ps aux | grep restic во время бэкапа не должен показывать ничего, кроме путей. Ключи AWS в файлах /etc/restic/aws.key и aws.secret держите с правами 600 и не копируйте в бэкап каталога /etc в другой репозиторий.

Ротация паролей и ключей доступа

restic key list
restic key add
restic key remove 2f1c4f1a
restic key passwd

Ротация без простоя: добавьте новый ключ командой restic key add и задайте новый пароль, обновите файл пароля на всех хостах, проверьте доступ через restic snapshots, затем удалите старый ключ по ID из restic key list. Итог проверки: restic key list показывает одну строку. Ключи доступа IAM меняйте не реже 90 дней: создайте второй ключ у пользователя, прогоните бэкап с новыми переменными, отключите первый и убедитесь, что следующий запуск завершился с кодом 0.

Retention policy: forget и prune на практике

Разница между forget и prune

forget удаляет снапшоты из индекса: данные пропадают из restic snapshots, но объекты в S3 остаются на месте и продолжают оплачиваться. prune пересобирает пакеты, физически удаляет ненужные блоки и переписывает индекс. Без prune репозиторий растёт бесконечно, даже если forget запускать каждую ночь. Обратная сторона: prune читает и заново загружает пакеты, поэтому в S3 это самая дорогая по API-запросам операция.

С версии 0.17 prune пересобирает только пакеты, где доля мусора выше порога --max-unused (по умолчанию 5%). Флаг --max-repack-size ограничивает объём пересборки за один запуск и спасает от многочасовых операций на репозиториях в терабайты.

Примеры команд forget с разными политиками

СценарийКомандаЧто остаётся в репозитории
Рабочая станция или небольшой серверrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune7 дневных, 4 недельных, 6 месячных снапшотов
Продакшен-БД с часовыми бэкапамиrestic forget --keep-hourly 24 --keep-daily 14 --keep-weekly 8 --pruneсутки почасовых копий, 2 недели дневных, 2 месяца недельных
Аудит и долгое архивное хранениеrestic forget --keep-daily 31 --keep-monthly 24 --keep-yearly 7 --pruneмесяц дневных, 2 года месячных, 7 лет годовых снапшотов
Экономия места при частых снапшотахrestic forget --keep-last 10 --keep-within 7d --group-by host,paths --prune10 последних снапшотов плюс всё попадающее в окно 7 дней
Проверка политики без удаленияrestic forget --keep-daily 7 --keep-monthly 12 --dry-runничего: команда только печатает список снапшотов к удалению

Флаг --group-by host,paths обязателен, когда в одном репозитории лежат несколько хостов или разные наборы путей. Без него --keep-last применится к репозиторию целиком и вырежет снапшоты редкого хоста. Флаг --keep-tag пригодится для отдельной политики по тегам: например, снапшоты с тегом archive хранятся год, а daily живут неделю.

Автоматизация retention через cron и systemd timer

#!/usr/bin/env bash
set -euo pipefail

export RESTIC_REPOSITORY=s3:s3.amazonaws.com/my-backup-bucket
export RESTIC_PASSWORD_FILE=/etc/restic/password
export AWS_ACCESS_KEY_ID=$(cat /etc/restic/aws.key)
export AWS_SECRET_ACCESS_KEY=$(cat /etc/restic/aws.secret)

restic forget \
  --group-by host,paths \
  --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 3 \
  --prune \
  --max-unused 5% \
  --max-repack-size 5G \
  >> /var/log/restic/forget.log 2>&1
# cron: воскресенье, 04:30
30 4 * * 0 /usr/local/bin/restic-forget.sh
# systemd timer догоняет пропущенный запуск
[Timer]
OnCalendar=Sun *-*-* 04:30:00
Persistent=true
RandomizedDelaySec=30m

Частота: forget ежедневно без prune, prune раз в неделю или месяц, в зависимости от скорости роста данных. Проверка результата: число снапшотов через restic snapshots --json | jq length до и после, объём уникальных блоков через restic stats --mode raw-data, а также длительность prune в логе. Если prune идёт больше часа, снижайте --max-repack-size и переносите его на выходные.

Проверка restore и целостности бэкапов

restic check: структура и данные

restic check без флагов читает индекс и метаданные, проверяет, что все упомянутые пакеты существуют в бакете, а хеши совпадают. Данные при этом не читаются, поэтому проверка дешёвая и укладывается в минуты на репозитории в сотни гигабайт. Полное чтение всех блоков включается флагом --read-data, выборочное флагом --read-data-subset.

restic check
restic check --read-data-subset=10%
restic check --read-data-subset=1/7
restic check --read-data

Схема с --read-data-subset=1/7 делит репозиторий на семь частей и проверяет одну за запуск: за неделю ежедневных проверок вы прочитаете все данные, не вытягивая весь объём в один день. Стоимость API-запросов при полном чтении репозитория 300 ГБ в S3 Standard держится в пределах долей доллара, но egress у части провайдеров тарифицируется отдельно, поэтому полную проверку планируйте на ночь или выходные.

Пошаговое тестовое восстановление

  1. Список снапшотов: restic snapshots --latest 3, найдите ID и время последнего.
  2. Просмотр содержимого без восстановления: restic ls latest /etc/nginx.
  3. Восстановление в отдельный каталог: restic restore latest --target /tmp/restore-test --include /etc/nginx.
  4. Сверка с рабочей копией: rsync -rcn --delete /etc/nginx/ /tmp/restore-test/etc/nginx/ (dry-run, сравнивает контрольные суммы).
  5. Проверка владельцев и прав: ls -ln /tmp/restore-test/etc/nginx/nginx.conf. При запуске от root uid и gid сохраняются, от обычного пользователя появится предупреждение.
  6. Сравнение двух снапшотов между собой: restic diff с ID старого и нового снапшота.
restic snapshots --latest 3
restic ls latest /etc/nginx
restic restore latest --target /tmp/restore-test --include /etc/nginx
rsync -rcn --delete /etc/nginx/ /tmp/restore-test/etc/nginx/
ls -ln /tmp/restore-test/etc/nginx/nginx.conf
restic diff 1a2b3c4d 5e6f7a8b
restic mount /mnt/restic

restic mount подключает репозиторий как файловую систему через FUSE: снапшоты видны как каталоги, файлы копируются обычным cp. Критерий успешного теста: число файлов в /tmp/restore-test совпадает с оригиналом, а rsync в режиме dry-run не показывает расхождений. Регламент, который работает на практике: check без чтения данных ежедневно, --read-data-subset=1/7 ежедневно, восстановление критичных сервисов в отдельный каталог раз в месяц, полный --read-data раз в полгода. Для баз данных к этому добавляется сверка дампов, пример регламента есть в руководстве по резервному копированию PostgreSQL с pgBackRest и PITR.

Автоматизация проверок и алерты

#!/usr/bin/env bash
set -euo pipefail

export RESTIC_REPOSITORY=s3:s3.amazonaws.com/my-backup-bucket
export RESTIC_PASSWORD_FILE=/etc/restic/password
export AWS_ACCESS_KEY_ID=$(cat /etc/restic/aws.key)
export AWS_SECRET_ACCESS_KEY=$(cat /etc/restic/aws.secret)

LOG=/var/log/restic/check-$(date +%F).log

if ! restic check --read-data-subset=1/7 >> "$LOG" 2>&1; then
  curl -s -X POST "$ALERT_WEBHOOK" -d "CHECK FAILED on $(hostname)" -o /dev/null
  exit 1
fi

TARGET=/tmp/restore-test-$(date +%s)
if ! restic restore latest --target "$TARGET" --include /srv/app >> "$LOG" 2>&1; then
  curl -s -X POST "$ALERT_WEBHOOK" -d "RESTORE TEST FAILED on $(hostname)" -o /dev/null
  exit 1
fi
rm -rf "$TARGET"

Скрипт возвращает ненулевой код, поэтому его удобно повесить на systemd-таймер с директивой OnFailure, которая поднимает сервис уведомления. В мониторинге различайте коды возврата Restic: 1 означает ошибку выполнения, 3 завершение с ошибками чтения части файлов, 10 и 11 указывают на отсутствующий репозиторий и проблему с блокировкой.

Метрики и мониторинг Restic в S3

Экспорт метрик: restic_exporter и JSON-вывод

Готовый вариант для Prometheus: отдельный экспортер (restic-exporter), который раз в час запускает restic snapshots и check, а результат отдаёт в формате метрик Prometheus. Имена метрик зависят от версии экспортера, типовой набор включает restic_check_success, restic_snapshots_total и метку времени последнего снапшота.

# Установка бинарника экспортера из релизов проекта
systemctl enable --now restic-exporter

# Фрагмент конфигурации
RESTIC_REPOSITORY=s3:s3.amazonaws.com/my-backup-bucket
RESTIC_PASSWORD_FILE=/etc/restic/password
LISTEN_ADDRESS=:9753
SCRAPE_INTERVAL=3600

Без экспортера достаточно парсить JSON-вывод и писать метрики через textfile collector node_exporter:

SNAP_TIME=$(restic snapshots --json | jq -r 'sort_by(.time) | last | .time')
printf 'restic_last_snapshot_timestamp_seconds %s\n' "$(date -d "$SNAP_TIME" +%s)" > /var/lib/node_exporter/textfile/restic.prom
printf 'restic_snapshots_total %s\n' "$(restic snapshots --json | jq length)" >> /var/lib/node_exporter/textfile/restic.prom
printf 'restic_repo_size_bytes %s\n' "$(restic stats --json | jq .total_size)" >> /var/lib/node_exporter/textfile/restic.prom

Что выводить на дашборд: размер репозитория, число снапшотов, время последнего успешного бэкапа, длительность последнего prune и объём новых данных за сутки (поле summary в выводе restic backup --json, доступно в свежих версиях). Рост размера репозитория на графике быстрее роста источника почти всегда означает сбой дедупликации: поменяли путь, права или включили шифрование на уровне файловой системы без нужды.

Алерты на сбои бэкапов

groups:
  - name: restic
    rules:
      - alert: ResticNoNewSnapshot
        expr: time() - restic_last_snapshot_timestamp_seconds > 90000
        for: 30m
        labels:
          severity: critical
        annotations:
          summary: Нет нового снапшота Restic более 25 часов
      - alert: ResticCheckFailed
        expr: restic_check_success == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: Проверка целостности репозитория не прошла
      - alert: ResticRepoGrowth
        expr: increase(restic_repo_size_bytes[7d]) > 5e11
        for: 1h
        labels:
          severity: warning
        annotations:
          summary: Репозиторий вырос больше чем на 500 ГБ за неделю

Порог 90000 секунд оставляет запас на суточный интервал бэкапа с учётом времени выполнения. Алерт на аномальный рост ловит случай, когда сломался chunker или приложение начало писать большие уникальные файлы: 500 ГБ прироста за неделю почти всегда означают проблему, а не рабочий сценарий. Дублируйте критичные алерты вторым каналом: если инцидент затрагивает мониторинг, сообщение всё равно должно найти адресата.

Диагностика типичных ошибок Restic + S3

Сообщение или кодПричинаЧто делать
403 Forbidden, AccessDeniedIAM-политика не даёт прав на бакет или ключ принадлежит другому аккаунтуПроверить политику, выполнить aws s3 ls s3://my-backup-bucket с теми же ключами, затем restic cat config. Праву s3:ListBucket нужен ресурс самого бакета, а не объектов
SignatureDoesNotMatchНеверный секретный ключ, расхождение региона или времениСверить AWS_SECRET_ACCESS_KEY и AWS_DEFAULT_REGION, синхронизировать время через chrony, для MinIO проверить endpoint и параметр s3.bucket-lookup
Fatal: unable to open config fileРепозиторий не создан или неверный путьПроверить RESTIC_REPOSITORY и права на бакет, при необходимости выполнить restic init --repository-version 2
Fatal: wrong passwordНеверный RESTIC_PASSWORD или повреждённый файл пароляПроверить содержимое файла пароля, попробовать второй ключ через restic key list, восстановить пароль из менеджера секретов
repository is already lockedПредыдущий процесс завершился аварийно и оставил блокировкуПосмотреть владельцев через restic list locks, снять блокировку командой restic unlock, при мёртвых блокировках использовать restic unlock --remove-all
no space left on deviceИсчерпана квота бакета или место в локальном кешеУвеличить квоту у провайдера, перенести кеш флагом --cache-dir на большой диск, проверить размер репозитория через restic stats
Fatal: repository contains errorsПовреждение пакетов в репозиторииНайти битые пакеты через restic check --read-data-subset=1/3, восстановить пострадавшие файлы из другого снапшота, при массовых повреждениях пересоздать репозиторий и залить бэкапы заново

Ошибки аутентификации и прав доступа

403 и AccessDenied почти всегда означают неполную политику. Restic нужен доступ к бакету для листинга объектов и доступ к объектам внутри для чтения, записи и удаления. MinIO и Wasabi требуют отдельного разрешения на многочастотную загрузку, без него первый же большой файл оборвётся ошибкой. Проверка по шагам: aws s3 ls s3://my-backup-bucket, затем restic cat config, затем пробный restic backup небольшого каталога с флагом --verbose.

SignatureDoesNotMatch при верных ключах указывает на расхождение региона или времени. Разница часов больше 15 минут ломает подпись AWS Signature V4, лечится chrony или systemd-timesyncd. Для S3-совместимых хранилищ проверьте endpoint: в RESTIC_REPOSITORY должен быть полный адрес со схемой https и портом, а бакет с path-style адресацией требует -o s3.bucket-lookup=path.

Ошибки блокировок и целостности репозитория

Блокировка остаётся после аварийного завершения процесса: смотрите владельцев через restic list locks, затем снимайте через restic unlock. Если в списке висят блокировки с давно прошедшим сроком и живых процессов нет, помогает restic unlock --remove-all. Ставьте таймаут на бэкап в systemd (RuntimeMaxSec=14400), чтобы зависший процесс не блокировал репозиторий до ручного вмешательства.

Ошибки вида Fatal: repository contains errors означают повреждение пакетов, чаще всего из-за обрыва загрузки или сбоя хранилища. Порядок действий: найти битые пакеты через restic check --read-data-subset=1/3, восстановить пострадавшие файлы из другого снапшота, при массовых повреждениях создать новый репозиторий и залить бэкапы заново. Восстановить данные с утраченным паролем нельзя ни одним из этих способов.

Проблемы с производительностью и стоимостью

prune в S3 стоит дорого по запросам: пересборка пакетов порождает тысячи GET и PUT. Рычаги: --max-repack-size 5G ограничивает объём за один прогон, --max-unused 10% заставляет prune реже пересобирать пакеты с малым количеством мусора, снижение частоты до одного раза в месяц уменьшает счёт. Проверяйте класс хранения: архивные классы вроде Glacier или Deep Archive для репозитория Restic не годятся, потому что prune требует удалять и перезаписывать объекты, а извлечение из архива занимает часы. Скорость загрузки на медленном канале регулируется флагом --limit-upload, число параллельных соединений к S3 параметром -o s3.connections.

Сравнение S3-провайдеров для Restic

Критерии выбора: цена, совместимость, надёжность

  • Стоимость хранения за ТБ в месяц и минимальный срок хранения объекта.
  • Плата за API-запросы: prune и check --read-data генерируют тысячи операций за прогон.
  • Стоимость egress: тестовые восстановления читают данные, часть провайдеров считает исходящий трафик.
  • Полнота S3 API: многочастотная загрузка, листинг префиксов, удаление объектов, path-style адресация.
  • Object Lock и версионирование, если нужно защитить копии от шифровальщиков и случайного удаления.

Тарифы меняются, цифры ниже дают порядок величин на сентябрь 2026 года, перед выбором сверяйте актуальные прайсы и лимиты провайдера.

ПровайдерХранение, ориентирЗапросы и трафикОсобенности для Restic
AWS S3 Standardоколо 0.023 доллара за ГБ в месяцзапросы и egress платныерегионы, IAM, versioning, Object Lock, lifecycle, лучшее покрытие для требований аудита
Backblaze B2около 6 долларов за ТБ в месяцтранзакции класса A и B без платы, egress бесплатный до трёхкратного объёма хранениядешёвый вариант для домашней лаборатории, ключи с ограничением по префиксу бакета
Wasabiоколо 6.99 доллара за ТБ в месяцзапросы и egress без отдельной платы при соблюдении fair useминимум 90 дней хранения объекта, иначе списывается как за полный период; подходит для больших репозиториев
MinIOстоимость серверов и дисковвнешних тарифов нетself-hosted, полный контроль, S3 API, годится для air-gapped контура
Yandex Object Storageориентировочно 1.5-2 рубля за ГБ в месяцоплата операций и трафика по прайсуlifecycle, версионирование, оплата в рублях, поддержка на русском языке
Timeweb Cloudтарифы в рублях по объёму и классуоперации и трафик по прайсуобъектное хранилище рядом с VDS, базами данных и Kubernetes в одном кабинете

Рекомендации по сценариям использования

  • Домашний сервер и лаборатория. Backblaze B2 или Wasabi, репозиторий до нескольких терабайт, восстановление запускается редко и по частям.
  • Небольшая компания. Провайдер с оплатой в рублях и данными в нужной юрисдикции: серверы и бакет удобно держать в одном кабинете, например в Timeweb Cloud.
  • Enterprise с требованиями аудита. AWS S3 с Object Lock, отдельный IAM-пользователь на каждый хост, versioning плюс lifecycle, централизованный мониторинг и алерты.
  • On-prem и закрытый контур. MinIO на своём железе с репликацией между площадками средствами самого MinIO.
  • Смешанная схема для NAS. Локальная репликация плюс облако: сравнение методов для TrueNAS разобрано в статье про выбор метода резервного копирования в TrueNAS.
Поделиться:
Сохранить гайд? В закладки браузера