Pinned GIT_REF/verify, release manifest, no blind reset --hard; suppress lifecycle and watchdog Telegram during updater; healthcheck via json.dumps.
9.7 KiB
Автообновление ssh-monitor
Скрипт update_ssh_monitor.sh обновляет /usr/local/bin/ssh-monitor из git и перезапускает systemd-сервис.
Основной путь: Security Alert Center
На продакшен-хостах обновление идёт через SAC, без cron:
- Админ нажимает «Обновить ssh-monitor (SSH)» в карточке хоста.
- SAC по SSH запускает
/opt/scripts/update_ssh_monitor.shсREPO_URL/GIT_BRANCHиз Настройки → Обновления агентов. - 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.
Что делает скрипт
- Создаёт рабочий каталог
UPDATE_DIR(по умолчанию/opt/scripts/update). - При
--deploy/ bootstrap SAC проверяетipsetи при отсутствии пытается установить через пакетный менеджер. Обычное обновление не вызываетapt-get. - В
UPDATE_DIRвыполняетgit cloneилиgit fetch+ checkout /git pull --ff-only(без слепогоreset --hard). - Проверяет
release/manifest-VERSION.json(SHA256 файлов + commit) до копирования в/usr/local/bin. - Ищет
ssh-monitorв клоне (GitLab layout или плоский репозиторий). - Сравнивает SHA256 с
LOCAL_SCRIPT_PATH(/usr/local/bin/ssh-monitor). - Всегда синхронизирует
sac-client.sh,ssh-monitor-perms.sh, watchdog. - Дописывает ключи конфига;
apply_runtime_security_hardening:chmod 600конфиг,700spool,600state/SAC-файлы, whitelist. - При изменении
ssh-monitor,sac-client.shили конфига —systemctl restart ssh-monitor.service. - Лог:
/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).