Files
ssh-monitor/docs/auto-update.ru.md
T
PapaTramp 6df83f1838 feat: release 2.2.1-SAC — phase 2 manifest verify and quiet SAC updates
Pinned GIT_REF/verify, release manifest, no blind reset --hard; suppress
lifecycle and watchdog Telegram during updater; healthcheck via json.dumps.
2026-07-08 11:48:34 +10:00

9.7 KiB
Raw Blame History

Автообновление ssh-monitor

Скрипт update_ssh_monitor.sh обновляет /usr/local/bin/ssh-monitor из git и перезапускает systemd-сервис.

Основной путь: Security Alert Center

На продакшен-хостах обновление идёт через SAC, без cron:

  1. Админ нажимает «Обновить ssh-monitor (SSH)» в карточке хоста.
  2. SAC по SSH запускает /opt/scripts/update_ssh_monitor.sh с REPO_URL / GIT_BRANCH из Настройки → Обновления агентов.
  3. Updater сам выполняет git pull, синхронизирует sac-client.sh и watchdog, дописывает отсутствующие ключи в /etc/ssh-monitor.conf, выставляет chmod/chown на конфиг, SAC-spool, счётчики и state-файлы, перезапускает ssh-monitor.service.

Участие админа на сервере не требуется (кроме первичной настройки SAC_URL / SAC_API_KEY в конфиге).

При первой установке (нет updater на хосте) SAC выполняет bootstrap с --deploy: clone, ipset при необходимости, systemd unit, полный hardening.

Cron / systemd timer — опциональная альтернатива с тем же скриптом и обязательным REPO_URL в окружении.

Watchdog и таймеры watchdog не изменяются при обычном update (кроме синхронизации скрипта watchdog из git).

Конфиг /etc/ssh-monitor.conf: при первой установке копируется из ssh-monitor.conf.example. При каждом update в существующий конфиг дописываются отсутствующие SAC-переменные и ключи безопасности; UseSAC=fallback. Telegram/SMTP и прочие ключи не перезаписываются.

Установка монитора и unit-файлов: README.md, зависимости: install-prerequisites.ru.md.

Что делает скрипт

  1. Создаёт рабочий каталог UPDATE_DIR (по умолчанию /opt/scripts/update).
  2. При --deploy / bootstrap SAC проверяет ipset и при отсутствии пытается установить через пакетный менеджер. Обычное обновление не вызывает apt-get.
  3. В UPDATE_DIR выполняет git clone или git fetch + checkout / git pull --ff-only (без слепого reset --hard).
  4. Проверяет release/manifest-VERSION.json (SHA256 файлов + commit) до копирования в /usr/local/bin.
  5. Ищет ssh-monitor в клоне (GitLab layout или плоский репозиторий).
  6. Сравнивает SHA256 с LOCAL_SCRIPT_PATH (/usr/local/bin/ssh-monitor).
  7. Всегда синхронизирует sac-client.sh, ssh-monitor-perms.sh, watchdog.
  8. Дописывает ключи конфига; apply_runtime_security_hardening: chmod 600 конфиг, 700 spool, 600 state/SAC-файлы, whitelist.
  9. При изменении ssh-monitor, sac-client.sh или конфига — systemctl restart ssh-monitor.service.
  10. Лог: /var/log/update_script.log (блок «Итог обновления», строки manifest и security hardening).
flowchart LR
  A[SAC или cron] --> B[update_ssh_monitor.sh]
  B --> C[git fetch/checkout]
  C --> M{manifest OK?}
  M -->|нет| X[exit 1]
  M -->|да/skip| D[sync sac-client + perms lib]
  C --> E{SHA256 ssh-monitor?}
  D --> F[harden config/spool/state]
  E -->|да| G[backup + cp ssh-monitor]
  E -->|нет| F
  G --> F
  F --> H{что-то изменилось?}
  H -->|да| I[restart ssh-monitor.service]
  H -->|нет| J[без перезапуска]

Настройка перед первым запуском

Переменная По умолчанию Назначение
UPDATE_DIR /opt/scripts/update Каталог для git-клона
REPO_URL (обязательно) URL git — задаётся SAC, export или Environment= в cron
GIT_BRANCH main Ветка для clone/pull, если GIT_REF не задан
GIT_REF (пусто) Тег (2.2.0-SAC), ветка или commit SHA для checkout
GIT_VERIFY_MODE off off | tag | commit — см. раздел ниже
GIT_ALLOW_RESET 0 1 = разрешить git reset --hard при расхождении истории (риск)
RELEASE_MANIFEST_STRICT 0 1 = exit 1, если manifest для версии не найден
LOCAL_SCRIPT_PATH /usr/local/bin/ssh-monitor Куда копировать монитор
LOG_FILE /var/log/update_script.log Лог обновлений
UPDATE_VIA_SAC (опционально) SAC выставляет 1; при отсутствии бинарника включается --deploy

Требования: root, git, python3 (manifest verify), доступ к репозиторию.

Pinned ref и manifest (2.2.0+)

Updater читает GIT_REF, GIT_VERIFY_MODE, GIT_ALLOW_RESET из env или /etc/ssh-monitor.conf.

Режимы GIT_VERIFY_MODE

Режим Поведение Когда
off После fetch принять ref как есть Тест, legacy; дефолт в скрипте
tag GIT_REF должен существовать как тег Рекомендуется для прода
commit GIT_REF = полный SHA commit Жёсткий pin без тегов

Если GIT_REF пуст, используется GIT_BRANCH (git pull --ff-only). При невозможности fast-forward updater не делает reset --hard (только с GIT_ALLOW_RESET=1).

Release manifest

В репозитории: release/manifest-VERSION.json — SHA256 ключевых файлов и git_commit. Updater сверяет manifest после git sync и до копирования бинарников.

  • Файл найден и hash не совпал → exit 1, ничего не перезаписывается.
  • Файл не найден → WARN, update продолжается (или exit 1 при RELEASE_MANIFEST_STRICT=1).
  • Копирование update_ssh_monitor.sh в /opt/scripts/ и re-exec — только если manifest для версии был и прошёл verify.

Генерация при релизе (после финального коммита кода, чтобы git_commit в manifest совпал с HEAD):

git commit -m "release: 2.2.0-SAC"
./scripts/build-release-manifest.sh 2.2.0-SAC
git add release/manifest-2.2.0-SAC.json && git commit -m "release: manifest 2.2.0-SAC"
git tag 2.2.0-SAC

Примеры для прода

SAC / env на хосте (через настройки SAC или unit):

REPO_URL=https://git.kalinamall.ru/PapaTramp/ssh-monitor.git
GIT_REF=2.2.0-SAC
GIT_VERIFY_MODE=tag

systemd timer (/etc/systemd/system/ssh-monitor-update.service):

[Service]
Type=oneshot
Environment=REPO_URL=https://git.kalinamall.ru/PapaTramp/ssh-monitor.git
Environment=GIT_REF=2.2.0-SAC
Environment=GIT_VERIFY_MODE=tag
ExecStart=/opt/scripts/update_ssh_monitor.sh

При доверенном закрытом зеркале manifest + GIT_REF=tag — достаточный минимум; GPG-подписи тегов — backlog (см. security-roadmap.ru.md).

Первичная установка (--deploy)

sudo REPO_URL=https://git.kalinamall.ru/PapaTramp/ssh-monitor.git ./update_ssh_monitor.sh --deploy
# или first_deploy.sh с REPO_URL в окружении

Через SAC bootstrap выполняется автоматически с --deploy.

Установка updater (если не через SAC bootstrap)

sudo mkdir -p /opt/scripts
sudo cp update_ssh_monitor.sh /opt/scripts/update_ssh_monitor.sh
sudo chmod 750 /opt/scripts/update_ssh_monitor.sh

Проверка:

sudo REPO_URL=https://git.kalinamall.ru/PapaTramp/ssh-monitor.git /opt/scripts/update_ssh_monitor.sh
sudo tail -30 /var/log/update_script.log

Запуск по расписанию (опционально)

Cron

0 4 * * * REPO_URL=https://git.kalinamall.ru/PapaTramp/ssh-monitor.git /opt/scripts/update_ssh_monitor.sh

systemd timer

См. предыдущие примеры ssh-monitor-update.service / .timer с Environment=REPO_URL=....

Откат

ls -la /usr/local/bin/ssh-monitor.backup.*
sudo cp /usr/local/bin/ssh-monitor.backup.YYYYMMDD_HHMMSS /usr/local/bin/ssh-monitor
sudo systemctl restart ssh-monitor.service

Ограничения

  • Секреты (SAC_API_KEY, Telegram) SAC не прописывает — только в /etc/ssh-monitor.conf на хосте.
  • При недоступном git git pull пишет предупреждение и продолжает с локальной копией.
  • REPO_URL без дефолта в скрипте — только доверенное зеркало (kalinamall / своё Gitea).