#!/bin/bash
# 自动分析 SSH 登录失败日志并封禁恶意 /24 段

# 1. 判断日志文件
if [ -f /var/log/secure ]; then
    LOGFILE="/var/log/secure"
elif [ -f /var/log/auth.log ]; then
    LOGFILE="/var/log/auth.log"
else
    echo "未找到 /var/log/secure 或 /var/log/auth.log"
    exit 1
fi

echo "使用日志文件: $LOGFILE"

# 2. 提取失败 IP
FAILED_IPS=$(grep "Failed password" $LOGFILE | awk '{print $(NF-3)}' | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}')

if [ -z "$FAILED_IPS" ]; then
    echo "未发现失败登录记录"
    exit 0
fi

# 3. 转换成 /24 段并统计
SUBNETS=$(echo "$FAILED_IPS" | awk -F. '{print $1"."$2"."$3".0/24"}' | sort | uniq -c | sort -nr)

# 4. 过滤次数 > 10
BAD_SUBNETS=$(echo "$SUBNETS" | awk '$1>10 {print $1,$2}')

if [ -z "$BAD_SUBNETS" ]; then
    echo "没有出现超过 10 次失败登录的 /24 段"
    exit 0
fi

echo "以下网段出现超过 10 次失败登录："
echo
i=1
declare -A SUBNET_MAP
while read -r count subnet; do
    echo "[$i] $subnet  (${count} 次失败)"
    SUBNET_MAP[$i]=$subnet
    i=$((i+1))
done <<< "$BAD_SUBNETS"
echo

# 5. 交互确认
read -p "请输入要【排除不封禁】的序号 (用空格分隔, 默认全封禁): " EXCLUDES

EXCLUDE_LIST=($EXCLUDES)

# 6. 执行封禁
echo
echo "准备封禁以下网段："
for idx in "${!SUBNET_MAP[@]}"; do
    skip=false
    for ex in "${EXCLUDE_LIST[@]}"; do
        if [ "$idx" == "$ex" ]; then
            skip=true
            break
        fi
    done
    if [ "$skip" = false ]; then
        echo "封禁: ${SUBNET_MAP[$idx]}"
        fail2ban-client set sshd banip "${SUBNET_MAP[$idx]}"
    else
        echo "跳过: ${SUBNET_MAP[$idx]}"
    fi
done

echo
echo "操作完成。"

