diff --git a/README.md b/README.md index 7508ce4..836d4a0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Bash-скрипт мониторинга **SSH**, **SUDO** и событий **` |------|------------| | **`ssh-monitor`** | Основной цикл: разбор журналов (**journalctl**: sshd, sudo, «тяжёлые» события, **systemd-logind**), цепочка уведомлений (Telegram, SMTP через **python3**, резервный webhook), при **`ENABLE_IP_BAN=1`** — учёт неудачных попыток, бан в **ipset** и согласование с **iptables**/**ip6tables**, ежедневный отчёт, heartbeat, опционально **Prometheus** textfile и JSON health. Режимы: **`--check-config`**, **`--dry-run`**. | | **`ssh-monitor-watchdog`** | Отдельный скрипт (обычно по **systemd timer**): проверяет, что сервис монитора активен и файл heartbeat не старше порога; при сбое выполняет **`systemctl restart`** и шлёт уведомление в Telegram или в **`BACKUP_WEBHOOK_URL`**. Читает те же `TELEGRAM_*` / webhook из `/etc/ssh-monitor.conf`. | -| **`update_ssh_monitor.sh`** | Опциональное автообновление: `git pull` / `clone`, сравнение SHA256 с `/usr/local/bin/ssh-monitor`, перезапуск `ssh-monitor.service`. См. [docs/auto-update.ru.md](docs/auto-update.ru.md). | +| **`update_ssh_monitor.sh`** | Опциональное автообновление: `git pull` / `clone`, сравнение SHA256 с `/usr/local/bin/ssh-monitor`, синхронизация **`sac-client.sh`** рядом с монитором, перезапуск `ssh-monitor.service`. См. [docs/auto-update.ru.md](docs/auto-update.ru.md). | **Системные пакеты и зависимости** (что поставить на сервер до запуска): пошагово в [docs/install-prerequisites.ru.md](docs/install-prerequisites.ru.md). @@ -123,7 +123,7 @@ Bash-скрипт мониторинга **SSH**, **SUDO** и событий **` ### Автообновление скрипта -Скрипт **`update_ssh_monitor.sh`** по расписанию (cron или systemd timer) выполняет `git pull` / `clone`, сравнивает SHA256 с `/usr/local/bin/ssh-monitor` и при отличии копирует новую версию и перезапускает **`ssh-monitor.service`**. Конфиг **`/etc/ssh-monitor.conf`** не трогается. +Скрипт **`update_ssh_monitor.sh`** по расписанию (cron или systemd timer) выполняет `git pull` / `clone`, сравнивает SHA256 с `/usr/local/bin/ssh-monitor`, **всегда** подтягивает **`/usr/local/bin/sac-client.sh`** и при изменении любого из файлов перезапускает **`ssh-monitor.service`**. Конфиг **`/etc/ssh-monitor.conf`** не трогается. Пошаговая настройка: [docs/auto-update.ru.md](docs/auto-update.ru.md). diff --git a/docs/auto-update.ru.md b/docs/auto-update.ru.md index b98e80d..ee1714d 100644 --- a/docs/auto-update.ru.md +++ b/docs/auto-update.ru.md @@ -13,20 +13,25 @@ - `$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. При отличии: - - резервная копия `ssh-monitor.backup.YYYYMMDD_HHMMSS`; - - `cp` + `chmod +x`; +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). -7. Пишет лог в **`LOG_FILE`** (по умолчанию `/var/log/update_script.log`). +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{SHA256 различается?} - D -->|да| E[backup + cp] - E --> F[restart ssh-monitor.service] - D -->|нет| G[без изменений] + 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[без изменений] ``` ## Настройка перед первым запуском diff --git a/update_ssh_monitor.sh b/update_ssh_monitor.sh index 6c02382..38f53a8 100644 --- a/update_ssh_monitor.sh +++ b/update_ssh_monitor.sh @@ -195,6 +195,78 @@ ensure_directories() { return 0 } +# Путь к sac-client.sh в клоне репозитория (корень git) +find_sac_client_remote() { + local candidates=( + "$UPDATE_DIR/$SCRIPT_NAME/sac-client.sh" + ) + local p + for p in "${candidates[@]}"; do + if [ -f "$p" ]; then + printf '%s\n' "$p" + return 0 + fi + done + return 1 +} + +# Копирует sac-client.sh рядом с LOCAL_SCRIPT_PATH (всегда после git pull, по checksum). +# Устанавливает SAC_CLIENT_CHANGED=1 при фактическом обновлении файла. +sync_sac_client() { + SAC_CLIENT_CHANGED=0 + local remote local_dst local_sum remote_sum + remote=$(find_sac_client_remote) || { + log_message "INFO" "WARNING: sac-client.sh not found in repository clone" + debug_step "sac-client.sh не найден в клоне репозитория" + return 0 + } + + local_dst="${LOCAL_SCRIPT_PATH%/*}/sac-client.sh" + remote_sum=$(sha256sum "$remote" 2>/dev/null | awk '{print $1}') + if [ -z "$remote_sum" ]; then + log_message "INFO" "ERROR: Failed to checksum remote sac-client.sh" + return 1 + fi + + if [ -f "$local_dst" ]; then + local_sum=$(sha256sum "$local_dst" 2>/dev/null | awk '{print $1}') + if [ "$local_sum" = "$remote_sum" ]; then + log_message "INFO" "sac-client.sh checksums match. No update needed." + debug_step "sac-client.sh без изменений" + return 0 + fi + else + log_message "INFO" "Local sac-client.sh not found. Will install." + debug_step "Локальный sac-client.sh отсутствует, будет установлен" + fi + + debug_step "Копируем sac-client.sh в $local_dst" + if ! cp "$remote" "$local_dst"; then + log_message "INFO" "ERROR: Failed to copy sac-client.sh" + return 1 + fi + chmod 644 "$local_dst" + SAC_CLIENT_CHANGED=1 + log_message "INFO" "sac-client.sh updated." + return 0 +} + +restart_ssh_monitor_service() { + debug_step "Перезапускаем сервис ssh-monitor.service" + if command -v systemctl &>/dev/null; then + if systemctl restart ssh-monitor.service 2>/dev/null; then + log_message "INFO" "Service restarted successfully." + debug_step "Сервис успешно перезапущен" + else + log_message "INFO" "WARNING: Failed to restart service (may not be running)" + debug_step "ПРЕДУПРЕЖДЕНИЕ: Не удалось перезапустить сервис" + fi + else + log_message "INFO" "systemctl not found, service not restarted" + debug_step "systemctl не найден, сервис не перезапущен" + fi +} + # Функция для обновления скрипта update_script() { log_message "INFO" "Starting script update..." @@ -248,6 +320,14 @@ update_script() { debug_step "Скрипт найден по альтернативному пути" fi + # sac-client.sh — отдельно от ssh-monitor: синхронизируем всегда (нужен для UseSAC/--check-sac) + SAC_CLIENT_CHANGED=0 + if ! sync_sac_client; then + return 1 + fi + + local script_changed=0 + # Проверяем наличие файла скрипта в репозитории if [ -n "$actual_script_path" ] && [ -f "$actual_script_path" ]; then log_message "INFO" "Remote script found. Comparing checksums..." @@ -287,33 +367,9 @@ update_script() { debug_step "Делаем скрипт исполняемым" chmod +x "$LOCAL_SCRIPT_PATH" - # sac-client.sh должен лежать рядом с ssh-monitor (тот же каталог) - SAC_CLIENT_LOCAL="${LOCAL_SCRIPT_PATH%/*}/sac-client.sh" - SAC_CLIENT_REMOTE="$UPDATE_DIR/$SCRIPT_NAME/sac-client.sh" - if [ -f "$SAC_CLIENT_REMOTE" ]; then - debug_step "Копируем sac-client.sh" - cp "$SAC_CLIENT_REMOTE" "$SAC_CLIENT_LOCAL" - chmod 644 "$SAC_CLIENT_LOCAL" - log_message "INFO" "sac-client.sh updated." - fi - + script_changed=1 log_message "INFO" "Script updated successfully." debug_step "Скрипт успешно обновлен" - - # Перезапускаем сервис - debug_step "Перезапускаем сервис ssh-monitor.service" - if command -v systemctl &>/dev/null; then - if systemctl restart ssh-monitor.service 2>/dev/null; then - log_message "INFO" "Service restarted successfully." - debug_step "Сервис успешно перезапущен" - else - log_message "INFO" "WARNING: Failed to restart service (may not be running)" - debug_step "ПРЕДУПРЕЖДЕНИЕ: Не удалось перезапустить сервис" - fi - else - log_message "INFO" "systemctl not found, service not restarted" - debug_step "systemctl не найден, сервис не перезапущен" - fi else log_message "INFO" "Checksums match. No update needed." debug_step "Контрольные суммы совпадают, обновление не требуется" @@ -333,6 +389,10 @@ update_script() { fi fi + if [ "$script_changed" -eq 1 ] || [ "${SAC_CLIENT_CHANGED:-0}" -eq 1 ]; then + restart_ssh_monitor_service + fi + # Логируем значения переменных скрипта при DEBUG=1 log_script_vars