feat: подпись сервера во всех уведомлениях и документация
Добавлены message_ensure_server_line и SERVER_DISPLAY_NAME; версия 1.1.3-server-label. Гайды по уведомлениям и автообновлению.
This commit is contained in:
+54
-27
@@ -7,7 +7,7 @@ IFS=$'\n\t'
|
||||
# ============================================
|
||||
|
||||
CONFIG_FILE="/etc/ssh-monitor.conf"
|
||||
SSH_MONITOR_VERSION="1.1.2-ipset"
|
||||
SSH_MONITOR_VERSION="1.1.3-server-label"
|
||||
|
||||
TELEGRAM_BOT_TOKEN=""
|
||||
TELEGRAM_CHAT_ID=""
|
||||
@@ -38,6 +38,8 @@ DAILY_REPORT_TOP_IPS=5
|
||||
DAILY_REPORT_TZ=""
|
||||
# IANA-зона для строк «🕐 Время» в Telegram/email. Пусто = тогда DAILY_REPORT_TZ, если она задана, иначе зона процесса (часто UTC у systemd — см. README).
|
||||
NOTIFY_TZ=""
|
||||
# Подпись сервера в уведомлениях: пусто = hostname (+ IPv4); иначе фиксированное имя (удобно при одинаковых hostname).
|
||||
SERVER_DISPLAY_NAME=""
|
||||
# Не слать повтор «Accepted» для той же пары user+IP чаще, чем раз в N секунд (разные port в журнале — один вход).
|
||||
SSH_ACCEPT_NOTIFY_DEDUP_SEC=5
|
||||
|
||||
@@ -162,6 +164,7 @@ load_config() {
|
||||
local cfg_daily_report_top_ips="${DAILY_REPORT_TOP_IPS}"
|
||||
local cfg_daily_report_tz="${DAILY_REPORT_TZ}"
|
||||
local cfg_notify_tz="${NOTIFY_TZ:-}"
|
||||
local cfg_server_display_name="${SERVER_DISPLAY_NAME:-}"
|
||||
local cfg_ssh_accept_notify_dedup_sec="${SSH_ACCEPT_NOTIFY_DEDUP_SEC:-5}"
|
||||
local cfg_last_ssh_check_file="${LAST_SSH_CHECK_FILE}"
|
||||
local cfg_last_sudo_check_file="${LAST_SUDO_CHECK_FILE}"
|
||||
@@ -231,6 +234,7 @@ load_config() {
|
||||
DAILY_REPORT_TOP_IPS="${DAILY_REPORT_TOP_IPS:-$cfg_daily_report_top_ips}"
|
||||
DAILY_REPORT_TZ="$(trim_value "${DAILY_REPORT_TZ:-$cfg_daily_report_tz}")"
|
||||
NOTIFY_TZ="$(trim_value "${NOTIFY_TZ:-$cfg_notify_tz}")"
|
||||
SERVER_DISPLAY_NAME="$(trim_value "${SERVER_DISPLAY_NAME:-$cfg_server_display_name}")"
|
||||
SSH_ACCEPT_NOTIFY_DEDUP_SEC="$(trim_value "${SSH_ACCEPT_NOTIFY_DEDUP_SEC:-$cfg_ssh_accept_notify_dedup_sec}")"
|
||||
if ! [[ "${SSH_ACCEPT_NOTIFY_DEDUP_SEC:-5}" =~ ^[0-9]+$ ]]; then
|
||||
SSH_ACCEPT_NOTIFY_DEDUP_SEC=5
|
||||
@@ -477,6 +481,53 @@ write_log() {
|
||||
echo "${timestamp} - ${message}"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Подпись сервера в текстах уведомлений
|
||||
# ============================================
|
||||
|
||||
# Для Telegram и отчётов: «hostname (IPv4)» или SERVER_DISPLAY_NAME (+ IPv4); без IPv4 — только имя.
|
||||
server_display_name_with_ip() {
|
||||
local hn ip
|
||||
if [ -n "${SERVER_DISPLAY_NAME:-}" ]; then
|
||||
hn="${SERVER_DISPLAY_NAME}"
|
||||
else
|
||||
hn=$(hostname 2>/dev/null | tr -d '\r\n')
|
||||
[ -z "$hn" ] && hn="(unknown)"
|
||||
fi
|
||||
ip=""
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
ip=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '/\bsrc\b/ {for (i = 1; i < NF; i++) if ($i == "src") { print $(i + 1); exit }}')
|
||||
[ -z "$ip" ] && ip=$(ip -4 route get 8.8.8.8 2>/dev/null | awk '/\bsrc\b/ {for (i = 1; i < NF; i++) if ($i == "src") { print $(i + 1); exit }}')
|
||||
fi
|
||||
if [ -z "$ip" ] && command -v hostname >/dev/null 2>&1; then
|
||||
if hostname -I >/dev/null 2>&1; then
|
||||
ip=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | grep -Ev '^(127\.|0\.0\.0\.0)$' | head -n1)
|
||||
fi
|
||||
fi
|
||||
if [ -n "$ip" ]; then
|
||||
printf '%s (%s)' "$hn" "$ip"
|
||||
else
|
||||
printf '%s' "$hn"
|
||||
fi
|
||||
}
|
||||
|
||||
# Вставляет «🖥️ Сервер: …» сразу после первой строки (заголовка), если строки ещё нет.
|
||||
message_ensure_server_line() {
|
||||
local msg="$1"
|
||||
if [[ "$msg" == *'🖥️ Сервер:'* ]]; then
|
||||
printf '%s' "$msg"
|
||||
return 0
|
||||
fi
|
||||
local first rest
|
||||
first="${msg%%$'\n'*}"
|
||||
if [ "$first" = "$msg" ]; then
|
||||
printf '%s\n🖥️ Сервер: %s' "$first" "$(server_display_name_with_ip)"
|
||||
else
|
||||
rest="${msg#*$'\n'}"
|
||||
printf '%s\n🖥️ Сервер: %s\n%s' "$first" "$(server_display_name_with_ip)" "$rest"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# УВЕДОМЛЕНИЯ: telegram / email — по NOTIFY_CHAIN во все перечисленные каналы; BACKUP_WEBHOOK только если все неуспешны.
|
||||
# ============================================
|
||||
@@ -603,6 +654,7 @@ PY
|
||||
|
||||
notify_send() {
|
||||
local message="$1"
|
||||
message="$(message_ensure_server_line "$message")"
|
||||
if [ "${DRY_RUN:-0}" = "1" ]; then
|
||||
printf '[DRY-RUN notify] %s\n' "$(printf '%s' "$message" | tr '\n' ' ')" >&2
|
||||
return 0
|
||||
@@ -1501,28 +1553,6 @@ monitor_logind() {
|
||||
echo "$current_time" >"$LAST_LOGIND_CHECK_FILE"
|
||||
}
|
||||
|
||||
# Для Telegram и отчётов: «hostname (IPv4)»; без доступного IPv4 — только hostname.
|
||||
server_display_name_with_ip() {
|
||||
local hn ip
|
||||
hn=$(hostname 2>/dev/null | tr -d '\r\n')
|
||||
[ -z "$hn" ] && hn="(unknown)"
|
||||
ip=""
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
ip=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '/\bsrc\b/ {for (i = 1; i < NF; i++) if ($i == "src") { print $(i + 1); exit }}')
|
||||
[ -z "$ip" ] && ip=$(ip -4 route get 8.8.8.8 2>/dev/null | awk '/\bsrc\b/ {for (i = 1; i < NF; i++) if ($i == "src") { print $(i + 1); exit }}')
|
||||
fi
|
||||
if [ -z "$ip" ] && command -v hostname >/dev/null 2>&1; then
|
||||
if hostname -I >/dev/null 2>&1; then
|
||||
ip=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | grep -Ev '^(127\.|0\.0\.0\.0)$' | head -n1)
|
||||
fi
|
||||
fi
|
||||
if [ -n "$ip" ]; then
|
||||
printf '%s (%s)' "$hn" "$ip"
|
||||
else
|
||||
printf '%s' "$hn"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Ежедневный отчёт
|
||||
# ============================================
|
||||
@@ -1606,7 +1636,6 @@ send_daily_report() {
|
||||
fi
|
||||
|
||||
local message=" 📊 ЕЖЕДНЕВНЫЙ ОТЧЕТ SSH МОНИТОРИНГА "$'\n'
|
||||
message="${message}🖥️ Сервер: $(server_display_name_with_ip)"$'\n'
|
||||
message="${message}🕐 Время отчета: ${current_time}"$'\n'
|
||||
message="${message}"$'\n'
|
||||
message="${message} 📈 СТАТИСТИКА ЗА ПОСЛЕДНИЕ 24 ЧАСА: "$'\n'
|
||||
@@ -1686,7 +1715,6 @@ send_heartbeat() {
|
||||
timestamp_human=$(notification_date '+%d.%m.%Y %H:%M:%S')
|
||||
|
||||
local message=" ❤️ Heartbeat - скрипт мониторинга работает "$'\n'
|
||||
message="${message}🖥️ Сервер: $(server_display_name_with_ip)"$'\n'
|
||||
message="${message}🕐 Время: ${timestamp_human}"
|
||||
|
||||
notify_send "$message"
|
||||
@@ -1745,7 +1773,6 @@ send_startup_notification() {
|
||||
|
||||
local message=" ✅ СКРИПТ МОНИТОРИНГА ЗАПУЩЕН "$'\n'
|
||||
message="${message}📌 Версия: ${SSH_MONITOR_VERSION:-?}"$'\n'
|
||||
message="${message}🖥️ Сервер: $(server_display_name_with_ip)"$'\n'
|
||||
message="${message}🕐 Время запуска: ${timestamp}"$'\n'
|
||||
message="${message}📊 Мониторинг SSH, SUDO и systemd-logind активирован"$'\n'
|
||||
if [ "${ENABLE_IP_BAN:-1}" = "1" ]; then
|
||||
@@ -1768,7 +1795,6 @@ send_shutdown_notification() {
|
||||
local timestamp
|
||||
timestamp=$(notification_date '+%d.%m.%Y %H:%M:%S')
|
||||
local message=" ⚠️ СКРИПТ МОНИТОРИНГА ОСТАНОВЛЕН "$'\n'
|
||||
message="${message}🖥️ Сервер: $(server_display_name_with_ip)"$'\n'
|
||||
message="${message}🕐 Время остановки: ${timestamp}"
|
||||
|
||||
notify_send "$message"
|
||||
@@ -1826,6 +1852,7 @@ run_check_config() {
|
||||
printf 'DAILY_REPORT_HOUR=%s\n' "$DAILY_REPORT_HOUR"
|
||||
printf 'DAILY_REPORT_TZ=%s (пусто = зона процесса/date)\n' "${DAILY_REPORT_TZ:-}"
|
||||
printf 'NOTIFY_TZ=%s (пусто = DAILY_REPORT_TZ или зона процесса; см. README)\n' "${NOTIFY_TZ:-}"
|
||||
printf 'SERVER_DISPLAY_NAME=%s (пусто = hostname; эффективно: %s)\n' "${SERVER_DISPLAY_NAME:-}" "$(server_display_name_with_ip)"
|
||||
printf 'SSH_ACCEPT_NOTIFY_DEDUP_SEC=%s\n' "${SSH_ACCEPT_NOTIFY_DEDUP_SEC:-5}"
|
||||
printf 'DAILY_REPORT_TOP_IPS=%s\n' "$DAILY_REPORT_TOP_IPS"
|
||||
printf 'BRUTE_WINDOW_SEC=%s BRUTE_MIN_FAILS=%s\n' "$BRUTE_WINDOW_SEC" "$BRUTE_MIN_FAILS"
|
||||
|
||||
Reference in New Issue
Block a user