mirror of
https://github.com/darold/sendmailanalyzer.git
synced 2026-05-15 14:15:56 -06:00
Add parsing of SPF/DKIM log entries. Thanks to r-sherwood for the feature request.
This commit is contained in:
parent
39bf967922
commit
709a398708
4 changed files with 325 additions and 8 deletions
|
|
@ -240,7 +240,6 @@ ERROR_CODE lang/ERROR_CODE
|
|||
# sender or recipient relay to determine the email direction.
|
||||
#VIRTUAL_DOMAIN_DB_QUERY SELECT name FROM virtual_domains
|
||||
|
||||
|
||||
# Syslog name of MimeDefang. Syslog write it to maillog with the pid as follow:
|
||||
# ... mimedefang.pl[1234] ... This is required to only parse relevant logged lines
|
||||
# Based on parsing mimedefang log generated by method md_graphdefang_log()
|
||||
|
|
@ -304,6 +303,10 @@ CLAMSMTPD_NAME clamsmtpd
|
|||
# Can be overwritten with --postgrey or -g
|
||||
POSTGREY_NAME postgrey|sqlgrey
|
||||
|
||||
# Syslog name of SPF and DKIM log entry. Syslog write it to maillog with the
|
||||
# pid as follow: ... opendmarc[1234] ...
|
||||
SPF_DKIM_NAME opendmarc|opendkim
|
||||
|
||||
# HTML charset to use. Default is iso-8859-1, but with cyrillics you may want
|
||||
# to use utf-8 instead.
|
||||
#HTML_CHARSET utf-8
|
||||
|
|
|
|||
4
debian/sendmailanalyzer.conf
vendored
4
debian/sendmailanalyzer.conf
vendored
|
|
@ -256,6 +256,10 @@ CLAMSMTPD_NAME clamsmtpd
|
|||
# Can be overwritten with --postgrey or -g
|
||||
POSTGREY_NAME postgrey|sqlgrey
|
||||
|
||||
# Syslog name of SPF and DKIM log entry. Syslog write it to maillog with the
|
||||
# pid as follow: ... opendmarc[1234] ...
|
||||
SPF_DKIM_NAME opendmarc|opendkim
|
||||
|
||||
# HTML charset to use. Default is iso-8859-1, but with cyrillics you may want
|
||||
# to use utf-8 instead.
|
||||
#HTML_CHARSET utf-8
|
||||
|
|
|
|||
236
sa_cache
236
sa_cache
|
|
@ -278,6 +278,7 @@ our %topauth = ();
|
|||
our %postgrey = ();
|
||||
our %toppostgrey = ();
|
||||
our %starttls = ();
|
||||
our %spf_dkim = ();
|
||||
|
||||
|
||||
####
|
||||
|
|
@ -634,6 +635,27 @@ sub do_hour_cache
|
|||
close(IN);
|
||||
}
|
||||
|
||||
$file = "$CONFIG{OUT_DIR}/$hostname/$year/$month/$day/spf_dkim.dat";
|
||||
if (open(IN, $file)) {
|
||||
while (my $l = <IN>) {
|
||||
chomp($l);
|
||||
# Format: Hour:Id:Type:Rule:Domain:Status
|
||||
@data = split(/:/, $l);
|
||||
$data[0] =~ /^(\d{2})/;
|
||||
next if ($1 ne $hour);
|
||||
if ($data[2] eq 'spf') {
|
||||
$localstat{$data[1]}{$data[2]}{$data[3]}{hour} = $data[0] if (!exists $localstat{$data[1]}{$data[2]}{$data[3]}{hour});
|
||||
#$localstat{$data[1]}{$data[2]}{$data[3]}{domain}{$data[4]}++;
|
||||
$localstat{$data[1]}{$data[2]}{$data[3]}{status}{$data[5]}++;
|
||||
} elsif ($data[2] eq 'dkim') {
|
||||
$localstat{$data[1]}{$data[2]}{hour} = $data[0] if (!exists $localstat{$data[1]}{$data[2]}{hour});
|
||||
#$localstat{$data[1]}{$data[2]}{domain}{$data[4]}++;
|
||||
$localstat{$data[1]}{$data[2]}{status}{$data[5]}++;
|
||||
}
|
||||
}
|
||||
close(IN);
|
||||
}
|
||||
|
||||
for my $typ (sort keys %ANTISPAM_NAME) {
|
||||
$file = "$CONFIG{OUT_DIR}/$hostname/$year/$month/$day/$typ.dat";
|
||||
if (open(IN, $file)) {
|
||||
|
|
@ -816,8 +838,6 @@ sub compute_top_stats
|
|||
$toppostgrey{rcpt}{$STATS->{$id}{rcpt}[$i]}++;
|
||||
}
|
||||
$toppostgrey{reason}{$STATS->{$id}{reason}}++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (exists $STATS->{$id}{spamtype} && grep(/^$STATS->{$id}{spamtype}$/, keys %ANTISPAM_NAME)) {
|
||||
|
|
@ -1475,6 +1495,25 @@ sub compute_global_stats
|
|||
$postgrey{reason}{$STATS->{$id}{reason}}++;
|
||||
}
|
||||
|
||||
if (exists $STATS->{$id}{spf}) {
|
||||
foreach my $r (keys %{ $STATS->{$id}{spf} }) {
|
||||
#foreach my $k (keys %{ $STATS->{$id}{spf}{$r}{domain} }) {
|
||||
# $spf_dkim{spf}{$r}{domain}{$k} += $STATS->{$id}{spf}{$r}{domain}{$k};
|
||||
#}
|
||||
foreach my $k (keys %{ $STATS->{$id}{spf}{$r}{status} }) {
|
||||
$spf_dkim{spf}{$r}{status}{$k} += $STATS->{$id}{spf}{$r}{status}{$k};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exists $STATS->{$id}{dkim}) {
|
||||
foreach my $k (keys %{ $STATS->{$id}{dkim}{status} }) {
|
||||
$spf_dkim{dkim}{status}{$k} += $STATS->{$id}{dkim}{status}{$k};
|
||||
}
|
||||
#foreach my $k (keys %{ $STATS->{$id}{dkim}{domain} }) {
|
||||
# $spf_dkim{dkim}{domain}{$k} += $STATS->{$id}{dkim}{domain}{$k};
|
||||
#}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Top STARTTLS stats
|
||||
|
|
@ -1637,6 +1676,32 @@ sub compute_global_stats
|
|||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%postgrey = ();
|
||||
|
||||
print OUT "\%::spf_dkim = (\n";
|
||||
print OUT "'spf' => {\n";
|
||||
foreach my $r (keys %{$spf_dkim{spf}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$spf_dkim{spf}{$r}}) {
|
||||
print OUT "\t\t'$s' => { ";
|
||||
foreach my $v (keys %{$spf_dkim{spf}{$r}{$s}}) {
|
||||
print OUT "'$v' => '$spf_dkim{spf}{$r}{$s}{$v}',";
|
||||
}
|
||||
print OUT " },\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT "'dkim' => {\n";
|
||||
foreach my $r (keys %{$spf_dkim{dkim}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$spf_dkim{dkim}{$r}}) {
|
||||
print OUT "\t\t'$s' => '$spf_dkim{dkim}{$r}{$s}',\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%spf_dkim = ();
|
||||
|
||||
# Viruses flows / Viruses delivery flows / syserr flows
|
||||
print OUT "\%::virus = (\n";
|
||||
|
|
@ -1831,6 +1896,7 @@ sub do_day_cache
|
|||
my %localpostgrey = ();
|
||||
my %localtoppostgrey = ();
|
||||
my %localstarttls = ();
|
||||
my %localspf_dkim = ();
|
||||
my $lbls = '';
|
||||
my %authval = ();
|
||||
foreach my $hour ("00" .. "23") {
|
||||
|
|
@ -1899,6 +1965,20 @@ sub do_day_cache
|
|||
$localpostgrey{reason}{$k} += $postgrey{reason}{$k};
|
||||
}
|
||||
%postgrey = ();
|
||||
|
||||
foreach my $r (keys %{$spf_dkim{spf}}) {
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{status}}) {
|
||||
$localspf_dkim{spf}{$r}{status}{$k} += $spf_dkim{spf}{$r}{status}{$k};
|
||||
}
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{domain}}) {
|
||||
$localspf_dkim{spf}{$r}{domain}{$k} += $spf_dkim{spf}{$r}{domain}{$k};
|
||||
}
|
||||
}
|
||||
foreach my $r (keys %{$spf_dkim{dkim}{status}}) {
|
||||
$localspf_dkim{dkim}{status}{$r} += $spf_dkim{dkim}{status}{$r};
|
||||
}
|
||||
%spf_dkim = ();
|
||||
|
||||
foreach my $k (keys %virus) {
|
||||
if (!grep(/^$k$/, 'lbls','x_label','values')) {
|
||||
$localvirus{$k} += $virus{$k};
|
||||
|
|
@ -2114,6 +2194,32 @@ sub do_day_cache
|
|||
print OUT ");\n\n";
|
||||
%localpostgrey = ();
|
||||
|
||||
print OUT "\%::spf_dkim = (\n";
|
||||
print OUT "'spf' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{spf}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{spf}{$r}}) {
|
||||
print OUT "\t\t'$s' => { ";
|
||||
foreach my $v (keys %{$localspf_dkim{spf}{$r}{$s}}) {
|
||||
print OUT "'$v' => '$localspf_dkim{spf}{$r}{$s}{$v}',";
|
||||
}
|
||||
print OUT " },\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT "'dkim' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{dkim}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{dkim}{$r}}) {
|
||||
print OUT "\t\t'$s' => '$localspf_dkim{dkim}{$r}{$s}',\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%localspf_dkim = ();
|
||||
|
||||
print OUT "\%::virus = (\n";
|
||||
print OUT "'inbound' => '$localvirus{inbound}',\n";
|
||||
print OUT "'inbound_bytes' => '$localvirus{inbound_bytes}',\n";
|
||||
|
|
@ -2644,6 +2750,7 @@ sub do_month_cache
|
|||
my %localpostgrey = ();
|
||||
my %localtoppostgrey = ();
|
||||
my %localstarttls = ();
|
||||
my %localspf_dkim = ();
|
||||
my $lbls = '';
|
||||
foreach my $day ("01" .. "31") {
|
||||
$lbls .= "$day:";
|
||||
|
|
@ -2712,6 +2819,20 @@ sub do_month_cache
|
|||
$localpostgrey{reason}{$k} += $postgrey{reason}{$k};
|
||||
}
|
||||
%postgrey = ();
|
||||
|
||||
foreach my $r (keys %{$spf_dkim{spf}}) {
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{status}}) {
|
||||
$localspf_dkim{spf}{$r}{status}{$k} += $spf_dkim{spf}{$r}{status}{$k};
|
||||
}
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{domain}}) {
|
||||
$localspf_dkim{spf}{$r}{domain}{$k} += $spf_dkim{spf}{$r}{domain}{$k};
|
||||
}
|
||||
}
|
||||
foreach my $r (keys %{$spf_dkim{dkim}{status}}) {
|
||||
$localspf_dkim{dkim}{status}{$r} += $spf_dkim{dkim}{status}{$r};
|
||||
}
|
||||
%spf_dkim = ();
|
||||
|
||||
foreach my $k (keys %virus) {
|
||||
if (!grep(/^$k$/, 'lbls','x_label','values')) {
|
||||
$localvirus{$k} += $virus{$k};
|
||||
|
|
@ -2928,6 +3049,32 @@ sub do_month_cache
|
|||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%localpostgrey = ();
|
||||
|
||||
print OUT "\%::spf_dkim = (\n";
|
||||
print OUT "'spf' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{spf}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{spf}{$r}}) {
|
||||
print OUT "\t\t'$s' => { ";
|
||||
foreach my $v (keys %{$localspf_dkim{spf}{$r}{$s}}) {
|
||||
print OUT "'$v' => '$localspf_dkim{spf}{$r}{$s}{$v}',";
|
||||
}
|
||||
print OUT " },\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT "'dkim' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{dkim}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{dkim}{$r}}) {
|
||||
print OUT "\t\t'$s' => '$localspf_dkim{dkim}{$r}{$s}',\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%localspf_dkim = ();
|
||||
|
||||
print OUT "\%::virus = (\n";
|
||||
print OUT "'inbound' => '$localvirus{inbound}',\n";
|
||||
|
|
@ -3452,6 +3599,7 @@ sub do_year_cache
|
|||
my %localpostgrey = ();
|
||||
my %localtoppostgrey = ();
|
||||
my %localstarttls = ();
|
||||
my %localspf_dkim = ();
|
||||
my $lbls = '';
|
||||
|
||||
foreach my $month ("01" .. "12") {
|
||||
|
|
@ -3520,6 +3668,20 @@ sub do_year_cache
|
|||
$localpostgrey{reason}{$k} += $postgrey{reason}{$k};
|
||||
}
|
||||
%postgrey = ();
|
||||
|
||||
foreach my $r (keys %{$spf_dkim{spf}}) {
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{status}}) {
|
||||
$localspf_dkim{spf}{$r}{status}{$k} += $spf_dkim{spf}{$r}{status}{$k};
|
||||
}
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{domain}}) {
|
||||
$localspf_dkim{spf}{$r}{domain}{$k} += $spf_dkim{spf}{$r}{domain}{$k};
|
||||
}
|
||||
}
|
||||
foreach my $r (keys %{$spf_dkim{dkim}{status}}) {
|
||||
$localspf_dkim{dkim}{status}{$r} += $spf_dkim{dkim}{status}{$r};
|
||||
}
|
||||
%spf_dkim = ();
|
||||
|
||||
foreach my $k (keys %virus) {
|
||||
if (!grep(/^$k$/, 'lbls','x_label','values')) {
|
||||
$localvirus{$k} += $virus{$k};
|
||||
|
|
@ -3739,7 +3901,33 @@ sub do_year_cache
|
|||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%localpostgrey = ();
|
||||
|
||||
|
||||
print OUT "\%::spf_dkim = (\n";
|
||||
print OUT "'spf' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{spf}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{spf}{$r}}) {
|
||||
print OUT "\t\t'$s' => { ";
|
||||
foreach my $v (keys %{$localspf_dkim{spf}{$r}{$s}}) {
|
||||
print OUT "'$v' => '$localspf_dkim{spf}{$r}{$s}{$v}',";
|
||||
}
|
||||
print OUT " },\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT "'dkim' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{dkim}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{dkim}{$r}}) {
|
||||
print OUT "\t\t'$s' => '$localspf_dkim{dkim}{$r}{$s}',\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%localspf_dkim = ();
|
||||
|
||||
print OUT "\%::virus = (\n";
|
||||
print OUT "'inbound' => '$localvirus{inbound}',\n";
|
||||
print OUT "'inbound_bytes' => '$localvirus{inbound_bytes}',\n";
|
||||
|
|
@ -4376,6 +4564,7 @@ sub do_week_cache
|
|||
my %localpostgrey = ();
|
||||
my %localtoppostgrey = ();
|
||||
my %localstarttls = ();
|
||||
my %localspf_dkim = ();
|
||||
my $lbls = '';
|
||||
my %authval = ();
|
||||
&clean_globals();
|
||||
|
|
@ -4448,6 +4637,20 @@ sub do_week_cache
|
|||
$localpostgrey{reason}{$k} += $postgrey{reason}{$k};
|
||||
}
|
||||
%postgrey = ();
|
||||
|
||||
foreach my $r (keys %{$spf_dkim{spf}}) {
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{status}}) {
|
||||
$localspf_dkim{spf}{$r}{status}{$k} += $spf_dkim{spf}{$r}{status}{$k};
|
||||
}
|
||||
foreach my $k (keys %{$spf_dkim{spf}{$r}{domain}}) {
|
||||
$localspf_dkim{spf}{$r}{domain}{$k} += $spf_dkim{spf}{$r}{domain}{$k};
|
||||
}
|
||||
}
|
||||
foreach my $r (keys %{$spf_dkim{dkim}{status}}) {
|
||||
$localspf_dkim{dkim}{status}{$r} += $spf_dkim{dkim}{status}{$r};
|
||||
}
|
||||
%spf_dkim = ();
|
||||
|
||||
foreach my $k (keys %virus) {
|
||||
if (!grep(/^$k$/, 'lbls','x_label','values')) {
|
||||
$localvirus{$k} += $virus{$k};
|
||||
|
|
@ -4673,6 +4876,32 @@ sub do_week_cache
|
|||
print OUT ");\n\n";
|
||||
%localpostgrey = ();
|
||||
|
||||
print OUT "\%::spf_dkim = (\n";
|
||||
print OUT "'spf' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{spf}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{spf}{$r}}) {
|
||||
print OUT "\t\t'$s' => { ";
|
||||
foreach my $v (keys %{$localspf_dkim{spf}{$r}{$s}}) {
|
||||
print OUT "'$v' => '$localspf_dkim{spf}{$r}{$s}{$v}',";
|
||||
}
|
||||
print OUT " },\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT "'dkim' => {\n";
|
||||
foreach my $r (keys %{$localspf_dkim{dkim}}) {
|
||||
print OUT "\t'$r' => {\n";
|
||||
foreach my $s (keys %{$localspf_dkim{dkim}{$r}}) {
|
||||
print OUT "\t\t'$s' => '$localspf_dkim{dkim}{$r}{$s}',\n";
|
||||
}
|
||||
print OUT "\t},\n";
|
||||
}
|
||||
print OUT "},\n";
|
||||
print OUT ");\n\n";
|
||||
%localspf_dkim = ();
|
||||
|
||||
print OUT "\%::virus = (\n";
|
||||
print OUT "'inbound' => '$localvirus{inbound}',\n";
|
||||
print OUT "'inbound_bytes' => '$localvirus{inbound_bytes}',\n";
|
||||
|
|
@ -4954,7 +5183,6 @@ sub do_week_cache
|
|||
print OUT ");\n\n";
|
||||
%localtoppostgrey = ();
|
||||
|
||||
|
||||
# Top virus statistics
|
||||
$top = 0;
|
||||
print OUT "\%::topvirus = (\n";
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ my %AMAVIS_ID = ();
|
|||
my %STARTTLS = ();
|
||||
my %SPAMPD = ();
|
||||
my %KEEP_TEMPORARY = ();
|
||||
my %SPF_DKIM = ();
|
||||
|
||||
# Collect command line arguments
|
||||
GetOptions (
|
||||
|
|
@ -116,6 +117,7 @@ GetOptions (
|
|||
'z|zcat=s' => \$CONFIG{ZCAT_PROG},
|
||||
'y|year=s' => \$CONFIG{DEFAULT_YEAR},
|
||||
'spamd=s' => \$CONFIG{SPAMD_NAME},
|
||||
'spf=s' => \$CONFIG{SPF_DKIM_NAME},
|
||||
'hostname=s' => \$HOSTNAME,
|
||||
);
|
||||
|
||||
|
|
@ -250,6 +252,8 @@ sendmailanalyzer v$VERSION usage:
|
|||
Default /usr/bin/zcat.
|
||||
--spamd name : syslog Spamd program name. Default: spamd.
|
||||
--hostname name : set a hostname for exim logs. Default: unknown.
|
||||
--spf name : syslog SPF and DKIM program name list.
|
||||
Default: opendmarc|opendkim.
|
||||
};
|
||||
exit 0;
|
||||
}
|
||||
|
|
@ -350,7 +354,7 @@ sub start_loop
|
|||
my $tmp_last_parsed = $l;
|
||||
# Only catch relevant logs
|
||||
next if ($CONFIG{EXCLUDE_LINE} && $tmp_last_parsed =~ m#$CONFIG{EXCLUDE_LINE}#);
|
||||
if ( ($tmp_last_parsed =~ /($CONFIG{MTA_NAME}|$CONFIG{MAILSCAN_NAME}|$CONFIG{AMAVIS_NAME}|$CONFIG{MD_NAME}|$CONFIG{CLAMD_NAME}|$CONFIG{POSTGREY_NAME}|$CONFIG{SPAMD_NAME}|$CONFIG{CLAMSMTPD_NAME})[\/\[:]/) || ($LAST_PARSED =~ $EXIM_REGEX) ) {
|
||||
if ( ($tmp_last_parsed =~ /($CONFIG{MTA_NAME}|$CONFIG{MAILSCAN_NAME}|$CONFIG{AMAVIS_NAME}|$CONFIG{MD_NAME}|$CONFIG{CLAMD_NAME}|$CONFIG{POSTGREY_NAME}|$CONFIG{SPAMD_NAME}|$CONFIG{CLAMSMTPD_NAME}|$CONFIG{SPF_DKIM_NAME})[\/\[:]/) || ($LAST_PARSED =~ $EXIM_REGEX) ) {
|
||||
if ($tmp_last_parsed ne $OLD_LAST_PARSED) {
|
||||
&dprint("Size is identique but data are more recent than the one at old offset. Rereading from start of the log file.") if ($CONFIG{DEBUG} > 0);
|
||||
seek(SA_FILE, 0, 0);
|
||||
|
|
@ -381,7 +385,7 @@ sub start_loop
|
|||
$l = '';
|
||||
# Only catch relevant logs
|
||||
next if ($CONFIG{EXCLUDE_LINE} && $LAST_PARSED =~ m#$CONFIG{EXCLUDE_LINE}#);
|
||||
if ( ($LAST_PARSED =~ /($CONFIG{MTA_NAME}|$CONFIG{MAILSCAN_NAME}|$CONFIG{AMAVIS_NAME}|$CONFIG{MD_NAME}|$CONFIG{CLAMD_NAME}|$CONFIG{POSTGREY_NAME}|$CONFIG{SPAMD_NAME}|$CONFIG{CLAMSMTPD_NAME})[\/\[:]/) || ($LAST_PARSED =~ $EXIM_REGEX) ) {
|
||||
if ( ($LAST_PARSED =~ /($CONFIG{MTA_NAME}|$CONFIG{MAILSCAN_NAME}|$CONFIG{AMAVIS_NAME}|$CONFIG{MD_NAME}|$CONFIG{CLAMD_NAME}|$CONFIG{POSTGREY_NAME}|$CONFIG{SPAMD_NAME}|$CONFIG{CLAMSMTPD_NAME}|$CONFIG{SPF_DKIM_NAME})[\/\[:]/) || ($LAST_PARSED =~ $EXIM_REGEX) ) {
|
||||
my $tmpos = tell(SA_FILE);
|
||||
if ($OLD_LAST_PARSED) {
|
||||
# Store the last position in the log
|
||||
|
|
@ -469,7 +473,7 @@ sub start_loop
|
|||
# Only catch relevant logs
|
||||
next if ($CONFIG{EXCLUDE_LINE} && $LAST_PARSED =~ m#$CONFIG{EXCLUDE_LINE}#);
|
||||
my $check_time = '';
|
||||
if ( ($LAST_PARSED =~ /($CONFIG{MTA_NAME}|$CONFIG{MAILSCAN_NAME}|$CONFIG{AMAVIS_NAME}|$CONFIG{MD_NAME}|$CONFIG{CLAMD_NAME}|$CONFIG{POSTGREY_NAME}|$CONFIG{SPAMD_NAME})[\/\[]/) || ($LAST_PARSED =~ $EXIM_REGEX) ) {
|
||||
if ( ($LAST_PARSED =~ /($CONFIG{MTA_NAME}|$CONFIG{MAILSCAN_NAME}|$CONFIG{AMAVIS_NAME}|$CONFIG{MD_NAME}|$CONFIG{CLAMD_NAME}|$CONFIG{POSTGREY_NAME}|$CONFIG{SPAMD_NAME}|$CONFIG{CLAMSMTPD_NAME}|$CONFIG{SPF_DKIM_NAME})[\/\[]/) || ($LAST_PARSED =~ $EXIM_REGEX) ) {
|
||||
# Extract common fields and store data in memory
|
||||
$check_time = &store_data(&parse_common_fields(split(/\s+/, $LAST_PARSED)));
|
||||
} else {
|
||||
|
|
@ -574,6 +578,8 @@ sub store_data
|
|||
&parse_postgrey("$date","$time",$host,$other);
|
||||
} elsif ($CONFIG{SPAMD_NAME} && ($type =~ /^$CONFIG{SPAMD_NAME}/i)) {
|
||||
&parse_spamd("$date","$time",$host,$other);
|
||||
} elsif ($CONFIG{SPF_DKIM_NAME} && ($type =~ /^$CONFIG{SPF_DKIM_NAME}/i)) {
|
||||
&parse_spf_dkim("$date","$time",$host,$other);
|
||||
} else {
|
||||
&dprint("Skipping unknown syslog report => $date $time $host [$type]: $other") if ($CONFIG{DEBUG} > 1);
|
||||
}
|
||||
|
|
@ -2137,6 +2143,44 @@ sub parse_spamd
|
|||
}
|
||||
}
|
||||
|
||||
####
|
||||
# Parse DKIM/SPF syslog output
|
||||
####
|
||||
sub parse_spf_dkim
|
||||
{
|
||||
my ($date,$time,$host,$str) = @_;
|
||||
|
||||
my $time_st = "$date$time";
|
||||
|
||||
#Jun 7 06:22:58 server opendmarc[980]: 2693E3640260: news.vendita--flash.com none
|
||||
if ($str =~ /^([^:]+): SPF\(([^\)]+)\): ([^\s]+) ([^\s]+)$/) {
|
||||
|
||||
my $id = $1;
|
||||
$SPF_DKIM{$host}{spf}{$id}{rule} = $2;
|
||||
$SPF_DKIM{$host}{spf}{$id}{status} = $4;
|
||||
$SPF_DKIM{$host}{spf}{$id}{domain} = &clean_relay($3);
|
||||
$SPF_DKIM{$host}{spf}{$id}{date} = $time_st;
|
||||
|
||||
#Jun 7 06:22:58 server opendkim[953]: 2693E3640260: DKIM verification successful
|
||||
} elsif ($str =~ /^([^:]+): DKIM (.*)$/) {
|
||||
|
||||
my $id = $1;
|
||||
$SPF_DKIM{$host}{dkim}{$id}{status} = $2;
|
||||
$SPF_DKIM{$host}{dkim}{$id}{date} = $time_st;
|
||||
|
||||
#Jun 7 08:43:51 server opendkim[953]: 07EE63640A96: DKIM-Signature field added (s=default, d=mydomain.com)
|
||||
} elsif ($str =~ /^([^:]+): DKIM-([^\(]+) \(s=([^,]+), d=([^\)]+)\)$/) {
|
||||
|
||||
my $id = $1;
|
||||
$SPF_DKIM{$host}{dkim}{$id}{status} = $2;
|
||||
$SPF_DKIM{$host}{dkim}{$id}{rule} = $3;
|
||||
$SPF_DKIM{$host}{dkim}{$id}{domain} = $4;
|
||||
$SPF_DKIM{$host}{dkim}{$id}{date} = $time_st;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
####
|
||||
# Decode email address and keep only email part
|
||||
####
|
||||
|
|
@ -2568,6 +2612,42 @@ sub flush_data
|
|||
# clear all postgrey memory storage
|
||||
%POSTGREY = ();
|
||||
|
||||
# SaveSPF/DKIM objects
|
||||
&dprint("Writing SPF/DKIM detail data to disk...");
|
||||
$nobj = 0;
|
||||
foreach my $host (keys %SPF_DKIM) {
|
||||
my %spf_dkims = ();
|
||||
foreach my $kind (keys %{$SPF_DKIM{$host}}) {
|
||||
foreach my $id (keys %{$SPF_DKIM{$host}{$kind}}) {
|
||||
if (exists $EXCLUDED{$id}) {
|
||||
delete $SPF_DKIM{$host}{$kind}{$id};
|
||||
next;
|
||||
}
|
||||
next if ($SPF_DKIM{$host}{$kind}{$id}{date} !~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
|
||||
# Key: year/month/day, Format: Hour:Id:type:rule:domain:status
|
||||
$spf_dkims{"$1/$2/$3"} .= "$4$5$6" . ':' . $id . ':' . $kind . ':' . $SPF_DKIM{$host}{$kind}{$id}{rule} . ':' . $SPF_DKIM{$host}{$kind}{$id}{domain} . ':' . $SPF_DKIM{$host}{$kind}{$id}{status} . "\n";
|
||||
$nobj++;
|
||||
}
|
||||
}
|
||||
foreach my $dir (keys %spf_dkims) {
|
||||
if (!-d "$CONFIG{OUT_DIR}/$host/$dir") {
|
||||
&create_directory("$host/$dir");
|
||||
}
|
||||
if (not open(OUT, ">>$CONFIG{OUT_DIR}/$host/$dir/spf_dkim.dat") ) {
|
||||
&logerror("Can't write to file $CONFIG{OUT_DIR}/$host/$dir/spf_dkim.dat: $!");
|
||||
&logerror("Data will be lost.");
|
||||
next;
|
||||
} else {
|
||||
print OUT $spf_dkims{$dir};
|
||||
close(OUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
&dprint("\tWrote $nobj spf/dkim object.");
|
||||
# clear all spf/dkim memory storage
|
||||
%SPF_DKIM = ();
|
||||
|
||||
|
||||
# Save Virus objects
|
||||
&dprint("Writing Virus data to disk...");
|
||||
$nobj = 0;
|
||||
|
|
@ -2840,6 +2920,7 @@ sub read_config
|
|||
$CONFIG{PID_DIR} ||= '/var/run';
|
||||
$CONFIG{POSTGREY_NAME} ||= 'postgrey|sqlgrey';
|
||||
$CONFIG{SPAMD_NAME} ||= 'spamd';
|
||||
$CONFIG{SPF_DKIM_NAME} ||= 'opendmarc|opendkim';
|
||||
}
|
||||
|
||||
####
|
||||
|
|
@ -3105,6 +3186,7 @@ sub clean_globals
|
|||
%STARTTLS = ();
|
||||
%SPAMPD = ();
|
||||
%KEEP_TEMPORARY = ();
|
||||
%SPF_DKIM = ();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue