/[rrd-simple-monitoring]/bin/rrd-client-mta-traffic.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /bin/rrd-client-mta-traffic.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Thu Jul 16 18:48:19 2009 UTC (14 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 9251 byte(s)
import upstream http://rrd.me.uk/rrd-simple-monitoring.tar.gz

without prerequisities

1 #!/usr/bin/perl -w
2 # vim:ts=4:sw=4:tw=78
3
4 use constant MAIL_LOG => '/var/log/maillog';
5 use constant RRD_SERVER_URL => 'http://rrd.me.uk/cgi-bin/rrd-server.cgi';
6 use constant DEBUG => $ENV{DEBUG} ? 1 : 0;
7 use constant RRD_STEPPING => 60; # seconds
8
9 ############################################################
10 #
11 # NO USER SERVICABLE PARTS BEYOND THIS POINT
12 #
13 ############################################################
14
15
16 use 5.6.1;
17 use strict;
18 use warnings;
19
20 use Parse::Syslog qw();
21 use File::Tail qw();
22 use Getopt::Std qw();
23 use LWP::UserAgent qw();
24 use HTTP::Request::Common qw();
25 use Proc::DaemonLite qw();
26
27 our $VERSION = sprintf('%d.%02d', q$Revision: 1.1 $ =~ /(\d+)/g);
28
29 my $this_minute;
30 my %opt = ('ignore-localhost' => 1);
31 my %sum = map { $_ => 0 } qw(sent received bounced rejected spam virus);
32
33 #my $tail = File::Tail->new(name => MAIL_LOG, tail => -1);
34 my $tail = File::Tail->new(name => MAIL_LOG, tail => 0);
35
36 my $parser = new Parse::Syslog($tail,
37 year => (localtime(time))[5]+1900,
38 arrayref => 1,
39 type => 'syslog'
40 );
41
42 my $pid = Proc::DaemonLite::init_server();
43
44 while (my $sl = $parser->next) {
45 process_line($sl);
46 }
47
48 exit;
49
50
51 sub process_line {
52 my $sl = shift;
53 my $time = $sl->[0];
54 my $prog = $sl->[2];
55 my $text = $sl->[4];
56
57 if($prog eq 'exim') {
58 if($text =~ /^[0-9a-zA-Z]{6}-[0-9a-zA-Z]{6}-[0-9a-zA-Z]{2} <= \S+/) {
59 event($time, 'received');
60 }
61 elsif($text =~ /^[0-9a-zA-Z]{6}-[0-9a-zA-Z]{6}-[0-9a-zA-Z]{2} => \S+/) {
62 event($time, 'sent');
63 }
64 # rejected after DATA: Your message scored 10.4 SpamAssassin point. Report follows:
65 elsif($text =~ / rejected because \S+ is in a black list at \S+/) {
66 if($opt{'rbl-is-spam'}) {
67 event($time, 'spam');
68 } else {
69 event($time, 'rejected');
70 }
71 }
72 elsif($text =~ / rejected RCPT \S+: (Sender verify failed|Unknown user)/) {
73 event($time, 'rejected');
74 }
75 }
76 elsif($prog =~ /^postfix\/(.*)/) {
77 my $prog = $1;
78 if($prog eq 'smtp') {
79 if($text =~ /\bstatus=sent\b/) {
80 return if $opt{'ignore-localhost'} and
81 $text =~ /\brelay=[^\s\[]*\[127\.0\.0\.1\]/;
82 return if $opt{'ignore-host'} and
83 $text =~ /\brelay=[^\s,]*$opt{'ignore-host'}/oi;
84 event($time, 'sent');
85 }
86 elsif($text =~ /\bstatus=bounced\b/) {
87 event($time, 'bounced');
88 }
89 }
90 elsif($prog eq 'local') {
91 if($text =~ /\bstatus=bounced\b/) {
92 event($time, 'bounced');
93 }
94 }
95 elsif($prog eq 'smtpd') {
96 if($text =~ /^[0-9A-Z]+: client=(\S+)/) {
97 my $client = $1;
98 return if $opt{'ignore-localhost'} and
99 $client =~ /\[127\.0\.0\.1\]$/;
100 return if $opt{'ignore-host'} and
101 $client =~ /$opt{'ignore-host'}/oi;
102 event($time, 'received');
103 }
104 elsif($opt{'virbl-is-virus'} and $text =~ /^(?:[0-9A-Z]+: |NOQUEUE: )?reject: .*: 554.* blocked using virbl.dnsbl.bit.nl/) {
105 event($time, 'virus');
106 }
107 elsif($opt{'rbl-is-spam'} and $text =~ /^(?:[0-9A-Z]+: |NOQUEUE: )?reject: .*: 554.* blocked using/) {
108 event($time, 'spam');
109 }
110 elsif($text =~ /^(?:[0-9A-Z]+: |NOQUEUE: )?reject: /) {
111 event($time, 'rejected');
112 }
113 }
114 elsif($prog eq 'error') {
115 if($text =~ /\bstatus=bounced\b/) {
116 event($time, 'bounced');
117 }
118 }
119 elsif($prog eq 'cleanup') {
120 if($text =~ /^[0-9A-Z]+: (?:reject|discard): /) {
121 event($time, 'rejected');
122 }
123 }
124 }
125 elsif($prog eq 'sendmail' or $prog eq 'sm-mta') {
126 if($text =~ /\bmailer=local\b/ ) {
127 event($time, 'received');
128 }
129 elsif($text =~ /\bmailer=relay\b/) {
130 event($time, 'received');
131 }
132 elsif($text =~ /\bstat=Sent\b/ ) {
133 event($time, 'sent');
134 }
135 elsif($text =~ /\bmailer=esmtp\b/ ) {
136 event($time, 'sent');
137 }
138 elsif($text =~ /\bruleset=check_XS4ALL\b/ ) {
139 event($time, 'rejected');
140 }
141 elsif($text =~ /\blost input channel\b/ ) {
142 event($time, 'rejected');
143 }
144 elsif($text =~ /\bruleset=check_rcpt\b/ ) {
145 event($time, 'rejected');
146 }
147 elsif($text =~ /\bstat=virus\b/ ) {
148 event($time, 'virus');
149 }
150 elsif($text =~ /\bruleset=check_relay\b/ ) {
151 if (($opt{'virbl-is-virus'}) and ($text =~ /\bivirbl\b/ )) {
152 event($time, 'virus');
153 } elsif ($opt{'rbl-is-spam'}) {
154 event($time, 'spam');
155 } else {
156 event($time, 'rejected');
157 }
158 }
159 elsif($text =~ /\bsender blocked\b/ ) {
160 event($time, 'rejected');
161 }
162 elsif($text =~ /\bsender denied\b/ ) {
163 event($time, 'rejected');
164 }
165 elsif($text =~ /\brecipient denied\b/ ) {
166 event($time, 'rejected');
167 }
168 elsif($text =~ /\brecipient unknown\b/ ) {
169 event($time, 'rejected');
170 }
171 elsif($text =~ /\bUser unknown$/i ) {
172 event($time, 'bounced');
173 }
174 elsif($text =~ /\bMilter:.*\breject=55/ ) {
175 event($time, 'rejected');
176 }
177 }
178 elsif($prog eq 'amavis' || $prog eq 'amavisd') {
179 if( $text =~ /^\([0-9-]+\) (Passed|Blocked) SPAM(?:MY)?\b/) {
180 event($time, 'spam'); # since amavisd-new-2004xxxx
181 }
182 elsif($text =~ /^\([0-9-]+\) (Passed|Not-Delivered)\b.*\bquarantine spam/) {
183 event($time, 'spam'); # amavisd-new-20030616 and earlier
184 }
185 ### UNCOMMENT IF YOU USE AMAVISD-NEW <= 20030616 WITHOUT QUARANTINE:
186 #elsif($text =~ /^\([0-9-]+\) Passed, .*, Hits: (\d*\.\d*)/) {
187 # if ($1 >= 5.0) { # amavisd-new-20030616 without quarantine
188 # event($time, 'spam');
189 # }
190 #}
191 elsif($text =~ /^\([0-9-]+\) (Passed |Blocked )?INFECTED\b/) {
192 if($text !~ /\btag2=/) { # ignore new per-recipient log entry (2.2.0)
193 event($time, 'virus');# Passed|Blocked inserted since 2004xxxx
194 }
195 }
196 elsif($text =~ /^\([0-9-]+\) (Passed |Blocked )?BANNED\b/) {
197 if($text !~ /\btag2=/) {
198 event($time, 'virus');
199 }
200 }
201 # elsif($text =~ /^\([0-9-]+\) Passed|Blocked BAD-HEADER\b/) {
202 # event($time, 'badh');
203 # }
204 elsif($text =~ /^Virus found\b/) {
205 event($time, 'virus');# AMaViS 0.3.12 and amavisd-0.1
206 }
207 }
208 elsif($prog eq 'vagatefwd') {
209 # Vexira antivirus (old)
210 if($text =~ /^VIRUS/) {
211 event($time, 'virus');
212 }
213 }
214 elsif($prog eq 'hook') {
215 # Vexira antivirus
216 if($text =~ /^\*+ Virus\b/) {
217 event($time, 'virus');
218 }
219 # Vexira antispam
220 elsif($text =~ /\bcontains spam\b/) {
221 event($time, 'spam');
222 }
223 }
224 elsif($prog eq 'avgatefwd' or $prog eq 'avmailgate.bin') {
225 # AntiVir MailGate
226 if($text =~ /^Alert!/) {
227 event($time, 'virus');
228 }
229 elsif($text =~ /blocked\.$/) {
230 event($time, 'virus');
231 }
232 }
233 elsif($prog eq 'avcheck') {
234 # avcheck
235 if($text =~ /^infected/) {
236 event($time, 'virus');
237 }
238 }
239 elsif($prog eq 'spamd') {
240 if($text =~ /^(?:spamd: )?identified spam/) {
241 event($time, 'spam');
242 }
243 # ClamAV SpamAssassin-plugin
244 elsif($text =~ /(?:result: )?CLAMAV/) {
245 event($time, 'virus');
246 }
247 }
248 elsif($prog eq 'dspam') {
249 if($text =~ /spam detected from/) {
250 event($time, 'spam');
251 }
252 }
253 elsif($prog eq 'spamproxyd') {
254 if($text =~ /^\s*SPAM/ or $text =~ /^identified spam/) {
255 event($time, 'spam');
256 }
257 }
258 elsif($prog eq 'drweb-postfix') {
259 # DrWeb
260 if($text =~ /infected/) {
261 event($time, 'virus');
262 }
263 }
264 elsif($prog eq 'BlackHole') {
265 if($text =~ /Virus/) {
266 event($time, 'virus');
267 }
268 if($text =~ /(?:RBL|Razor|Spam)/) {
269 event($time, 'spam');
270 }
271 }
272 elsif($prog eq 'MailScanner') {
273 if($text =~ /(Virus Scanning: Found)/ ) {
274 event($time, 'virus');
275 }
276 elsif($text =~ /Bounce to/ ) {
277 event($time, 'bounced');
278 }
279 elsif($text =~ /^Spam Checks: Found ([0-9]+) spam messages/) {
280 my $cnt = $1;
281 for (my $i=0; $i<$cnt; $i++) {
282 event($time, 'spam');
283 }
284 }
285 }
286 elsif($prog eq 'clamsmtpd') {
287 if($text =~ /status=VIRUS/) {
288 event($time, 'virus');
289 }
290 }
291 elsif($prog eq 'clamav-milter') {
292 if($text =~ /Intercepted/) {
293 event($time, 'virus');
294 }
295 }
296 # uncommment for clamassassin:
297 #elsif($prog eq 'clamd') {
298 # if($text =~ /^stream: .* FOUND$/) {
299 # event($time, 'virus');
300 # }
301 #}
302 elsif ($prog eq 'smtp-vilter') {
303 if ($text =~ /clamd: found/) {
304 event($time, 'virus');
305 }
306 }
307 elsif($prog eq 'avmilter') {
308 # AntiVir Milter
309 if($text =~ /^Alert!/) {
310 event($time, 'virus');
311 }
312 elsif($text =~ /blocked\.$/) {
313 event($time, 'virus');
314 }
315 }
316 elsif($prog eq 'bogofilter') {
317 if($text =~ /Spam/) {
318 event($time, 'spam');
319 }
320 }
321 elsif($prog eq 'filter-module') {
322 if($text =~ /\bspam_status\=(?:yes|spam)/) {
323 event($time, 'spam');
324 }
325 }
326 elsif($prog eq 'sta_scanner') {
327 if($text =~ /^[0-9A-F]+: virus/) {
328 event($time, 'virus');
329 }
330 }
331 }
332
333 sub event {
334 my ($t, $type) = @_;
335 update($t) && $sum{$type}++;
336 }
337
338 # returns 1 if $sum should be updated
339 sub update($) {
340 my $t = shift;
341 my $m = $t - $t % RRD_STEPPING;
342 $this_minute = $m unless defined $this_minute;
343 return 1 if $m == $this_minute;
344 return 0 if $m < $this_minute;
345
346 my $data = '';
347 for (sort keys %sum) {
348 $data .= "$this_minute.mail.traffic.$_ $sum{$_}\n";
349 }
350 warn $data if DEBUG;
351
352 my $ua = LWP::UserAgent->new(agent => $0);
353 my $resp = $ua->request(
354 HTTP::Request::Common::POST(
355 RRD_SERVER_URL,
356 Content_Type => 'text/plain',
357 Content => $data
358 )
359 );
360 if ($resp->is_success) {
361 printf("%s\n",$resp->content);
362 } else {
363 warn 'Posting Error: '.$resp->status_line;
364 }
365
366 $this_minute = $m;
367 $sum{$_} = 0 for keys %sum;
368 return 1;
369 }
370
371 __END__
372

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26