Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Автоматическое резервное копирование по SFTP: bash-скрипт и конфиг

Linux и DevOps

Автоматизированное резервное копирование по 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.
  • Минимум один раз в месяц выполнять тестовое восстановление из архива, подтверждая работоспособность всей цепочки резервного копирования.

Надёжная стратегия бэкапов остаётся базовым элементом безопасности и устойчивости любой инфраструктуры.

Оцените статью
ctrllife.ru
Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x