Страница 1 из 1

Dovecot Postfix SASL Report Auth attempts

Добавлено: 05 сен 2026, 16:57
Padonak
скрипт, который анализирует логи Dovecot, Postfix и выводит статистику неудачных попыток входа за последний день и отправляет отчёт на почту.

установка:

Код: Выделить всё

 vim /usr/local/bin/dovecot_failed_auth.sh

Код: Выделить всё

#!/bin/bash

# ============================================================
# Скрипт для анализа неудачных попыток входа с геолокацией
# ============================================================

EMAIL_TO="admin@padonak.su"
HOSTNAME=$(hostname -f)

DOVECOT_LOG="/var/log/dovecot/dovecot_info.log"
POSTFIX_LOG="/var/log/mail.log"

REPORT_FILE=$(mktemp)

# Функция для получения геолокации по IP
get_geo() {
    local ip=$1
    # Локальные IP
    if [[ "$ip" == 127.0.0.1 || "$ip" == ::1 || "$ip" == 192.168.* || "$ip" == 10.* || "$ip" == 172.16.* || "$ip" == 93.95.101.238 ]]; then
        echo "Локальный"
        return
    fi
    # Пробуем через ip-api.com
    local geo=$(curl -s "http://ip-api.com/line/$ip?fields=country,city,isp" 2>/dev/null)
    if [ -n "$geo" ]; then
        country=$(echo "$geo" | sed -n '1p')
        city=$(echo "$geo" | sed -n '2p')
        isp=$(echo "$geo" | sed -n '3p')
        echo "${country:-Неизв}, ${city:-Неизв}"
    else
        echo "Неизвестно"
    fi
}

{
    echo "============================================================"
    echo "  📊 ОТЧЁТ ПО НЕУДАЧНЫМ ПОПЫТКАМ ВХОДА"
    echo "  Сервер: $HOSTNAME"
    echo "  Дата: $(date '+%Y-%m-%d %H:%M:%S')"
    echo "============================================================"
    echo ""

    # ============================================================
    # 1. НЕУДАЧНЫЕ ПОПЫТКИ IMAP (Dovecot) С ГЕОЛОКАЦИЕЙ
    # ============================================================
    echo "📧 1. НЕУДАЧНЫЕ ПОПЫТКИ IMAP (Dovecot) — за 24 часа"
    echo "------------------------------------------------------------------------------------------"
    printf "  %-30s %-18s %-25s %5s\n" "USERNAME" "IP ADDRESS" "COUNTRY/CITY" "ATTEMPTS"
    echo "------------------------------------------------------------------------------------------"

    # Собираем данные в массив
    declare -A geo_cache
    tail -5000 "$DOVECOT_LOG" 2>/dev/null | \
    grep -E "auth failed|auth_failed" | \
    awk '
    {
        if (match($0, /user=<([^>]*)>/, u) && match($0, /rip=([0-9\.]*)/, i)) {
            key = u[1] "|" i[1]
            count[key]++
        }
    }
    END {
        for (key in count) {
            split(key, parts, "|")
            printf "%s|%s|%d\n", parts[1], parts[2], count[key]
        }
    }' | sort -t'|' -k3 -n -r | head -20 | \
    while IFS='|' read username ip attempts; do
        # Получаем геолокацию (с кешированием)
        if [ -z "${geo_cache[$ip]}" ]; then
            geo_cache[$ip]=$(get_geo "$ip")
        fi
        geo="${geo_cache[$ip]}"
        printf "  %-30s %-18s %-25s %5d\n" "$username" "$ip" "$geo" "$attempts"
    done

    echo "------------------------------------------------------------------------------------------"
    echo ""

    # ============================================================
    # 2. НЕУДАЧНЫЕ ПОПЫТКИ SASL (Postfix) С ГЕОЛОКАЦИЕЙ
    # ============================================================
    echo "📨 2. НЕУДАЧНЫЕ ПОПЫТКИ SASL (Postfix SMTP) — за 24 часа"
    echo "------------------------------------------------------------------------------------------"
    printf "  %-30s %-18s %-25s %5s\n" "USERNAME" "IP ADDRESS" "COUNTRY/CITY" "ATTEMPTS"
    echo "------------------------------------------------------------------------------------------"

    # Очищаем кеш для SASL
    unset geo_cache
    declare -A geo_cache
    tail -50000 "$POSTFIX_LOG" 2>/dev/null | \
    grep "SASL PLAIN authentication failed" | \
    awk '
    {
        if (match($0, /sasl_username=([^,]*)/, u)) {
            username = u[1]
            if (match($0, /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/, ip)) {
                key = username "|" ip[0]
                count[key]++
            }
        }
    }
    END {
        for (key in count) {
            split(key, parts, "|")
            printf "%s|%s|%d\n", parts[1], parts[2], count[key]
        }
    }' | sort -t'|' -k3 -n -r | head -20 | \
    while IFS='|' read username ip attempts; do
        # Получаем геолокацию (с кешированием)
        if [ -z "${geo_cache[$ip]}" ]; then
            geo_cache[$ip]=$(get_geo "$ip")
        fi
        geo="${geo_cache[$ip]}"
        printf "  %-30s %-18s %-25s %5d\n" "$username" "$ip" "$geo" "$attempts"
    done

    echo "------------------------------------------------------------------------------------------"
    echo ""

    # ============================================================
    # 3. ГЕОЛОКАЦИЯ АТАКУЮЩИХ IP (топ-10)
    # ============================================================
    echo "🌍 3. ГЕОЛОКАЦИЯ АТАКУЮЩИХ IP (топ-10)"
    echo "------------------------------------------------------------"
    echo "  IP ADDRESS          COUNTRY/CITY               ATTEMPTS"
    echo "------------------------------------------------------------"

    tail -50000 "$POSTFIX_LOG" 2>/dev/null | \
    grep "SASL PLAIN authentication failed" | \
    grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | \
    sort | uniq -c | sort -rn | head -10 | \
    while read count ip; do
        geo=$(get_geo "$ip")
        printf "  %-18s %-25s %5d\n" "$ip" "$geo" "$count"
    done

    echo "------------------------------------------------------------"
    echo ""

    # ============================================================
    # 4. ОБЩАЯ СТАТИСТИКА
    # ============================================================
    echo "📊 4. ОБЩАЯ СТАТИСТИКА"
    echo "------------------------------------------------------------"

    IMAP_TOTAL=$(tail -5000 "$DOVECOT_LOG" 2>/dev/null | grep -E "auth failed|auth_failed" | wc -l)
    SASL_TOTAL=$(tail -50000 "$POSTFIX_LOG" 2>/dev/null | grep "SASL PLAIN authentication failed" | wc -l)
    UNIQ_IMAP_USERS=$(tail -5000 "$DOVECOT_LOG" 2>/dev/null | grep -E "auth failed|auth_failed" | sed -n 's/.*user=<\([^>]*\)>.*/\1/p' | sort -u | wc -l)
    UNIQ_SASL_USERS=$(tail -50000 "$POSTFIX_LOG" 2>/dev/null | grep "SASL PLAIN authentication failed" | sed -n 's/.*sasl_username=\([^,]*\).*/\1/p' | sort -u | wc -l)

    echo "  📧 IMAP: $IMAP_TOTAL попыток, $UNIQ_IMAP_USERS уникальных пользователей"
    echo "  📨 SASL: $SASL_TOTAL попыток, $UNIQ_SASL_USERS уникальных пользователей"
    echo "------------------------------------------------------------"
    echo ""

    echo "============================================================"
    echo "Отчёт сгенерирован: $(date '+%Y-%m-%d %H:%M:%S')"
    echo "============================================================"
} > "$REPORT_FILE"

mail -s "[Dovecot/Postfix Report] Auth attempts on $HOSTNAME" "$EMAIL_TO" < "$REPORT_FILE"

rm -f "$REPORT_FILE"
echo "✅ Отчёт отправлен на $EMAIL_TO"

Код: Выделить всё

chmod +x /usr/local/bin/dovecot_failed_auth.sh
добавление в cron

Код: Выделить всё

sudo crontab -e

Код: Выделить всё

0 8 * * * /usr/local/bin/dovecot_failed_auth.sh
часть из письма :

Код: Выделить всё

 3. ГЕОЛОКАЦИЯ АТАКУЮЩИХ IP (топ-10)
------------------------------------------------------------
  IP ADDRESS          COUNTRY/CITY               ATTEMPTS
------------------------------------------------------------
  210.0.90.82        Australia, Forest Lodge      10
  222.117.0.253      South Korea, Anyang-si        8
  210.0.90.81        Australia, Forest Lodge       6
  111.0.81.84        China, Hangzhou               5
  45.178.227.0       Brazil, Paquetá              4
  131.0.190.152      Brazil, Santa Luzia           4
  49.0.82.4          Thailand, Bangkok             3
  31.173.0.140       Russia, Moscow                3
  201.46.124.0       Colombia, Bogotá             3
  180.111.0.21       China, Nanjing                3
------------------------------------------------------------

📊 4. ОБЩАЯ СТАТИСТИКА
------------------------------------------------------------
  📧 IMAP: 5 попыток, 3 уникальных пользователей
  📨 SASL: 1161 попыток, 116 уникальных пользователей
------------------------------------------------------------

============================================================
Отчёт сгенерирован: 2026-09-05 16:56:09
============================================================