Bienvenido de nuevo de ElCidJJ.
La respuesta depende de, exactamente, qué es lo que necesitas.
Quiero decir, que no es lo mismo enterarte
inmediatamente de cuando llega un correo, o al contrario, recibir el aviso con 5 minutos de retraso (de media).
En el primer caso, se podría poner un sistema basado en inotify para vigilar el archivo del buzón que quieres vigilar.
En el segundo caso, se podría poner un script que mirase los registros de actividad (logs) del correo electrónico, para ver los últimos 5 minutos y buscar por algo interesante.
Aquí te pongo un ejemplo propio. Este script analiza el log cada 5 minutos para ver las conexiones externas de Dovecot para ver si hay usuarios locales que se están conectando desde IP localizadas fuera de España. Y en ese caso, reportarlas por correo al administrador.
Using perl Syntax Highlighting
#!/usr/bin/perl
use v5.14.2;
use autodie;
use Geo::IP;
use Cache::FileCache;
# Leer puntero anterior
my $archivo_puntero = '/tmp/dovecot_mainlog.txt';
my $puntero = 0;
if (-f $archivo_puntero) {
open my $ARCHIVO, $archivo_puntero;
$puntero = 0+ <$ARCHIVO>;
close $ARCHIVO;
}
# Analizar registro de actividad smtp
my $archivo_log = '/var/log/mail.log';
$puntero = 0 if $puntero > -s $archivo_log;
exit if $puntero == -s $archivo_log;
my $gi = Geo::IP->open("/usr/share/GeoIP/GeoIP.dat", GEOIP_STANDARD);
my $gi_city = Geo::IP->open("/usr/share/GeoIP/GeoIPCity.dat", GEOIP_STANDARD);
my $gi_as = Geo::IP->open("/usr/share/GeoIP/GeoIPASNum.dat", GEOIP_STANDARD);
my %ip_mias = ( '37.187.72.99' => 1, '127.0.0.1' => 1 );
my %isp_legales = map { $_ => 1 }
(
'AS15169 Google LLC',
'AS15169 Google Inc.',
'AS18705 BlackBerry Limited',
'AS12479 France Telecom Espana SA',
'AS3215 Orange S.A.',
'AS60476 MRG Hosting B.V.',
'AS14618 Amazon.com, Inc.',
'AS47764 Mail.Ru',
);
my %ya_visto;
my $listado;
my $cache = Cache::FileCache->new({
'namespace' => 'Dovecot',
'default_expires_in' => '30 day',
'auto_purge_on_get' => 1,
});
open my $DOVECOT, '<', $archivo_log;
seek $DOVECOT, $puntero, 0;
while (my $linea = <$DOVECOT>) {
next if $linea !~ /^(?<time>.+?) ns3369693 dovecot: (?:imap|pop3)-login: Login: user=<(?<email>.+?@(?<dominio>.+?))>, .+? rip=(?<IP>.+?),/;
next if exists $ip_mias{ $+{IP} };
next if $ya_visto{"$+{IP}|$+{email}"}++;
my $pais = $gi->country_code_by_addr($+{IP});
next if $pais eq 'ES';
# casos especiales
my $record = $gi_city->record_by_addr($+{IP});
my $isp = $gi_as->name_by_addr($+{IP});
my $whois;
if (defined $record) {
$pais = $record->country_name;
}
else {
$whois = join('' => qx(whois $+{IP}));
($pais) = $whois =~ /country:\s+(\S+)/;
}
if (not defined $isp) {
$whois = join('' => qx(whois $+{IP})) if not $whois;
($isp) = $whois =~ /origin:\s+(\S+)/;
}
defined $isp or warn "ERROR al sacar registro de IP [$+{IP}]" and next;
next if exists $isp_legales{$isp};
my $clave = "$+{IP}|$+{email}";
my $en_cache = $cache->get($clave);
next if $en_cache;
$listado .= sprintf "$+{time} %-15s %36s %-20s %s\n", $+{IP}, $+{email}, $pais, $isp;
$cache->set($clave, 1);
}
$puntero = tell;
close $DOVECOT;
if ($listado) {
require Mail::Send;
my $msg = Mail::Send->new(
Subject => 'Conexiones dovecot sospechosas',
);
$msg->add('Content-Type', 'text/plain; charset=UTF-8');
my $fh = $msg->open;
print $fh $listado;
$fh->close;
}
open my $ARCHIVO, '>', $archivo_puntero;
print $ARCHIVO $puntero;
close $ARCHIVO;
Coloreado en 0.005 segundos, usando
GeSHi 1.0.8.4
El funcionamiento de la parte interesante es el siguiente:
- 8: uso un archivo en /tmp/ para guardar la posición de última lectura del registro
- 11: leo el archivo, que contiene esa posición (un número entero, nada más)
- 20: reposiciono la posición, en caso de que el registro se haya reducido (caso de renovación del registro)
- 21: salgo si no hubo actividad (!)
- 42: uso un objeto Cache::FileCache para recordar qué IP ya he analizado en el pasado. De esta manera, no envío informes duplicados
- 48: abrimos el registro y
- 49: colocamos el puntero de lectura
- 51: para todas las líneas del registro (hasta el final del archivo)
- 52: salto las líneas que no me interesan, y aprovecho para capturar los datos que necesito (la línea dice "salta a la siguiente línea si no coincide con esto", pero si es "esto" entonces los paréntesis de captura me atrapan lo que quiero)
- 53: salto a la línea siguiente si es una IP local mía
- 54: salto a la línea siguiente si es una IP asociada a un determinado buzón de correo que ya he analizado en este informe
- el resto del script analiza la localización de la IP (país, proveedor) y genera un informe que envía por correo al root.