El registro de todos los eventos es una de las funciones más importantes de cualquier sistema corporativo. Los registros permiten resolver problemas, auditar el funcionamiento de los sistemas de información y también investigar incidentes de seguridad de la información. Zimbra OSE también lleva registros detallados de su funcionamiento. En ellos se registran todos los datos, desde el rendimiento del servidor hasta el envío y recepción de correos por parte de los usuarios. Sin embargo, leer los registros generados por Zimbra OSE es una tarea bastante compleja. En este artículo, a través de un ejemplo concreto, explicaremos cómo leer los registros de Zimbra OSE y cómo centralizarlos.

Todos los registros locales de Zimbra OSE se almacenan en la carpeta /opt/zimbra/log, y también se pueden encontrar en el archivo /var/log/zimbra.log. El más importante de ellos es mailbox.log. En este se registran todas las acciones que ocurren en el servidor de correo. Entre ellas están la transferencia de correos, datos sobre la autenticación de los usuarios, intentos fallidos de inicio de sesión, entre otros. Las entradas en mailbox.log representan una cadena de texto que contiene la hora en que ocurrió el evento, el nivel del evento, el número del hilo en el que se produjo el evento, el nombre de usuario y su dirección IP, así como una descripción textual del evento.

El nivel del registro indica el grado de influencia del evento en el funcionamiento del servidor. Por defecto, se utilizan 4 niveles de eventos: INFO, WARN, ERROR y FATAL. Analicemos todos los niveles en orden creciente de gravedad.
- INFO — los eventos en este nivel están destinados a informar sobre el progreso del funcionamiento de Zimbra OSE. Entre los mensajes de este nivel se encuentran informes sobre la creación o eliminación de un buzón de correo, etc.
- WARN — los eventos en este nivel informan sobre situaciones que son potencialmente peligrosas, pero que no afectan el funcionamiento del servidor. Por ejemplo, un mensaje sobre un intento fallido de inicio de sesión de un usuario se marca con el nivel WARN.
- ERROR — este nivel de evento en el registro informa sobre la aparición de un error que es local y no impide el funcionamiento del servidor. Un ejemplo de este nivel podría ser un error en el que los datos de índice de un usuario en particular resultaron dañados.
- FATAL — este nivel se utiliza para marcar errores que impiden que el servidor continúe funcionando normalmente. Por ejemplo, un registro de FATAL podría ocurrir si no se puede conectar a la base de datos.
El archivo de registros del servidor de correo se actualiza todos los días. La versión más reciente del archivo siempre se llama Mailbox.log, mientras que los registros de un día determinado tienen la fecha en el nombre y están en un archivo comprimido. Por ejemplo, mailbox.log.2020-09-29.tar.gz. Esto simplifica significativamente la realización de copias de seguridad de los registros de acciones y la búsqueda en los logs.
Para la comodidad del administrador del sistema, en la carpeta /opt/zimbra/log/ se encuentran otros registros. Estos incluyen solo aquellos registros que se refieren a elementos específicos de Zimbra OSE. Por ejemplo, en audit.log solo se encuentran registros sobre la autenticación de usuarios, en clamd.log datos sobre el funcionamiento del antivirus y así sucesivamente. Cabe destacar que un excelente método de protección del servidor Zimbra OSE contra atacantes es , que funciona precisamente basado en audit.log. También es una buena práctica agregar una tarea cron para ejecutar el comando grep -ir "invalid password" /opt/zimbra/log/audit.log, para recibir diariamente información sobre los intentos fallidos de acceso.

Ejemplo de cómo en el log audit.log aparecen dos veces una contraseña incorrecta y un intento de inicio de sesión exitoso.
Los logs en Zimbra OSE pueden ser extremadamente útiles para determinar las causas de diversos fallos críticos. En el momento en que ocurre un error crítico, el administrador generalmente no tiene tiempo para leer los logs. Se requiere restaurar el funcionamiento del servidor lo más rápido posible. Sin embargo, luego, cuando el servidor vuelve a funcionar y genera una gran cantidad de logs, puede ser complicado encontrar el registro necesario en un archivo grande. Para encontrar rápidamente un registro de error, basta con saber el tiempo en que se reinició el servidor y buscar en los logs el registro datado en ese momento. El registro anterior será el que corresponda al error ocurrido. También se puede encontrar un mensaje de error mediante una búsqueda por la palabra clave FATAL.
Los logs de Zimbra OSE también permiten identificar fallos no críticos. Por ejemplo, para encontrar excepciones del manejador, se puede buscar la frase handler exception. A menudo, los errores generados por los manejadores vienen acompañados de un seguimiento de pila, que explica la causa de la excepción. En caso de errores en la entrega de correo, se debe comenzar la búsqueda con la palabra clave LmtpServer, mientras que para errores relacionados con los protocolos POP o IMAP, se pueden usar las palabras clave ImapServer y Pop3Server.
Los logs también pueden ayudar en la investigación de incidentes de seguridad informática. Consideremos un ejemplo concreto. El 20 de septiembre, uno de los empleados envió un correo infectado por un virus a un cliente. Como resultado, los datos en la computadora del cliente fueron cifrados. Sin embargo, el empleado jura que no envió nada. En el marco de la investigación del incidente, el departamento de seguridad de la empresa solicita al administrador del sistema los logs del servidor de correo del 20 de septiembre, relacionados con el usuario que está siendo investigado. Gracias a la marca de tiempo, el administrador del sistema encuentra el archivo necesario con los logs, extrae la información requerida y se la entrega a los de seguridad. Estos, a su vez, la revisan y descubren que la dirección IP desde la que se envió el correo correspondía. IP a la computadora del usuario. Las grabaciones de las cámaras de seguridad confirmaron que el empleado estaba en su lugar de trabajo al momento de enviar el correo. Esta información fue suficiente para acusarlo de violar las normas de seguridad informática y despedirlo.

Ejemplo de extracción de registros de una de las cuentas del log Mailbox.log a un archivo separado.
Todo se complica significativamente cuando se trata de una infraestructura multiservidor. Dado que los logs se recopilan localmente, trabajar con ellos en un entorno de infraestructura multiservidor es muy inconveniente, y por lo tanto surge la necesidad de centralizar la recolección de logs. Esto se puede lograr configurando un host para la recolección de logs. No es necesario añadir un host dedicado a la infraestructura. Cualquier servidor de correo puede funcionar como nodo para la recolección de logs. En nuestro caso, será el nodo Mailstore01.
En este servidor, necesitamos introducir los comandos que se detallan a continuación:
sudo su – zimbra
zmcontrol stop
exit
sudo /opt/zimbra/libexec/zmfixperms -e -vEdite el archivo /etc/sysconfig/rsyslog y establezca el parámetro SYSLOGD_OPTIONS="-r -c 2"
Edite /etc/rsyslog.conf y descomente las siguientes líneas:
$ModLoad imudp
$UDPServerRun 514
Ingrese los siguientes comandos:
sudo /etc/init.d/rsyslog stop
sudo /etc/init.d/rsyslog start
sudo su – zimbra
zmcontrol start
exit
sudo /opt/zimbra/libexec/zmloggerinit
sudo /opt/zimbra/bin/zmsshkeygen
sudo /opt/zimbra/bin/zmupdateauthkeysVerifique que todo funcione con el comando zmprov gacf | grep zimbraLogHostname. Después de ejecutar el comando, debería aparecer el nombre del host que recopila los logs. Para cambiarlo, debe ingresar el comando zmprov mcf zimbraLogHostname mailstore01.company.ru.
En todos los demás servidores de infraestructura (LDAP, MTA y otros almacenes de correo), ejecute el comando zmprov gacf | grep zimbraLogHostname para ver el nombre del host al que se envían los logs. También puede cambiarlo ingresando el comando zmprov mcf zimbraLogHostname mailstore01.company.ru.
Además, en cada servidor debe ingresar los siguientes comandos:
sudo su - zimbra
/opt/zimbra/bin/zmsshkeygen
/opt/zimbra/bin/zmupdateauthkeys
exit
sudo /opt/zimbra/libexec/zmsyslogsetup
sudo service rsyslog restart
sudo su - zimbra
zmcontrol restartDespués de esto, todos los logs se registrarán en el servidor que usted haya indicado, donde se podrán revisar de manera conveniente. Además, en la consola de administración de Zimbra OSE, en la pantalla con información sobre el estado de los servidores, el servicio Logger en funcionamiento solo aparecerá en el servidor mailstore01.

Otro dolor de cabeza para el administrador puede ser rastrear un correo electrónico específico. Dado que los correos electrónicos en Zimbra OSE pasan por varios eventos, como la verificación de antivirus, anti-spam, etc., antes de ser aceptados o enviados, puede resultar problemático para el administrador rastrear en qué etapa se perdió un correo electrónico si no llega.
Para resolver este problema, se puede utilizar un script especial desarrollado por el especialista en seguridad informática Víctor Dúkhoven y recomendado para su uso por los desarrolladores de Postfix. Este script concatena entradas de los registros de un proceso específico y permite visualizar rápidamente todas las entradas relacionadas con el envío de un determinado correo electrónico basado en su identificador. Su funcionamiento ha sido probado en todas las versiones de Zimbra OSE desde la 8.7. A continuación, se presenta el texto del script.
#! /usr/bin/perl
use strict;
use warnings;
# Postfix delivery agents
my @agents = qw(discard error lmtp local pipe smtp virtual);
my $instre = qr{(?x)
A # Absolute line start
(?:S+ s+){3} # Timestamp, adjust for other time formats
S+ s+ # Hostname
(postfix(?:-[^/s]+)?) # Capture instance name stopping before first '/'
(?:/S+)* # Optional non-captured '/'-delimited qualifiers
/ # Final '/' before the daemon program name
};
my $cmdpidre = qr{(?x)
G # Continue from previous match
(S+)[(d+)]:s+ # command[pid]:
};
my %smtpd;
my %smtp;
my %transaction;
my $i = 0;
my %seqno;
my %isagent = map { ($_, 1) } @agents;
while (<>) {
next unless m{$instre}ogc; my $inst = $1;
next unless m{$cmdpidre}ogc; my $command = $1; my $pid = $2;
if ($command eq "smtpd") {
if (m{Gconnect from }gc) {
# Start new log
$smtpd{$pid}->{"log"} = $_; next;
}
$smtpd{$pid}->{"log"} .= $_;
if (m{G(w+): client=}gc) {
# Fresh transaction
my $qid = "$inst/$1";
$smtpd{$pid}->{"qid"} = $qid;
$transaction{$qid} = $smtpd{$pid}->{"log"};
$seqno{$qid} = ++$i;
next;
}
my $qid = $smtpd{$pid}->{"qid"};
$transaction{$qid} .= $_
if (defined($qid) && exists $transaction{$qid});
delete $smtpd{$pid} if (m{Gdisconnect from}gc);
next;
}
if ($command eq "pickup") {
if (m{G(w+): uid=}gc) {
my $qid = "$inst/$1";
$transaction{$qid} = $_;
$seqno{$qid} = ++$i;
}
next;
}
# bounce(8) logs transaction start after cleanup(8) already logged
# the message-id, so the cleanup log entry may be first
#
if ($command eq "cleanup") {
next unless (m{G(w+): }gc);
my $qid = "$inst/$1";
$transaction{$qid} .= $_;
$seqno{$qid} = ++$i if (! exists $seqno{$qid});
next;
}
if ($command eq "qmgr") {
next unless (m{G(w+): }gc);
my $qid = "$inst/$1";
if (defined($transaction{$qid})) {
$transaction{$qid} .= $_;
if (m{Gremoved$}gc) {
print delete $transaction{$qid}, "n";
}
}
next;
}
# Save pre-delivery messages for smtp(8) and lmtp(8)
#
if ($command eq "smtp" || $command eq "lmtp") {
$smtp{$pid} .= $_;
if (m{G(w+): to=}gc) {
my $qid = "$inst/$1";
if (defined($transaction{$qid})) {
$transaction{$qid} .= $smtp{$pid};
}
delete $smtp{$pid};
}
next;
}
if ($command eq "bounce") {
if (m{G(w+): .*? notification: (w+)$}gc) {
my $qid = "$inst/$1";
my $newid = "$inst/$2";
if (defined($transaction{$qid})) {
$transaction{$qid} .= $_;
}
$transaction{$newid} =
$_ . $transaction{$newid};
$seqno{$newid} = ++$i if (! exists $seqno{$newid});
}
next;
}
if ($isagent{$command}) {
if (m{G(w+): to=}gc) {
my $qid = "$inst/$1";
if (defined($transaction{$qid})) {
$transaction{$qid} .= $_;
}
}
next;
}
}
# Dump logs of incomplete transactions.
foreach my $qid (sort {$seqno{$a} <=> $seqno{$b}} keys %transaction) {
print $transaction{$qid}, "n";
}El script está escrito en Perl y para ejecutarlo es necesario guardarlo en un archivo. collate.pl, hacerlo ejecutable y luego ejecutar el archivo especificando el archivo de registro y utilizando pgrep para extraer la información de identificación del correo buscado. collate.pl /var/log/zimbra.log | pgrep ''. El resultado será la salida secuenciada de las líneas que contienen información sobre el movimiento del correo en el servidor.
# collate.pl /var/log/zimbra.log | pgrep '<20200929101700.user@mail.company.ru>'
Oct 13 10:17:00 mail postfix/pickup[4089]: 4FF14284F45: uid=1034 from=********
Oct 13 10:17:00 mail postfix/cleanup[26776]: 4FF14284F45: message-id=*******
Oct 13 10:17:00 mail postfix/qmgr[9946]: 4FF14284F45: from=********, size=1387, nrcpt=1 (queue active)
Oct 13 10:17:00 mail postfix/smtp[7516]: Anonymous TLS connection established to mail.*******[168.*.*.4]:25: TLSv1 with cipher ADH-AES256-SHA (256/256 bits)
Oct 13 10:17:00 mail postfix/smtp[7516]: 4FF14284F45: to=*********, relay=mail.*******[168.*.*.4]:25, delay=0.25, delays=0.02/0.02/0.16/0.06, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 878833424CF)
Oct 13 10:17:00 mail postfix/qmgr[9946]: 4FF14284F45: removed
Oct 13 10:17:07 mail postfix/smtpd[21777]: connect from zimbra.******[168.*.*.4]
Oct 13 10:17:07 mail postfix/smtpd[21777]: Anonymous TLS connection established from zimbra.******[168.*.*.4]: TLSv1 with cipher ADH-AES256-SHA (256/256 bits)
Oct 13 10:17:08 mail postfix/smtpd[21777]: 0CB69282F4E: client=zimbra.******[168.*.*.4]
Oct 13 10:17:08 mail postfix/cleanup[26776]: 0CB69282F4E: message-id=zimbra.******
Oct 13 10:17:08 mail postfix/qmgr[9946]: 0CB69282F4E: from=zimbra.******, size=3606, nrcpt=1 (queue active)
Oct 13 10:17:08 mail postfix/virtual[5291]: 0CB69282F4E: to=zimbra.******, orig_to=zimbra.******, relay=virtual, delay=0.03, delays=0.02/0/0/0.01, dsn=2.0.0, status=sent (delivered to maildir)
Oct 13 10:17:08 mail postfix/qmgr[9946]: 0CB69282F4E: removedPara cualquier pregunta relacionada con Zextras Suite, puede ponerse en contacto con la representante de la empresa "Zextras" Ekaterina Triandafiliidi al correo electrónico katerina@zextras.com
Fuente: habr.com
