Назад към каталога
Илюстрация на архивиране: дискове, база данни и сейф с щит
Архивиране ⭐ Препоръчан v1.1.0 • 23.10.2026 г. • 🐚 bash

MikroTik Backup Automation през SSH с Bash скрипт

Автоматичен backup на MikroTik рутери през SSH: binary backup + .rsc export, сваляне към Linux сървър, верификация, ретенция и ntfy известия. Готов за cron.

Зависимости

bashopenssh-clientflock (util-linux)findcurl (по избор, за ntfy)

Употреба

./mikrotik-backup.sh
MikroTikRouterOSBackupSSHBashCron

Какво прави

Скрипт за автоматично архивиране на MikroTik рутери. За всеки рутер от списъка създава binary backup (пълно състояние на RouterOS) и текстов .rsc export (портабил конфигурация), сваля двата файла през SFTP на локалния сървър, верифицира, че не са празни, изтрива временните файлове от рутера и прилага ретенция — старите директории отпадат автоматично. При проблем праща известие към ntfy.sh (по избор) и връща ненулев exit code, който мониторингът може да прихване.

Пълното ръководство със стъпка по стъпка настройка, импорт на SSH ключ в RouterOS и инструкция за възстановяване: Автоматичен backup на MikroTik рутер.

Кой къде каква роля има

Преди всичко друго — разпределянето на ролите, което спестява най-много главобълскане:

УстройствоРоляКакво се инсталира там
MikroTik рутерПази конфигурацията; по заявка създава backup и exportНищо — само му импортираш SSH ключ
Linux сървър (LXC на Proxmox)Изпълнява скрипта, свързва се с рутера, пази архивите, праща известияСкриптът + cron задача
Твоят компютър (WSL2)Участва само веднъж — пишеш файла и го качваш на сървъраНищо трайно

Скриптът не се записва нито на рутера, нито на Windows. Живее на Linux машина, включена 24/7. Cron-ът на сървъра го пуска всяка нощ — рутерът просто приема връзката, създава файловете и ги дава за сваляне.

Два терминала — кой каква команда разбира

Това е грешката №1 при първа настройка: командите се пишат в грешния прозорец. Имаш два терминала и те не се смесват:

Linux терминал (WSL или сървъра)WinBox → New Terminal
Промптfedia@host ~ $[fedia@Fedia-MikroTik] >
Кой говориЛинуксътСамият рутер
Команди тамssh, ssh-keygen, scp, nano, chmod, git/ip service …, /user ssh-keys import …, /system backup …

Ориентирът е прост: команди с наклонена черта отпред (/ip …, /user …) — за рутера. Команди като ssh, scp, nano — за Linux машината. Ако рутерът ти отговори bad command name — си пиши в грешния прозорец; нищо не е счупено, просто смени прозореца.

Характеристики

  • Архивира няколко рутера в един пуск — отказът на един не спира останалите
  • Създава и двата формата: .backup за бързо възстановяване и .rsc за миграция/одит
  • SSH ключова автентикация (BatchMode=yes) — без пароли в скриптове
  • Поддържа нестандартен SSH порт на всеки рутер — задава се в конфигурацията (виж по-долу)
  • Верификация след сваляне — празен файл се брои за грешка, не за успех
  • Ретенция: директории по-стари от KEEP_DAYS дни се изтриват автоматично
  • flock защита срещу паралелни изпълнения (cron + ръчно пуск)
  • Логва всичко в backup.log с timestamp
  • Известия към ntfy.sh при успех или неуспех (по избор)

Код

#!/usr/bin/env bash
# ============================================================
#  mikrotik-backup.sh — Автоматичен backup на MikroTik рутери
#  Статия: https://linuxdevops.dev/tutorials/mikrotik-backup-avtomatizacia/
# ============================================================

set -euo pipefail

# ============================ КОНФИГУРАЦИЯ ============================

# Формат: "име|хост|ПОРТ|потребител"
# Портът е ТРЕТОТО поле — ако SSH ти слуша на нестандартен порт, запиши го там.
ROUTERS=(
  "main|192.168.88.1|22|backup"
  # "garage|192.168.88.2|22|backup"
  # "office|10.0.0.254|22222|backup"   ← пример: SSH на нестандартен порт
)

BACKUP_DIR="/var/backups/mikrotik"  # къде се пазят локално
KEEP_DAYS=30                        # колко дни да се пазят стари директории
SSH_TIMEOUT=20                      # timeout за SSH връзката (сек)
NTFY_TOPIC=""                       # по избор: "https://ntfy.sh/таен-topic-тук"

LOG="$BACKUP_DIR/backup.log"
DATE="$(date +%F)"
LOCK="/tmp/mikrotik-backup.lock"

SSH_OPTS=(-o BatchMode=yes
          -o ConnectTimeout="$SSH_TIMEOUT"
          -o StrictHostKeyChecking=accept-new)

log() { printf '[%s] %s\n' "$(date '+%F %T')" "$*" | tee -a "$LOG"; }

notify() {
  if [ -n "$NTFY_TOPIC" ]; then
    curl -sS --max-time 10 -H "Title: MikroTik backup" -d "$1" "$NTFY_TOPIC" >/dev/null 2>&1 || true
  fi
}

# Забрана на паралелни изпълнения (cron + ръчно пуск)
mkdir -p "$BACKUP_DIR"
exec 9>"$LOCK"
if ! flock -n 9; then
  log "❌ Друг backup процес вече работи. Излизам."
  exit 1
fi

# backup_router <име> <хост> <порт> <потребител>
backup_router() {
  local name="$1" host="$2" port="$3" user="$4"
  local dest="$BACKUP_DIR/$name/$DATE"
  local bname="${name}-${DATE}"

  mkdir -p "$dest"
  log "→ $name ($host): започвам…"

  # 1. Binary backup на рутера
  if ! ssh "${SSH_OPTS[@]}" -p "$port" "$user@$host" \
        "/system backup save name=$bname dont-encrypt=yes" >>"$LOG" 2>&1; then
    log "❌ $name: не успях да създам binary backup"
    return 1
  fi

  # 2. Текстов export (RouterOS v7: show-sensitive; за v6 махни флага)
  if ! ssh "${SSH_OPTS[@]}" -p "$port" "$user@$host" \
        "/export show-sensitive file=$bname" >>"$LOG" 2>&1; then
    log "❌ $name: не успях да създам .rsc export"
    return 1
  fi

  # 3. Сваляне на двата файла през SFTP
  if ! scp -P "$port" "${SSH_OPTS[@]}" \
        "$user@$host:$bname.backup" "$user@$host:$bname.rsc" "$dest/" >>"$LOG" 2>&1; then
    log "❌ $name: не успях да сваля файловете"
    return 1
  fi

  # 4. Верификация — празен бекъп е по-лош от липсващ
  if [ ! -s "$dest/$bname.rsc" ] || [ ! -s "$dest/$bname.backup" ]; then
    log "❌ $name: някой от файловете е празен!"
    return 1
  fi

  # 5. Чисти временните файлове от рутера
  ssh "${SSH_OPTS[@]}" -p "$port" "$user@$host" \
      "/file remove [find name~\"$bname\"]" >>"$LOG" 2>&1 || true

  log "✅ $name: OK — $(du -h "$dest/$bname.backup" | cut -f1) backup, $(du -h "$dest/$bname.rsc" | cut -f1) rsc"
}

cleanup_old() {
  log "🧹 Изтривам бекъпи по-стари от $KEEP_DAYS дни…"
  find "$BACKUP_DIR" -mindepth 2 -maxdepth 2 -type d \
      -name "20*" -mtime "+$KEEP_DAYS" -exec rm -rf {} \; 2>>"$LOG" || true
}

log "🚀 MikroTik backup стартира за ${#ROUTERS[@]} рутер(а)"

OK=0; FAILED=0; FAILED_LIST=""
for entry in "${ROUTERS[@]}"; do
  IFS='|' read -r name host port user <<< "$entry"
  if backup_router "$name" "$host" "$port" "$user"; then
    OK=$((OK + 1))
  else
    FAILED=$((FAILED + 1))
    FAILED_LIST="$FAILED_LIST $name"
  fi
done

cleanup_old

log "🏁 Край: ✅ $OK успешни, ❌ $FAILED неуспешни"

if [ "$FAILED" -gt 0 ]; then
  notify "❌ MikroTik backup: $FAILED неуспешни рутера:$FAILED_LIST (✅ $OK успешни)"
  exit 1
fi

notify "✅ MikroTik backup: всички $OK рутера са архивирани успешно."
exit 0

Използване

# Първо ръчно изпълнение (задължително преди cron)
chmod +x mikrotik-backup.sh
./mikrotik-backup.sh

# Резултатът отива в:
# /var/backups/mikrotik/<рутер>/YYYY-MM-DD/<рутер>-YYYY-MM-DD.{backup,rsc}

Преди cron винаги пусни веднъж ръчно — и провери връзката още по-рано с еднострочен тест:

ssh -i ~/.ssh/ключа -p ПОРТА backup@IP-НА-РУТЕРА "/system identity print"
# отпечатва името на рутера = връзката работи, скриптът ще работи

Конфигурация

Всичко е в горната част на скрипта:

ПроменливаОписание
ROUTERSСписък "име|хост|порт|потребител" — по един ред на рутер. Портът е третото поле — ако SSH не слуша на 22, просто запиши реалния
BACKUP_DIRЛокална директория за бекъпите (препоръчително /var/backups/…)
KEEP_DAYSКолко дни да се пазят стари дневни директории
SSH_TIMEOUTTimeout на SSH връзката в секунди
NTFY_TOPICntfy.sh topic за известия — остави празно, ако не ползваш

SSH на нестандартен порт

Смяна на порта е добра практика — автоматичните скенери блъскат по 22, а по 22222 никой не пита. Но тогава всичко трябва да сочи новия порт. Проверката кой порт всъщност слуша:

# в WinBox → New Terminal:
/ip service print
# редът "ssh" показва реалния PORT

Ако портът е друг (да речем 22222), настройката се разпростира на три места и всичко трябва да е съгласувано:

  1. Скриптът — "main|192.168.88.1|22222|backup" (третото поле)
  2. Ръчните команди — ssh -p 22222 … (малка буква), scp -P 22222 … (ГЛАВНА буква — класическа грешка, при scp портът е с P)
  3. Нищо друго — скриптът сам подава порта на ssh и scp с правилния флаг

И тъй като портът е сменен, затвори кръга с whitelist — SSH да е видим само за сървъра, който прави бекъпите:

# в WinBox → New Terminal (смени IP-то с това на своя сървър):
/ip service set ssh address=192.168.88.50/32

Резултатът: от целия интернет и от останалите устройства SSH-ът е невидим — няма какво да се сканира, независимо от порта. Единствено сървърът с бекъпите го вижда. Заедно с потребител, чиято политика е само read,ssh, дори компрометиран ключ не позволява писане по конфигурацията — само четене, което е точно всичко, от което backup-ът се нуждае.

Автоматизация с cron

# MikroTik backup — всеки ден в 03:00 (като root)
0 3 * * * /usr/local/bin/mikrotik-backup.sh >/dev/null 2>&1

Изисквания

  • MikroTik рутер с RouterOS v7 (за v6 — махни show-sensitive от export командата)
  • Импортнат SSH публичен ключ на рутера за съответния потребител
  • Linux машина с openssh-client и flock (стандартно на Debian/Ubuntu)
  • Ако SSH е на нестандартен порт — той се задава в ROUTERS, скриптът не го уговаря

Бележки

  • .backup и .rsc файловете съдържат пароли и ключове — пази ги на сигурно място с ограничени права
  • За възстановяване: /system backup load name=… (binary) или /import file-name=… (rsc след reset)
  • Тествай възстановяването веднъж поне — бекъп без тест е надежда, не backup