#!/usr/bin/env bash
#=============================================================================
# Sentinela ? Intelligent Linux Security Framework
# cron/cron.sh ? Gestión de tareas programadas
#=============================================================================
#
# Administra las tareas cron de Sentinela.
#
# Tareas:
# */5 * * * * IDS scan (logs de Apache/SSH)
# 0 * * * * Reputación (actualizar listas externas)
# 0 3 * * * Backup diario
# */30 * * * * Limpieza de cachés
#=============================================================================
# shellcheck source=lib/common.sh
source "${SENTINELA_DIR}/lib/common.sh"
#=============================================================================
# Variables
#=============================================================================
CRON_FILE="/etc/cron.d/sentinela"
#=============================================================================
# Instalar tareas cron
#=============================================================================
cron_install() {
require_root
log_info "Instalando tareas cron de Sentinela..."
cat > "${CRON_FILE}" << 'CRONEOF'
#=============================================================================
# Sentinela ? Intelligent Linux Security Framework
# Tareas programadas (generado automáticamente)
#=============================================================================
# IDS Scan (cada 5 minutos)
*/5 * * * * root /usr/local/bin/sentinela scan >> /var/log/sentinela/cron.log 2>&1
# Actualizar reputación (cada hora)
0 * * * * root /usr/local/bin/sentinela reputation >> /var/log/sentinela/cron.log 2>&1
# Backup diario (3:00 AM)
0 3 * * * root /usr/local/bin/sentinela backup >> /var/log/sentinela/cron.log 2>&1
# Limpieza de cachés (cada 30 minutos)
*/30 * * * * root /usr/local/bin/sentinela cleanup >> /var/log/sentinela/cron.log 2>&1
# Health check (cada 10 minutos)
*/10 * * * * root /usr/local/bin/sentinela health >> /var/log/sentinela/cron.log 2>&1
CRONEOF
chmod 644 "${CRON_FILE}"
log_info "Tareas cron instaladas en ${CRON_FILE}"
}
#=============================================================================
# Desinstalar tareas cron
#=============================================================================
cron_uninstall() {
require_root
if [[ -f "${CRON_FILE}" ]]; then
rm -f "${CRON_FILE}"
log_info "Tareas cron desinstaladas"
fi
}
#=============================================================================
# Ejecutar escaneo IDS (llamado por cron)
#=============================================================================
cron_scan() {
log_info "Ejecutando escaneo IDS programado..."
# Apache scan
if log_check_exists "apache_access"; then
source "${SENTINELA_IDS}/apache.sh"
apache_scan
fi
# SSH brute force
if log_check_exists "ssh_auth"; then
source "${SENTINELA_IDS}/ssh.sh"
ssh_brute_force_detect
fi
# Limpiar caché de escáneres
source "${SENTINELA_IDS}/scanners.sh"
scanner_cleanup_cache
log_info "Escaneo IDS completado"
}
#=============================================================================
# Ejecutar actualización de reputación
#=============================================================================
cron_reputation() {
if [[ "${REPUTATION_ENABLE}" != "yes" ]]; then
return 0
fi
log_info "Actualizando listas de reputación..."
source "${SENTINELA_DIR}/ipset/manager.sh"
# Asegurar que el ipset existe
if ! ${IPSET} list SENTINELA_REPUTATION &>/dev/null; then
${IPSET} create SENTINELA_REPUTATION hash:net timeout 86400 2>/dev/null || true
fi
local IFS=' '
for url in ${REPUTATION_LISTS}; do
if [[ -z "${url}" ]]; then
continue
fi
log_debug "Descargando lista: ${url}"
local temp_file
temp_file=$(mktemp)
if curl -sL "${url}" --max-time 30 -o "${temp_file}" 2>/dev/null; then
local count=0
while IFS= read -r line; do
# Ignorar comentarios y líneas vacías
[[ "${line}" =~ ^# ]] && continue
[[ -z "${line}" ]] && continue
# Extraer CIDR o IP
local entry
entry=$(echo "${line}" | grep -oP '\b[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(/[0-9]{1,2})?\b' || true)
if [[ -n "${entry}" ]]; then
${IPSET} add SENTINELA_REPUTATION "${entry}" timeout 86400 2>/dev/null || true
count=$((count + 1))
fi
done < "${temp_file}"
rm -f "${temp_file}"
log_info " ${url}: ${count} redes agregadas"
else
log_warn " Fallo al descargar: ${url}"
rm -f "${temp_file}"
fi
done
log_info "Actualización de reputación completada"
}
#=============================================================================
# Limpieza general
#=============================================================================
cron_cleanup() {
log_debug "Ejecutando limpieza programada..."
# Limpiar logs antiguos
find "${LOG_DIR}" -name "*.log" -type f -mtime "+${LOG_ROTATE_DAYS}" -delete 2>/dev/null || true
# Limpiar snapshots antiguos
source "${SENTINELA_DIR}/lib/snapshot.sh"
snapshot_cleanup
# Limpiar backups antiguos
source "${SENTINELA_DIR}/backup/restore.sh"
backup_cleanup
# Limpiar caché de escáneres
rm -f "${SENTINELA_DIR}/logs/.scanner_cache" 2>/dev/null || true
rm -f "${SENTINELA_DIR}/logs/.ssh_fail_cache" 2>/dev/null || true
# Limpiar state files antiguos de logging (nombres legacy)
rm -f "${SENTINELA_DIR}/logs/.apache_last_pos" 2>/dev/null || true
rm -f "${SENTINELA_DIR}/logs/.ssh_last_pos" 2>/dev/null || true
}
#=============================================================================
# Health check
#=============================================================================
cron_health() {
local issues=0
# Verificar que las cadenas de iptables existen
if ! ${IPTABLES} -L SENTINELA_INPUT &>/dev/null; then
log_warn "Health: Cadena SENTINELA_INPUT no existe"
issues=$((issues + 1))
fi
if ! ${IPTABLES} -L SENTINELA_NEW &>/dev/null; then
log_warn "Health: Cadena SENTINELA_NEW no existe"
issues=$((issues + 1))
fi
# Verificar ipsets
for set_name in SENTINELA_TRUSTED SENTINELA_BLACKLIST SENTINELA_DDOS SENTINELA_REPUTATION SENTINELA_HONEY; do
if ! ${IPSET} list "${set_name}" &>/dev/null; then
log_debug "Health: Ipset ${set_name} no existe"
issues=$((issues + 1))
fi
done
# Verificar conectividad (DNS)
if ! host -W 2 google.com &>/dev/null; then
log_warn "Health: No hay resolución DNS"
issues=$((issues + 1))
fi
if [[ "${issues}" -eq 0 ]]; then
log_info "Health: Todos los sistemas operan correctamente"
else
log_warn "Health: Se detectaron ${issues} problema(s)"
fi
return "${issues}"
}
|