Что такое 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 блоки сжимаются, что уменьшает объём плохо дедуплицируемых данных: логов, дампов, бинарников, архивов.
Требования и подготовка окружения
- Restic версии 0.17.0 или новее. Проверка: restic version. Репозиторий формата 2 создаётся флагом --repository-version 2, он снимает часть ограничений формата 1 на больших репозиториях.
- S3-совместимый бакет и отдельный IAM-пользователь под бэкапы, без прав на остальные бакеты аккаунта.
- Синхронизированное время (chrony или systemd-timesyncd). Расхождение часов ломает подпись запросов AWS Signature V4.
- Место под локальный кеш: по умолчанию ~/.cache/restic, для репозиториев в сотни гигабайт закладывайте 5-10 ГБ. Каталог меняется флагом --cache-dir.
- Файл пароля с правами 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 --prune | 7 дневных, 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 --prune | 10 последних снапшотов плюс всё попадающее в окно 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 у части провайдеров тарифицируется отдельно, поэтому полную проверку планируйте на ночь или выходные.
Пошаговое тестовое восстановление
- Список снапшотов: restic snapshots --latest 3, найдите ID и время последнего.
- Просмотр содержимого без восстановления: 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/ (dry-run, сравнивает контрольные суммы).
- Проверка владельцев и прав: ls -ln /tmp/restore-test/etc/nginx/nginx.conf. При запуске от root uid и gid сохраняются, от обычного пользователя появится предупреждение.
- Сравнение двух снапшотов между собой: 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, AccessDenied | IAM-политика не даёт прав на бакет или ключ принадлежит другому аккаунту | Проверить политику, выполнить 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.