feat: подпись сервера во всех уведомлениях и документация
Добавлены message_ensure_server_line и SERVER_DISPLAY_NAME; версия 1.1.3-server-label. Гайды по уведомлениям и автообновлению.
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
# Автообновление ssh-monitor
|
||||
|
||||
Скрипт **`update_ssh_monitor.sh`** в корне репозитория обновляет установленный **`/usr/local/bin/ssh-monitor`** из git-репозитория и перезапускает systemd-сервис. Конфиг **`/etc/ssh-monitor.conf`**, watchdog и таймеры **не изменяются**.
|
||||
|
||||
Установка самого монитора и 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. При отличии:
|
||||
- резервная копия `ssh-monitor.backup.YYYYMMDD_HHMMSS`;
|
||||
- `cp` + `chmod +x`;
|
||||
- **`systemctl restart ssh-monitor.service`** (если есть systemctl).
|
||||
7. Пишет лог в **`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[без изменений]
|
||||
```
|
||||
|
||||
## Настройка перед первым запуском
|
||||
|
||||
Отредактируйте переменные в начале **`update_ssh_monitor.sh`**:
|
||||
|
||||
| Переменная | По умолчанию | Назначение |
|
||||
|------------|--------------|------------|
|
||||
| `UPDATE_DIR` | `/opt/scripts/update` | Каталог для git-клона |
|
||||
| `REPO_URL` | `https://GIT/user/ssh-monitor.git` | **Замените** на ваш реальный URL |
|
||||
| `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` в файле.
|
||||
|
||||
## Установка
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Ограничения
|
||||
|
||||
- Обновляется **только** файл **`ssh-monitor`**, не конфиг и не watchdog.
|
||||
- При недоступном git **`git pull`** пишет предупреждение и продолжает с локальной копией.
|
||||
- Placeholder **`REPO_URL`** в репозитории нужно заменить на боевой URL до использования в продакшене.
|
||||
@@ -145,3 +145,8 @@ sudo journalctl -u ssh-monitor-watchdog.service -f
|
||||
- [ ] (По желанию) настроено сохранение правил после перезагрузки.
|
||||
|
||||
Далее: установка самого **`ssh-monitor`**, unit **systemd** и проверка — в [README.md](../README.md).
|
||||
|
||||
Дополнительно:
|
||||
|
||||
- [notifications.ru.md](notifications.ru.md) — подпись **«🖥️ Сервер»** в уведомлениях, типы алертов, часовые пояса.
|
||||
- [auto-update.ru.md](auto-update.ru.md) — автообновление скрипта через **`update_ssh_monitor.sh`**.
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# Уведомления ssh-monitor
|
||||
|
||||
Документ описывает, **какие сообщения** отправляет монитор, **какие поля** в них есть и как настроить **подпись сервера** и **часовой пояс**.
|
||||
|
||||
См. также: [README.md](../README.md), пример конфига [ssh-monitor.conf.example](../ssh-monitor.conf.example).
|
||||
|
||||
## Подпись сервера (🖥️ Сервер)
|
||||
|
||||
Начиная с версии **1.1.3-server-label**, каждое уведомление, проходящее через **`notify_send()`**, получает строку **«🖥️ Сервер: …»** сразу **после первой строки** (заголовка алерта).
|
||||
|
||||
Формат значения:
|
||||
|
||||
| Условие | Пример |
|
||||
|---------|--------|
|
||||
| `SERVER_DISPLAY_NAME` пусто, IPv4 найден | `web01 (10.1.20.5)` |
|
||||
| `SERVER_DISPLAY_NAME` пусто, IPv4 нет | `web01` |
|
||||
| Задан `SERVER_DISPLAY_NAME="prod-db-01"` | `prod-db-01 (10.1.20.5)` |
|
||||
|
||||
IPv4 определяется через `ip -4 route get` (исходящий адрес) или `hostname -I`. Нужны утилиты **`hostname`** и **`ip`** — см. [install-prerequisites.ru.md](install-prerequisites.ru.md).
|
||||
|
||||
Если в тексте сообщения уже есть подстрока **`🖥️ Сервер:`**, вторая строка **не добавляется** (защита от дубля при ручной вставке).
|
||||
|
||||
### Пример: успешный SSH
|
||||
|
||||
```
|
||||
✅ УСПЕШНОЕ SSH ПОДКЛЮЧЕНИЕ
|
||||
🖥️ Сервер: myhost (10.1.20.5)
|
||||
👤 Пользователь: alice
|
||||
🌐 IP адрес: 10.1.20.1
|
||||
🕐 Время: 25.05.2026 09:08:22
|
||||
```
|
||||
|
||||
### Пример: sudo
|
||||
|
||||
```
|
||||
⚠️ ИСПОЛЬЗОВАНИЕ SUDO
|
||||
🖥️ Сервер: myhost (10.1.20.5)
|
||||
👤 Пользователь: alice
|
||||
🔑 От имени USER: root
|
||||
💻 Команда: /bin/bash
|
||||
📁 Директория: /home/alice
|
||||
🕐 Время: 24.05.2026 16:54:49
|
||||
```
|
||||
|
||||
## Настройка в `/etc/ssh-monitor.conf`
|
||||
|
||||
```bash
|
||||
# Пусто = hostname (+ IPv4 при возможности)
|
||||
SERVER_DISPLAY_NAME=""
|
||||
|
||||
# Или фиксированное имя для этого хоста в общем чате:
|
||||
# SERVER_DISPLAY_NAME="dc1-app-03"
|
||||
```
|
||||
|
||||
Проверка эффективной подписи:
|
||||
|
||||
```bash
|
||||
sudo ssh-monitor --check-config
|
||||
```
|
||||
|
||||
В выводе будет строка `SERVER_DISPLAY_NAME=... (эффективно: ...)`.
|
||||
|
||||
## Типы уведомлений
|
||||
|
||||
| Событие | Заголовок (первая строка) | Доп. поля |
|
||||
|---------|----------------------------|-----------|
|
||||
| Успешный SSH | ✅ УСПЕШНОЕ SSH ПОДКЛЮЧЕНИЕ | пользователь, IP клиента, время |
|
||||
| SSH под root | 🔑 SSH ВХОД ПОД ROOT | IP, время |
|
||||
| Неудачная попытка SSH | ❌ НЕУДАЧНАЯ ПОПЫТКА SSH | пользователь, IP, счётчик попыток, время |
|
||||
| Sudo | ⚠️ ИСПОЛЬЗОВАНИЕ SUDO | пользователь, USER=, команда, PWD, время |
|
||||
| Бан IP | 🚫 IP ЗАБЛОКИРОВАН АВТОМАТИЧЕСКИ | IP, попытки, длительность, время |
|
||||
| Порог без бана | ⚠️ ЛИМИТ НЕУДАЧНЫХ SSH (автобан отключён…) | IP, попытки, время |
|
||||
| Брутфорс | 🧨 ВОЗМОЖНЫЙ МАССОВЫЙ БРУТФОРС SSH | IP, счётчик за окно, время |
|
||||
| Host key / MITM | 🔐 ВНИМАНИЕ: изменение SSH host key… | фрагмент журнала, время |
|
||||
| logind: новая сессия | 🖥️ НОВАЯ СЕССИЯ (systemd-logind) | пользователь, ID сессии, время |
|
||||
| logind: сбой | ❌ СБОЙ (systemd-logind) | строка журнала, время |
|
||||
| Ежедневный отчёт | 📊 ЕЖЕДНЕВНЫЙ ОТЧЕТ SSH МОНИТОРИНГА | статистика 24 ч, баны, топ IP, сессии |
|
||||
| Heartbeat | ❤️ Heartbeat - скрипт мониторинга работает | время |
|
||||
| Старт / стоп | ✅ СКРИПТ МОНИТОРИНГА ЗАПУЩЕН / ⚠️ ОСТАНОВЛЕН | версия, каналы, время |
|
||||
|
||||
Во всех перечисленных случаях **🖥️ Сервер** добавляется автоматически (кроме сообщений, где вы сами вставили эту строку).
|
||||
|
||||
## Время в сообщениях (🕐)
|
||||
|
||||
Строки **«🕐 Время»** формируются функцией **`notification_date()`**:
|
||||
|
||||
1. Если задан **`NOTIFY_TZ`** (IANA, например `Europe/Moscow`) — используется он.
|
||||
2. Иначе, если задан **`DAILY_REPORT_TZ`** — он.
|
||||
3. Иначе — зона процесса (`date` у systemd-сервиса; часто UTC, если в unit указано `Environment=TZ=UTC`).
|
||||
|
||||
Ежедневный отчёт по календарю и часу **`DAILY_REPORT_HOUR`** использует **`DAILY_REPORT_TZ`** (или зону процесса) — см. README.
|
||||
|
||||
## Каналы доставки
|
||||
|
||||
- **`NOTIFY_CHAIN`**: `telegram`, `email` — при каждом событии попытка **во все** каналы списка.
|
||||
- **`BACKUP_WEBHOOK_URL`**: только если **все** каналы цепочки не доставили сообщение.
|
||||
|
||||
Режим **`--dry-run`**: уведомления не отправляются; в stderr печатается текст **уже с подписью сервера**.
|
||||
Reference in New Issue
Block a user