feat: release 2.1.8-SAC — security phase 1 and SAC-first update hardening
Updater applies chmod/chown on config, spool and state paths on every run. SAC is the primary update path; optional cron uses the same behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+113
-174
@@ -1,174 +1,113 @@
|
||||
# Автообновление ssh-monitor
|
||||
|
||||
Скрипт **`update_ssh_monitor.sh`** в корне репозитория обновляет установленный **`/usr/local/bin/ssh-monitor`** из git-репозитория и перезапускает systemd-сервис. Watchdog и таймеры **не изменяются**.
|
||||
|
||||
**Конфиг `/etc/ssh-monitor.conf`:** при первой установке копируется из `ssh-monitor.conf.example`. При каждом deploy/обновлении в **существующий** конфиг **дописываются** отсутствующие SAC-переменные (`UseSAC`, `SAC_URL`, `SAC_API_KEY`, spool, timeout и т.д.) и выставляется **`UseSAC=fallback`**. Telegram/SMTP и прочие ключи **не перезаписываются**.
|
||||
|
||||
Установка самого монитора и unit-файлов: [README.md](../README.md), зависимости: [install-prerequisites.ru.md](install-prerequisites.ru.md).
|
||||
|
||||
## Что делает скрипт
|
||||
|
||||
1. Создаёт рабочий каталог **`UPDATE_DIR`** (по умолчанию `/opt/scripts/update`).
|
||||
2. Проверяет наличие **`ipset`**; при отсутствии пытается установить через пакетный менеджер (apt, yum, dnf, pacman, zypper). Без ipset скрипт завершается с ошибкой — новая версия монитора с **`ENABLE_IP_BAN=1`** требует ipset.
|
||||
3. В **`UPDATE_DIR`** выполняет **`git clone`** или **`git pull origin main`** репозитория.
|
||||
4. Ищет файл **`ssh-monitor`** в клоне:
|
||||
- `$UPDATE_DIR/ssh-monitor/src/branch/main/ssh-monitor` (структура GitLab);
|
||||
- `$UPDATE_DIR/ssh-monitor/ssh-monitor` (плоский репозиторий, как в этом проекте).
|
||||
5. Сравнивает **SHA256** удалённого файла с **`LOCAL_SCRIPT_PATH`** (по умолчанию `/usr/local/bin/ssh-monitor`).
|
||||
6. **Всегда** (независимо от шага 5) синхронизирует **`sac-client.sh`** в каталог рядом с монитором (по умолчанию **`/usr/local/bin/sac-client.sh`**) — нужен для **`UseSAC`** и **`--check-sac`**.
|
||||
7. При отличии checksum **`ssh-monitor`** и/или **`sac-client.sh`**:
|
||||
- резервная копия `ssh-monitor.backup.YYYYMMDD_HHMMSS` (только для основного скрипта);
|
||||
- `cp` + `chmod +x` для `ssh-monitor`, `chmod 644` для `sac-client.sh`;
|
||||
- **`systemctl restart ssh-monitor.service`** (если есть systemctl).
|
||||
8. Пишет лог в **`LOG_FILE`** (по умолчанию `/var/log/update_script.log`).
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[cron/timer] --> B[update_ssh_monitor.sh]
|
||||
B --> C[git pull/clone]
|
||||
C --> D[sync sac-client.sh]
|
||||
C --> E{SHA256 ssh-monitor?}
|
||||
D --> F{что-то обновилось?}
|
||||
E -->|да| G[backup + cp ssh-monitor]
|
||||
E -->|нет| F
|
||||
G --> F
|
||||
F -->|да| H[restart ssh-monitor.service]
|
||||
F -->|нет| I[без изменений]
|
||||
```
|
||||
|
||||
## Настройка перед первым запуском
|
||||
|
||||
Отредактируйте переменные в начале **`update_ssh_monitor.sh`**:
|
||||
|
||||
| Переменная | По умолчанию | Назначение |
|
||||
|------------|--------------|------------|
|
||||
| `UPDATE_DIR` | `/opt/scripts/update` | Каталог для git-клона |
|
||||
| `REPO_URL` | `https://git.kalinamall.ru/PapaTramp/ssh-monitor.git` | URL репозитория (на закрытом зеркале — URL своего Gitea) |
|
||||
| `LOCAL_SCRIPT_PATH` | `/usr/local/bin/ssh-monitor` | Куда копировать бинарник |
|
||||
| `LOG_FILE` | `/var/log/update_script.log` | Лог обновлений |
|
||||
| `DEBUG` | `0` | `1` — подробный DEBUG в лог |
|
||||
|
||||
Требования на сервере:
|
||||
|
||||
- **root** (или sudo) для `cp`, `systemctl`, установки ipset;
|
||||
- **git** и сетевой доступ к репозиторию (SSH-ключ или HTTPS);
|
||||
- ветка в скрипте жёстко **`main`** — при другой ветке измените `git pull` в файле.
|
||||
|
||||
## Первичная установка (--deploy)
|
||||
|
||||
Один сценарий для нового сервера (клон git, `ssh-monitor`, `sac-client.sh`, пример конфига, systemd unit):
|
||||
|
||||
```bash
|
||||
cd /path/to/ssh-monitor # или curl/clone репозитория
|
||||
sudo ./first_deploy.sh
|
||||
# то же самое:
|
||||
sudo ./update_ssh_monitor.sh --deploy
|
||||
```
|
||||
|
||||
Скрипт выводит в консоль, **куда что скопировано**, и список переменных для **`/etc/ssh-monitor.conf`**. Существующий конфиг **не перезаписывается**.
|
||||
|
||||
После установки отредактируйте конфиг и проверьте:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/ssh-monitor.conf
|
||||
sudo /usr/local/bin/ssh-monitor --check-config
|
||||
sudo /usr/local/bin/ssh-monitor --check-sac
|
||||
sudo systemctl restart ssh-monitor.service
|
||||
```
|
||||
|
||||
## Установка updater (для последующих обновлений)
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
Проверка вручную:
|
||||
|
||||
```bash
|
||||
sudo /opt/scripts/update_ssh_monitor.sh
|
||||
sudo tail -20 /var/log/update_script.log
|
||||
sudo systemctl status ssh-monitor
|
||||
```
|
||||
|
||||
## Запуск по расписанию
|
||||
|
||||
### Cron (пример: каждый день в 04:00)
|
||||
|
||||
```bash
|
||||
sudo crontab -e
|
||||
```
|
||||
|
||||
Добавьте:
|
||||
|
||||
```
|
||||
0 4 * * * /opt/scripts/update_ssh_monitor.sh
|
||||
```
|
||||
|
||||
### systemd timer (альтернатива)
|
||||
|
||||
Создайте `/etc/systemd/system/ssh-monitor-update.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Update ssh-monitor from git
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/scripts/update_ssh_monitor.sh
|
||||
```
|
||||
|
||||
И `/etc/systemd/system/ssh-monitor-update.timer`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Daily ssh-monitor update
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 04:00:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now ssh-monitor-update.timer
|
||||
```
|
||||
|
||||
## Откат после неудачного обновления
|
||||
|
||||
Резервные копии лежат рядом с установленным скриптом:
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
## Лог и диагностика «мгновенного» завершения
|
||||
|
||||
Все шаги пишутся в **`/var/log/update_script.log`**. При обычном запуске те же строки дублируются в stdout (кроме **`--quiet`**).
|
||||
|
||||
В конце каждого прогона — блок **«Итог обновления»**: статус `ssh-monitor` / `sac-client` / git / перезапуск и **причина**, если файлы не копировались (checksum совпал, git pull failed, скрипт не найден в клоне).
|
||||
|
||||
```bash
|
||||
sudo /opt/scripts/update_ssh_monitor.sh
|
||||
sudo tail -40 /var/log/update_script.log
|
||||
```
|
||||
|
||||
**Важно:** после `git pull` в клоне скрипт **сам обновляет** `/opt/scripts/update_ssh_monitor.sh` из репозитория и один раз перезапускает себя (если вызывали именно этот путь). Если в логе старые строки вроде `Checksums match` без блока «Итог обновления» — на сервере ещё старая копия updater; один раз:
|
||||
|
||||
```bash
|
||||
sudo cp /opt/scripts/update/ssh-monitor/update_ssh_monitor.sh /opt/scripts/update_ssh_monitor.sh
|
||||
sudo chmod 750 /opt/scripts/update_ssh_monitor.sh
|
||||
sudo /opt/scripts/update_ssh_monitor.sh
|
||||
```
|
||||
|
||||
## Ограничения
|
||||
|
||||
- Обновляется **только** файл **`ssh-monitor`**, не конфиг и не watchdog.
|
||||
- При недоступном git **`git pull`** пишет предупреждение и продолжает с локальной копией.
|
||||
- На **закрытом зеркале** в `update_ssh_monitor.sh` задайте **`REPO_URL`** своего Gitea; в публичном GitHub по умолчанию — `git.kalinamall.ru/PapaTramp/ssh-monitor`.
|
||||
# Автообновление 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](../README.md), зависимости: [install-prerequisites.ru.md](install-prerequisites.ru.md).
|
||||
|
||||
|
||||
|
||||
## Что делает скрипт
|
||||
|
||||
|
||||
|
||||
1. Создаёт рабочий каталог **`UPDATE_DIR`** (по умолчанию `/opt/scripts/update`).
|
||||
|
||||
2. При **`--deploy`** / bootstrap SAC проверяет **`ipset`** и при отсутствии пытается установить через пакетный менеджер. Обычное обновление **не** вызывает `apt-get`.
|
||||
|
||||
3. В **`UPDATE_DIR`** выполняет **`git clone`** или **`git pull`** репозитория.
|
||||
|
||||
4. Ищет **`ssh-monitor`** в клоне (GitLab layout или плоский репозиторий).
|
||||
|
||||
5. Сравнивает **SHA256** с **`LOCAL_SCRIPT_PATH`** (`/usr/local/bin/ssh-monitor`).
|
||||
|
||||
6. **Всегда** синхронизирует **`sac-client.sh`**, **`ssh-monitor-perms.sh`**, watchdog.
|
||||
|
||||
7. Дописывает ключи конфига; **`apply_runtime_security_hardening`**: `chmod 600` конфиг, `700` spool, `600` state/SAC-файлы, whitelist.
|
||||
|
||||
8. При изменении **`ssh-monitor`**, **`sac-client.sh`** или конфига — **`systemctl restart ssh-monitor.service`**.
|
||||
|
||||
9. Лог: **`/var/log/update_script.log`** (блок «Итог обновления», строка `security hardening`).
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
flowchart LR
|
||||
|
||||
A[SAC или cron] --> B[update_ssh_monitor.sh]
|
||||
|
||||
B --> C[git pull/clone]
|
||||
|
||||
C --> 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 |
|
||||
|
||||
Reference in New Issue
Block a user