Logs de Email: Guía Completa de Análisis y Diagnóstico
Introducción
Los logs del servidor de email son tu herramienta de diagnóstico más valiosa, conteniendo información detallada sobre cada mensaje, conexión, intento de autenticación y error que ocurre en tu sistema. Sin embargo, el gran volumen de datos en los logs de correo puede ser abrumador—un servidor ocupado puede generar miles de entradas de log por hora. Sin técnicas efectivas de análisis, la información crítica queda enterrada en el ruido.
Comprender cómo leer, analizar y extraer conocimientos significativos de los logs de email es esencial para mantener un servidor de correo confiable. Los logs revelan problemas de entrega, fallos de autenticación, patrones de spam, cuellos de botella de rendimiento, amenazas de seguridad y problemas de configuración. Proporcionan la evidencia necesaria para diagnosticar problemas, verificar entregas exitosas, rastrear rutas de mensajes y optimizar el rendimiento del servidor.
Esta guía completa te enseña cómo analizar efectivamente los logs de email usando herramientas de línea de comandos, identificar patrones y problemas comunes, extraer información específica, crear scripts de monitoreo automatizados y mantener logs para rendimiento y cumplimiento óptimos. Aprenderás a encontrar rápidamente la información que necesitas, detectar problemas antes de que se vuelvan críticos y mantener visibilidad completa de tu infraestructura de email.
Ya sea que estés rastreando un email perdido, investigando fallos de autenticación, monitoreando ataques o simplemente verificando que tu servidor está operando correctamente, esta guía proporciona el conocimiento y los comandos necesarios para dominar el análisis de logs de email.
Requisitos Previos
Antes de sumergirte en el análisis de logs, asegúrate de tener:
Acceso al Sistema
- Acceso root o sudo al servidor de correo
- Acceso SSH al servidor
- Comprensión de tu programación de rotación de logs
- Acceso a logs de respaldo si es necesario
Requisitos de Conocimiento
- Competencia básica en línea de comandos de Linux
- Comprensión de protocolos de email (SMTP, IMAP, POP3)
- Familiaridad con Postfix y Dovecot
- Conocimiento básico de regex (útil pero no requerido)
Herramientas Requeridas
Las herramientas estándar de Linux deben estar disponibles:
# Verify tools are available
which grep tail cat less awk sed sort uniq wc head
# Install if missing
sudo apt install coreutils grep gawk sed -y
Comprensión de las Ubicaciones de Archivos de Log
Logs de Postfix
Ubuntu/Debian:
/var/log/mail.log # Main mail log
/var/log/mail.err # Mail errors only
/var/log/mail.warn # Warnings
CentOS/Rocky Linux:
/var/log/maillog # Main mail log
Sistemas alternativos/systemd:
# View via journalctl
journalctl -u postfix
Logs de Dovecot
Ubicación configurada (revisa dovecot.conf):
/var/log/dovecot.log # Main Dovecot log
/var/log/dovecot-info.log
O en logs del sistema:
/var/log/syslog # Ubuntu/Debian
/var/log/messages # CentOS/Rocky
Otros Logs Relacionados
/var/log/auth.log # Authentication attempts
/var/log/syslog # System messages
/var/log/spamassassin/spamd.log # SpamAssassin
/var/log/opendkim.log # OpenDKIM (if configured)
Comprensión del Formato de Entradas de Log
Formato de Log de Postfix
Entrada de log estándar de Postfix:
Jan 11 10:30:45 mail postfix/smtp[12345]: ABCD1234: to=<[email protected]>, relay=mx.example.com[203.0.113.10]:25, delay=0.52, delays=0.01/0.02/0.15/0.34, dsn=2.0.0, status=sent (250 OK)
Componentes:
Jan 11 10:30:45- Marca de tiempomail- Nombre del hostpostfix/smtp- Servicio/demonio[12345]- ID de procesoABCD1234- Queue ID (identificador único de mensaje)to=<[email protected]>- Dirección del destinatariorelay=mx.example.com[203.0.113.10]:25- Servidor de destinodelay=0.52- Tiempo total de entrega (segundos)delays=0.01/0.02/0.15/0.34- antes de cola/en cola/conexión/transmisióndsn=2.0.0- Código de Notificación de Estado de Entregastatus=sent- Estado final de entrega(250 OK)- Respuesta SMTP
Formato de Log de Dovecot
Entrada de log estándar de Dovecot:
Jan 11 10:30:45 mail dovecot: imap-login: Login: user=<[email protected]>, method=PLAIN, rip=203.0.113.20, lip=203.0.113.10, mpid=12346, secured, session=<abc123>
Componentes:
Jan 11 10:30:45- Marca de tiempomail- Nombre del hostdovecot:- Servicioimap-login:- ComponenteLogin:- Acciónuser=<[email protected]>- Nombre de usuariomethod=PLAIN- Método de autenticaciónrip=203.0.113.20- IP remotalip=203.0.113.10- IP localmpid=12346- ID de proceso maestrosecured- Conexión cifradasession=<abc123>- ID de sesión
Comandos Básicos de Visualización de Logs
Ver Logs Recientes
# Last 50 lines
sudo tail -50 /var/log/mail.log
# Last 100 lines
sudo tail -100 /var/log/mail.log
# Real-time monitoring (follow mode)
sudo tail -f /var/log/mail.log
# Exit tail -f: Press Ctrl+C
Ver Archivo de Log Completo
# View with less (scrollable)
sudo less /var/log/mail.log
# Navigation in less:
# - Space: Next page
# - b: Previous page
# - /pattern: Search forward
# - ?pattern: Search backward
# - q: Quit
# View entire file with cat
sudo cat /var/log/mail.log
Ver Logs Antiguos
# List available log files
ls -lh /var/log/mail.log*
# View yesterday's log (if rotated)
sudo cat /var/log/mail.log.1
# View compressed older logs
sudo zcat /var/log/mail.log.2.gz
sudo zless /var/log/mail.log.3.gz
Búsqueda en Logs con Grep
Uso Básico de Grep
# Search for specific email address
sudo grep "[email protected]" /var/log/mail.log
# Case-insensitive search
sudo grep -i "error" /var/log/mail.log
# Show line numbers
sudo grep -n "bounced" /var/log/mail.log
# Show 3 lines of context (before and after)
sudo grep -C 3 "authentication failed" /var/log/mail.log
# Show only 5 lines after match
sudo grep -A 5 "connection timeout" /var/log/mail.log
# Count matches
sudo grep -c "status=sent" /var/log/mail.log
Patrones Avanzados de Grep
# Multiple patterns (OR)
sudo grep -E "bounced|deferred" /var/log/mail.log
# Pattern from file
echo "[email protected]" > /tmp/patterns.txt
echo "[email protected]" >> /tmp/patterns.txt
sudo grep -f /tmp/patterns.txt /var/log/mail.log
# Invert match (show lines NOT matching)
sudo grep -v "status=sent" /var/log/mail.log
# Recursive search in directory
sudo grep -r "specific-queue-id" /var/log/
# Search compressed logs
sudo zgrep "pattern" /var/log/mail.log.*.gz
Patrones de Expresiones Regulares
# Match email addresses
sudo grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" /var/log/mail.log
# Match IPv4 addresses
sudo grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /var/log/mail.log
# Match queue IDs (Postfix format)
sudo grep -E "[A-F0-9]{10}" /var/log/mail.log
# Match specific time range
sudo grep "Jan 11 10:[0-5][0-9]:" /var/log/mail.log
Tareas Comunes de Análisis de Logs
Tarea 1: Rastrear Email Específico
Rastrear un email por destinatario:
# Find all entries for recipient
sudo grep "to=<[email protected]>" /var/log/mail.log
# Get queue ID for email
QUEUE_ID=$(sudo grep "to=<[email protected]>" /var/log/mail.log | tail -1 | grep -oE "[A-F0-9]{10}")
# Track entire message flow by queue ID
sudo grep "$QUEUE_ID" /var/log/mail.log
Tarea 2: Contar Volumen Diario de Email
# Count emails sent today
sudo grep "status=sent" /var/log/mail.log | grep "$(date '+%b %d')" | wc -l
# Count by hour today
for hour in {00..23}; do
count=$(sudo grep "status=sent" /var/log/mail.log | grep "$(date '+%b %d') $hour:" | wc -l)
echo "Hour $hour: $count emails"
done
# Total sent this month
sudo grep "status=sent" /var/log/mail.log* | grep "$(date '+%b')" | wc -l
Tarea 3: Encontrar Emails Rebotados
# All bounced emails
sudo grep "status=bounced" /var/log/mail.log
# Bounced emails today
sudo grep "status=bounced" /var/log/mail.log | grep "$(date '+%b %d')"
# Bounced emails with reasons
sudo grep "status=bounced" /var/log/mail.log | grep -A 1 "status=bounced"
# Count bounces by reason
sudo grep "status=bounced" /var/log/mail.log | awk -F'[()]' '{print $2}' | sort | uniq -c | sort -rn
Tarea 4: Encontrar Fallos de Autenticación
# All authentication failures
sudo grep "authentication failed" /var/log/mail.log
# Failed auth with usernames
sudo grep "authentication failed" /var/log/mail.log | grep -oE "sasl_username=[^ ]*"
# Failed auth by IP
sudo grep "authentication failed" /var/log/mail.log | grep -oE "rip=[0-9.]+" | sort | uniq -c | sort -rn
# Failed IMAP/POP3 logins (Dovecot)
sudo grep "auth failed" /var/log/dovecot.log
Tarea 5: Encontrar Conexiones Rechazadas
# All rejected connections
sudo grep "reject:" /var/log/mail.log
# Rejections today
sudo grep "reject:" /var/log/mail.log | grep "$(date '+%b %d')"
# Count rejections by reason
sudo grep "reject:" /var/log/mail.log | awk -F'reject: ' '{print $2}' | cut -d: -f1 | sort | uniq -c | sort -rn
# Rejected by IP
sudo grep "reject:" /var/log/mail.log | grep -oE "\[[0-9.]+\]" | sort | uniq -c | sort -rn
Tarea 6: Encontrar Emails Diferidos
# All deferred emails
sudo grep "status=deferred" /var/log/mail.log
# Deferred with reasons
sudo grep "status=deferred" /var/log/mail.log | tail -20
# Count deferrals by reason
sudo grep "status=deferred" /var/log/mail.log | awk -F'[()]' '{print $2}' | sort | uniq -c | sort -rn
# Emails deferred to specific domain
sudo grep "status=deferred" /var/log/mail.log | grep "relay=mx.example.com"
Tarea 7: Encontrar Detección de Spam
# SpamAssassin detections
sudo grep "X-Spam-Status: Yes" /var/log/mail.log
# High spam scores
sudo grep "X-Spam-Status: Yes, score=" /var/log/mail.log | grep -oE "score=[0-9.]+" | sort -t= -k2 -rn | head -20
# Spam from specific sender
sudo grep "X-Spam-Status: Yes" /var/log/mail.log | grep "from=<[email protected]>"
Análisis Avanzado de Logs con AWK
AWK es poderoso para análisis estructurado de logs.
Extraer Campos Específicos
# Extract queue IDs
sudo grep "status=sent" /var/log/mail.log | awk '{print $6}' | cut -d: -f1
# Extract recipient addresses
sudo grep "to=<" /var/log/mail.log | grep -oE "to=<[^>]+>" | cut -d= -f2 | tr -d '<>'
# Extract sender addresses
sudo grep "from=<" /var/log/mail.log | grep -oE "from=<[^>]+>" | cut -d= -f2 | tr -d '<>'
Calcular Estadísticas
# Average delay time
sudo grep "status=sent" /var/log/mail.log | grep -oE "delay=[0-9.]+" | cut -d= -f2 | awk '{sum+=$1; count++} END {print "Average delay:", sum/count, "seconds"}'
# Maximum delay
sudo grep "status=sent" /var/log/mail.log | grep -oE "delay=[0-9.]+" | cut -d= -f2 | sort -rn | head -1
# Message size statistics
sudo grep "size=" /var/log/mail.log | grep -oE "size=[0-9]+" | cut -d= -f2 | awk '{sum+=$1; count++} END {print "Average size:", sum/count/1024, "KB"; print "Total:", sum/1024/1024, "MB"}'
Principales Remitentes/Destinatarios
# Top 10 senders
sudo grep "from=<" /var/log/mail.log | grep -oE "from=<[^>]+>" | sort | uniq -c | sort -rn | head -10
# Top 10 recipients
sudo grep "to=<" /var/log/mail.log | grep -oE "to=<[^>]+>" | sort | uniq -c | sort -rn | head -10
# Top sending domains
sudo grep "from=<" /var/log/mail.log | grep -oE "@[a-zA-Z0-9.-]+" | sort | uniq -c | sort -rn | head -10
# Top receiving domains
sudo grep "to=<" /var/log/mail.log | grep -oE "@[a-zA-Z0-9.-]+" | sort | uniq -c | sort -rn | head -10
Análisis de Conexiones
# Top connecting IPs
sudo grep "connect from" /var/log/mail.log | grep -oE "\[[0-9.]+\]" | sort | uniq -c | sort -rn | head -10
# Connections per hour today
for hour in {00..23}; do
count=$(sudo grep "connect from" /var/log/mail.log | grep "$(date '+%b %d') $hour:" | wc -l)
echo "$hour:00 - $count connections"
done
Creación de Scripts de Análisis Automatizados
Script de Reporte Diario de Email
sudo nano /usr/local/bin/daily-mail-report.sh
Agregar:
#!/bin/bash
DATE=$(date '+%b %d')
LOG="/var/log/mail.log"
echo "=== Daily Mail Report for $(date '+%Y-%m-%d') ==="
echo ""
echo "Email Volume:"
echo " Sent: $(grep "status=sent" $LOG | grep "$DATE" | wc -l)"
echo " Bounced: $(grep "status=bounced" $LOG | grep "$DATE" | wc -l)"
echo " Deferred: $(grep "status=deferred" $LOG | grep "$DATE" | wc -l)"
echo " Rejected: $(grep "reject:" $LOG | grep "$DATE" | wc -l)"
echo ""
echo "Authentication:"
echo " Failed attempts: $(grep "authentication failed" $LOG | grep "$DATE" | wc -l)"
echo " Successful logins: $(grep "Login:" /var/log/dovecot.log | grep "$DATE" | wc -l)"
echo ""
echo "Top 5 Senders:"
grep "from=<" $LOG | grep "$DATE" | grep -oE "from=<[^>]+>" | sort | uniq -c | sort -rn | head -5
echo ""
echo "Top 5 Recipients:"
grep "to=<" $LOG | grep "$DATE" | grep -oE "to=<[^>]+>" | sort | uniq -c | sort -rn | head -5
echo ""
echo "Recent Errors:"
grep -i "error" $LOG | grep "$DATE" | tail -10
Hacer ejecutable:
sudo chmod +x /usr/local/bin/daily-mail-report.sh
Programar diariamente:
sudo crontab -e
Agregar:
0 8 * * * /usr/local/bin/daily-mail-report.sh | mail -s "Daily Mail Report" [email protected]
Script de Alerta en Tiempo Real
sudo nano /usr/local/bin/mail-alert.sh
Agregar:
#!/bin/bash
LOG="/var/log/mail.log"
ALERT_EMAIL="[email protected]"
THRESHOLD=10
# Check authentication failures in last 5 minutes
AUTH_FAILURES=$(grep "authentication failed" $LOG | tail -100 | wc -l)
if [ $AUTH_FAILURES -gt $THRESHOLD ]; then
echo "WARNING: $AUTH_FAILURES authentication failures detected" | \
mail -s "ALERT: High Authentication Failures" $ALERT_EMAIL
fi
# Check queue size
QUEUE_SIZE=$(mailq | tail -1 | awk '{print $5}')
if [ "$QUEUE_SIZE" != "empty" ] && [ $QUEUE_SIZE -gt 100 ]; then
echo "WARNING: Mail queue has $QUEUE_SIZE messages" | \
mail -s "ALERT: Large Mail Queue" $ALERT_EMAIL
fi
Hacer ejecutable y programar:
sudo chmod +x /usr/local/bin/mail-alert.sh
sudo crontab -e
Agregar:
*/5 * * * * /usr/local/bin/mail-alert.sh
Script de Panel de Análisis de Logs
sudo nano /usr/local/bin/mail-dashboard.sh
Agregar:
#!/bin/bash
clear
echo "╔════════════════════════════════════════════════╗"
echo "║ MAIL SERVER DASHBOARD ║"
echo "╚════════════════════════════════════════════════╝"
echo ""
LOG="/var/log/mail.log"
TODAY=$(date '+%b %d')
# Real-time stats
echo "Real-time Statistics (today):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
SENT=$(grep "status=sent" $LOG | grep "$TODAY" | wc -l)
BOUNCED=$(grep "status=bounced" $LOG | grep "$TODAY" | wc -l)
DEFERRED=$(grep "status=deferred" $LOG | grep "$TODAY" | wc -l)
REJECTED=$(grep "reject:" $LOG | grep "$TODAY" | wc -l)
printf " %-20s %10s\n" "Sent:" "$SENT"
printf " %-20s %10s\n" "Bounced:" "$BOUNCED"
printf " %-20s %10s\n" "Deferred:" "$DEFERRED"
printf " %-20s %10s\n" "Rejected:" "$REJECTED"
echo ""
# Queue status
echo "Mail Queue:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
mailq | tail -1
echo ""
# Recent activity
echo "Last 5 Sent Emails:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
grep "status=sent" $LOG | tail -5 | awk '{print $1, $2, $3, $7}' | sed 's/to=<//g' | sed 's/>.*//g'
echo ""
# Errors
echo "Recent Errors:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
grep -i "error\|fatal" $LOG | tail -3
echo ""
echo "Last updated: $(date)"
Hacer ejecutable y ejecutar:
sudo chmod +x /usr/local/bin/mail-dashboard.sh
sudo /usr/local/bin/mail-dashboard.sh
Rotación y Gestión de Logs
Configurar Logrotate
sudo nano /etc/logrotate.d/rsyslog
Configurar:
/var/log/mail.log
{
rotate 7
daily
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
Opciones explicadas:
rotate 7: Mantener 7 días de logsdaily: Rotar diariamentecompress: Comprimir logs antiguosdelaycompress: No comprimir el log de ayer (aún se está escribiendo)
Rotación Manual de Logs
# Manually trigger rotation
sudo logrotate -f /etc/logrotate.d/rsyslog
# Check rotation status
sudo cat /var/lib/logrotate/status
Archivar Logs Antiguos
# Create archive directory
sudo mkdir -p /var/log/mail-archive
# Archive logs older than 30 days
sudo find /var/log -name "mail.log.*.gz" -mtime +30 -exec mv {} /var/log/mail-archive/ \;
# Create monthly archive
sudo tar czf /var/log/mail-archive/mail-$(date +%Y-%m).tar.gz /var/log/mail.log.*.gz
Limpiar Logs (¡Precaución!)
# Clear log file (keeps file, removes content)
sudo truncate -s 0 /var/log/mail.log
# Or
sudo > /var/log/mail.log
# NEVER delete log files while service is running!
# Always truncate or rotate instead
Optimización de Rendimiento
Limitar Verbosidad de Logs
Si los logs son demasiado grandes:
# Reduce Postfix verbosity
sudo postconf -e "smtpd_tls_loglevel = 0"
sudo postconf -e "smtp_tls_loglevel = 0"
sudo systemctl reload postfix
# Reduce Dovecot verbosity
sudo nano /etc/dovecot/conf.d/10-logging.conf
Establecer:
auth_verbose = no
auth_debug = no
mail_debug = no
Recargar:
sudo systemctl reload dovecot
Excluir Entradas Ruidosas
Usar rsyslog para filtrar:
sudo nano /etc/rsyslog.d/50-mail-filter.conf
Agregar:
# Exclude noisy entries
:msg, contains, "statistics:" stop
:msg, contains, "connect from localhost" stop
Reiniciar rsyslog:
sudo systemctl restart rsyslog
Seguridad y Cumplimiento
Proteger Archivos de Log
# Set restrictive permissions
sudo chmod 640 /var/log/mail.log
sudo chown syslog:adm /var/log/mail.log
# Protect log directory
sudo chmod 755 /var/log
Retención de Logs para Cumplimiento
Diferentes regulaciones requieren diferentes retenciones:
- GDPR: Período mínimo necesario
- HIPAA: 6 años
- SOX: 7 años
- PCI-DSS: 1 año
Configurar en consecuencia:
sudo nano /etc/logrotate.d/rsyslog
Para retención de 1 año:
/var/log/mail.log
{
rotate 365
daily
compress
delaycompress
}
Eliminar Datos Sensibles
Antes de compartir logs:
# Redact email addresses
sed 's/[a-zA-Z0-9._%+-]*@[a-zA-Z0-9.-]*/***@***/g' /var/log/mail.log
# Redact IP addresses
sed 's/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/XXX.XXX.XXX.XXX/g' /var/log/mail.log
Solución de Problemas con Logs
Patrones Comunes de Log
Éxito:
status=sent (250 2.0.0 OK)
Usuario desconocido:
status=bounced (User unknown)
Tiempo de espera de conexión agotado:
status=deferred (Connection timed out)
Fallo de autenticación:
authentication failed
auth failed
Error TLS:
TLS library problem
SSL_connect error
Disco lleno:
No space left on device
Mail queue file write error
Referencia de Códigos de Error
Códigos 2xx: Éxito
- 250: OK
- 251: Usuario no local; se reenviará
Códigos 4xx: Fallo temporal (reintentar más tarde)
- 421: Servicio no disponible
- 450: Buzón no disponible (ocupado)
- 451: Error local en el procesamiento
- 452: Almacenamiento del sistema insuficiente
- 454: TLS no disponible
Códigos 5xx: Fallo permanente (no reintentar)
- 550: Buzón no disponible (no existe)
- 551: Usuario no local
- 552: Asignación de almacenamiento excedida
- 553: Nombre de buzón no permitido
- 554: Transacción fallida
Conclusión
Ahora tienes conocimiento completo del análisis y diagnóstico de logs de email. Estas habilidades te permiten identificar rápidamente problemas, rastrear el flujo de mensajes, monitorear la salud del servidor y mantener operaciones de email óptimas.
Puntos Clave
- Comprender formatos de log: Saber cómo leer logs de Postfix y Dovecot
- Usar herramientas apropiadas: grep, awk, sed para análisis eficiente
- Crear reportes automatizados: El monitoreo regular detecta problemas temprano
- Mantener logs apropiadamente: Rotación, archivo y retención
- Asegurar datos sensibles: Proteger logs y redactar al compartir
Mejores Prácticas
- Monitorear diariamente: Revisar logs regularmente en busca de anomalías
- Automatizar alertas: Capturar problemas críticos inmediatamente
- Documentar patrones: Construir base de conocimientos de problemas comunes
- Retener apropiadamente: Equilibrar cumplimiento con costos de almacenamiento
- Asegurar acceso: Los logs contienen información sensible
Calendario Recomendado
Diario:
- Revisión rápida de errores y advertencias
- Verificar fallos de autenticación
- Verificar volumen normal de email
Semanal:
- Análisis detallado de tendencias
- Revisar principales remitentes/destinatarios
- Verificar estadísticas de diferidos/rebotados
Mensual:
- Archivar logs antiguos
- Actualizar scripts de análisis
- Revisar políticas de retención
Con estas habilidades y herramientas de análisis de logs, puedes mantener visibilidad completa de tu infraestructura de email, diagnosticar rápidamente problemas y asegurar operaciones de email confiables y seguras.


