Автоматизированное резервное копирование по SFTP позволяет регулярно сохранять конфигурации, пользовательские данные и Docker volumes на отдельный сервер, минимизируя риск потери информации. Ниже рассмотрен production-ready linux backup script на bash с конфигом, логированием, учётом прав доступа, chroot-ограничений и базовой обработкой ошибок.
Почему важно регулярно делать бэкапы
Автоматическое резервное копирование по SFTP защищает инфраструктуру от:
- потери данных из-за отказа дисков или контроллеров;
- некорректных обновлений и ошибочных изменений конфигурации;
- случайной перезаписи или удаления файлов администраторами и пользователями;
- повреждения данных внутри контейнеров Docker и Docker volumes.
Оптимальный сценарий — ежедневные или еженедельные резервные копии с отправкой архивов на отдельный SFTP backup сервер, изолированный от основного окружения.
Структура решения
Базовая структура файлов:
/usr/local/bin/backup.sh # Основной bash-скрипт резервного копирования
/etc/backup.conf # Конфигурационный файл linux backup script
/var/log/myproject-backup.log # Журнал логирования выполнения бэкапа
Такое разделение обеспечивает:
- отделение логики от конфигурации — один скрипт, разные окружения;
- простое управление параметрами бэкапа через backup.conf;
- централизованное логирование и контроль ошибок;
- удобную интеграцию с cron и внешним мониторингом.
Зависимости и подготовка окружения
Для работы bash-скрипта резервного копирования требуются следующие компоненты:
tar— создание архивов;sftp(обычно пакетopenssh-client) — передача файлов по SFTP;sshpass— автоматизация аутентификации по паролю;coreutils— утилитыdate,find,hostnameи т.п.
Установка на Debian/Ubuntu:
sudo apt update
sudo apt install -y openssh-client sshpass tar Установка на RHEL/CentOS/Rocky/AlmaLinux:
sudo dnf install -y openssh-clients sshpass tar Использование sshpass и пароля в конфиге снижает уровень безопасности. Рекомендуется выделенный SFTP-пользователь с ограниченными правами, chroot-окружением и минимальными доступами только к каталогу бэкапов.
Размещение файлов и права доступа:
sudo cp backup.sh /usr/local/bin/backup.sh
sudo chmod 700 /usr/local/bin/backup.sh
sudo chown root:root /usr/local/bin/backup.sh
sudo cp backup.conf /etc/backup.conf
sudo chmod 600 /etc/backup.conf
sudo chown root:root /etc/backup.conf
Пример файла backup.conf (универсальный)
Конфиг задаёт параметры подключения к SFTP и перечень данных для резервного копирования. Это позволяет использовать один и тот же скрипт на разных серверах, меняя только backup.conf.
############################################################
# REMOTE_BASE_DIR — каталог на удалённом SFTP-сервере.
#
# Указывается путь относительно корня SFTP-сессии,
# который видит пользователь (учитывая chroot).
#
# Как определить директорию:
# sftp> pwd — стартовая директория
# sftp> mkdir test — проверка прав на запись
# sftp> rmdir test
#
# Примеры:
# REMOTE_BASE_DIR="backup"
# REMOTE_BASE_DIR="/home/backup"
# REMOTE_BASE_DIR="data/backups"
############################################################
REMOTE_BASE_DIR="backup"
# Параметры подключения к SFTP-серверу
SFTP_HOST="1.2.3.4"
SFTP_PORT="22"
SFTP_USER="sftp_user"
SFTP_PASSWORD="your_password"
# Каталоги для резервного копирования
SOURCE_DIRS="/etc /home /var/lib/docker/volumes /opt"
# Локальный лог-файл и временный каталог
LOG_FILE="/var/log/myproject-backup.log"
TMP_DIR="/tmp"
# Количество дней хранения локальных временных архивов (cleanup)
BACKUP_RETENTION_DAYS=7
Разбор основных параметров
REMOTE_BASE_DIR— базовый каталог на SFTP-сервере. Внутри него автоматически создаются подкаталоги по имени хоста и дате.SFTP_HOST,SFTP_PORT,SFTP_USER,SFTP_PASSWORD— параметры подключения для SFTP backup. Пароль передаётся в sshpass.SOURCE_DIRS— список директорий для архивации: системные конфигурации (/etc), домашние каталоги (/home), Docker volumes (/var/lib/docker/volumes), сервисы в/optи т.д.LOG_FILE— файл журнала, в который записываются все операции скрипта.TMP_DIR— локальный каталог для временного хранения архива перед отправкой по SFTP.BACKUP_RETENTION_DAYS— срок хранения локальных временных архивов вTMP_DIR(используется для очистки после неуспешных запусков).
Ротация архивов на удалённом SFTP-сервере не выполняется этим скриптом и обычно реализуется отдельной задачей на стороне сервера хранения (cron, systemd timer, специализированный софт).
Готовый скрипт backup.sh
Ниже приведён универсальный bash-скрипт резервного копирования для Linux-сервера. Скрипт читает конфигурацию из /etc/backup.conf, создаёт архив, передаёт его на SFTP-сервер и пишет события в лог.
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
CONFIG_FILE="/etc/backup.conf"
log() {
local level="$1"
local msg="$2"
local ts
ts="$(date '+%Y-%m-%d %H:%M:%S')"
echo "${ts} [${level}] ${msg}" | tee -a "${LOG_FILE:-/var/log/myproject-backup.log}"
}
require_cmd() {
local cmd="$1"
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Command not found: ${cmd}" >&2
exit 1
fi
}
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "Config not found: $CONFIG_FILE" >&2
exit 1
fi
# shellcheck source=/etc/backup.conf
source "$CONFIG_FILE"
# Проверка обязательных переменных
: "${SFTP_HOST:?SFTP_HOST is not set}"
: "${SFTP_PORT:?SFTP_PORT is not set}"
: "${SFTP_USER:?SFTP_USER is not set}"
: "${SFTP_PASSWORD:?SFTP_PASSWORD is not set}"
: "${REMOTE_BASE_DIR:?REMOTE_BASE_DIR is not set}"
: "${SOURCE_DIRS:?SOURCE_DIRS is not set}"
: "${LOG_FILE:?LOG_FILE is not set}"
: "${TMP_DIR:?TMP_DIR is not set}"
: "${BACKUP_RETENTION_DAYS:?BACKUP_RETENTION_DAYS is not set}"
# Проверка зависимостей
require_cmd tar
require_cmd sshpass
require_cmd sftp
require_cmd hostname
require_cmd date
require_cmd find
# Создание каталога для лога, если отсутствует
LOG_DIR="$(dirname "$LOG_FILE")"
if [[ ! -d "$LOG_DIR" ]]; then
mkdir -p "$LOG_DIR"
fi
DATE_FULL="$(date +'%Y-%m-%d_%H-%M-%S')"
DATE_SHORT="$(date +'%Y-%m-%d')"
HOST_NAME="$(hostname)"
ARCHIVE_NAME="backup_${HOST_NAME}_${DATE_FULL}.tar.gz"
ARCHIVE_PATH="${TMP_DIR%/}/${ARCHIVE_NAME}"
BATCH_FILE="${TMP_DIR%/}/sftp_batch_${HOST_NAME}_${DATE_FULL}.txt"
log "INFO" "Запуск бэкапа. Хост: ${HOST_NAME}, источники: ${SOURCE_DIRS}"
log "INFO" "Создание архива: ${ARCHIVE_PATH}"
# Создание архива
if tar -czpf "$ARCHIVE_PATH" $SOURCE_DIRS >>"$LOG_FILE" 2>&1; then
log "INFO" "Архивация успешно завершена"
else
log "ERROR" "Ошибка при выполнении tar"
rm -f "$ARCHIVE_PATH"
exit 1
fi
# Формирование batch-файла для SFTP
cat >"$BATCH_FILE" <<EOF
cd ${REMOTE_BASE_DIR}
mkdir ${HOST_NAME}
cd ${HOST_NAME}
mkdir ${DATE_SHORT}
cd ${DATE_SHORT}
put ${ARCHIVE_PATH}
EOF
log "INFO" "Отправка архива на SFTP-сервер ${SFTP_HOST}:${SFTP_PORT} в ${REMOTE_BASE_DIR}/${HOST_NAME}/${DATE_SHORT}"
set +o errexit
sshpass -p "$SFTP_PASSWORD" \
sftp -o PubkeyAuthentication=no \
-o PreferredAuthentications=password \
-P "$SFTP_PORT" \
"${SFTP_USER}@${SFTP_HOST}" < "$BATCH_FILE" >>"$LOG_FILE" 2>&1
SFTP_EXIT_CODE=$?
set -o errexit
if [[ $SFTP_EXIT_CODE -ne 0 ]]; then
log "ERROR" "Передача по SFTP завершилась с ошибкой (exit code ${SFTP_EXIT_CODE})"
# Архив намеренно не удаляется для возможной ручной отправки
rm -f "$BATCH_FILE"
exit 1
fi
log "INFO" "Архив успешно отправлен на SFTP"
# Очистка временных файлов
rm -f "$ARCHIVE_PATH" "$BATCH_FILE"
# Очистка старых локальных архивов после неуспешных запусков (если остались)
find "$TMP_DIR" -maxdepth 1 -type f -name "backup_*.tar.gz" \
-mtime +"$BACKUP_RETENTION_DAYS" -print -delete >>"$LOG_FILE" 2>&1 || true
log "INFO" "Бэкап завершён успешно"
Особенности реализации скрипта
- Использование
set -o errexit -o nounset -o pipefailповышает надёжность и позволяет раннее обнаружение ошибок. - Функция
require_cmdгарантирует наличие всех необходимых бинарников до начала бэкапа. - Каталоги на SFTP строятся по схеме
REMOTE_BASE_DIR/<hostname>/<YYYY-MM-DD>/backup_<host>_<timestamp>.tar.gz, что упрощает навигацию и поиск нужной точки восстановления. - Логирование выполняется в единый файл, что упрощает интеграцию со стеком мониторинга и алертинга.
- При ошибке передачи по SFTP архив сохраняется локально для возможной ручной отправки.
Для чувствительных данных рекомендуется рассмотреть аутентификацию по SSH-ключу и использование утилит, поддерживающих SFTP с ключами, вместо пароля и sshpass.
Права, chroot и проверка доступной директории на SFTP
Перед включением скрипта в cron рекомендуется вручную проверить доступность каталога для REMOTE_BASE_DIR и права записи в условиях chroot-ограничений на SFTP-сервере.
Пример проверки:
sftp -P 22 sftp_user@1.2.3.4
sftp> pwd
sftp> ls
sftp> mkdir test
sftp> ls
sftp> rmdir test
sftp> exit
Результаты проверки:
- команда
pwdпоказывает стартовую директорию, к которой привязан SFTP-пользователь (возможен chroot); - успешный
mkdirподтверждает права на запись в текущем каталоге; - ошибка
Permission deniedприmkdirозначает отсутствие прав на запись в данном пути — для REMOTE_BASE_DIR следует выбрать другой каталог.
Хранение пароля SFTP-пользователя в открытом виде в /etc/backup.conf допустимо только при строгих правах доступа на файл (600) и ограниченных правах самого пользователя на SFTP-сервере.
Автоматизация через cron
После проверки работы linux backup script в ручном режиме можно включить автоматический запуск через cron. Скрипт должен выполняться от пользователя с достаточными правами на чтение резервируемых директорий (root или специализированный сервисный пользователь).
Редактирование crontab для root:
sudo crontab -e
Пример задания: запуск каждый день в 03:00:
0 3 * * * PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /usr/local/bin/backup.sh
PATHзадан явно, чтобы утилитыtar,sshpass,sftpиfindгарантированно были доступны в окружении cron;- использование полного пути до скрипта исключает ошибки, связанные со сменой рабочей директории.
Желательно один раз в определённый период запускать скрипт вручную и проверять лог, чтобы убедиться в корректной работе cron и отсутствии неожиданных ошибок (quota, переполнение диска, изменение прав на SFTP и т.п.).
FAQ
Можно ли использовать этот скрипт на любом Linux-сервере?
Да, при условии наличия утилит tar, sshpass, sftp и базовых GNU-инструментов. Путь к конфигу /etc/backup.conf и расположение скрипта можно адаптировать под локальные требования.
Поддерживаются ли Docker volumes?
Да, каталог /var/lib/docker/volumes входит в список SOURCE_DIRS и архивируется целиком. При необходимости в конфигурации можно исключить отдельные подкаталоги или добавить специфичные тома.
Можно ли работать без интерактивного SSH-доступа, только через SFTP?
Да, выполнению скрипта достаточно SFTP-доступа с заданными параметрами подключения. Обычный shell-доступ по SSH на сервер хранения не обязателен.
Как изменить срок хранения резервных копий?
Переменная BACKUP_RETENTION_DAYS управляет очисткой локальных временных архивов в TMP_DIR. Для управления сроком хранения архивов на SFTP-сервере обычно настраивается отдельный механизм ротации на стороне сервера хранения.
Как добавить дополнительные директории в бэкап?
В конфиге /etc/backup.conf в переменную SOURCE_DIRS можно добавить любые пути, разделённые пробелом, например: SOURCE_DIRS="/etc /opt/app /var/www". После изменения конфига рекомендуется выполнить пробный запуск скрипта.
Можно ли дополнительно шифровать архивы?
Да, перед отправкой по SFTP могут применяться GPG или другие инструменты шифрования. В таком случае в скрипт добавляется шаг шифрования перед блоком передачи файла.
Заключение
Приведённая связка backup.sh + backup.conf формирует структурированное и контролируемое автоматическое резервное копирование для Linux-серверов с передачей архивов по SFTP. Решение подходит для бэкапа системных конфигураций, пользовательских данных и Docker volumes, корректно работает в окружениях с chroot-ограничениями и легко расширяется для добавления шифрования, интеграции с мониторингом и уведомлений в Telegram.
- Рекомендуется проверить права доступа к каталогу назначения на SFTP-сервере и корректность REMOTE_BASE_DIR.
- Настроить cron для регулярных бэкапов и контролировать лог-файл
/var/log/myproject-backup.log. - Минимум один раз в месяц выполнять тестовое восстановление из архива, подтверждая работоспособность всей цепочки резервного копирования.
Надёжная стратегия бэкапов остаётся базовым элементом безопасности и устойчивости любой инфраструктуры.









