Hello Marcel, > does ClamAV provide SNMP support? My idea is that ClamAV sends snmp > traps with all information (like the results at the prompt) to a snmp > server like OpenNMS, when a virus was found. OpenNMS is a network > management system. Primary it monitors network infrastructures. But > you can also handle snmp traps from printers, servers, programs and > and and... > So why not from ClamAV?
You're talking about the command line (prompt) so I guess you are not scanning emails but rather directories... but, who knows, this might give you ideas. I use ClamAV for mail scanning and I don't send traps on mail viruses and spams as there are too many of them, but I let my management system query the mail relay via SNMP every 5 minutes. I added this to my snmpd.conf: exec 1.3.6.1.4.1.2021.8.990 mailstat.pl /usr/sbin/mailstat.pl -t exec 1.3.6.1.4.1.2021.8.991 mailstat.pl /usr/sbin/mailstat.pl -v And I created the mailstat.pl as follows. Of course, depending on your needs and on the tools you use, you might have to tune this... It computes statistics out of /var/log/syslog and out of the output of /usr/bin/mailstats (that you might need to initialize first, and reset at midnight for instance). Persistent counters are saved in /var/log/mailstats. --mailstat.pl--------------------------- #!/usr/bin/perl # Dhn, 2008/06/30 # Script used by snmpd to collect and return mail statistics but # it can run from the CLI too. # Usage: mailstat.pl [-t] [-v] # Returns the "title:value" statistics by defaults, or only the titles (-t) # or only the values (-v). The statistics are always displayed in the # same order (see @keys array). #use strict; # Defaults my $in="/var/log/syslog"; # log pipe my $stats="/var/log/mailstats"; # persistent counters my $fl = ""; # flags for output (''|t|v) my %ctr = (); # current counters my $w = 0; # write flag my @ln = (); # splitted line my @arr = (); # splitted word my @stat = (); # file stats my $key = ""; # one hash key my $out = ""; # buffer for outputt #my $pos = 0; # current position my @keys = qw/accepted blacklisted discard greeting ham mail pca seen spam unknown virus bytesfr bytesto msgsfr msgsto connfr connto mailq inode position zlast/; # Functions / handlers sub writestats { $ctr{"seen"} = $ctr{"greeting"} + $ctr{"blacklisted"} + $ctr{"unknown"} + $ctr{"spam"} + + $ctr{"virus"} + $ctr{"ham"}; $ctr{"accepted"} = $ctr{"spam"} - $ctr{"discard"} + $ctr{"ham"}; $ctr{"pca"} = int(($ctr{"seen"} != 0) ? (10000 * $ctr{"accepted"} / $ctr{"seen"}) : 0)/100; #$ctr{"position"} = $pos; open OUT, ">", $stats or die "Cannot open $stats for writing: $!\n"; $out = ""; #foreach $key (sort keys %ctr) { foreach $key (@keys) { if ($key eq "zlast") { printf OUT "%12s: %-60s\n", $key, $ctr{$key}; } else { printf OUT "%12s: %12d\n", $key, $ctr{$key}; } &saveout($key); } close OUT; $w = 0; } sub saveout { my $key = @_[0]; return if ($key eq "inode" || $key eq "position" || $key eq "zlast"); if ($fl eq "t") { $out .= "$key\n"; } elsif ($fl eq "v") { $out .= "$ctr{$key}\n"; } else { $out .= sprintf("%12s: %12d\n", $key, $ctr{$key}); } } sub computestats { seek IN, $ctr{"position"}, SEEK_SET; #$pos = $ctr{"position"}; while (<IN>) { #$pos += length($_); $ctr{"position"} += length($_); $ctr{"zlast"} = substr($_, 0, 60); @ln = split; if (/ sendmail.* reject=550 5.7.1 Spam blocked /) { $ctr{"blacklisted"}++; $w++; } elsif (/ sendmail.* reject=550 5.1.1 .* User unknown/) { $ctr{"unknown"}++; $w++; } elsif (/ sendmail.* due to pre-greeting traffic/) { $ctr{"greeting"}++; $w++; } elsif ($ln[4] =~ /^mimedefang.pl/ && $ln[8] =~ /^MDLOG,/) { @arr = split /,/, $ln[8]; #if ($arr[2] eq "spam" && $arr[3] > 9) { # $ctr{"spam"}++; $ctr{"discard"}++; $w++; if ($arr[2] eq "spamd") { $ctr{"spam"}++; $ctr{"discard"}++; $w++; } elsif ($arr[2] eq "spam") { $ctr{"spam"}++; $w++; } elsif ($arr[2] eq "virus") { if ($arr[3] =~ /^Sanesecurity/) { $ctr{"spam"}++; $ctr{"discard"}++; $w++; } else { $ctr{"virus"}++; $w++; } } elsif ($arr[2] eq "ham") { $ctr{"ham"}++; $w++; } elsif ($arr[2] eq "mail_in") { $ctr{"mail"}++; $w++; } } &writestats if ($w >= 100); } } sub sendmailstats { open STATS, "/usr/bin/mailstats|" or die "$0: mailstats error /usr/bin/mailstats: $!"; while (chomp ($line = <STATS>)) { if ($. > 2) { ($m, $line) = split(' ', $line, 2); if ($m eq "T") { ($msgsfr, $bytesfr, $msgsto, $bytesto) = (split (/ +/, $line))[0,1,2,3]; chop $bytesfr; # remove "K" chop $bytesto; } elsif ($m eq "C") { ($connfr, $connto, $connrej) = split (/ +/, $line); } } } close STATS; $ctr{"bytesfr"} = $bytesfr * 1024; $ctr{"bytesto"} = $bytesto * 1024; $ctr{"msgsfr"} = $msgsfr; $ctr{"msgsto"} = $msgsto; $ctr{"connfr"} = $connfr; $ctr{"connto"} = $connto; $mailq = qx:ls /var/spool/mqueue/q* 2>/dev/null | wc -l:; $mailq =~ s/\s//g; $ctr{"mailq"} = $mailq; $w++; } sub terminate { &writestats if ($w >= 1); print $out; exit 0; } $SIG{"INT"} = \&terminate; $SIG{"QUIT"} = \&terminate; $SIG{"TERM"} = \&terminate; $SIG{"HUP"} = \&writestats; # Parse arguments while ($o = shift @ARGV) { if ($o eq "-t") { $fl = "t"; } elsif ($o eq "-v") { $fl = "v"; } else { print "Usage: $0 [-t|-v]\n"; print " Compute mail statistics and display the result (counters).\n"; print " -t display only titles, -v display only values\n"; exit 1; } } # Read current counters open IN, $stats or die "Cannot open $stats for reading: $!\n"; while (chomp($_ = <IN>)) { /^ *(\S+): +(.+)$/; $ctr{$1} = $2; &saveout($1); } close IN; &sendmailstats; # Compute new totals open IN, $in or die "Cannot open $in for reading: $!\n"; @stat = stat IN; $ctr{"inode"} = @stat[1] unless (defined $ctr{"inode"}); $ctr{"position"} = 0 unless (defined $ctr{"position"}); if ($stat[1] != $ctr{"inode"}) { close IN; open IN, "$in.0" or die "Cannot open $in.0 for reading: $!\n"; &computestats; close IN; open IN, $in or die "Cannot open $in for reading: $!\n"; $ctr{"inode"} = @stat[1]; $ctr{"position"} = 0; #$pos = 0; &writestats; } &computestats; close IN; &terminate; # End of script ----------------------------------- I give no guarantee on this script... and I don't say it is the best ever written but it works well here. HTH, Pierre _______________________________________________ Help us build a comprehensive ClamAV guide: visit http://wiki.clamav.net http://www.clamav.net/support/ml