source: postfix-logtools/poststat/poststat

Last change on this file was 632, checked in by ben, 9 years ago

adding mi_virus, see #28

  • Property svn:executable set to *
File size: 7.0 KB
Line 
1#!/usr/bin/env perl
2
3# 2010-06-26 vschmitt@bearstech.com
4# 2009-04-23 vcaron@bearstech.com
5
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19# Grep Postfix logs and gather various counters in JSON format,
20# one file per counter (useful to feed to some Flotr based graph)
21# Note:
22# - no real need to filter ou mon probes (24 checks/day)
23# - need to be careful to filter a/v email reinjections
24
25use strict;
26use warnings;
27use Getopt::Long;
28
29my %stat = (
30  ce_blacklist       => 0,
31  ce_hangup          => 0,
32  ce_helo_no_dns     => 0,
33  ce_helo_not_fqdn   => 0,
34  ce_ok              => 0,
35  ce_proto_error     => 0,
36  ce_psbl            => 0,
37  ce_sorbs           => 0,
38  ce_spamhaus        => 0,
39  ce_ssl_error       => 0,
40  ce_timeout         => 0,
41  ci_brute_force     => 0,
42  ci_connect_auth    => 0,
43  ci_connect_ext     => 0,
44  ci_connect_ext_tot => 0,
45  ci_connect_global  => 0,
46  ci_connect_int_tot => 0,
47  ci_connect_lan     => 0,
48  ci_connect_local   => 0,
49  ci_connect_mx      => 0,
50  ci_connect_tot     => 0,
51  ci_connect_wm      => 0,
52  grey_spf           => 0,
53  grey_delayed       => 0,
54  grey_autowl        => 0,
55  grey_hard_wl       => 0,
56  me_no_relay        => 0,
57  me_no_target       => 0,
58  me_sender_no_dns   => 0,
59  me_sender_not_fqdn => 0,
60  mi_bounced         => 0,
61  mi_count           => 0,
62  mi_deliver         => 0,
63  mi_ham             => 0,
64  mi_inbox           => 0,
65  mi_robot           => 0,
66  mi_size            => 0,
67  mi_spam            => 0,
68  mi_tot             => 0,
69  mi_unsure          => 0,
70  mi_vir_amav        => 0,
71  mi_vir_milt        => 0,
72  mi_virus           => 0,
73  mo_bounced         => 0,
74  mo_deferred        => 0,
75  mo_sent            => 0,
76);
77my @backupmx;
78my @lanservers;
79my @spamdir;
80my @unsuredir;
81GetOptions(
82  "backup-mx=s{,}"   => \@backupmx,
83  "lan-servers=s{,}" => \@lanservers,
84  "spam-dir=s{,}"    => \@spamdir,
85  "unsure-dir=s{,}"  => \@unsuredir
86);
87
88while (<STDIN>) {
89  # get greylisting info
90  $stat{grey_spf}++,            next if /.* milter-greylist: .* are SPF-compliant/;
91  $stat{grey_delayed}++,        next if /.* milter-greylist: .* delayed for/;
92  $stat{grey_autowl}++,         next if /.* milter-greylist: .* autowhitelisted for another/;
93  $stat{grey_hard_wl}++,        next if /.* milter-greylist: .* skipping greylist because.*is whitelisted/;
94
95  # spam
96  if (@spamdir) {
97      foreach my $spam (@spamdir) {
98          $stat{mi_spam}++,     next if /deliver\(.* mail .*$spam/;
99      }
100  }
101  if (@unsuredir) {
102      foreach my $unsure (@unsuredir) {
103           $stat{mi_unsure}++,  next if /deliver\(.* mail .*$unsure/;
104      }
105  }
106  $stat{mi_deliver}++,          next if /deliver\(.* mail /;
107
108  # virus with amavis
109  $stat{mi_vir_amav}++,         next if / amavis.*quarantine: .*virus-/;
110
111  next if !s/.* postfix\/(.*?)\[\d+\]: //;
112  my $prog = $1;
113  my $local_qid;
114
115  if ($prog eq 'smtpd') {
116    # Incoming SMTP connexions
117    if (@backupmx) {
118        foreach my $mx (@backupmx) {
119            $stat{ci_connect_mx}++,       next if /^connect from $mx/;
120        }
121    }
122    if (@lanservers) {
123         foreach my $lan (@lanservers) {
124            $stat{ci_connect_lan}++,      next if /^connect from $lan/;
125        }
126    }
127    $stat{ci_connect_wm}++,      next if /^([[:xdigit:]]{8,16}): client=localhost\[.*, sasl_username=/;
128    $stat{ci_connect_auth}++,    next if /^([[:xdigit:]]{8,16}): .*, sasl_username=/;
129    $stat{ci_connect_local}++,   next if /^connect from localhost/;
130    $stat{ci_connect_global}++,  next if /^connect/;
131    $stat{ci_brute_force}++,     next if /SASL LOGIN authentication failed/;
132
133    # Rejected connexions (no delivery)
134    $stat{ce_proto_error}++,     next if /^too many errors/;
135    $stat{ce_ssl_error}++,       next if /^SSL_accept error/;
136    $stat{ce_helo_not_fqdn}++,   next if /Helo command rejected: need fully-qualified hostname/;
137    $stat{ce_helo_no_dns}++,     next if /Helo command rejected: Host not found/;
138    # FIXME Did never match in tests
139    # try with /Recipient address rejected/ ?
140    $stat{ce_blacklist}++,       next if /Client host rejected/;
141    $stat{ce_psbl}++,            next if /blocked using psbl\.surriel\.com/;
142    $stat{ce_sorbs}++,           next if /blocked using dnsbl\.sorbs\.net/;
143    $stat{ce_spamhaus}++,        next if /blocked using sbl-xbl\.spamhaus\.org/;
144    $stat{ce_timeout}++,         next if /^timeout/;
145    $stat{ce_hangup}++,          next if /^lost connection/;
146
147    # Rejected messages
148    $stat{me_no_relay}++,        next if /Relay access denied/;
149    $stat{me_no_target}++,       next if /User unknown in (local recipient|virtual mailbox) table/;
150    $stat{me_sender_not_fqdn}++, next if /Sender address rejected: need fully-qualified address/;
151    $stat{me_sender_no_dns}++,   next if /Sender address rejected: Domain not found/;
152
153    $local_qid = $1 if /^([[:xdigit:]]{8,16}): client=localhost/;
154
155    #next if /^disconnect/;
156    #next if /^warning:/;
157    #next if /^table/;
158    next; # Ignore all other smtpd messages
159  }
160
161  if ($prog eq 'qmgr') {
162    next if !/^([[:xdigit:]]{8,16}): .*, size=(\d+), nrcpt=(\d+)/;
163    next if defined $local_qid and $1 eq $local_qid; # Ignore local emails (reinjections from a/v)
164
165    # Messages input (what's submitted)
166    $stat{mi_size} += $2;
167    $stat{mi_count} += $3;
168
169    next;
170  }
171
172  if ($prog eq 'cleanup') {
173    # virus with milter
174    $stat{mi_vir_milt}++,        next if / virus found: /;
175
176    next;
177  }
178
179  if ($prog eq 'pipe') {
180    $stat{mi_inbox}++,           next if / status=sent \(delivered via dovecot service\)/;
181    $stat{mi_bounced}++,         next if / status=bounced /;
182   
183    next;
184  }
185
186  if ($prog eq 'local') {
187    $stat{mi_robot}++,           next if / status=sent \(delivered to command/;
188   
189    next;
190  }
191
192  if ($prog eq 'smtp') {
193    $stat{mo_sent}++,            next if / status=sent /;
194    $stat{mo_bounced}++,         next if / status=bounced /;
195    $stat{mo_deferred}++,        next if / status=deferred /;
196
197  }
198}
199
200$stat{mi_ham}             = $stat{mi_deliver} - $stat{mi_spam} - $stat{mi_unsure};
201
202$stat{mi_virus}           = $stat{mi_vir_milt} + $stat{mi_vir_amav};
203
204$stat{ci_connect_ext_tot} = $stat{ci_connect_global} - $stat{ci_connect_auth};
205$stat{ci_connect_ext}     = $stat{ci_connect_ext_tot} - $stat{ci_connect_mx} - $stat{ci_connect_lan};
206$stat{ci_connect_int_tot} = $stat{ci_connect_auth} + $stat{ci_connect_wm};
207$stat{ci_connect_tot}     = $stat{ci_connect_ext_tot} + $stat{ci_connect_int_tot};
208
209$stat{mi_tot}             = $stat{mi_inbox} + $stat{mi_robot} + $stat{mi_bounced} + $stat{mo_sent} + $stat{mo_bounced};
210
211printf("%-20s: %u\n", $_, $stat{$_}) foreach sort keys %stat;
212
Note: See TracBrowser for help on using the repository browser.