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
# 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
#!/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
#!/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 "Requests Página " >> "$REPORT_FILE"
awk '{print $7}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -10 | \
while read count page; do
echo "$count $page " >> "$REPORT_FILE"
done
echo "
" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 3. Códigos de respuesta
echo "" >> "$REPORT_FILE"
echo "📋 Códigos de Respuesta
" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "Código Cantidad Descripción " >> "$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 "$code $count $desc " >> "$REPORT_FILE"
done
echo "
" >> "$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 "Requests IP " >> "$REPORT_FILE"
awk '{print $1}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -10 | \
while read count ip; do
echo "$count $ip " >> "$REPORT_FILE"
done
echo "
" >> "$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 "Cantidad User Agent " >> "$REPORT_FILE"
awk -F'"' '{print $6}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -5 | \
while read count agent; do
echo "$count $agent " >> "$REPORT_FILE"
done
echo "
" >> "$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 "Cantidad URL " >> "$REPORT_FILE"
awk '$9 == "404" {print $7}' "$ACCESS_LOG" | sort | uniq -c | sort -nr | head -10 | \
while read count url; do
echo "$count $url " >> "$REPORT_FILE"
done
echo "
" >> "$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
#!/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 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
#!/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:
#!/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
Disco Tamaño Usado Disponible % Uso
EOF
# Agregar información de discos
df -h | grep -E "^/dev/" | while read line; do
echo "" >> "$report_file"
echo "$line" | awk '{printf "%s %s %s %s %s \n", $1, $2, $3, $4, $5}' >> "$report_file"
echo " " >> "$report_file"
done
cat >> "$report_file" << EOF
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