Procesamiento de Logs

Técnicas profesionales para análisis, monitoreo y gestión de archivos de log

Módulo 5 ⏱️ 45-50 min 📊 Análisis 🔍 Monitoreo 📈 Avanzado

Importancia de los Logs

Los archivos de log son el sistema nervioso de cualquier infraestructura IT. Contienen información vital sobre el funcionamiento del sistema, errores, accesos de usuarios, rendimiento y eventos de seguridad. Un administrador de sistemas competente debe dominar el arte del análisis de logs.

Seguridad

Detectar intrusiones, ataques y actividades sospechosas

Rendimiento

Identificar cuellos de botella y optimizar sistemas

Diagnóstico

Resolver problemas y errores del sistema

Estadística Importante

Un servidor típico puede generar entre 1-10 GB de logs por día. Los servidores de alta actividad pueden producir hasta 100 GB diarios. Sin herramientas adecuadas de procesamiento, esta información sería inmanejable.

Ubicaciones de Logs en Linux

En sistemas Linux, los logs se almacenan principalmente en el directorio /var/log. Cada servicio y componente del sistema mantiene sus propios archivos de log.

Logs Principales del Sistema

Logs del Sistema
  • /var/log/syslog - Mensajes generales del sistema
  • /var/log/kern.log - Mensajes del kernel
  • /var/log/auth.log - Autenticación y autorización
  • /var/log/daemon.log - Daemons del sistema
  • /var/log/cron.log - Tareas programadas
Logs de Servicios
  • /var/log/apache2/ - Servidor web Apache
  • /var/log/nginx/ - Servidor web Nginx
  • /var/log/mysql/ - Base de datos MySQL
  • /var/log/mail.log - Servidor de correo
  • /var/log/firewall.log - Firewall
# Explorar logs del sistema
$ ls -la /var/log/ | head -10
drwxr-xr-x  3 root   root       4096 oct 15 10:30 apache2/
-rw-r--r--  1 syslog adm     1234567 oct 15 12:45 auth.log
-rw-r--r--  1 syslog adm      987654 oct 15 12:45 syslog
-rw-r--r--  1 syslog adm      456789 oct 15 12:30 daemon.log

# Ver tamaños de logs más grandes
$ du -sh /var/log/* | sort -hr | head -5
45M     /var/log/apache2
23M     /var/log/syslog
15M     /var/log/auth.log
8.5M    /var/log/kern.log
6.2M    /var/log/daemon.log

Análisis Básico de Logs

El análisis básico implica examinar, filtrar y extraer información específica de los archivos de log usando herramientas de línea de comandos.

Comandos Fundamentales

# Ver las últimas entradas de un log
$ tail -f /var/log/syslog
Oct 15 12:45:23 servidor systemd[1]: Started Daily apt download activities
Oct 15 12:45:24 servidor CRON[1234]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Oct 15 12:45:25 servidor kernel: [123456.789] USB disconnect, address 1

# Ver logs históricos con menos páginas
$ less /var/log/auth.log

# Buscar eventos específicos
$ grep "Failed password" /var/log/auth.log | tail -5
Oct 15 12:30:15 servidor sshd[1234]: Failed password for invalid user admin from 192.168.1.100 port 22 ssh2
Oct 15 12:30:18 servidor sshd[1235]: Failed password for root from 10.0.0.15 port 22 ssh2

# Contar ocurrencias
$ grep -c "ERROR" /var/log/apache2/error.log
42

# Ver logs entre fechas específicas
$ grep "Oct 15 12:[3-4][0-9]" /var/log/syslog

Análisis de Patrones Comunes

Patrones de análisis Copiar
# 1. Top 10 IPs con más intentos fallidos de SSH
grep "Failed password" /var/log/auth.log | \
grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | \
sort | uniq -c | sort -nr | head -10

# 2. Códigos de respuesta HTTP más comunes
awk '{print $9}' /var/log/apache2/access.log | \
sort | uniq -c | sort -nr

# 3. Usuarios más activos en el sistema
grep "sudo:" /var/log/auth.log | \
grep -oE "USER=[a-zA-Z0-9_-]+" | \
cut -d'=' -f2 | sort | uniq -c | sort -nr

# 4. Errores más frecuentes
grep -i error /var/log/syslog | \
cut -d':' -f4- | sort | uniq -c | sort -nr | head -10

# 5. Actividad por horas del día
grep "$(date '+%b %d')" /var/log/syslog | \
cut -d':' -f1 | cut -d' ' -f4 | sort | uniq -c

Scripts de Análisis Automatizado

La automatización del análisis de logs permite monitoreo continuo y detección proactiva de problemas. Aquí crearemos scripts especializados para diferentes tipos de análisis.

Monitor de Seguridad

Monitor de seguridad Copiar
#!/bin/bash
# security_monitor.sh - Monitor de eventos de seguridad

LOG_FILE="/tmp/security_report.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
ALERT_THRESHOLD=5

echo "=== Reporte de Seguridad - $DATE ===" > "$LOG_FILE"

# 1. Intentos de login fallidos por IP
echo -e "\n--- Intentos de Login Fallidos (últimas 24h) ---" >> "$LOG_FILE"
FAILED_LOGINS=$(grep "Failed password" /var/log/auth.log | \
    grep "$(date '+%b %d')" | \
    grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | \
    sort | uniq -c | sort -nr)

if [[ -n "$FAILED_LOGINS" ]]; then
    echo "$FAILED_LOGINS" | while read count ip; do
        echo "IP: $ip - $count intentos fallidos" >> "$LOG_FILE"
        if [[ $count -gt $ALERT_THRESHOLD ]]; then
            echo "🚨 ALERTA: IP $ip superó el umbral ($count > $ALERT_THRESHOLD)" >> "$LOG_FILE"
        fi
    done
else
    echo "✅ No se detectaron intentos de login fallidos" >> "$LOG_FILE"
fi

# 2. Usuarios con actividad de sudo
echo -e "\n--- Actividad sudo (últimas 24h) ---" >> "$LOG_FILE"
SUDO_ACTIVITY=$(grep "sudo:" /var/log/auth.log | \
    grep "$(date '+%b %d')" | \
    grep -oE "USER=[a-zA-Z0-9_-]+" | \
    cut -d'=' -f2 | sort | uniq -c | sort -nr)

if [[ -n "$SUDO_ACTIVITY" ]]; then
    echo "$SUDO_ACTIVITY" | while read count user; do
        echo "Usuario: $user - $count comandos sudo ejecutados" >> "$LOG_FILE"
    done
else
    echo "ℹ️  No hay actividad sudo registrada" >> "$LOG_FILE"
fi

# 3. Conexiones SSH exitosas
echo -e "\n--- Conexiones SSH Exitosas ---" >> "$LOG_FILE"
SSH_SUCCESS=$(grep "Accepted password" /var/log/auth.log | \
    grep "$(date '+%b %d')" | \
    awk '{print $11, $9}' | sort | uniq -c | sort -nr)

if [[ -n "$SSH_SUCCESS" ]]; then
    echo "$SSH_SUCCESS" | head -10 >> "$LOG_FILE"
else
    echo "ℹ️  No hay conexiones SSH exitosas registradas hoy" >> "$LOG_FILE"
fi

# 4. Verificar procesos sospechosos
echo -e "\n--- Verificación de Procesos ---" >> "$LOG_FILE"
SUSPICIOUS_PROCS=$(ps aux | grep -E "(nc|netcat|nmap|hydra|john)" | grep -v grep)
if [[ -n "$SUSPICIOUS_PROCS" ]]; then
    echo "⚠️  PROCESOS SOSPECHOSOS DETECTADOS:" >> "$LOG_FILE"
    echo "$SUSPICIOUS_PROCS" >> "$LOG_FILE"
else
    echo "✅ No se detectaron procesos sospechosos" >> "$LOG_FILE"
fi

# 5. Resumen final
echo -e "\n--- RESUMEN ---" >> "$LOG_FILE"
echo "Fecha del reporte: $DATE" >> "$LOG_FILE"
echo "IPs únicas con intentos fallidos: $(echo "$FAILED_LOGINS" | wc -l)" >> "$LOG_FILE"
echo "Usuarios con actividad sudo: $(echo "$SUDO_ACTIVITY" | wc -l)" >> "$LOG_FILE"

# Mostrar reporte
cat "$LOG_FILE"
echo -e "\n📋 Reporte guardado en: $LOG_FILE"

Analizador de Rendimiento Web

Analizador web performance Copiar
#!/bin/bash
# web_performance_analyzer.sh - Análisis de rendimiento de servidor web

ACCESS_LOG="/var/log/apache2/access.log"
ERROR_LOG="/var/log/apache2/error.log"
REPORT_FILE="/tmp/web_performance_report.html"

# Crear datos de prueba si no existen logs reales
if [[ ! -f "$ACCESS_LOG" ]]; then
    mkdir -p "$(dirname "$ACCESS_LOG")"
    cat > "$ACCESS_LOG" << 'EOF'
192.168.1.100 - - [15/Oct/2024:10:15:22 +0000] "GET / HTTP/1.1" 200 1234 "-" "Mozilla/5.0"
10.0.0.15 - - [15/Oct/2024:10:16:33 +0000] "GET /images/logo.png HTTP/1.1" 200 5678 "http://example.com/" "Mozilla/5.0"
192.168.1.100 - - [15/Oct/2024:10:17:44 +0000] "POST /login HTTP/1.1" 404 0 "http://example.com/login" "Mozilla/5.0"
172.16.0.50 - - [15/Oct/2024:10:18:55 +0000] "GET /api/users HTTP/1.1" 500 2048 "-" "curl/7.68.0"
EOF
fi

# Función para generar HTML
generate_html_header() {
    cat > "$REPORT_FILE" << 'EOF'




    Reporte de Rendimiento Web
    


📊 Reporte de Rendimiento Web

Fecha: $(date)

EOF } echo "🔍 Analizando logs del servidor web..." # Generar header HTML generate_html_header # 1. Estadísticas generales echo "
" >> "$REPORT_FILE" echo "

📈 Estadísticas Generales

" >> "$REPORT_FILE" TOTAL_REQUESTS=$(wc -l < "$ACCESS_LOG") UNIQUE_IPS=$(awk '{print $1}' "$ACCESS_LOG" | sort -u | wc -l) echo "

Total de requests: $TOTAL_REQUESTS

" >> "$REPORT_FILE" echo "

IPs únicas: $UNIQUE_IPS

" >> "$REPORT_FILE" echo "
" >> "$REPORT_FILE" # 2. Top 10 páginas más solicitadas echo "
" >> "$REPORT_FILE" echo "

🏆 Top 10 Páginas Más Solicitadas

" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" awk '{print $7}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -10 | \ while read count page; do echo "" >> "$REPORT_FILE" done echo "
RequestsPágina
$count$page
" >> "$REPORT_FILE" echo "
" >> "$REPORT_FILE" # 3. Códigos de respuesta echo "
" >> "$REPORT_FILE" echo "

📋 Códigos de Respuesta

" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" awk '{print $9}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | \ while read count code; do case $code in 200) desc="✅ OK" ;; 404) desc="❌ No encontrado" ;; 500) desc="💥 Error del servidor" ;; 403) desc="🚫 Prohibido" ;; *) desc="❓ Otro" ;; esac echo "" >> "$REPORT_FILE" done echo "
CódigoCantidadDescripción
$code$count$desc
" >> "$REPORT_FILE" echo "
" >> "$REPORT_FILE" # 4. IPs más activas echo "
" >> "$REPORT_FILE" echo "

🌐 Top 10 IPs Más Activas

" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" awk '{print $1}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -10 | \ while read count ip; do echo "" >> "$REPORT_FILE" done echo "
RequestsIP
$count$ip
" >> "$REPORT_FILE" echo "
" >> "$REPORT_FILE" # 5. Análisis de User Agents echo "
" >> "$REPORT_FILE" echo "

🤖 Navegadores/Bots Más Comunes

" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" awk -F'"' '{print $6}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -5 | \ while read count agent; do echo "" >> "$REPORT_FILE" done echo "
CantidadUser Agent
$count$agent
" >> "$REPORT_FILE" echo "
" >> "$REPORT_FILE" # 6. Errores 404 más comunes echo "
" >> "$REPORT_FILE" echo "

❌ Errores 404 Más Comunes

" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" awk '$9 == "404" {print $7}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -10 | \ while read count url; do echo "" >> "$REPORT_FILE" done echo "
CantidadURL
$count$url
" >> "$REPORT_FILE" echo "
" >> "$REPORT_FILE" # Cerrar HTML echo "" >> "$REPORT_FILE" echo "✅ Reporte generado en: $REPORT_FILE" echo "🌐 Abrir con: firefox $REPORT_FILE"

Monitoreo en Tiempo Real

El monitoreo en tiempo real permite detectar problemas inmediatamente cuando ocurren, en lugar de descubrirlos después durante el análisis.

Herramientas de Seguimiento

# 1. Seguimiento básico con tail -f
$ tail -f /var/log/syslog

# 2. Seguimiento de múltiples archivos
$ tail -f /var/log/syslog /var/log/auth.log /var/log/apache2/error.log

# 3. Filtrado en tiempo real con grep
$ tail -f /var/log/auth.log | grep --line-buffered "Failed password"

# 4. Seguimiento con multitail (más avanzado)
$ sudo apt-get install multitail
$ multitail /var/log/syslog /var/log/auth.log

# 5. Usando watch para estadísticas en tiempo real
$ watch -n 5 'tail -20 /var/log/auth.log | grep "Failed password" | wc -l'

Monitor de Eventos Críticos

Monitor de eventos críticos Copiar
#!/bin/bash
# realtime_monitor.sh - Monitor de eventos críticos en tiempo real

ALERT_EMAIL="[email protected]"
ALERT_THRESHOLD=3
TEMP_DIR="/tmp/log_monitor"
mkdir -p "$TEMP_DIR"

# Colores para output
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

log_alert() {
    local level=$1
    local message=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    case $level in
        "CRITICAL")
            echo -e "${RED}🚨 [$timestamp] CRÍTICO: $message${NC}"
            echo "[$timestamp] CRÍTICO: $message" >> "$TEMP_DIR/alerts.log"
            ;;
        "WARNING")
            echo -e "${YELLOW}⚠️  [$timestamp] ADVERTENCIA: $message${NC}"
            echo "[$timestamp] ADVERTENCIA: $message" >> "$TEMP_DIR/alerts.log"
            ;;
        "INFO")
            echo -e "${GREEN}ℹ️  [$timestamp] INFO: $message${NC}"
            ;;
    esac
}

# Función para monitorear intentos de login fallidos
monitor_failed_logins() {
    tail -f /var/log/auth.log | grep --line-buffered "Failed password" | \
    while read line; do
        ip=$(echo "$line" | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}")
        user=$(echo "$line" | grep -oE "for [a-zA-Z0-9_-]+" | cut -d' ' -f2)
        
        # Contar intentos recientes de esta IP
        recent_attempts=$(grep "$ip" "$TEMP_DIR/failed_ips.log" 2>/dev/null | wc -l)
        echo "$ip" >> "$TEMP_DIR/failed_ips.log"
        
        if [[ $recent_attempts -ge $ALERT_THRESHOLD ]]; then
            log_alert "CRITICAL" "IP $ip ha fallado $recent_attempts intentos de login para usuario '$user'"
            # Aquí podrías agregar el bloqueo automático de IP
            # iptables -A INPUT -s $ip -j DROP
        else
            log_alert "WARNING" "Intento fallido de login desde $ip para usuario '$user'"
        fi
        
        # Limpiar archivo de IPs cada 10 minutos
        find "$TEMP_DIR/failed_ips.log" -mmin +10 -delete 2>/dev/null
    done &
}

# Función para monitorear errores del sistema
monitor_system_errors() {
    tail -f /var/log/syslog | grep --line-buffered -E "(error|critical|fatal)" | \
    while read line; do
        if echo "$line" | grep -qE "(Out of memory|Kernel panic|segfault)"; then
            log_alert "CRITICAL" "Error crítico del sistema detectado: $line"
        else
            log_alert "WARNING" "Error del sistema: $line"
        fi
    done &
}

# Función para monitorear espacio en disco
monitor_disk_space() {
    while true; do
        df -h | grep -E "^/dev/" | while read line; do
            usage=$(echo "$line" | awk '{print $5}' | sed 's/%//')
            device=$(echo "$line" | awk '{print $1}')
            mountpoint=$(echo "$line" | awk '{print $6}')
            
            if [[ $usage -gt 90 ]]; then
                log_alert "CRITICAL" "Disco $device ($mountpoint) al $usage% de capacidad"
            elif [[ $usage -gt 80 ]]; then
                log_alert "WARNING" "Disco $device ($mountpoint) al $usage% de capacidad"
            fi
        done
        sleep 300  # Verificar cada 5 minutos
    done &
}

# Función para monitorear carga del sistema
monitor_load() {
    while true; do
        load=$(uptime | grep -oE "load average: [0-9.]+" | grep -oE "[0-9.]+$")
        if (( $(echo "$load > 5.0" | bc -l) )); then
            log_alert "CRITICAL" "Carga del sistema muy alta: $load"
        elif (( $(echo "$load > 2.0" | bc -l) )); then
            log_alert "WARNING" "Carga del sistema elevada: $load"
        fi
        sleep 60  # Verificar cada minuto
    done &
}

# Función de limpieza al salir
cleanup() {
    echo -e "\n${GREEN}🔄 Deteniendo monitoreo...${NC}"
    kill $(jobs -p) 2>/dev/null
    log_alert "INFO" "Monitor de logs detenido"
    exit 0
}

# Capturar Ctrl+C
trap cleanup INT TERM

echo "🚀 Iniciando monitor de logs en tiempo real..."
echo "📁 Logs de alertas en: $TEMP_DIR/alerts.log"
echo "❌ Presiona Ctrl+C para detener"
echo

log_alert "INFO" "Monitor de logs iniciado"

# Iniciar todos los monitores en background
monitor_failed_logins
monitor_system_errors
monitor_disk_space
monitor_load

# Mantener el script ejecutándose
while true; do
    sleep 10
    # Limpiar archivos temporales antiguos
    find "$TEMP_DIR" -name "*.log" -mtime +7 -delete 2>/dev/null
done

Gestión y Rotación de Logs

Los logs crecen constantemente, por lo que es esencial implementar estrategias de rotación, compresión y archivado para mantener el sistema funcionando eficientemente.

Logrotate

Configuración logrotate Copiar
# Configuración personalizada de logrotate
# /etc/logrotate.d/mi-aplicacion

/var/log/mi-aplicacion/*.log {
    daily                    # Rotar diariamente
    missingok               # No error si el log no existe
    rotate 30               # Mantener 30 archivos rotados
    compress                # Comprimir archivos antiguos
    delaycompress          # Comprimir en la siguiente rotación
    notifempty             # No rotar si está vacío
    create 0644 www-data www-data  # Crear nuevo log con permisos
    postrotate
        # Recargar servicio después de rotar
        systemctl reload mi-aplicacion > /dev/null 2>&1 || true
    endscript
}

# Configuración para logs de alta actividad
/var/log/aplicacion-activa/*.log {
    size 100M               # Rotar cuando alcance 100MB
    hourly                  # Verificar cada hora
    rotate 48               # Mantener 48 archivos (2 días)
    compress
    delaycompress
    missingok
    notifempty
    copytruncate           # Copiar y truncar (para apps que mantienen el FD abierto)
}

# Probar configuración
sudo logrotate -d /etc/logrotate.d/mi-aplicacion

# Forzar rotación inmediata
sudo logrotate -f /etc/logrotate.d/mi-aplicacion

Script de Limpieza Automática

Limpieza automática Copiar
#!/bin/bash
# log_cleanup.sh - Script para limpieza automática de logs

LOG_DIR="/var/log"
BACKUP_DIR="/var/backups/logs"
MAX_AGE_DAYS=30
MAX_SIZE_MB=1000
COMPRESS_AGE_DAYS=7

# Función para logging
log_action() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a /var/log/log_cleanup.log
}

# Crear directorio de backup si no existe
mkdir -p "$BACKUP_DIR"

log_action "🧹 Iniciando limpieza de logs"

# 1. Comprimir logs antiguos
log_action "📦 Comprimiendo logs antiguos (>$COMPRESS_AGE_DAYS días)"
find "$LOG_DIR" -name "*.log" -mtime +$COMPRESS_AGE_DAYS ! -name "*.gz" ! -name "*.bz2" | \
while read logfile; do
    if [[ -w "$logfile" ]]; then
        log_action "  Comprimiendo: $logfile"
        gzip "$logfile"
    fi
done

# 2. Archivar logs muy antiguos
log_action "📚 Archivando logs muy antiguos (>$MAX_AGE_DAYS días)"
find "$LOG_DIR" -name "*.log.gz" -mtime +$MAX_AGE_DAYS | \
while read oldlog; do
    filename=$(basename "$oldlog")
    log_action "  Archivando: $filename"
    mv "$oldlog" "$BACKUP_DIR/"
done

# 3. Limpiar logs que superan el tamaño máximo
log_action "📏 Verificando logs grandes (>$MAX_SIZE_MB MB)"
find "$LOG_DIR" -name "*.log" -size +${MAX_SIZE_MB}M | \
while read biglog; do
    size=$(du -m "$biglog" | cut -f1)
    log_action "  ⚠️ Log grande encontrado: $biglog ($size MB)"
    
    # Mantener solo las últimas 10000 líneas
    tail -10000 "$biglog" > "$biglog.tmp"
    mv "$biglog.tmp" "$biglog"
    log_action "  ✅ Truncado a últimas 10000 líneas"
done

# 4. Eliminar backups muy antiguos
log_action "🗑️  Eliminando backups muy antiguos (>$((MAX_AGE_DAYS * 2)) días)"
find "$BACKUP_DIR" -name "*.log.gz" -mtime +$((MAX_AGE_DAYS * 2)) -delete

# 5. Generar reporte de espacio
log_action "📊 Reporte de espacio en disco:"
du -sh "$LOG_DIR" | tee -a /var/log/log_cleanup.log
du -sh "$BACKUP_DIR" | tee -a /var/log/log_cleanup.log

# 6. Optimizar base de datos de locate (si existe)
if command -v updatedb > /dev/null; then
    log_action "🔍 Actualizando base de datos locate"
    updatedb 2>/dev/null || true
fi

log_action "✅ Limpieza completada"

# Enviar reporte por email (opcional)
if command -v mail > /dev/null && [[ -n "$ADMIN_EMAIL" ]]; then
    tail -20 /var/log/log_cleanup.log | mail -s "Reporte de limpieza de logs - $(hostname)" "$ADMIN_EMAIL"
fi
Precauciones Importantes
  • Siempre respalda logs críticos antes de eliminarlos
  • Verifica que las aplicaciones no mantengan file descriptors abiertos
  • Considera el espacio en disco y requisitos de auditoría
  • Prueba scripts de limpieza en entorno de desarrollo primero
  • Mantén logs de seguridad por más tiempo que logs de aplicación

Ejercicio Práctico Final

Proyecto: Sistema Completo de Monitoreo de Logs

Desarrolla un sistema integral que combine análisis, monitoreo y alertas:

Sistema integral de logs Copiar
#!/bin/bash
# complete_log_system.sh - Sistema integral de monitoreo de logs

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_DIR="$SCRIPT_DIR/config"
REPORTS_DIR="$SCRIPT_DIR/reports"
ALERTS_DIR="$SCRIPT_DIR/alerts"

# Crear estructura de directorios
mkdir -p "$CONFIG_DIR" "$REPORTS_DIR" "$ALERTS_DIR"

# Configuración general
cat > "$CONFIG_DIR/main.conf" << 'EOF'
# Configuración principal
ALERT_EMAIL="[email protected]"
RETENTION_DAYS=30
ALERT_THRESHOLD_FAILED_LOGINS=5
ALERT_THRESHOLD_DISK_USAGE=80
ALERT_THRESHOLD_LOAD=3.0
MONITOR_INTERVAL=60
REPORT_INTERVAL=3600
EOF

source "$CONFIG_DIR/main.conf"

# Sistema principal
main() {
    case "$1" in
        "start")
            echo "🚀 Iniciando sistema de monitoreo completo"
            start_monitoring
            ;;
        "stop")
            echo "🛑 Deteniendo sistema de monitoreo"
            stop_monitoring
            ;;
        "report")
            echo "📊 Generando reporte"
            generate_daily_report
            ;;
        "alert-test")
            echo "🧪 Probando sistema de alertas"
            test_alerts
            ;;
        "status")
            echo "📋 Estado del sistema"
            show_status
            ;;
        *)
            echo "Uso: $0 {start|stop|report|alert-test|status}"
            echo
            echo "Comandos disponibles:"
            echo "  start      - Iniciar monitoreo en tiempo real"
            echo "  stop       - Detener todos los procesos de monitoreo"
            echo "  report     - Generar reporte diario"
            echo "  alert-test - Probar sistema de alertas"
            echo "  status     - Mostrar estado del sistema"
            exit 1
            ;;
    esac
}

# Función para iniciar monitoreo
start_monitoring() {
    # Verificar si ya está ejecutándose
    if [[ -f "$SCRIPT_DIR/monitor.pid" ]]; then
        echo "⚠️  El sistema de monitoreo ya está ejecutándose"
        return 1
    fi
    
    # Iniciar procesos de monitoreo
    (monitor_security) &
    echo $! > "$SCRIPT_DIR/security.pid"
    
    (monitor_performance) &
    echo $! > "$SCRIPT_DIR/performance.pid"
    
    (generate_periodic_reports) &
    echo $! > "$SCRIPT_DIR/reports.pid"
    
    echo "$$" > "$SCRIPT_DIR/monitor.pid"
    echo "✅ Sistema de monitoreo iniciado"
    echo "📁 PIDs guardados en $SCRIPT_DIR/"
}

# Función de monitoreo de seguridad
monitor_security() {
    while true; do
        # Monitorear intentos fallidos de login
        failed_count=$(grep "Failed password.*$(date '+%b %d')" /var/log/auth.log 2>/dev/null | wc -l)
        
        if [[ $failed_count -gt $ALERT_THRESHOLD_FAILED_LOGINS ]]; then
            send_alert "SECURITY" "Detectados $failed_count intentos fallidos de login hoy"
        fi
        
        # Monitorear procesos sospechosos
        suspicious=$(ps aux | grep -E "(nc|netcat|nmap|hydra)" | grep -v grep)
        if [[ -n "$suspicious" ]]; then
            send_alert "SECURITY" "Procesos sospechosos detectados: $suspicious"
        fi
        
        sleep $MONITOR_INTERVAL
    done
}

# Función de monitoreo de rendimiento
monitor_performance() {
    while true; do
        # Monitorear carga del sistema
        load=$(uptime | grep -oE "load average: [0-9.]+" | awk '{print $3}' | cut -d',' -f1)
        if (( $(echo "$load > $ALERT_THRESHOLD_LOAD" | bc -l) )); then
            send_alert "PERFORMANCE" "Carga del sistema alta: $load"
        fi
        
        # Monitorear espacio en disco
        df -h | grep -E "^/dev/" | while read line; do
            usage=$(echo "$line" | awk '{print $5}' | sed 's/%//')
            device=$(echo "$line" | awk '{print $1}')
            if [[ $usage -gt $ALERT_THRESHOLD_DISK_USAGE ]]; then
                send_alert "PERFORMANCE" "Disco $device al $usage% de capacidad"
            fi
        done
        
        sleep $MONITOR_INTERVAL
    done
}

# Sistema de alertas
send_alert() {
    local level=$1
    local message=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local alert_file="$ALERTS_DIR/$(date '+%Y%m%d').log"
    
    # Registrar alerta
    echo "[$timestamp] $level: $message" >> "$alert_file"
    
    # Mostrar en consola
    case $level in
        "SECURITY")
            echo -e "🚨 [$timestamp] SEGURIDAD: $message"
            ;;
        "PERFORMANCE")
            echo -e "⚡ [$timestamp] RENDIMIENTO: $message"
            ;;
        *)
            echo -e "ℹ️  [$timestamp] INFO: $message"
            ;;
    esac
    
    # Enviar por email si está configurado
    if command -v mail >/dev/null 2>&1 && [[ -n "$ALERT_EMAIL" ]]; then
        echo "$message" | mail -s "[$level] Alerta del sistema - $(hostname)" "$ALERT_EMAIL"
    fi
}

# Generar reportes periódicos
generate_periodic_reports() {
    while true; do
        generate_hourly_summary
        sleep $REPORT_INTERVAL
    done
}

generate_hourly_summary() {
    local report_file="$REPORTS_DIR/hourly_$(date '+%Y%m%d_%H').txt"
    
    {
        echo "=== Resumen Horario - $(date) ==="
        echo
        
        echo "📊 Estadísticas de Sistema:"
        echo "  Carga promedio: $(uptime | grep -oE 'load average: [0-9., ]+')"
        echo "  Memoria libre: $(free -h | grep '^Mem:' | awk '{print $7}')"
        echo "  Espacio en disco:"
        df -h | grep -E "^/dev/" | awk '{printf "    %s: %s usado de %s (%s)\n", $1, $3, $2, $5}'
        
        echo
        echo "🔐 Eventos de Seguridad:"
        recent_failed=$(grep "Failed password.*$(date '+%b %d %H:')" /var/log/auth.log 2>/dev/null | wc -l)
        echo "  Intentos fallidos última hora: $recent_failed"
        
        echo
        echo "🌐 Actividad Web (si aplica):"
        if [[ -f "/var/log/apache2/access.log" ]]; then
            recent_requests=$(grep "$(date '+%d/%b/%Y:%H:')" /var/log/apache2/access.log 2>/dev/null | wc -l)
            echo "  Requests última hora: $recent_requests"
        fi
        
    } > "$report_file"
    
    echo "📝 Resumen horario guardado: $report_file"
}

# Generar reporte diario completo
generate_daily_report() {
    local report_file="$REPORTS_DIR/daily_$(date '+%Y%m%d').html"
    
    cat > "$report_file" << EOF




    Reporte Diario - $(date '+%Y-%m-%d')
    


    

📊 Reporte Diario del Sistema - $(date '+%Y-%m-%d')

🖥️ Estado del Sistema

Hostname: $(hostname)

Uptime: $(uptime -p)

Usuarios conectados: $(who | wc -l)

📈 Estadísticas del Día

Intentos fallidos de login: $(grep "Failed password.*$(date '+%b %d')" /var/log/auth.log 2>/dev/null | wc -l)

Conexiones SSH exitosas: $(grep "Accepted.*$(date '+%b %d')" /var/log/auth.log 2>/dev/null | wc -l)

Alertas generadas: $(find "$ALERTS_DIR" -name "$(date '+%Y%m%d').log" -exec wc -l {} \; 2>/dev/null | awk '{print $1}')

💾 Uso de Recursos

EOF # Agregar información de discos df -h | grep -E "^/dev/" | while read line; do echo "" >> "$report_file" echo "$line" | awk '{printf "\n", $1, $2, $3, $4, $5}' >> "$report_file" echo "" >> "$report_file" done cat >> "$report_file" << EOF
DiscoTamañoUsadoDisponible% Uso
%s%s%s%s%s
EOF echo "📊 Reporte diario generado: $report_file" } # Probar sistema de alertas test_alerts() { echo "🧪 Enviando alerta de prueba..." send_alert "TEST" "Sistema de alertas funcionando correctamente" } # Mostrar estado show_status() { echo "📋 Estado del Sistema de Monitoreo" echo "==================================" if [[ -f "$SCRIPT_DIR/monitor.pid" ]]; then echo "✅ Monitor principal: EJECUTÁNDOSE (PID: $(cat "$SCRIPT_DIR/monitor.pid"))" else echo "❌ Monitor principal: DETENIDO" fi for service in security performance reports; do if [[ -f "$SCRIPT_DIR/${service}.pid" ]]; then pid=$(cat "$SCRIPT_DIR/${service}.pid") if kill -0 "$pid" 2>/dev/null; then echo "✅ Monitor $service: EJECUTÁNDOSE (PID: $pid)" else echo "❌ Monitor $service: PROCESO NO ENCONTRADO" fi else echo "❌ Monitor $service: DETENIDO" fi done echo echo "📁 Archivos recientes:" echo " Alertas: $(find "$ALERTS_DIR" -name "*.log" -mtime -1 | wc -l) archivos" echo " Reportes: $(find "$REPORTS_DIR" -name "*.txt" -o -name "*.html" -mtime -1 | wc -l) archivos" } # Función para detener monitoreo stop_monitoring() { for pidfile in "$SCRIPT_DIR"/*.pid; do if [[ -f "$pidfile" ]]; then pid=$(cat "$pidfile") if kill -0 "$pid" 2>/dev/null; then kill "$pid" echo "🛑 Detenido proceso $pid" fi rm "$pidfile" fi done echo "✅ Sistema de monitoreo detenido" } # Ejecutar función principal con argumentos main "$@"

Para usar el sistema:

# Hacer executable el script
chmod +x complete_log_system.sh

# Iniciar monitoreo
./complete_log_system.sh start

# Verificar estado
./complete_log_system.sh status

# Generar reporte
./complete_log_system.sh report

# Detener sistema
./complete_log_system.sh stop