#!/usr/bin/env bash
#=============================================================================
# Sentinela ? Intelligent Linux Security Framework
# ids/ddos.sh ? Detección de DDoS en logs
#=============================================================================
#
# Detecta comportamientos DDoS:
# - Alta frecuencia de solicitudes desde una IP
# - Múltiples IPs atacando el mismo recurso
# - Patrones de User-Agent (homogéneo = ataque)
# - Picos de tráfico
#=============================================================================
# shellcheck source=lib/common.sh
source "${SENTINELA_DIR}/lib/common.sh"
#=============================================================================
# Analizar línea de log y detectar DDoS
#=============================================================================
ddos_analyze() {
local log_content="$1"
local log_type="${2:-apache}" # apache | nginx
# Si no hay contenido, salir
if [[ -z "${log_content}" ]]; then
return 0
fi
# Contar solicitudes por IP
local ip_count
ip_count=$(echo "${log_content}" | awk '{print $1}' | sort | uniq -c | sort -rn)
if [[ -z "${ip_count}" ]]; then
return 0
fi
local threshold="${DDOS_THRESHOLD}"
local attack_count=0
while IFS= read -r line; do
local count ip
count=$(echo "${line}" | awk '{print $1}')
ip=$(echo "${line}" | awk '{print $2}')
if [[ -z "${ip}" ]] || ! is_valid_ip "${ip}"; then
continue
fi
if [[ "${count}" -ge "${threshold}" ]]; then
attack_count=$((attack_count + 1))
log_attack "DDOS|${ip}|frecuencia: ${count} solicitudes|threshold: ${threshold}"
# Banear IP
source "${SENTINELA_DIR}/firewall/blacklist.sh"
blacklist_add "${ip}" "ddos: ${count} requests" "${DDOS_BAN_TIME}"
# Agregar a ipset DDOS
ddos_add_to_set "${ip}"
# Alerta Telegram
if [[ "${TELEGRAM_ENABLE}" == "yes" ]]; then
source "${SENTINELA_DIR}/telegram/telegram.sh"
telegram_send_alert "${ip}" "ddos" "DDoS detectado: ${count} solicitudes (threshold: ${threshold})" "" "" "" "DDOS"
fi
fi
done <<< "${ip_count}"
if [[ "${attack_count}" -gt 0 ]]; then
log_info "DDoS scan: ${attack_count} atacantes detectados"
fi
return 0
}
#=============================================================================
# Agregar IP al ipset de DDoS
#=============================================================================
ddos_add_to_set() {
local ip="$1"
if ! ${IPSET} list SENTINELA_DDOS &>/dev/null; then
${IPSET} create SENTINELA_DDOS hash:ip timeout "${DDOS_BAN_TIME}" 2>/dev/null || {
${IPSET} destroy SENTINELA_DDOS 2>/dev/null || true
${IPSET} create SENTINELA_DDOS hash:ip timeout "${DDOS_BAN_TIME}"
}
fi
${IPSET} add SENTINELA_DDOS "${ip}" timeout "${DDOS_BAN_TIME}" 2>/dev/null || true
}
|