fix(notify): отправка во все каналы NOTIFY_ORDER, не только первый успех
- BACKUP_WEBHOOK только если все каналы неуспешны - README/conf.example; версия 0.9.5.3 Made-with: Cursor
This commit is contained in:
@@ -14,14 +14,14 @@ Bash-скрипт мониторинга **SSH**, **SUDO** и событий **`
|
||||
- для **Telegram**: `TELEGRAM_BOT_TOKEN` и `TELEGRAM_CHAT_ID`;
|
||||
- или настройте **Zabbix** / **почту** по переменным ниже при `NOTIFY_ORDER=""` (автовыбор каналов).
|
||||
|
||||
**Обязательное условие:** после загрузки конфигурации в цепочке **`NOTIFY_CHAIN`** должен быть **минимум один** канал (`telegram`, `zabbix` или `email`). Если каналов **нет** (пустой `NOTIFY_ORDER` и ни Telegram, ни Zabbix, ни SMTP не удовлетворяют критериям «настроен», либо в `NOTIFY_ORDER` остались только неизвестные имена), скрипт **не входит** в основной цикл и завершается с кодом **1**, в stderr: **`Не настроен ни один канал отправки оповещений`**. Это же правило действует для **`--check-config`** и **`--dry-run`**. Резервный **`BACKUP_WEBHOOK_URL`** в эту проверку **не входит** — он используется только когда основные каналы уже есть, но доставка через них не удалась.
|
||||
**Обязательное условие:** после загрузки конфигурации в цепочке **`NOTIFY_CHAIN`** должен быть **минимум один** канал (`telegram`, `zabbix` или `email`). Если каналов **нет** (пустой `NOTIFY_ORDER` и ни Telegram, ни Zabbix, ни SMTP не удовлетворяют критериям «настроен», либо в `NOTIFY_ORDER` остались только неизвестные имена), скрипт **не входит** в основной цикл и завершается с кодом **1**, в stderr: **`Не настроен ни один канал отправки оповещений`**. Это же правило действует для **`--check-config`** и **`--dry-run`**. Резервный **`BACKUP_WEBHOOK_URL`** в эту проверку **не входит** — он используется только если **ни один** канал из **`NOTIFY_CHAIN`** не смог доставить сообщение.
|
||||
|
||||
Поддерживаемые параметры:
|
||||
|
||||
- `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`
|
||||
- `NOTIFY_ORDER` — явная очередь каналов оповещений (`telegram`, `zabbix`, `email` и сокращения); пусто = в цепочку попадают только настроенные каналы (порядок по умолчанию см. в `ssh-monitor.conf.example`). Если итоговая цепочка пуста — скрипт не стартует (см. раздел **«Каналы оповещений и пустой NOTIFY_CHAIN»**).
|
||||
- `NOTIFY_ORDER` — список каналов (`telegram`, `zabbix`, `email` и сокращения **tg**, **zbx**, **mail**); при каждом оповещении скрипт **пытается отправить во все перечисленные** каналы по порядку (не «первый успешный — и стоп»). Пусто = в цепочку попадают только настроенные каналы (порядок по умолчанию см. в `ssh-monitor.conf.example`). Если итоговая цепочка пуста — скрипт не стартует (см. раздел **«Каналы оповещений и пустой NOTIFY_CHAIN»**).
|
||||
- `ZABBIX_SERVER`, `ZABBIX_HOST_NAME`, `ZABBIX_ALERT_KEY`, `ZABBIX_SEQ_KEY` — отправка в Zabbix через `zabbix_sender`; подробнее — раздел **«Zabbix (`zabbix_sender`)»** ниже
|
||||
- `BACKUP_WEBHOOK_URL` — резервная доставка JSON `{"text":"..."}` (например Slack Incoming Webhook), если каналы из **`NOTIFY_CHAIN`** недоступны или вернули ошибку; **не заменяет** обязательность хотя бы одного основного канала (см. шаг 3)
|
||||
- `BACKUP_WEBHOOK_URL` — резервная доставка JSON `{"text":"..."}` (например Slack Incoming Webhook), если **все** каналы из **`NOTIFY_CHAIN`** не смогли доставить сообщение; **не заменяет** обязательность хотя бы одного основного канала (см. шаг 3)
|
||||
- `LOG_FILE`, `LAST_HEARTBEAT_FILE`, `LAST_REPORT_FILE`, `LAST_SSH_CHECK_FILE`, `LAST_SUDO_CHECK_FILE`, `LAST_SECURITY_EVENTS_FILE`, `LAST_LOGIND_CHECK_FILE`, `BAN_LIST_FILE`
|
||||
- `ENABLE_LOGIND_MONITOR`, `LOGIND_NOTIFY_NEW`, `LOGIND_NOTIFY_REMOVED`, `LOGIND_NOTIFY_FAILED`, `LOGIND_SKIP_REMOTE` — см. раздел «Мониторинг systemd-logind» ниже
|
||||
- `DAILY_REPORT_HOUR` (0..23), `DAILY_REPORT_TZ` (опционально), `NOTIFY_TZ` (опционально), `SSH_ACCEPT_NOTIFY_DEDUP_SEC`, `DAILY_REPORT_TOP_IPS`
|
||||
@@ -38,7 +38,7 @@ Bash-скрипт мониторинга **SSH**, **SUDO** и событий **`
|
||||
|
||||
- `TELEGRAM_BOT_TOKEN` — токен Telegram-бота для отправки уведомлений.
|
||||
- `TELEGRAM_CHAT_ID` — ID чата/пользователя, куда отправляются уведомления.
|
||||
- `NOTIFY_ORDER` — CSV имён каналов (`telegram`, `zabbix`, `email` или `tg`, `zbx`, `mail`). Пустая строка: автоматически собирается цепочка только из реально настроенных каналов (по умолчанию порядок telegram → zabbix → email; критерии «настроен» — **таблица** в разделе **«Каналы оповещений и пустой NOTIFY_CHAIN»**). Если после сборки цепочки **нет ни одного** канала, скрипт **сразу завершается** с ошибкой: **«Не настроен ни один канал отправки оповещений»** (в том числе режим `--check-config` и `--dry-run`).
|
||||
- `NOTIFY_ORDER` — CSV имён каналов (`telegram`, `zabbix`, `email` или `tg`, `zbx`, `mail`). Для **каждого** оповещения выполняется попытка доставки **во все** перечисленные каналы (при ошибке одного остальные всё равно пробуются; неудачи пишутся в **`LOG_FILE`**). Пустая строка: автоматически собирается цепочка только из реально настроенных каналов (по умолчанию порядок telegram → zabbix → email; критерии «настроен» — **таблица** в разделе **«Каналы оповещений и пустой NOTIFY_CHAIN»**). Если после сборки цепочки **нет ни одного** канала, скрипт **сразу завершается** с ошибкой: **«Не настроен ни один канал отправки оповещений»** (в том числе режим `--check-config` и `--dry-run`).
|
||||
- `ZABBIX_SERVER` — имя или IP сервера Zabbix для `zabbix_sender -z` (пусто = канал Zabbix отключён).
|
||||
- `ZABBIX_HOST_NAME` — имя **хоста в Zabbix**, как в конфигурации агента/шаблона (`-s` у `zabbix_sender`); должно совпадать с тем, для какого хоста созданы trapper-элементы.
|
||||
- `ZABBIX_ALERT_KEY` — ключ **первого** trapper-элемента: в него уходит **текст** оповещения (одна строка, переводы строк заменены пробелами).
|
||||
|
||||
+22
-11
@@ -7,7 +7,7 @@ IFS=$'\n\t'
|
||||
# ============================================
|
||||
|
||||
CONFIG_FILE="/etc/ssh-monitor.conf"
|
||||
SSH_MONITOR_VERSION="0.9.5.2"
|
||||
SSH_MONITOR_VERSION="0.9.5.3"
|
||||
|
||||
TELEGRAM_BOT_TOKEN=""
|
||||
TELEGRAM_CHAT_ID=""
|
||||
@@ -291,7 +291,7 @@ is_email_configured() {
|
||||
}
|
||||
|
||||
# Заполняет NOTIFY_CHAIN: при пустом NOTIFY_ORDER — только реально настроенные каналы (telegram → zabbix → email).
|
||||
# При непустом NOTIFY_ORDER — ровно указанная очередь (имена каналов), без добавления «лишних».
|
||||
# При непустом NOTIFY_ORDER — ровно указанный список (имена каналов), без добавления «лишних»; notify_send шлёт во ВСЕ каналы из списка.
|
||||
refresh_notify_chain() {
|
||||
NOTIFY_CHAIN=()
|
||||
local order_raw
|
||||
@@ -470,7 +470,7 @@ write_log() {
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# УВЕДОМЛЕНИЯ: telegram / zabbix / email (каскад по NOTIFY_CHAIN)
|
||||
# УВЕДОМЛЕНИЯ: telegram / zabbix / email — по NOTIFY_CHAIN во все перечисленные каналы; BACKUP_WEBHOOK только если все неуспешны.
|
||||
# ============================================
|
||||
|
||||
send_email_raw() {
|
||||
@@ -638,33 +638,44 @@ notify_send() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
local any_ok=0
|
||||
local ch
|
||||
for ch in "${NOTIFY_CHAIN[@]}"; do
|
||||
case "$ch" in
|
||||
telegram)
|
||||
if send_telegram_raw "$message"; then
|
||||
return 0
|
||||
any_ok=1
|
||||
else
|
||||
write_log "WARN: канал telegram: не удалось отправить уведомление"
|
||||
fi
|
||||
;;
|
||||
zabbix)
|
||||
if send_zabbix_trapper "$message"; then
|
||||
return 0
|
||||
any_ok=1
|
||||
else
|
||||
write_log "WARN: канал zabbix: не удалось отправить (zabbix_sender, сеть, имя хоста/ключи в Zabbix)"
|
||||
fi
|
||||
;;
|
||||
email)
|
||||
if send_email_raw "$message"; then
|
||||
return 0
|
||||
any_ok=1
|
||||
else
|
||||
write_log "WARN: канал email: не удалось отправить уведомление"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if send_backup_webhook_raw "$message"; then
|
||||
write_log "WARN: основные каналы недоступны, сообщение ушло в BACKUP_WEBHOOK_URL"
|
||||
if [ "$any_ok" -eq 1 ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
write_log "WARN: не удалось доставить уведомление (каналы: $(notify_chain_human); BACKUP_WEBHOOK не задан или недоступен)"
|
||||
if send_backup_webhook_raw "$message"; then
|
||||
write_log "WARN: все каналы из NOTIFY_CHAIN недоступны, сообщение ушло в BACKUP_WEBHOOK_URL"
|
||||
return 0
|
||||
fi
|
||||
|
||||
write_log "WARN: не удалось доставить уведомление ни в один канал ($(notify_chain_human); BACKUP_WEBHOOK не задан или недоступен)"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -1620,7 +1631,7 @@ send_startup_notification() {
|
||||
message="${message}🚫 Автоблокировка IP после ${MAX_ATTEMPTS} попыток на ${BAN_TIME} секунд"$'\n'
|
||||
message="${message}⚪ Белый список: ${whitelist_count} IP/подсетей"$'\n'
|
||||
message="${message}❤️ Heartbeat будет отправляться каждые 12 часов"$'\n'
|
||||
message="${message}📢 Каналы уведомлений (каскад): $(notify_chain_human)"
|
||||
message="${message}📢 Каналы уведомлений (все по списку): $(notify_chain_human)"
|
||||
|
||||
notify_send "$message"
|
||||
write_log "Скрипт мониторинга запущен (белый список: $whitelist_count записей)"
|
||||
@@ -1678,7 +1689,7 @@ run_check_config() {
|
||||
printf 'Проверка конфигурации ssh-monitor\n'
|
||||
printf 'SSH_MONITOR_VERSION=%s\n' "${SSH_MONITOR_VERSION:-}"
|
||||
printf 'CONFIG_FILE=%s\n' "$CONFIG_FILE"
|
||||
printf 'NOTIFY_ORDER=%s (пусто = авто: только настроенные, порядок telegram,zabbix,email)\n' "${NOTIFY_ORDER:-}"
|
||||
printf 'NOTIFY_ORDER=%s (пусто = авто: только настроенные; при событии — отправка во все каналы списка)\n' "${NOTIFY_ORDER:-}"
|
||||
printf 'NOTIFY_CHAIN (эффективная очередь)=%s\n' "$(notify_chain_human)"
|
||||
printf 'TELEGRAM: %s\n' "$([ -n "$TELEGRAM_BOT_TOKEN" ] && echo настроен || echo НЕ настроен)"
|
||||
printf 'BACKUP_WEBHOOK_URL: %s\n' "$([ -n "${BACKUP_WEBHOOK_URL:-}" ] && echo настроен || echo не задан)"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
TELEGRAM_BOT_TOKEN="replace_with_telegram_bot_token"
|
||||
TELEGRAM_CHAT_ID="replace_with_telegram_chat_id"
|
||||
|
||||
# Резервный webhook, если все каналы из NOTIFY_CHAIN недоступны (JSON {"text":"..."}).
|
||||
# Резервный webhook, если ВСЕ каналы из NOTIFY_CHAIN не смогли доставить сообщение (JSON {"text":"..."}).
|
||||
# ВАЖНО: BACKUP_WEBHOOK_URL НЕ заменяет основной канал — без хотя бы одного из telegram/zabbix/email
|
||||
# скрипт сразу завершится с ошибкой в stderr: «Не настроен ни один канал отправки оповещений» (код 1),
|
||||
# в том числе при --check-config и --dry-run. Сначала настройте Telegram, Zabbix или SMTP ниже.
|
||||
@@ -9,6 +9,8 @@ BACKUP_WEBHOOK_URL=""
|
||||
|
||||
# --- Очередь оповещений (NOTIFY_ORDER) ---
|
||||
# CSV: telegram, zabbix, email (или сокращения tg, zbx, mail).
|
||||
# При каждом событии скрипт ПЫТАЕТСЯ ОТПРАВИТЬ ВО ВСЕ перечисленные каналы по порядку (не только в первый успешный).
|
||||
# Неудача одного канала не отменяет отправку в остальные; подробности — в LOG_FILE (WARN по каналам).
|
||||
#
|
||||
# Пустая строка NOTIFY_ORDER="" = авто: в цепочку NOTIFY_CHAIN попадают ТОЛЬКО реально настроенные каналы,
|
||||
# порядок по умолчанию: telegram → zabbix → email (см. критерии «настроен» в README, раздел про каналы).
|
||||
|
||||
Reference in New Issue
Block a user