Fwd: Patches for amavis emerge vsftpd Dovecot Postfix
"Kirk Bauer" <[email protected]>
| Newsgroups | gmane.comp.log.logwatch.devel |
|---|---|
| Message-ID | <[email protected]> |
------------------------------------------------------ Kirk Bauer <[email protected]> http://linux.kaybee.org | www.logwatch.org Author, Automating UNIX & Linux Administration ---------- Forwarded message ---------- From: Johny Ă…gotnes <[email protected]> Date: Sun, Sep 14, 2008 at 3:53 AM Subject: Patches for amavis emerge vsftpd Dovecot Postfix To: [email protected] Please find attached some tidy-ups to deal with recent versions of these programs. As I've updated my Gentoo server the logfile generated grew to some 650kb with all the exceptions left in, now down to some 6kb and more focused for my needs. Most changes should be generic and useful to anyone, feel free to use as you see fit. Postfix might not be so useful though, it is based on the 7.3.6 release as I much preferred this format over the CVS version. There is a definite need to trim the output from Postfix 2.5.5 though as it has a massive exception list. Thanks for a great wee log analyser! :)Johny --- /root/logwatch/scripts/services/dovecot 2008-08-11 17:38:02.000000000 +0200 +++ dovecot 2008-09-14 11:57:57.000000000 +0200 @@ -130,7 +130,7 @@ $Disconnected{$Reason}++; } elsif (($Reason, $Host) = ($ThisLine =~ /TLS initialization failed/) ) { $TLSInitFail++; - } elsif (($Host) = ($ThisLine =~ /Aborted login \[(.*)\]/) ) { + } elsif (($Host) = ($ThisLine =~ /^dovecot: imap-login: Aborted login/) ) { $Aborted{$Host}++; # This is for Dovecot 1.0 series @@ -143,6 +143,8 @@ $Disconnected{"no reason"}++; } elsif (($Reason) = ($ThisLine =~ /pop3-login: Disconnected: (.+)/) ) { $Disconnected{"no reason"}++; + } elsif (($Reason) = ($ThisLine =~ /imap-login: Disconnected (.+)/) ) { + $Disconnected{"no reason"}++; } elsif (($Reason) = ($ThisLine =~ /imap-login: Disconnected: (.+)/) ) { $Disconnected{"no reason"}++; } elsif (($Reason) = ($ThisLine =~ /IMAP.+: Disconnected: (.+)/) ) { @@ -165,7 +167,7 @@ print "\nDovecot was killed, and not restarted afterwards.\n"; } -if ( ( $Detail >=5 ) and $Restarts ) { +if ( ( $Detail >=0 ) and $Restarts ) { print "\nDovecot restarted $Restarts time(s)."; } @@ -215,7 +217,7 @@ " |" . " " x $totalSpaceLength . $TotalCount . "\n"; } -if ( ( $Detail >= 10 ) and (keys %Login)) { +if ( ( $Detail >= 0 ) and (keys %Login)) { print "\n\nDovecot IMAP and POP3 Successful Logins:"; $LoginCount = 0; foreach my $User (keys %Login) { @@ -245,7 +247,7 @@ print "\n\nTotal: $LoginCount successful logins"; } -if (keys %Disconnected) { +if ((keys %Disconnected) && ($Detail >= 10)) { print "\n\nDovecot disconnects:"; foreach my $Reason (sort keys %Disconnected) { print "\n $Reason: $Disconnected{$Reason} Time(s)"; --- /root/logwatch/scripts/services/emerge 2008-07-01 01:07:51.000000000 +0200 +++ emerge 2008-09-14 12:13:28.000000000 +0200 @@ -49,6 +49,7 @@ ($ThisLine =~ /Compiling/) or ($ThisLine =~ /=== sync/) or ($ThisLine =~ /Starting rsync with/i) or + ($ThisLine =~ /Starting retry/) or ($ThisLine =~ /Merging/) or ($ThisLine =~ /Unmerging./) or ($ThisLine =~ /AUTOCLEAN/) or --- /root/logwatch/scripts/services/postfix 2008-08-11 17:33:53.000000000 +0200 +++ postfix 2008-09-14 11:31:50.000000000 +0200 @@ -1,32 +1,117 @@ +#!/usr/bin/perl ########################################################################## -# $Id: postfix,v 1.41 2008/08/11 15:33:53 mike Exp $ +# $Id: postfix,v 1.35 2007/05/14 17:27:27 mrc Exp $ ########################################################################## - -##################################################### -## Copyright (c) 2008 Sven Conrad -## Covered under the included MIT/X-Consortium License: -## http://www.opensource.org/licenses/mit-license.php -## All modifications and contributions by other persons to -## this script are assumed to have been donated to the -## Logwatch project and thus assume the above copyright -## and licensing terms. If you want to make contributions -## under your own copyright or a different license this -## must be explicitly stated in the contribution an the -## Logwatch project reserves the right to not accept such -## contributions. If you have made significant -## contributions to this script and want to claim -## copyright please contact [email protected]. -######################################################### -# # $Log: postfix,v $ -# Revision 1.41 2008/08/11 15:33:53 mike -# Lost connection patch from Peter Johnson -mgt -# -# Revision 1.40 2008/06/30 23:07:51 kirk -# fixed copyright holders for files where I know who they should be -# -# Revision 1.39 2008/05/25 01:16:22 mike -# Reverting to version before the major rewrite -mgt +# Revision 1.35 2007/05/14 17:27:27 mrc +# - Support for running in standalone mode (independent of logwatch) +# - Support postfix 2.5 TLS message changes (smtpd_tls_loglevel > 0) +# - Handle and report postfix/policydweight lines (postfix_PolicydWeight) +# - Handle and report Host offered STARTTLS lines +# - Move 4xx temporary rejects into their own section (experimental feature) +# - Allow for hold messages that do not contain a recipient +# - Escape metacharacters from being interpreted in recipient_delimiter +# - Never split mailer-daemon, double-bounce, or when recipient_delimiter +# is a "-" (dash) never split owner- or -request localparts +# - Add relay=virtual to "local" class for local vs. remote bounces +# - Generalize "maildrop: Unable to create a dot-lock at <path>" messages +# - Consolodate similar MX errors +# - set IP address to 127.0.0.1 when from=local, and reporting both host/hostip +# - More cleanup (refactor common code, replace most global variables with lexicals, +# lowercase non-global variable names, shorten variable names, etc.) +# - Capture postsuper hold messages +# +# Revision 1.34 2007/03/27 01:13:47 mrc +# - Lowercase recipient addresses in several Reject sections +# - Capture and report postfix-spf lines +# - New config variable postfix_PolicySPF +# - Capture and report reject_uknown_reverse_client_hostname +# - Capture and report as config warning: "looking for plugins" NSF error +# - fix reject header|body RE to allow "local" as host/ip +# - really ignore lines that don't match SyslogName; +# - add inc_unmatched subroutine for easier debug of unmatched lines +# - Capture and summarize postfix-script output (starts, stops, refresh, etc.) +# - Remove redundant chomps +# +# Revision 1.33 2007/02/27 20:28:20 mrc +# - Fix problem in sort routine where IP addresses were being captured +# anywhere in an output line for comparison via pack 'C4' - only +# attempt IP comparison if an IP address is the start of an output line +# - Provide support for syslog_name in Postfix 2.4 via postfix.conf +# variable postfix_Syslog_Name +# - Classify PIX workarounds based on type (there are several) +# - Change summary output criteria to check for any non-zero Totals +# - Don't interpolate log lines into printf; they may contain % chars +# +# Revision 1.32 2007/02/17 18:41:22 mrc +# - Ensure no output occurs when nothing is captured +# +# Revision 1.31 2007/02/16 06:18:45 mrc +# - Make reject and warn_if_reject distinct sections +# - Track Qids to properly report messages and bytes sent / accepted +# - Track both messages deferred and total deferrals +# - Place recipients and senders in their own keys, instead of combined +# - Consider reject VRFY a reject and accumulate in reject totals +# - Move header/body and 'MAIL from' reject code into main reject code block +# - Remove unused variable +# - Print row heading seperator lines only when appropriate +# - Move printing of report headings into printReports +# - Change Sent header to Sent via SMTP (orthogonal to Sent via LMTP) +# +# Revision 1.30 2007/02/09 22:26:39 mrc +# - Added new postfix.conf configuration variable "postfix_Recipient_Delimiter", +# which can be set to match the postfix variable "recipient_delimiter". +# Allows Delivered and Sent reports to be grouped by email addresses +# minus their address extension. +# - Added new postfix.conf configuration variable "postfix_Max_Report_Width", +# to control maximum report width in postfix.conf +# - All line widths in report now obey max report width +# - Added VFRY reject section +# - Added RFC 3463 DSN code messages to bounce/deferred sections +# - Created a SASL authenticated relayed messages which hits with +# sasl_sender is present in smtpd messages +# - Split orig_to email addresses into a subkey. Allows reports +# to be grouped by primary "to" address, instead of various aliases. +# - Split Host & HostIP into their own keys for Bounce Remote section +# - For Pix Workaround section, format Host & HostIP similar to others +# - Add 'o' option where missing in REs +# - Parse and canonicalize various "host...said" remote server messages for +# few report sections +# - Add Sent via LMTP section, removing lmtp-delivered mail out of Delivered. +# Allows users with lmtp-based content filters to avoid double counting +# (but only for message counts; byte counts are still about 50% too large). +# Configuration variable postfix_MsgsSentLmtp controls display +# - Added pre-queue content-filter overload section +# - Reworked Bounce (local/remote) and Deferred sections +# - Fixed several reversed captures of Host and HostIP +# - Format Host and HostIP in Numeric hostname section +# - Changed all From -> To lines to To <- From. From address +# is often bogus and To is more interesting to see. +# - Made Reason the primary key in Deliverable/Undeliverable sendmail -bv tests +# - Modified re_DSN RE to capture DSNs missing 3 number response code +# - Enhanced SASL authenticated messages to capture missing log lines +# - Added milter-reject section +# - Updated 'Reject server configuration error' RE for older postfix versions +# - Fix copy/paste error which caused use of incorrect variable in bad size limit +# - Add Concurrency limit reached section +# - Add "maildrop" to the list of relay's considered local in Bounce section +# - Thanks: Jorey Bump, Mike Horwath, +# +# Revision 1.29 2007/01/27 20:21:46 mrc +# Rewrite by Mike Cappella (MrC) +# - Provide more useful information and summaries +# - Provide increasing detail as requested via --detail +# - Provide ability to configure per section maximum detail +# - Optimize and combine the numerous REs +# - Capture and summarize many more log lines +# - Pin important errors to top of report +# - Sort by hits, IP, and lexically +# - Handle IPv6 addresses +# - Generalize log line capturing and reporting +# - Eliminate excessive copy/paste reporting code +# - Requires updated postfix.conf file +# - Thanks: Eray Aslan, Jorey Bump, Harald Geiger, Bill Hudacek, +# Frederic Jacquet, Geert Janssens, Leon Kolchinsky, Rob Myroon # # Revision 1.28 2006/12/15 06:24:49 bjorn # Filtering "sender non-delivery notification", by Ivana Varekova. @@ -144,20 +229,9 @@ # Revision 1.1 2002/03/29 15:32:14 kirk # Added some filters found in RH's release # -# # Revision ??? 2000/07/12 Simon Liddington <[email protected]> # converted from sendmail to postfix Sven Conrad <[email protected]> -# added unknown users -# added relay denials -# todo: -# add authentication warnings -# add forward errors -# add returns after 4 hours -# ignores alias database building -# ignores daemon start messages -# ignores clone messages -# ignores all to= lines whatever follows stat= -# +# added unknown users, relay denials # # Revision 1.1 2003/03/21 21:10 sven # Initial revision @@ -167,1033 +241,2173 @@ ########################################################################## ######################################################## -# This was written and is maintained by: -# ??? Kenneth Porter <[email protected]> ??? -# changed by Sven Conrad <[email protected]> -# -# Please send all comments, suggestions, bug reports, -# etc, to ?? [email protected].?? -# Sven Conrad <[email protected]> +# Major rewrite by: +# Mike "MrC" Cappella <[email protected]> +# +# Please send all comments, suggestions, bug reports to the logwatch +# mailing list ([email protected]), or to the email address above. +# I will respond as timely as possible. [MrC] +# +# This file was originally written by: +# Kenneth Porter # ######################################################## +# +# Test data included via inline comments starting with "#TD" and optionally +# followed by an integer indicating replication count. +# +# Generate test data via the command: +# +# perl -e 'while (<>) { print "$2\n" x ($1 ? $1:1) if /^\s*#TD(\d+)? (.*)$/}' postfix | sed "s#^#`date +"%b %d %H:%M:%S"` `hostname` postfix/smtp[12345]: #" +# -my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; -my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; +use warnings; +no warnings "uninitialized"; +use strict; + +use Getopt::Long; +use File::Basename; + +my $Version = "1.35.1"; +my $progname = fileparse($0); +my $progname_prefix = 'postfix'; + +my %Opts = (); + +# Comamnd line options : config file variable +$Opts{'detail'} = 10; # report level detail +$Opts{'max_report_width'} = 100; # maximum line width for report output : postfix_max_report_width +$Opts{'syslog_name'} = "postfix"; # smtpd name (postconf(5), syslog_name) : postfix_syslog_name +$Opts{'ipaddr_width'} = 15; # width for printing ip addresses : postfix_ipaddr_width + + +# The postfix-logwatch.conf file is used only in +# standalone mode, and contains configuration variables +# set prior to command line variables. +# XXX: make configurable via command line switch +my $config_file = "/usr/local/etc/${progname_prefix}-logwatch.conf"; + +# Logwatch passes a filter's options via environment variables. +# When running standalone (w/out logwatch), use command line options +# +my $standalone = $ENV{LOGWATCH_DETAIL_LEVEL} eq '' ? 1 : 0; + +unless ($standalone) { + $Opts{'detail'} = $ENV{LOGWATCH_DETAIL_LEVEL}; +} + +# Totals and Counts are the log line accumulators. +# Totals: maintains section grand total for use in Summary section +# Counts: maintains per-level key totals +my (%Totals, %Counts); + +my (%UnmatchedList, %DeferredByQid, %Qids); + +my $OrigLine; # used globally + +# Notes: +# +# IN REs, always use /o option at end of RE when RE uses interpolated vars +# In REs, sender addresses may be empty "<>" - capture using *, not + ( eg. from=<[^>]*> ) + +# IPv4 only +#my $re_IP = '(?:\d{1,3}\.){3}(?:\d{1,3})'; + +# IPv4 and IPv6 +# See syntax in RFC 2821 IPv6-address-literal, +# eg. IPv6:2001:630:d0:f102:230:48ff:fe77:96e +my $re_IP = '(?:(?:::(?:ffff:|FFFF:)?)?(?:\d{1,3}\.){3}\d{1,3}|(?:[\da-fA-F]{0,4}:){2}(?:[\da-fA-F]{0,4}:){0,5}[\da-fA-F]{0,4})'; + +my $re_DSN = '(?:(?:\d{3})?(?: ?\d\.\d\.\d)?)'; +my $re_QID = '[A-Z\d]+'; +my $re_DDD = '(?:(?:conn_use=\d+ )?delay=-?[\d.]+(?:, delays=[\d\/.]+)?(?:, dsn=[\d.]+)?)'; + +sub usage($); +sub version($); +sub commify($); +sub inc_unmatched($ $); +sub get_vars_from_file($); +sub env_to_cmdline(\%); +sub buildTree(\% $ $); +sub printTree($); +sub printReports ($ \@); + +sub formathost($ $); +sub cleanhostreply($ $ $ $); +sub parse_spf($); +sub parse_policydweight($); + + +# References to these are used in the Formats table below; we'll predeclare them. +$Totals{'TotalRejects'} = 0; +$Totals{'TotalRejectWarns'} = 0; +$Totals{'TotalAcceptPlusReject'} = 0; + +# +# The Formats table drives reports. For each entry in the table, a summary line and/or +# detailed report section is a candidate for output, depending upon logwatch Detail +# level, and .conf configuration variables. Each entry below has four fields: +# +# 1: Key to %Counts and %Totals accumulator hashes +# 2: Numeric output format specifier +# 3: Summary and Section Title +# 4: A hash to a divisor used to calculate the percentage of a total for that key +# +# Alternatively, when field 1 contains a single character, this character will +# cause a line filled with that character to be output, but only if there was +# output for that section. +# The special name '__SECTION' is used to indicate the beginning of a new section. +# This ensures the printReports routine does not print needless horizontal lines. +# +my @Formats = ( + # Place configuration and critical errors appear first + + [ '__SECTION' ], + [ 'PanicError', "d", "*Panic: General panic" ], + [ 'FatalFileTooBig', "d", "*Fatal: Message file too big" ], + [ 'FatalConfigError', "d", "*Fatal: Configuration error" ], + [ 'FatalError', "d", "*Fatal: General fatal" ], + [ 'WarnFileTooBig', "d", "*Warning: Queue file size limit exceeded" ], + [ 'WarnInsufficientSpace', "d", "*Warning: Insufficient system storage error" ], + [ 'WarnConfigError', "d", "*Warning: Server configuration error" ], + [ 'QueueWriteError', "d", "*Warning: Error writing queue file" ], + [ 'MessageWriteError', "d", "*Warning: Error writing message file" ], + [ 'DatabaseGeneration', "d", "*Warning: Database file needs update" ], + [ 'MailerLoop', "d", "*Warning: Mailer loop" ], + [ 'StartupError', "d", "*Warning: Startup error" ], + [ 'MapProblem', "d", "*Warning: Map lookup problem" ], + [ 'PrematureEOI', "d", "*Warning: Premature end of input" ], + [ 'ConcurrencyLimit', "d", "*Warning: Connection concurrency limit reached" ], + [ 'ConnectionLostOverload', "d", "*Warning: Pre-queue content-filter connection overload" ], + [ 'ProcessExit', "d", "Process exited" ], + [ 'Hold', "d", "Placed on hold" ], + [ 'CommunicationError', "d", "Postfix communications error" ], + [ 'SaslAuthFail', "d", "SASL authentication failed" ], + [ 'LdapError', "d", "LDAP error" ], + [ 'WarningsOther', "d", "Miscellaneous warnings" ], + [ 'TotalRejectWarns', "d", "Reject warnings (warn_if_reject)" ], + [ '\n' ], + + [ '__SECTION' ], + [ 'BytesAccepted', "Z", "Bytes accepted " ], # Z means print scaled as in 1k, 1m, etc. + [ 'BytesDelivered', "Z", "Bytes delivered" ], + [ '=' ], + [ '\n' ], + + [ '__SECTION' ], + [ 'MsgsAccepted', "d", "Accepted", \$Totals{'TotalAcceptPlusReject'} ], + [ 'TotalRejects', "d", "Rejected", \$Totals{'TotalAcceptPlusReject'} ], + [ '-', "", "", \$Totals{'TotalAcceptPlusReject'} ], + [ 'TotalAcceptPlusReject', "d", "Total", \$Totals{'TotalAcceptPlusReject'} ], + [ '=', ], + [ '\n' ], + + [ '__SECTION' ], + [ 'RejectRelay', "d", "Reject relay denied", \$Totals{'TotalRejects'} ], + [ 'RejectHelo', "d", "Reject HELO/EHLO", \$Totals{'TotalRejects'} ], + [ 'RejectUnknownUser', "d", "Reject unknown user", \$Totals{'TotalRejects'} ], + [ 'RejectRecip', "d", "Reject recipient address", \$Totals{'TotalRejects'} ], + [ 'RejectSender', "d", "Reject sender address", \$Totals{'TotalRejects'} ], + [ 'RejectClient', "d", "Reject client host", \$Totals{'TotalRejects'} ], + [ 'RejectUnknownClient', "d", "Reject unknown client host", \$Totals{'TotalRejects'} ], + [ 'RejectUnknownReverseClient', "d", "Reject unknown reverse client host", \$Totals{'TotalRejects'} ], + [ 'RejectRBL', "d", "Reject RBL", \$Totals{'TotalRejects'} ], + [ 'RejectHeader', "d", "Reject header", \$Totals{'TotalRejects'} ], + [ 'RejectBody', "d", "Reject body", \$Totals{'TotalRejects'} ], + [ 'RejectSize', "d", "Reject message size", \$Totals{'TotalRejects'} ], + [ 'RejectMilter', "d", "Reject milter", \$Totals{'TotalRejects'} ], + [ 'RejectInsufficientSpace', "d", "Reject insufficient space", \$Totals{'TotalRejects'} ], + [ 'RejectConfigError', "d", "Reject server configuration error", \$Totals{'TotalRejects'} ], + [ 'RejectVerify', "d", "Reject VRFY", \$Totals{'TotalRejects'} ], + [ '-', ], + [ 'TotalRejects', "d", "Total Rejects", \$Totals{'TotalRejects'} ], + [ '=', ], + [ '\n' ], + + [ '__SECTION' ], + [ 'TempRejectRelay', "d", "4xx Reject relay denied", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectHelo', "d", "4xx Reject HELO/EHLO", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectUnknownUser', "d", "4xx Reject unknown user", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectRecip', "d", "4xx Reject recipient address", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectSender', "d", "4xx Reject sender address", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectClient', "d", "4xx Reject client host", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectUnknownClient', "d", "4xx Reject unknown client host", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectUnknownReverseClient', "d", "4xx Reject unknown reverse client host", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectRBL', "d", "4xx Reject RBL", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectHeader', "d", "4xx Reject header", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectBody', "d", "4xx Reject body", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectSize', "d", "4xx Reject message size", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectMilter', "d", "4xx Reject milter", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectInsufficientSpace', "d", "4xx Reject insufficient space", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectConfigError', "d", "4xx Reject server configuration error", \$Totals{'TotalTempRejects'} ], + [ 'TempRejectVerify', "d", "4xx Reject VRFY", \$Totals{'TotalTempRejects'} ], + [ '-', ], + [ 'TotalTempRejects', "d", "Total 4xx Rejects", \$Totals{'TotalTempRejects'} ], + [ '=', ], + [ '\n' ], + + [ '__SECTION' ], + [ 'RejectWarnRelay', "d", "Reject warning relay denied", ], + [ 'RejectWarnHelo', "d", "Reject warning HELO/EHLO" ], + [ 'RejectWarnUnknownUser', "d", "Reject warning unknown user" ], + [ 'RejectWarnRecip', "d", "Reject warning recipient address" ], + [ 'RejectWarnSender', "d", "Reject warning sender address" ], + [ 'RejectWarnClient', "d", "Reject warning client host" ], + [ 'RejectWarnUnknownClient', "d", "Reject warning unknown client host" ], + [ 'RejectWarnUnknownReverseClient', "d", "Reject warning unknown reverse client host" ], + [ 'RejectWarnRBL', "d", "Reject warning via RBL" ], + [ 'RejectWarnInsufficientSpace', "d", "Reject warning insufficient space" ], + [ 'RejectWarnConfigError', "d", "Reject warning server configuration error" ], + [ 'RejectWarnVerify', "d", "Reject warning VRFY" ], + [ '-', ], + [ 'TotalRejectWarns', "d", "Total Reject Warnings" ], + [ '=', ], + [ '\n' ], + + [ '__SECTION' ], + [ 'ConnectionInbound', "d", "Connections made" ], + [ 'ConnectionLost', "d", "Connections lost" ], + [ 'Disconnection', "d", "Disconnections" ], + [ 'RemovedFromQueue', "d", "Removed from queue" ], + [ 'MsgsDelivered', "d", "Delivered" ], + [ 'MsgsSent', "d", "Sent via SMTP" ], + [ 'MsgsSentLmtp', "d", "Sent via LMTP" ], + [ 'MsgsForwarded', "d", "Forwarded" ], + [ 'MsgsResent', "d", "Resent" ], + [ 'MsgsDeferred', "d", "Deferred" ], + [ 'Deferrals', "d", "Deferrals" ], + [ 'BounceLocal', "d", "Bounce (local)" ], + [ 'BounceRemote', "d", "Bounce (remote)" ], + [ 'Filtered', "d", "Filtered" ], + [ 'Discarded', "d", "Discarded" ], + [ 'Requeued', "d", "Requeued messages" ], + [ 'ReturnedToSender', "d", "Expired and returned to sender" ], + [ 'SenderDelayNotification', "d", "Sender delay notification" ], + [ 'DSNDelivered', "d", "DSNs delivered" ], + [ 'DSNUndelivered', "d", "DSNs undeliverable" ], + [ 'PolicySPF', "d", "Policy SPF" ], + [ 'PolicydWeight', "d", "Policyd-weight" ], + [ '\n' ], + + [ '__SECTION' ], + [ 'ConnectToFailure', "d", "Connection failure (outbound)" ], + [ 'TimeoutInbound', "d", "Timeout (inbound)" ], + [ 'HeloError', "d", "HELO/EHLO conversations errors" ], + [ 'IllegalAddrSyntax', "d", "Illegal address syntax in SMTP command" ], + [ 'WarningHeader', "d", "Header warning" ], + [ 'ReleasedFromHold', "d", "Released from hold" ], + [ 'RBLError', "d", "RBL lookup error" ], + [ 'MxError', "d", "MX error" ], + [ 'NumericHostname', "d", "Numeric hostname" ], + [ 'SmtpConversationError', "d", "SMTP commands dialog error" ], + [ 'TooManyErrors', "d", "Excessive errors in SMTP commands dialog" ], + [ 'HostnameVerification', "d", "Hostname verification errors" ], + [ 'HostnameValidationError', "d", "Hostname validation error" ], + [ 'Deliverable', "d", "Address is deliverable (sendmail -bv)" ], + [ 'Undeliverable', "d", "Address is undeliverable (sendmail -bv)" ], + [ 'TableChanged', "d", "Restarts due to lookup table change" ], + [ 'PixWorkaround', "d", "Enabled PIX workaround" ], + [ 'TlsServerConnect', "d", "TLS connections (server)" ], + [ 'TlsClientConnect', "d", "TLS connections (client)" ], + [ 'SaslAuth', "d", "SASL authenticated messages" ], + [ 'SaslAuthRelay', "d", "SASL authenticated relayed messages" ], + [ 'TlsUnverified', "d", "TLS certificate unverified" ], + [ 'TlsOffered', "d", "Host offered TLS" ], + [ '\n' ], + + [ '__SECTION' ], + [ 'PostfixStart', "d", "Postfix start" ], + [ 'PostfixStop', "d", "Postfix stop" ], + [ 'PostfixRefresh', "d", "Postfix refresh" ], + [ 'PostfixWaiting', "d", "Postfix waiting to terminate" ], +); + +#------------------------------------------------- +# RFC 3463 DSN Codes +# http://www.faqs.org/rfcs/rfc3463.html +# +# Class.Subject.Detail +# +# Class +my %dsn_codes = ( + class => { + "2" => "Success", + "4" => "Persistent Transient Failure", + "5" => "Permanent Failure", + }, + + subject => { + "0" => "Other or Undefined Status", + "1" => "Addressing Status", + "2" => "Mailbox Status", + "3" => "Mail System Status", + "4" => "Network & Routing Status", + "5" => "Mail Delivery Protocol Status", + "6" => "Message Content or Media Status", + "7" => "Security or Policy Status", + }, + + detail => { + "0.0" => "Other undefined status", + "1.0" => "Other address status", + "1.1" => "Bad destination mailbox address", + "1.2" => "Bad destination system address", + "1.3" => "Bad destination mailbox address syntax", + "1.4" => "Destination mailbox address ambiguous", + "1.5" => "Destination mailbox address valid", + "1.6" => "Mailbox has moved", + "1.7" => "Bad sender's mailbox address syntax", + "1.8" => "Bad sender's system address", + + "2.0" => "Other or undefined mailbox status", + "2.1" => "Mailbox disabled, not accepting messages", + "2.2" => "Mailbox full", + "2.3" => "Message length exceeds administrative limit.", + "2.4" => "Mailing list expansion problem", + + "3.0" => "Other or undefined mail system status", + "3.1" => "Mail system full", + "3.2" => "System not accepting network messages", + "3.3" => "System not capable of selected features", + "3.4" => "Message too big for system", + + "4.0" => "Other or undefined network or routing status", + "4.1" => "No answer from host", + "4.2" => "Bad connection", + "4.3" => "Routing server failure", + "4.4" => "Unable to route", + "4.5" => "Network congestion", + "4.6" => "Routing loop detected", + "4.7" => "Delivery time expired", + + "5.0" => "Other or undefined protocol status", + "5.1" => "Invalid command", + "5.2" => "Syntax error", + "5.3" => "Too many recipients", + "5.4" => "Invalid command arguments", + "5.5" => "Wrong protocol version", + + "6.0" => "Other or undefined media error", + "6.1" => "Media not supported", + "6.2" => "Conversion required & prohibited", + "6.3" => "Conversion required but not supported", + "6.4" => "Conversion with loss performed", + "6.5" => "Conversion failed", + + "7.0" => "Other or undefined security status", + "7.1" => "Delivery not authorized, message refused", + "7.2" => "Mailing list expansion prohibited", + "7.3" => "Security conversion required but not possible", + "7.4" => "Security features not supported", + "7.5" => "Cryptographic failure", + "7.6" => "Cryptographic algorithm not supported", + "7.7" => "Message integrity failure", + }, +); + +# Initialize the Getopts option list +my @format_opts = (); +push @format_opts, 'help'; +push @format_opts, 'version'; +push @format_opts, 'debug'; +push @format_opts, 'detail=i'; +push @format_opts, 'max_report_width=i'; +push @format_opts, 'deferred=i', \$Opts{'msgsdeferred'}; # backwards compatability +push @format_opts, 'ipaddr_width=i', \$Opts{'ipaddr_width'}; +push @format_opts, 'recipient_delimiter=s', \$Opts{'recipient_delimiter'}; +push @format_opts, 'syslog_name=s', \$Opts{'syslog_name'}; + +# Continue building the Getopts option list from the keys +# in the Formats list. Any option that matches a key in the Formats list +# controls the max print level for that section. +foreach ( @Formats ) { + # ignore output formatting specifiers + next if ($_->[0] =~ /^.$/); + next if ($_->[0] =~ /^\\n$/); + next if ($_->[0] =~ /^__/); + + # all Formats-derived options are integers + push @format_opts, "\L$_->[0]=i"; +} + +# All options are placed into, and processed from ARGV. +# Most recently seen options override earlier options. +# +if ($standalone) { + # In standalone mode, obtain any options specified in + # a logwatch-style config file + my $href = get_vars_from_file($config_file); + if (-f "$config_file") { + get_vars_from_file($config_file); + unshift @ARGV, env_to_cmdline(%$href); + } +} else { + # logwatch passes all config vars via environment variables + @ARGV=env_to_cmdline(%ENV); +} + +#print "ARGC: ", scalar @ARGV, ", ARGV: @ARGV\n"; +#$Getopt::Long::debug = 1; + +GetOptions (\%Opts, @format_opts) || usage(undef); + +exists $Opts{'version'} && version(undef); +exists $Opts{'help'} && usage(undef); + +#map { print "KEY: $_ => $Opts{$_}\n"} keys %Opts; +#print "ARGC: ", scalar @ARGV, "ARGV: @ARGV\n"; + +# Main processing loop +# +while ( <> ) { + my $p1 = $_; + + chomp ($p1);; + $OrigLine = $p1; + #print "OrigLine: \"$OrigLine\"\n"; + + my ($postfix_svc); + + unless (($postfix_svc, $p1) = ( $OrigLine =~ /^... .. ..:..:.. [^ ]* $Opts{'syslog_name'}\/([^[:]+)(?:\[\d+\])?: (?:\[ID \d+ \w+\.\w+\] )?(.*)$/o) ) { + next; + } + $p1 =~ s/\s+$//; + + # We don't care about these, but see also less frequent log entries at the of the while loop + next if ( + ( $p1 =~ /^Deleted: \d message$/ ) + or ( $p1 =~ /: replace: header / ) + or ( $p1 =~ /: Greylisted for / ) # Greylisting has it's own statistics tool + #XXX Perhaps the following are candidates for extended statistics + or ( $p1 =~ /certificate verification failed for/o ) + or ( $p1 =~ /Server certificate could not be verified/o ) + or ( $p1 =~ /certificate peer name verification failed/o ) + # SSL rubbish when logging at/above INFO level + or ( $p1 =~ /^[a-f\d]{4} [a-f\d]{2}/ ) + or ( $p1 =~ /^[a-f\d]{4} - <SPACES/ ) + # more from mail.info level and above + or ( $p1 =~ m/^read from [a-f\d]{8}/ ) + or ( $p1 =~ m/^write to [a-f\d]{8}/ ) + + ); + + my ($helo, $relay, $from, $origto, $to, $domain, $status, + $type, $reason, $reason2, $filter, $site, $cmd, $qid, $p2, + $rej_action, $host, $hostip); + + # ^fatal: ... + if ( ($reason) = ($p1 =~ /^fatal: (.*)$/ )) { + + if ($reason =~ /^[^ ]*\(\d+\): Message file too big$/) { + #TD fatal: root(0): Message file too big + $Totals{'FatalFileTooBig'}++; + + # XXX its not clear this is at all useful - consider falling through to last case + } elsif ( $reason =~ /^config variable ([^ ]*): (.*)$/ ) { + #TD fatal: config variable inet_interfaces: host not found: 10.0.0.1:2525 + #TD fatal: config variable inet_interfaces: host not found: all:2525 + $Totals{'FatalConfigError'}++; + $Counts{'FatalConfigError'}{$reason}++; + } + else { + #TD fatal: watchdog timeout + #TD fatal: bad boolean configuration: smtpd_use_tls = + $Totals{'FatalError'}++; + $Counts{'FatalError'}{"\u$reason"}++; + } + } -my $re_DSN = '(?:\d{3}(?: \d\.\d\.\d)?)'; -my $re_MsgID = '[a-zA-Z\d]+'; + # Policy-spf + elsif ($postfix_svc eq 'policy-spf') { -$MsgsQueue = 0; -$BytesTransferred = 0; -$FourHourReturns = 0; -$ReturnedToSender = 0; -$ResentMessages = 0; -$RemovedFromQueue = 0; -$UnsupportedFamily = 0; -$TableChanged = 0; -$QueueSizeExceeded = 0; -$RejectedRBL = 0; -$ErrorRBL = 0; -$NoFreeSpace = 0; -$RejectClients = 0; -$RejectUnknownClients = 0; -$Undeliverable = 0; -$Deliverable = 0; + my ($reason, $domain, $IP, $reason2) = parse_spf($p1); + next unless ($reason); -while (defined($ThisLine = <STDIN>)) { - if ( - ( $ThisLine =~ m/^$re_MsgID: client=([^ ]*\[[^ ]*\])\s*$/ ) or - ( $ThisLine =~ m/^$re_MsgID: message-id/ ) or - ( $ThisLine =~ m/^$re_MsgID: skipped, still being delivered/ ) or - ( $ThisLine =~ m/^$re_MsgID: to=\<.*>, relay=.*, delay=[\d.]+,(?: delays=[\d\/.]+, dsn=[\d.]+,)? status=(?:sent|deferred)/ ) or - ( $ThisLine =~ m/^$re_MsgID: host [^ ]*\[[^ ]*\] said: 4[0-9][0-9]/ ) or - ( $ThisLine =~ m/^$re_MsgID: host [^ ]*\[[^ ]*\] refused to talk to me: 4[0-9][0-9]/ ) or - ( $ThisLine =~ m/^$re_MsgID: sender non-delivery notification: $re_MsgID/ ) or - ( $ThisLine =~ m/^Deleted: \d message$/ ) or - ( $ThisLine =~ m/^Peer certficate could not be verified$/ ) or #postfix typo - ( $ThisLine =~ m/^Peer certificate could not be verified$/ ) or - ( $ThisLine =~ m/^Peer verification:/ ) or - ( $ThisLine =~ m/^SSL_accept error from/ ) or - ( $ThisLine =~ m/^Verified: / ) or - ( $ThisLine =~ m/^cert has expired/ ) or - ( $ThisLine =~ m/^connect/ ) or - ( $ThisLine =~ m/^daemon started$/ ) or - ( $ThisLine =~ m/^daemon started -- version / ) or - ( $ThisLine =~ m/^dict_eval_action:/ ) or - ( $ThisLine =~ m/^disconnect/ ) or - ( $ThisLine =~ m/^mynetworks:/ ) or - ( $ThisLine =~ m/^name_mask:/ ) or - ( $ThisLine =~ m/^reload configuration/ ) or - ( $ThisLine =~ m/^setting up TLS connection (from|to)/ ) or - ( $ThisLine =~ m/^starting TLS engine$/ ) or - ( $ThisLine =~ m/^terminating on signal 15$/ ) or - ( $ThisLine =~ m/^warning: $re_MsgID: skipping further client input$/ ) or - ( $ThisLine =~ m/^warning: (?:smtpd_peer_init: )?[\.0-9]+: address not listed for hostname/ ) or - ( $ThisLine =~ m/^warning: (?:smtpd_peer_init: )?[\.0-9]+: hostname .* verification failed: Host not found/ ) or - ( $ThisLine =~ m/^warning: (?:smtpd_peer_init: )?[\.0-9]+: hostname .* verification failed: Name or service not known/ ) or - ( $ThisLine =~ m/^warning: (?:smtpd_peer_init: )?[\.0-9]+: hostname .* verification failed: Temporary failure in name resolution/ ) or - ( $ThisLine =~ m/^warning: Mail system is down -- accessing queue directly$/ ) or - ( $ThisLine =~ m/^warning: SASL authentication failure: Password verification failed$/ ) or - ( $ThisLine =~ m/^warning: SASL authentication failure: no secret in database$/ ) or - ( $ThisLine =~ m/^warning: no MX host for .* has a valid A record$/ ) or - ( $ThisLine =~ m/^warning: numeric domain name in resource data of MX record for .*$/ ) or - ( $ThisLine =~ m/^warning: premature end-of-input from cleanup socket while reading input attribute name$/ ) or - ( $ThisLine =~ m/^warning: uid=\d: Broken pipe$/ ) or - ( $ThisLine =~ m/^verify error:num=/ ) or - ( $ThisLine =~ m/hold: header / ) - or ( $ThisLine =~ m/^statistics: max / ) - or ( $ThisLine =~ m/^statistics: start interval / ) - or ( $ThisLine =~ m/^statistics: (address|domain) lookup / ) - or ( $ThisLine =~ m/: replace: header / ) - or ( $ThisLine =~ m/: Greylisted for / ) # Greylisting has it's own statistics tool - or ( $ThisLine =~ m/certificate verification failed for/o ) # Perhaps a candidate for extended statistics - or ( $ThisLine =~ m/Server certificate could not be verified/o ) # Perhaps a candidate for extended statistics - or ( $ThisLine =~ m/certificate peer name verification failed/o ) # Perhaps a candidate for extended statistics - or ( $ThisLine =~ m/sender non-delivery notification:/o ) # Perhaps a candidate for extended statistics - ) { - # We don't care about these - } elsif ( ($Bytes) = ($ThisLine =~ /^$re_MsgID: from=[^,]+, size=(\d+), .*$/o) ) { - #fixme count - $MsgsQueue++; - $BytesTransferred += $Bytes; - } elsif (($User) = ($ThisLine =~ /^$re_MsgID: to=\<([^ ]*)>,(?: orig_to=\<(?:[^ ]*)>,)? relay=local, delay=-?\d+, status=bounced \((?:unknown user|user unknown)/)) { - # unknown user - $UnknownUsers{$User}++; - } elsif (($User) = ($ThisLine =~ /^$re_MsgID: reject: RCPT from (?:[^ ]*): $re_DSN <([^ ]*)>:(?:[^:]+: )?User unknown in(?: \w+)+ table/)) { - # unknown local mailbox, alias, virtual user - $UnknownUsers{$User}++; - } elsif (($User) = ($ThisLine =~ /^$re_MsgID: to=\<([^ ]*)>,(?: orig_to=\<(?:[^ ]*)>,)? .*, status=bounced .*: User unknown in virtual (alias|mailbox) table/)) { - # another unknown user probably could combine with local unknown but again my perl is weak - $UnknownUsers{$User}++; - } elsif (($Dest, $Relay, $Msg) = ($ThisLine =~ /^$re_MsgID: to=\<([^ ]*)>,(?: orig_to=\<(?:[^ ]*)>,)? relay=([^ ]*).*, delay=-?[\d.]+(?:, delays=[\d\/.]+, dsn=[\d.]+)?, status=bounced \(([^)]*)/ )) { - # unknown user - # $Msg = " hello " - # print "bounce message from " . $Dest . " msg : " . $Relay . "\n"; - if ($Relay =~ m/^(none|local|avcheck|127\.0\.0\.1)/) { - $Temp = "To " . $Dest . " Msg=\"" . $Msg . "\""; - $LocalBounce{$Temp}++; + $Totals{'PolicySPF'}++; + if ($IP) { + $Counts{'PolicySPF'}{$reason}{$domain}{$IP}{$reason2}++; } else { - $Temp = "To " . $Dest . " Msg=\"" . $Msg . "\""; - $ForeignBounce{$Temp}++; + $Counts{'PolicySPF'}{$reason}{$domain}{$reason2}++; } - } elsif ( ($Relay,$Dest) = ($ThisLine =~ m/reject: RCPT from ([^ ]*): $re_DSN <([^ ]*)>.* Relay access denied.* to=([^ ]*)/) ) { - # print "reject: " . $ThisLine . "\n"; - # print "Relay :" . $Relay . " to " . $Dest . "\n"; - $Temp = "From " . $Relay . " to " . $Dest; - $RelayDenied{$Temp}++; - } elsif ( ($User,$From) = ($ThisLine =~ /^$re_MsgID: uid=([^ ]*) from=\<([^ ]*)>/)) { - #Messages sent by user - $Temp = $From . " (uid=" . $User . "): "; - $SentBy{$Temp}++; - } elsif ( ($From) = ($ThisLine =~ /^$re_MsgID: from=<([^ ]*)>, status=expired, returned to sender$/)) { - $ReturnedToSender++; - } elsif ( (undef) = ($ThisLine =~ /^$re_MsgID: resent-message-id=<([^ ]*)>$/)) { - $ResentMessages++; - } elsif ( - ($Command,$Host) = ($ThisLine =~ /lost connection after (.*) from ([^ ]*)$/) or - ($Host,$Command) = ($ThisLine =~ /^$re_MsgID: lost connection with ([^ ]*) while (.*)$/) - ) { - # Make some better summary with hosts - $ConnectionLost{$Command}++; - } elsif ( - ($Command,$Host) = ($ThisLine =~ /timeout after (.*) from ([^ ]*)$/) or - ($Host,$Command) = ($ThisLine =~ /^$re_MsgID: conversation with ([^ ]*) timed out while (.*)$/) - ) { - # Make some better summary with hosts - $ConnectionLost{$Command}++; - } elsif ( ($Rejected,undef,undef,undef,$Reason) = ($ThisLine =~ /^$re_MsgID: reject: header (.*); from=<([^ ]*)> to=<([^ ]*)>( proto=[^ ]* helo=<[^ ]*>)?: (.*)$/)) { - $HeaderReject{$Reason}{$Rejected}++; - } elsif ( ($Warning,undef,undef,undef,$Reason) = ($ThisLine =~ /^$re_MsgID: warning: header (.*); from=<([^ ]*)> to=<([^ ]*)>( proto=[^ ]* helo=<[^ ]*>)?: (.*)$/)) { - $HeaderWarning{$Reason}{$Warning}++; - } elsif ( ($Warning,undef,undef,undef) = ($ThisLine =~ /^$re_MsgID: warning: header (.*); from=<([^ ]*)> to=<([^ ]*)>( proto=[^ ]* helo=<[^ ]*>)?$/)) { - $HeaderWarning{"Unknown Reason"}{$Warning}++; - } elsif ( ($Rejected,undef,undef,undef,$Reason) = ($ThisLine =~ /^$re_MsgID: reject: body (.*); from=<([^ ]*)> to=<([^ ]*)>( proto=[^ ]* helo=<[^ ]*>)?: (.*)$/)) { - $BodyReject{$Reason}{$Rejected}++; - } elsif ( (undef,undef,undef,$Reason) = ($ThisLine =~ /^$re_MsgID: to=<([^ ]*)>,( orig_to=<[^ ]*>,)? relay=([^ ]*), delay=\d+, status=undeliverable \((.*)\)$/)) { - $Undeliverable++; - $UndeliverableMsg{$Reason}++; - } elsif ( (undef,undef,undef,undef) = ($ThisLine =~ /^$re_MsgID: to=<([^ ]*)>,( orig_to=<[^ ]*>,)? relay=([^ ]*), delay=\d+, status=deliverable \((.*)\)$/)) { - $Deliverable++; - } elsif ( ($Host,$Sender,$Reason) = ($ThisLine =~ /reject: RCPT from ([^ ]*\[[^ ]*\]): $re_DSN <(.*)>: Sender address rejected: (.*);/)) { - $RejectSender{$Reason}{$Host}{$Sender}++; - $RejectSenderHost{$Reason}{$Host}++; - $RejectSenderReason{$Reason}++; - } elsif ( ($Host,$Reason,$Sender,$Recip) = ($ThisLine =~ /reject: RCPT from ([^ ]*\[[^ ]*\]): $re_DSN <[^ ]*\[[^ ]*\]>: Client host rejected: (.*); from=<(.*)> to=<(.*)> proto=/)) { - $RejectClient{$Reason}{$Host}{$Sender}{$Recip}++; - $RejectClientHost{$Reason}{$Host}++; - $RejectClientReason{$Reason}++; - } elsif ( ($Host,$Sender,$Recip,$Helo) = ($ThisLine =~ /reject: RCPT from [^ ]*\[([^ ]*)\]: $re_DSN Client host rejected: cannot find your hostname, \[\d+\.\d+\.\d+\.\d+\]; from=<(.*?)> to=<(.*?)> proto=\S+ helo=<(.*)>/)) { - $RejectUnknownClient{$Host}{$Helo}{$Sender}{$Recip}++; - $RejectUnknownClientHost{"$Host helo=<$Helo>"}++; - $RejectUnknownClients++; - } elsif ( ($Host,$Recip,$Reason) = ($ThisLine =~ /reject: RCPT from ([^ ]*\[[^ ]*\]): $re_DSN <(.*)>: Recipient address rejected: (.*);/)) { - $Temp = "$Host : $Reason"; - $RejectRecip{$Recip}{$Temp}++; - } elsif ( ($Host,undef) = ($ThisLine =~ /reject: RCPT from ([^ ]*\[[^ ]*\]): $re_DSN <(.*)>: Sender address rejected: Access denied;/)) { - $RejectAddress{$Host}++; - } elsif ( ($Host,$Site,$Reason) = ($ThisLine =~ /reject: RCPT from ([^ ]*\[[^ ]*\]): $re_DSN Service unavailable; (?:Client host )?\[[^ ]*\] blocked using ([^ ]*), reason: (.*);/)) { - $Temp = "$Host : $Reason"; - $RejectRBL{$Site}{$Temp}++; - $RejectedRBL++; - } elsif ( ($Host,$Site) = ($ThisLine =~ /reject: RCPT from ([^ ]*\[[^ ]*\]): $re_DSN Service unavailable; (?:Sender address |Client host )?\[[^ ]*\] blocked using ([^ ]*);/)) { - $RejectRBL{$Site}{$Host}++; - $RejectedRBL++; - } elsif ( ($Host,$Site,$Reason) = ($ThisLine =~ /warning: ([^ ]*): RBL lookup error: Name service error for \d+\.\d+\.\d+\.\d+\.([^ ]*): (.*)$/)) { - $Temp = "$Host : $Reason"; - $RBLError{$Site}{$Temp}++; - $ErrorRBL++; - } elsif ( ($Host,$Site,$Reason) = ($ThisLine =~ /discard: RCPT from ([^ ]*\[[^ ]*\]): ([^ ]*): ([^;]*);/)) { - $Discarded{$Site}{$Reason}++; - } elsif ( (undef,undef,$Error) = ($ThisLine =~ /warning: ([^ ]*): hostname ([^ ]*) verification failed: (.*)$/)) { - $HostnameVerification{$Error}++; - } elsif ( $ThisLine =~ /^$re_MsgID: removed\s*$/) { - $RemovedFromQueue++; - } elsif ( ($Host) = ($ThisLine =~ /^$re_MsgID: enabling PIX <CRLF>.<CRLF> workaround for ([^ ]*\[[^ ]*\])$/)) { - $PixWorkaround{$Host}++; - } elsif ( ($Message) = ($ThisLine =~ /warning: valid_hostname: (.*)$/)) { - $ValidHostname{$Message}++; - } elsif ( ($Host,$Error) = ($ThisLine =~ /warning: host ([^ ]*\[[^ ]*\]) (greeted me with my own hostname [^ ]*)$/)) { - $HeloError{$Error}{$Host}++; - } elsif ( ($Host,$Error) = ($ThisLine =~ /warning: host ([^ ]*\[[^ ]*\]) (replied to HELO\/EHLO with my own hostname [^ ]*)$/)) { - $HeloError{$Error}{$Host}++; - } elsif ( ($Host,$Error) = ($ThisLine =~ /reject: RCPT from ([^ ]*\[[^ ]*\]): $re_DSN <.*>: (Helo command rejected: .*);/)) { - $HeloError{$Error}{$Host}++; - } elsif ( ($Error,$Host) = ($ThisLine =~ /(bad size limit "\([^ ]*\)" in EHLO reply) from ([^ ]*\[[^ ]*\])$/)) { - $HeloError{$Error}{$Host}++; - } elsif ( ($Host,$Command) = ($ThisLine =~ /warning: Illegal address syntax from ([^ ]*\[[^ ]*\]) in ([^ ]*) command:/)) { - $IllegalAddressSyntax{$Command}{$Host}++; - } elsif ( ($Error) = ($ThisLine =~ /warning: mailer loop: (.*)$/)) { - $MailerLoop{$Error}++; - } elsif ( ($Host) = ($ThisLine =~ /warning: ([^ ]*\[[^ ]*\]): SASL .* authentication failed/)) { - $SaslAuthenticationFail{$Host}++; - } elsif ( - ($Host,$User) = ($ThisLine =~ /^$re_MsgID: client=([^ ]*\[[^ ]*\]), .* sasl_username=([^ ]*)$/) or - ($Host,$User) = ($ThisLine =~ /^$re_MsgID: client=([^ ]*\[[^ ]*\]), sasl_sender=([^ ]*)$/) or - ($Host,$User) = ($ThisLine =~ /^$re_MsgID: client=([^ ]*\[[^ ]*\]), .* sasl_username=([^ ]*), sasl_sender=[^ ]*$/) - ) { - chomp($User); - $SaslAuth{$Host}{$User}++; - } elsif ( ($Host) = ($ThisLine =~ /TLS connection established from ([^ ]*\[[^ ]*\]):/)) { - $TLSconnectFrom{$Host}++; - } elsif ( ($Host) = ($ThisLine =~ /TLS connection established to ([^ ]*):/)) { - $TLSconnectTo{$Host}++; - } elsif ( ($Cert) = ($ThisLine =~ /^Unverified: (.*)/)) { - $TLSunverified{$Cert}++; - } elsif ( ($Domain) = ($ThisLine =~ /warning: malformed domain name in resource data of MX record (.*)$/)) { - $MxError{$Domain}++; - } elsif ( ($Host,$Command) = ($ThisLine =~ /warning: ([^ ]*\[[^ ]*\]) sent .* header instead of ([^ ]*) command: /)) { - $Error = "Sent message header instead of $Command command"; - $SmtpConversationError{$Error}{$Host}++; - } elsif ( - ($ThisLine =~ m/warning: smtp_connect_addr: socket: Address family not supported by protocol/) or - ($ThisLine =~ m/warning: smtp_addr_one: unknown address family \d for [^ ]*/) - ) { - $UnsupportedFamily++; - } elsif ( - ($ThisLine =~ m/(lookup |)table has changed -- exiting$/) or - ($ThisLine =~ m/table ([^ ]*) has changed -- restarting$/) - ) { - $TableChanged++; - } elsif ( - ($ThisLine =~ m/^fatal: [^ ]*\(\d+\): Message file too big$/) or - ($ThisLine =~ m/^warning: $re_MsgID: queue file size limit exceeded$/) or - ($ThisLine =~ m/^warning: uid=\d+: File too large$/) - ) { - $QueueSizeExceeded++; - } elsif ( ($Command,$Host) = ($ThisLine =~ /too many errors after ([^ ]*) from ([^ ]*\[[^ ]*\])$/)) { - $TooManyErrors{$Command}{$Host}++; - } elsif ( (undef,undef,$To) = ($ThisLine =~ /^reject: RCPT from ([^ ]*\[[^ ]*\]): 552 Message size exceeds fixed limit; from=<([^ ]*)> to=<([^ ]*)>$/)) { - $SizeLimit{"$From -> $To"}++; - } elsif ( ($Server) = ($ThisLine =~ /^NOQUEUE: reject: MAIL from ([^ ]*\[[^ ]*\]): 552 Message size exceeds fixed limit; proto=[^ ]* helo=<[^ ]*>$/)) { - $SizeLimit{"MAIL from $Server"}++; - } elsif ( (undef,$Source) = ($ThisLine =~ /^warning: database ([^ ]*) is older than source file ([a-zA-Z0-9\/]+)$/)) { - $DatabaseGeneration{$Source}++; - } elsif ( ($Reason) = ($ThisLine =~ /^warning: $re_MsgID: write queue file: (.*)$/)) { - $QueueWriteError{$Reason}++; - } elsif ( ($Reason) = ($ThisLine =~ /^warning: open active $re_MsgID: (.*)$/)) { - $QueueWriteError{"open active: $Reason"}++; - } elsif ( ($Reason) = ($ThisLine =~ /^warning: qmgr_active_corrupt: save corrupt file queue active id $re_MsgID: (.*)$/)) { - $QueueWriteError{"active corrupt: $Reason"}++; - } elsif ( ($Reason) = ($ThisLine =~ /^warning: qmgr_active_done_3_generic: remove $re_MsgID: (.*)$/)) { - $QueueWriteError{"remove active: $Reason"}++; - } elsif ( ($Reason) = ($ThisLine =~ /^warning: [^ ]*\/$re_MsgID: (Error writing message file)$/)) { - $MessageWriteError{$Reason}++; - } elsif ( $ThisLine =~ /reject: RCPT from [^ ]*\[[^ ]*\]: \d+ Insufficient system storage; from=<.*> to=<.*>/) { - $NoFreeSpace++; - } elsif ( ($Process,$Status) = ($ThisLine =~ /^warning: process ([^ ]*) pid \d+ exit status (\d+)$/)) { - $ProcessExit{$Status}{$Process}++; - } elsif ( ($Option,$Reason) = ($ThisLine =~ /^fatal: config variable ([^ ]*): (.*)$/)) { - $ConfigError{$Option}{$Reason}++; - } elsif ( ($Warn) = ($ThisLine =~ /^warning: (.*)/)) { - # keep this as the next to last condition - $UnknownWarnings{$Warn}++; - } else { - push @OtherList,$ThisLine; } -} -################################################################## + # PolicydWeight + elsif ($postfix_svc =~ /policyd-?weight/) { -#CRITICAL WARNINGS -if ($NoFreeSpace > 0) { - print "\nWARNING!!!\n"; - print "Insufficient system storage error $NoFreeSpace Time(s)\n"; -} + my ($reason, $reason2) = parse_policydweight($p1); + next unless ($reason); -#STATS -if ($MsgsQueue > 0) { - print "STATISTICS\n"; - print "----------\n"; - print "\n$BytesTransferred bytes transferred"; - print "\n$MsgsQueue messages accepted for queue"; -} + $Totals{'PolicydWeight'}++; + $Counts{'PolicydWeight'}{$reason}{$reason2}++; + } -if ($FourHourReturns > 0) { - print "\n$FourHourReturns messages returned after 4 hours"; -} + ### postfix-script + elsif ($postfix_svc eq 'postfix-script') { + if ($p1 =~ /^starting the Postfix mail system/) { + $Totals{'PostfixStart'}++; + } elsif ($p1 =~ /^stopping the Postfix mail system/) { + $Totals{'PostfixStop'}++; + } elsif ($p1 =~ /^refreshing the Postfix mail system/) { + $Totals{'PostfixRefresh'}++; + } elsif ($p1 =~ /^waiting for the Postfix mail system to terminate/) { + $Totals{'PostfixWaiting'}++; + } + else { + inc_unmatched('postfix-script', $OrigLine); + } + } -if ($Deliverable > 0) { - print "\n$Deliverable messages accepted as deliverable"; -} + # common log entries up front + elsif ($p1 =~ /^connect from/) { + #TD25 connect from sample.net[10.0.0.1] + #TD connect from mail.example.com[2001:dead:beef::1] + #TD connect from localhost.localdomain[127.0.0.1] + $Totals{'ConnectionInbound'}++; + } + elsif ($p1 =~ /^disconnect from/) { + #TD25 disconnect from sample.net[10.0.0.1] + #TD disconnect from mail.example.com[2001:dead:beef::1] + $Totals{'Disconnection'}++; + } + elsif (($host,$hostip,$reason) = ($p1 =~ /^connect to ([^[]*)\[($re_IP)\]: (.*)$/o)) { + # all "connect to" messages indicate a problem with the connection + #TD connect to example.org[10.0.0.1]: Connection refused (port 25) + #TD connect to mail.sample.com[10.0.0.1]: No route to host (port 25) + #TD connect to sample.net[192.168.0.1]: read timeout (port 25) + #TD connect to mail.example.com[10.0.0.1]: server dropped connection without sending the initial SMTP greeting (port 25) + #TD connect to mail.example.com[192.168.0.1]: server dropped connection without sending the initial SMTP greeting (port 25) + #TD connect to ipv6-1.example.com[2001:dead:beef::1]: Connection refused (port 25) + #TD connect to ipv6-2.example.com[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]: Connection refused (port 25) + #TD connect to ipv6-3.example.com[1080:0:0:0:8:800:200C:4171]: Connection refused (port 25) + #TD connect to ipv6-4.example.com[3ffe:2a00:100:7031::1]: Connection refused (port 25) + #TD connect to ipv6-5.example.com[1080::8:800:200C:417A]: Connection refused (port 25) + #TD connect to ipv6-6.example.com[::192.9.5.5]: Connection refused (port 25) + #TD connect to ipv6-7.example.com[::FFFF:129.144.52.38]: Connection refused (port 25) + #TD connect to ipv6-8.example.com[2010:836B:4179::836B:4179]: Connection refused (port 25) + $Totals{'ConnectToFailure'}++; + $Counts{'ConnectToFailure'}{$reason}{formathost($hostip,$host)}++; + } + + elsif ( ($reason) = ($p1 =~ /^panic: (.*)$/)) { + #TD panic: myfree: corrupt or unallocated memory block + $Totals{'PanicError'}++; + $Counts{'PanicError'}{"\u$reason"}++; + } + + # ^warning: ... + elsif (my ($warning) = ($p1 =~ /^warning: (.*)$/ )) { + # Skip these + next if ( $warning =~ /$re_QID: skipping further client input$/o ); + next if ( $warning =~ /^Mail system is down -- accessing queue directly$/ ); + next if ( $warning =~ /^SASL authentication failure: (?:Password verification failed|no secret in database)$/ ); + next if ( $warning =~ /^no MX host for .* has a valid A record$/ ); + next if ( $warning =~ /^uid=\d: Broken pipe$/ ); + + #TD warning: connect to 127.0.0.1:12525: Connection refused + #TD warning: problem talking to server 127.0.0.1:12525: Connection refused + #TD warning: valid_ipv4_hostaddr: invalid octet count: + + my ($addr, $size); + + if ( ($hostip,$host,$reason) = ($warning =~ /^(?:smtpd_peer_init: )?($re_IP): hostname ([^ ]+) verification failed: (.*)$/o ) or + ($hostip,$reason,$host) = ($warning =~ /^(?:smtpd_peer_init: )?($re_IP): (address not listed for hostname) (.*)$/o )) { + #TD warning: 10.0.0.1: hostname sample.com verification failed: Host not found + #TD warning: smtpd_peer_init: 192.168.0.1: hostname example.com verification failed: Name or service not known + #TD warning: 192.168.0.1: address not listed for hostname sample.net + $Totals{'HostnameVerification'}++; + $Counts{'HostnameVerification'}{"\u$reason"}{formathost($hostip,$host)}++; + + } elsif ( ($warning =~ /^$re_QID: queue file size limit exceeded$/o ) or + ($warning =~ /^uid=\d+: File too large$/)) { + $Totals{'WarnFileTooBig'}++; + + } elsif ( my ($source) = ($warning =~ /^database (?:[^ ]*) is older than source file ([\w\/]+)$/)) { + #TD warning: database /etc/postfix/client_checks.db is older than source file /etc/postfix/client_checks + $Totals{'DatabaseGeneration'}++; + $Counts{'DatabaseGeneration'}{$source}++; + + } elsif ( ($reason,$qid,$reason2) = ($warning =~ /^(open active) ($re_QID): (.*)$/o ) or + ($reason,$qid,$reason2) = ($warning =~ /^qmgr_active_corrupt: (save corrupt file queue active) id ($re_QID): (.*)$/o ) or + ($qid,$reason,$reason2) = ($warning =~ /^($re_QID): (write queue file): (.*)$/o )) { + + #TD warning: open active BDB9B1309F7: No such file or directory + #TD warning: qmgr_active_corrupt: save corrupt file queue active id 4F4272F342: No such file or directory + #TD warning: E669DE52: write queue file: No such file or directory + + $Totals{'QueueWriteError'}++; + $Counts{'QueueWriteError'}{"$reason: $reason2"}{$qid}++; + + } elsif ( ($qid,$reason) = ($warning =~ /^qmgr_active_done_3_generic: remove ($re_QID) from active: (.*)$/o )) { + #TD warning: qmgr_active_done_3_generic: remove AF0F223FC05 from active: No such file or directory + $Totals{'QueueWriteError'}++; + $Counts{'QueueWriteError'}{"remove from active: $reason"}{$qid}++; + + } elsif ( my ($queue,$qid) = ($warning =~ /^([^\/]*)\/($re_QID): Error writing message file$/o )) { + #TD warning: maildrop/C9E66ADF: Error writing message file + $Totals{'MessageWriteError'}++; + $Counts{'MessageWriteError'}{$queue}{$qid}++; + + } elsif (my ($process,$status) = ($warning =~ /^process ([^ ]*) pid \d+ exit status (\d+)$/)) { + #TD warning: process /usr/lib/postfix/smtp pid 9724 exit status 1 + $Totals{'ProcessExit'}++; + $Counts{'ProcessExit'}{"$process: exit status $status"}++; + + } elsif ( ($reason) = ($warning =~ /^mailer loop: (.*)$/)) { + #TD warning: mailer loop: best MX host for example.com is local + $Totals{'MailerLoop'}++; + $Counts{'MailerLoop'}{$reason}++; + + } elsif ( ($reason,$domain) = ($warning =~ /^(malformed domain name in resource data of MX record) for (.*):$/)) { + #TD warning: malformed domain name in resource data of MX record for mail.example.com: + $Totals{'MxError'}++; + $Counts{'MxError'}{"\u$reason"}{$domain}{""}++; + + } elsif ( ($reason,$host,$reason2) = ($warning =~ /^(Unable to look up MX host) for ([^:]*): (.*)$/)) { + #TD warning: Unable to look up MX host for example.com: Host not found + $reason2 = 'Host not found' if ($reason2 =~ /^Host not found, try again/); + $Totals{'MxError'}++; + $Counts{'MxError'}{"\u$reason"}{"\u$reason2"}{$host}{""}++; + + } elsif ( ($reason,$host,$to,$reason2) = ($warning =~ /^(Unable to look up MX host) (.*) for Sender address ([^:]*): (.*)$/)) { + #TD warning: Unable to look up MX host mail.example.com for Sender address [email protected]: hostname nor servname provided, or not known + $reason2 = 'Host not found' if ($reason2 =~ /^Host not found, try again/); + my ($name, $domain) = split ('@', "\L$to"); + $Totals{'MxError'}++; + $Counts{'MxError'}{"\u$reason"}{"\u$reason2"}{$host}{$name}++; + + } elsif ( ($host,$hostip,$type) = ($warning =~ /^([^[]+)\[($re_IP)\] sent \w+ header instead of SMTP command: (.*)$/o ) or + ($host,$hostip,$type) = ($warning =~ /^non-SMTP command from ([^[]+)\[($re_IP)\]: (.*)$/o )) { + # ancient + #TD warning: example.com[192.168.0.1] sent message header instead of SMTP command: From: "Someone" <40245426501example.com> + # current + #TD warning: non-SMTP command from sample.net[10.0.0.1]: Received: from 192.168.0.1 (HELO bogus.sample.com) + + $Totals{'SmtpConversationError'}++; + $Counts{'SmtpConversationError'}{formathost($hostip,$host)}{$type}++; + + } elsif ( my ($msg) = ($warning =~ /^valid_hostname: (.*)$/)) { + #TD warning: valid_hostname: empty hostname + $Totals{'HostnameValidationError'}++; + $Counts{'HostnameValidationError'}{$msg}++; + + } elsif ( ($host,$hostip,$type) = ($warning =~ /^([^[]+)\[($re_IP)\]: SASL (.*) authentication failed/o )) { + #TD warning: example.com[192.168.0.1]: SASL DIGEST-MD5 authentication failed + $Totals{'SaslAuthFail'}++; + $Counts{'SaslAuthFail'}{formathost($hostip,$host)}++; + + } elsif ( ($host,$site,$reason) = ($warning =~ /^([^:]*): RBL lookup error:.* Name service error for (?:name=)?$re_IP\.([^:]*): (.*)$/o )) { + #TD warning: 192.168.0.1.sbl.spamhaus.org: RBL lookup error: Host or domain name not found. Name service error for name=192.168.0.1.sbl.spamhaus.org type=A: Host not found, try again + + #TD warning: 10.0.0.1.relays.osirusoft.com: RBL lookup error: Name service error for 10.0.0.1.relays.osirusoft.com: Host not found, try again + $Totals{'RBLError'}++; + $Counts{'RBLError'}{$site}{$reason}{$host}++; + + } elsif ( + ($host,$hostip,$reason,$helo) = ($warning =~ /^host ([^[]+)\[($re_IP)\] (greeted me with my own hostname) ([^ ]*)$/o ) or + ($host,$hostip,$reason,$helo) = ($warning =~ /^host ([^[]+)\[($re_IP)\] (replied to HELO\/EHLO with my own hostname) ([^ ]*)$/o )) { + #TD warning: host example.com[192.168.0.1] greeted me with my own hostname example.com + #TD warning: host example.com[192.168.0.1] replied to HELO/EHLO with my own hostname example.com + $Totals{'HeloError'}++; + $Counts{'HeloError'}{"\u$reason"}{formathost($hostip,$host)}++; + + } elsif ( ($host,$hostip,$cmd,$addr) = ($warning =~ /^Illegal address syntax from ([^[]+)\[($re_IP)\] in ([^ ]*) command: (.*)/o )) { + #TD warning: Illegal address syntax from example.com[192.168.0.1] in MAIL command: [email protected] + $addr =~ s/[<>]//g; + $Totals{'IllegalAddrSyntax'}++; + $Counts{'IllegalAddrSyntax'}{$cmd}{$addr}{formathost($hostip,$host)}++; + + } elsif ( ($reason, $host) = ($warning =~ /^numeric (hostname): ($re_IP)$/o ) or + ($reason, $host) = ($warning =~ /^numeric domain name in (resource data of MX record) for (.*)$/ )) { + #TD warning: numeric hostname: 192.168.0.1 + #TD warning: numeric domain name in resource data of MX record for sample.com: 192.168.0.1 + + if (($host,$hostip) = ($host =~ /([^:]+): ($re_IP)/o)) { + $host = formathost($hostip,$host); + } + $Totals{'NumericHostname'}++; + $Counts{'NumericHostname'}{"\u$reason"}{$host}++; + + } elsif (my ($service,$when) = ($warning =~ /^premature end-of-input on ([^ ]+) (.*)$/ )) { + #TD warning: premature end-of-input on private/anvil while reading input attribute name + $Totals{'PrematureEOI'}++; + $Counts{'PrematureEOI'}{$service}{$when}++; + + } elsif (($service,$reason) = ($warning =~ /^(.*): (bad command startup -- throttling)/o )) { + #TD warning: /usr/libexec/postfix/trivial-rewrite: bad command startup -- throttling + $Totals{'StartupError'}++; + $Counts{'StartupError'}{"Service: $service"}{$reason}++; + + } elsif (($service,$reason) = ($warning =~ /(problem talking to service [^:]*): (.*)$/o )) { + #TD warning: problem talking to service rewrite: Connection reset by peer + #TD warning: problem talking to service rewrite: Success + $Totals{'CommunicationError'}++; + $Counts{'CommunicationError'}{"\u$service"}{$reason}++; + + } elsif (my ($map,$key) = ($warning =~ /^$re_QID: ([^ ]*) map lookup problem for (.*)$/o )) { + #TD warning: 6F74F74431: virtual_alias_maps map lookup problem for [email protected] + $Totals{'MapProblem'}++; + $Counts{'MapProblem'}{"$map"}{$key}++; + + } elsif (($map,$reason) = ($warning =~ /pcre map ([^,]+), (.*)$/ )) { + #TD warning: pcre map /etc/postfix/body_checks, line 92: unknown regexp option "F": skipping this rule + $Totals{'MapProblem'}++; + $Counts{'MapProblem'}{$map}{$reason}++; + + } elsif (($reason) = ($warning =~ /dict_ldap_lookup: (.*)$/ )) { + #TD warning: dict_ldap_lookup: Search error 80: Internal (implementation specific) error + $Totals{'LdapError'}++; + $Counts{'LdapError'}{$reason}++; + + } elsif ( ($size,$host,$hostip) = ($warning =~ /^bad size limit "([^"]+)" in EHLO reply from ([^[]+)\[($re_IP)\]$/o )) { + #TD warning: bad size limit "-679215104" in EHLO reply from example.com[192.168.0.1] + $Totals{'HeloError'}++; + $Counts{'HeloError'}{"Bad size limit in EHLO reply"}{formathost($hostip,$host)}{"$size"}++; + + } elsif ( ($size,$host,$hostip,$service) = ($warning =~ /^Connection concurrency limit exceeded: (\d+) from ([^[]+)\[($re_IP)\] for service (.*)/o )) { + #TD warning: Connection concurrency limit exceeded: 51 from example.com[192.168.0.1] for service smtp + $Totals{'ConcurrencyLimit'}++; + $Counts{'ConcurrencyLimit'}{$service}{formathost($hostip,$host)}{$size}++; -if ($Undeliverable > 0) { - print "\n$Undeliverable messages rejected as undeliverable"; -} + } else { + #TD warning: No server certs available. TLS won't be enabled + #TD warning: smtp_connect_addr: bind <localip>: Address already in use + $Totals{'WarningsOther'}++; + $Counts{'WarningsOther'}{$warning}++; + } + } + # end of warnings section + + + # ^$re_QID: ... + elsif ( ($qid, $p2) = ($p1 =~ /^($re_QID): (.*)$/o ) ) { + next if ( $p2 =~ /^client=(?:[^ ]*\[[^ ]*\])\s*$/o ); + next if ( $p2 =~ /^skipped, still being delivered/o ); + next if ( $p2 =~ /^host [^ ]*\[[^ ]*\] said: 4[0-9][0-9]/o ); + next if ( $p2 =~ /^host [^ ]*\[[^ ]*\] refused to talk to me: 4[0-9][0-9]/o ); + # postsuper double reports the following 3 lines + next if ( $p2 =~ /^released from hold$/o ); + next if ( $p2 =~ /^placed on hold$/o ); + next if ( $p2 =~ /^requeued$/o ); + + #TD DA080C2E0B: client=example.com[192.168.0.1] + #TD NOQUEUE: client=mail.example.com[2001:dead:beef::1] + #TD F0EC9BBE2: client=mail.example.com[2001:dead:beef::1] + #TD F0EC9BBE2: message-id=<C1BEA2A0.188572%[email protected]> + + next if ( $p2 =~ /^message-id=/ ); + # XXX probably don't care about message-id; for now, useful debug aid + #if (($p3) = ($p2 =~ /^message-id=<(.*)>$/ )) { + # if (exists $Qids{$qid}) { + # print "Error: Duplicate QID: $qid, $p3\n"; + # } + # $Qids{$qid}{'message-id'} = $p3; + #} + + my ($p3, $dsn, $DDD, $trigger); + + # $re_QID: reject: ... + # $re_QID: reject_warning: ... + if (($rej_action,$p3) = ($p2 =~ /^(reject(?:_warning)?): (.*)$/ )) { + $rej_action =~ s/^r/R/; $rej_action =~ s/_warning$/Warn/; + + # $re_QID: reject: RCPT from ... + if (my ($p4) = ($p3 =~ /^RCPT from (.*)$/o )) { + my ($p5, $p6, $recip); + #print "p4: $p4\n"; + + # Recipient address rejected: Unknown users and via check_recipient_access + + if ( $p4 !~ /^([^[]+)\[($re_IP)\]: ($re_DSN) (.*)$/o ) { + inc_unmatched('reject1', $OrigLine); + next; + } -if ($ReturnedToSender >0) { - print "\n$ReturnedToSender messages expired and returned to sender"; -} + ($host,$hostip,$dsn,$p5) = ($1,$2,$3,$4); + #print "host: $host, hostip: $hostip, dsn: $dsn, p5: \"$p5\"\n"; + $rej_action = "Temp$rej_action" if ($dsn =~ /^4/); + + # XXX there may be many semicolon separated messages; need to parse based on "from=" + if ( ($recip,$reason,$p6) = ($p5 =~ /^<(.*)>: Recipient address rejected: ([^;]*);(.*)$/o )) { + # Unknown users; local mailbox, alias, virtual, relay user, unspecified + if (($reason) =~ s/^User unknown *//o) { + my ($table) = ($reason =~ /^in ((?:\w+ )+table)/o); + ($from) = ($p6 =~ /^ from=<([^>]*)>/o ); + $table = "Address table unavailable" if ($table =~ /^$/); # when show_user_unknown_table_name=no + $from = "<>" if ($from =~ /^$/); + + #TD NOQUEUE: reject: RCPT from sample.net[192.168.0.1]: 550 <[email protected]>: Recipient address rejected: User unknown in local recipient table; from=<> to=<[email protected]> proto=SMTP helo=<sample.net> + #TD NOQUEUE: reject_warning: RCPT from sample.net[192.168.0.1]: 550 <[email protected]>: Recipient address rejected: User unknown in local recipient table; from=<> to=<[email protected]> proto=SMTP helo=<sample.net> + #TD NOQUEUE: reject: RCPT from localhost[127.0.0.1]: 550 5.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual address table; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<localhost> + #TD NOQUEUE: reject: RCPT from example.com[10.0.0.1]: 450 4.1.1 <[email protected]>: Recipient address rejected: User unknown in virtual mailbox table; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<example.com> + #TD NOQUEUE: reject: RCPT from sample.net[10.0.0.1]: 550 5.5.0 <[email protected]>: Recipient address rejected: User unknown; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<[10.0.0.1]> + #TD NOQUEUE: reject: RCPT from example.com[2001:dead:beef::1]: 450 <[email protected]>: Recipient address rejected: Greylisted; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<example.com> + #print "User: $User, table: $table\n"; + + $Totals{"${rej_action}UnknownUser"}++; + $Counts{"${rej_action}UnknownUser"}{"\u$table"}{"\L$recip"}{$from}++; + + # check_recipient_access + } else { + #TD NOQUEUE: reject: RCPT from example.com[10.0.0.1]: 454 4.7.1 <[email protected]>: Recipient address rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<example.com> + #TD NOQUEUE: reject_warning: RCPT from example.com[10.0.0.1]: 454 4.7.1 <[email protected]>: Recipient address rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<example.com> + #TD NOQUEUE: reject: RCPT from example.com[10.0.0.1]: 450 4.1.2 <[email protected]>: Recipient address rejected: Domain not found; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<sample.net> + #TD NOQUEUE: reject: RCPT from example.com[10.0.0.1]: 554 <[email protected]>: Recipient address rejected: Please see http://www.openspf.org/why.html?sender=from%40example.net&ip=10.0.0.1&receiver=mx.example.net; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<[email protected]> + #TD NOQUEUE: reject: RCPT from mail.example.com[10.0.0.1]: 550 <[email protected]>: Recipient address rejected: undeliverable address: host mail.example.net[192.168.0.1] said: 550 <[email protected]>: User unknown in virtual alias table (in reply to RCPT TO command); from=<[email protected]> to=<[email protected]> proto=SMTP helo=<mail.example.com> + #TD NOQUEUE: reject: RCPT from unknown[10.0.0.1]: 554 <[email protected]>: Recipient address rejected: Please see http://spf.pobox.com/why.html?sender=user%40example.com&ip=10.0.0.1&receiver=mail; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<10.0.0.1> + + if ($reason =~ m{^Please see http://[^/]+/why\.html}) { + $reason = 'SPF reject'; + } elsif ($reason =~ /^undeliverable address: host ([^[]+)\[($re_IP)\] said:/o) { + $reason = 'undeliverable address: remote host rejected recipient'; + } -if ($ResentMessages > 0) { - print "\n$ResentMessages resent messages"; -} + $Totals{"${rej_action}Recip"}++; + $Counts{"${rej_action}Recip"}{"\u$reason"}{"\L$recip"}{formathost($hostip,$host)}++; + } -if ($RemovedFromQueue > 0) { - print "\n$RemovedFromQueue messages removed from queue"; -} + } elsif ( ($to) = ($p5 =~ /^<([^ ]*)>.* Relay access denied.* to=([^ ]*)/o ) ) { + #TD NOQUEUE: reject: RCPT from example.com[192.168.0.1]: 554 <[email protected]>: Relay access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<example.com> + #TD NOQUEUE: reject_warning: RCPT from example.com[192.168.0.1]: 554 <[email protected]>: Relay access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<example.com> + # print "host: \"$host\", hostip: \"$hostip\", To: \"$to\"\n"; + + $Totals{"${rej_action}Relay"}++; + $Counts{"${rej_action}Relay"}{formathost($hostip,$host)}{$to}++; + + } elsif ( ($from,$reason) = ($p5 =~ /^<(.*)>: Sender address rejected: (.*);/o )) { + #TD NOQUEUE: reject: RCPT from sample.net[10.0.0.1]: 450 4.1.8 <[email protected]>: Sender address rejected: Domain not found; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<sample.net> + #TD NOQUEUE: reject_warning: RCPT from sample.net[10.0.0.1]: 450 4.1.8 <[email protected]>: Sender address rejected: Domain not found; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<sample.net> + #TD NOQUEUE: reject: RCPT from mail.example.com[10.0.0.1]: 550 <[email protected]>: Sender address rejected: undeliverable address: host mail.example.net[192.168.0.1] said: 550 <[email protected]>: User unknown in virtual alias table (in reply to RCPT TO command); from=<[email protected]> to=<[email protected]> proto=SMTP helo=<mail.example.com> + # print "host: \"$host\", hostip: \"$hostip\", from: \"$from\", reason: \"$reason\"\n"; + $from = "<>" if ($from =~ /^$/); + if ($reason =~ /^undeliverable address: host ([^[]+)\[($re_IP)\] said:/o) { + $reason = 'undeliverable address: remote host rejected sender'; + } + $Totals{"${rej_action}Sender"}++; + $Counts{"${rej_action}Sender"}{"\u$reason"}{formathost($hostip,$host)}{$from}++; -if ($QueueSizeExceeded > 0) { - print "\n$QueueSizeExceeded messages exceeded queue or message file size limit and removed"; -} + } elsif ( ($reason,$from,$recip) = ($p5 =~ /^<[^[]+\[$re_IP\]>: Client host rejected: (.*); from=<(.*)> to=<(.*)> proto=/o )) { -if ($TableChanged > 0) { - print "\n$TableChanged exited after table change detection"; -} + #TD NOQUEUE: reject: RCPT from sample.net[10.0.0.1]: 554 <sample.net[10.0.0.1]>: Client host rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<friend> + #TD NOQUEUE: reject_warning: RCPT from sample.net[10.0.0.1]: 554 <sample.net[10.0.0.1]>: Client host rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<friend> + #TD NOQUEUE: reject: RCPT from sample.net[10.0.0.1]: 450 Client host rejected: cannot find your hostname, [10.0.0.1]; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<sample.net> + $from = "<>" if ($from =~ /^$/); + $Totals{"${rej_action}Client"}++; + $Counts{"${rej_action}Client"}{"\u$reason"}{formathost($hostip,$host)}{"\L$recip"}{$from}++; + + } elsif ( (my $p6) = ($p5 =~ /^Client host rejected: cannot find your (.*)$/o )) { + if ( ($from,$recip,$helo) = ($p6 =~ /^hostname, \[$re_IP\]; from=<(.*?)> to=<(.*?)> proto=\S+ helo=<(.*)>/o )) { + #TD NOQUEUE: reject: RCPT from unknown[10.0.0.1]: 450 Client host rejected: cannot find your hostname, [10.0.0.1]; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<example.com> + #TD NOQUEUE: reject_warning: RCPT from unknown[10.0.0.1]: 450 Client host rejected: cannot find your hostname, [10.0.0.1]; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<example.com> + $from = "<>" if ($from =~ /^$/); + $Totals{"${rej_action}UnknownClient"}++; + $Counts{"${rej_action}UnknownClient"}{$host}{$helo}{$from}{"\L$recip"}++; + + # reject_unknown_reverse_client_hostname (no DNS PTR record for client's IP) + + } elsif ( $p6 =~ /^reverse hostname, \[$re_IP\]/o ) { + #TD NOQUEUE: reject: RCPT from unknown[192.168.0.1]: 550 5.7.1 Client host rejected: cannot find your reverse hostname, [192.168.0.1] + $Totals{"${rej_action}UnknownReverseClient"}++; + $Counts{"${rej_action}UnknownReverseClient"}{$host}++ + } else { + inc_unmatched('rejectclienthost', $OrigLine); + } -if ($UnsupportedFamily > 0) { - print "\nUnknown address family $UnsupportedFamily Time(s)\n"; -} + } elsif ( ($site,$reason) = ($p5 =~ /^Service unavailable; (?:Client host |Sender address )?\[[^ ]*\] blocked using ([^ ]*)(, reason: .*)?;/o )) { + # Note: similar code below: search RejectRBL + #TD NOQUEUE: reject: RCPT from example.com[10.0.0.1]: 554 5.7.1 Service unavailable; Client host [10.0.0.1] blocked using sbl-xbl.spamhaus.org; http://www.spamhaus.org/query/bl?ip=10.0.0.1; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<friend> + #TD NOQUEUE: reject_warning: RCPT from example.com[10.0.0.1]: 554 5.7.1 Service unavailable; Client host [10.0.0.1] blocked using sbl-xbl.spamhaus.org; http://www.spamhaus.org/query/bl?ip=10.0.0.1; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<friend> + + $Totals{"${rej_action}RBL"}++; + if ($reason =~ /^$/) { + $Counts{"${rej_action}RBL"}{$site}{formathost($hostip,$host)}++; + } else { + $Counts{"${rej_action}RBL"}{$site}{formathost($hostip,$host)}{$reason}++; + } -#DETAILS -if ($MsgsQueue > 0) { - print "\n\nDETAILS\n"; - print "_______\n"; -} + } elsif ( ($reason,$helo) = ($p5 =~ /^<.*>: Helo command rejected: (.*);.* helo=<(.*)>$/o )) { + #TD NOQUEUE: reject: RCPT from sample.net[10.0.0.1]: 454 4.7.1 <localhost>: Helo command rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<localhost> + #TD NOQUEUE: reject_warning: RCPT from sample.net[10.0.0.1]: 454 4.7.1 <localhost>: Helo command rejected: Access denied; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<localhost> + $Totals{"${rej_action}Helo"}++; + $Counts{"${rej_action}Helo"}{$reason}{formathost($hostip,$host)}{"$helo"}++; + + } elsif ( ($from,$to) = ($p5 =~ /^Insufficient system storage; from=<([^>]*)> to=<([^>]+)>/o )) { + #TD NOQUEUE: reject: RCPT from example.com[192.168.0.1]: 452 Insufficient system storage; from=<[email protected]> to=<[email protected]> + #TD NOQUEUE: reject_warning: RCPT from example.com[192.168.0.1]: 452 Insufficient system storage; from=<[email protected]> to=<[email protected]> + $from = "<>" if ($from =~ /^$/); + $Totals{"${rej_action}InsufficientSpace"}++; + $Counts{"${rej_action}InsufficientSpace"}{formathost($hostip,$host)}{$to}{$from}++; + + $Totals{'WarnInsufficientSpace'}++; # to show in Warnings section + + } elsif ( ($from,$to) = ($p5 =~ /^Server configuration (?:error|problem); from=<([^>]*)> to=<([^>]+)>/o )) { + #TD NOQUEUE: reject: RCPT from example.com[10.0.0.1]: 451 4.3.5 Server configuration error; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<example.com> + #TD NOQUEUE: reject_warning: RCPT from example.com[10.0.0.1]: 451 4.3.5 Server configuration error; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<example.com> + #TD NOQUEUE: reject: RCPT from sample.net[192.168.0.1]: 450 Server configuration problem; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<sample.net> + $from = "<>" if ($from =~ /^$/); + $Totals{"${rej_action}ConfigError"}++; + $Counts{"${rej_action}ConfigError"}{formathost($hostip,$host)}{$to}{$from}++; + + $Totals{'WarnConfigError'}++; # to show in Warnings section + + # This would capture all other rejects, but I think it might be more useful to add + # additional capture sections based on user reports of uncapture lines. + # + #} elsif ( ($reason) = ($p5 =~ /^([^;]+);/o)) { + # $Totals{"${rej_action}Other"}++; + # $Counts{"${rej_action}Other"}{$reason}++; -if (keys %ConfigError) { - print "\n\nWARNING!!!\n"; - print "Configuration Errors:\n"; - foreach $Option (sort {$a cmp $b} keys %ConfigError) { - print " Option: $Option\n"; - foreach $Reason (sort {$a cmp $b} keys %{$ConfigError{$Option}} ) { - print " $Reason: $ConfigError{$Option}{$Reason} Time(s)\n"; - } - } -} + } else { + inc_unmatched('rejectother', $OrigLine); + } + } + # end of $re_QID: reject: RCPT from ... -if (keys %QueueWriteError) { - if ($Detail >= 5) { - print "\n\nError writing queue file:\n"; - foreach $Reason (sort {$a cmp $b} keys %QueueWriteError) { - print " $Reason : $QueueWriteError{$Reason} Time(s)\n"; - } - } - else { - $n=0; - foreach $Reason (keys %QueueWriteError) { - $n+=$QueueWriteError{$Reason}; - } - print "\n\nError writing queue file: $n Time(s)"; - } -} + # $re_QID: reject: body ... + # $re_QID: reject: header ... + elsif ( ($reason,$host,$to,$reason2) = ($p3 =~ /^(?:header|body) (.*) from ([^;]+); from=<(?:[^ ]*)>(?: to=<([^>]*)>)?(?: proto=[^ ]* helo=<[^ ]*>)?: (.*)$/o )) { + #TD 9804DB31C2: reject: header To: <[email protected]> from sample.net[192.168.0.1]; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<anywhere.com>: Any reason + #TD 831C2C2E0D: reject: body Quality Replica watches!!! from example.com[192.168.0.1]; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<example.com>: 5.7.1 Spam: Watches + #TD 26B6AC2DB5: reject: body xx Subject: Cheapest Viagra and Cialis you can find! from local; from=<root@localhost>: 5.7.1 Spam: Drugs + # Note: reject_warning does not seem to occur -if (keys %MessageWriteError) { - if ($Detail >= 5) { - print "\n\nError writing message file:\n"; - foreach $Reason (sort {$a cmp $b} keys %MessageWriteError) { - print " $Reason : $MessageWriteError{$Reason} Time(s)\n"; - } - } - else { - $n=0; - foreach $Reason (keys %MessageWriteError) { - $n+=$MessageWriteError{$Reason}; - } - print "\n\nError writing message file: $n Time(s)"; - } -} + if ($host =~ /^local$/) { + $hostip = '127.0.0.1'; + } + elsif ($host =~ /([^[]+)\[($re_IP)\]/) { + $host = $1; $hostip = $2; + } -if (keys %DatabaseGeneration) { - if ($Detail >= 5) { - print "\n\nDatabase files are not up-to-date (probably rehash is needed):\n"; - foreach $Source (sort {$a cmp $b} keys %DatabaseGeneration) { - print " $Source : $DatabaseGeneration{$Source} Time(s)\n"; - } - } - else { - $n=0; - $fn=scalar(keys %DatabaseGeneration); - foreach $Source (keys %DatabaseGeneration) { - $n+=$DatabaseGeneration{$Source}; - } - print "\n\nDatabase files are not up-to-date (probably rehash is needed): $fn File(s), $n Time(s)"; - } -} + $reason =~ s/\s+/ /g; + if ($p3 =~ /^body/) { + $Totals{'RejectBody'}++; + $Counts{'RejectBody'}{$reason2}{$to}{formathost($hostip,$host)}{"$reason"}++; + } + else { + #print "reason: \"$reason\", host: \"$host\", hostip: \"$hostip\", to: \"$to\", reason2: \"$reason2\"\n"; + $Totals{'RejectHeader'}++; + $Counts{'RejectHeader'}{$reason2}{$to}{formathost($hostip,$host)}{"$reason"}++; + } + } -if (keys %PixWorkaround) { - if ($Detail >= 5) { - print "\n\nEnabled PIX <CRLF>.<CRLF> workaround for:\n"; - foreach $Host (sort {$a cmp $b} keys %PixWorkaround) { - print " $Host : $PixWorkaround{$Host} Time(s)\n"; - } - } - else { - $n=0; - $hn=scalar(keys %PixWorkaround); - foreach $Host (keys %PixWorkaround) { - $n+=$PixWorkaround{$Host}; - } - print "\n\nEnabled PIX <CRLF>.<CRLF> workaround for: $hn Host(s), $n Time(s)"; - } -} + # $re_QID: reject: MAIL from ... + elsif ( ($host,$hostip) = ($p3 =~ /^MAIL from ([^[]+)\[($re_IP)\]: $re_DSN Message size exceeds fixed limit; proto=[^ ]* helo=<[^>]+>$/o )) { + # Postfix responds with this message after a MAIL FROM:<...> SIZE=nnn command, where postfix consider's nnn excessive + # Note: similar code below: search RejectSize + # Note: reject_warning does not seem to occur + #TD NOQUEUE: reject: MAIL from localhost[127.0.0.2]: 552 Message size exceeds fixed limit; proto=ESMTP helo=<localhost> + #TD NOQUEUE: reject: MAIL from example.com[192.168.0.2]: 452 4.3.4 Message size exceeds fixed limit; proto=ESMTP helo=<example.com> + $Totals{'RejectSize'}++; + $Counts{'RejectSize'}{formathost($hostip,$host)}{'unknown'}++; + } + + # $re_QID: reject: CONNECT from ... + elsif (($p4) = ($p3 =~ /^CONNECT from (.*)$/o )) { + + if ( ($host,$hostip,$dsn,$reason) = ($p4 =~ /([^[]+)\[($re_IP)\]: ($re_DSN) <.*>: Client host rejected: ([^;]*);/o )) { + #TD NOQUEUE: reject: CONNECT from unknown[192.168.0.1]: 503 5.5.0 <unknown[192.168.0.1]>: Client host rejected: Improper use of SMTP command pipelining; proto=SMTP + $rej_action = "Temp$rej_action" if ($dsn =~ /^4/); + $Totals{"${rej_action}Client"}++; + $Counts{"${rej_action}Client"}{"\u$reason"}{formathost($hostip,$host)}{""}++; # XXX currently need to keep same key depth - add CONNECT key to do so + } else { + inc_unmatched('connfrom', $OrigLine); + } + } -if (($Detail >=5) and (keys %SentBy)) { - print "\n\nTop ten local senders:\n"; - foreach $ThisSender (sort {$a cmp $b} keys %SentBy) { - $ThisNumber = $SentBy{$ThisSender}; - push(@{$ThisIsNumber{$ThisNumber}}, $ThisSender); - } - my $ListRank = 10; - foreach $SenderRank (sort {$b <=> $a} keys %ThisIsNumber) { - last unless ($ListRank > 0); - print " $SenderRank messages sent by:\n"; - foreach $ThisSender (@{$ThisIsNumber{$SenderRank}}) { - last unless ($ListRank > 0); - $ListRank--; - print" $ThisSender\n"; - } - } -} + # $re_QID: reject: VRFY from ... + elsif (($p4) = ($p3 =~ /^VRFY from (.*)$/o )) { + #TD NOQUEUE: reject: VRFY from example.com[10.0.0.1]: 550 5.1.1 <:>: Recipient address rejected: User unknown in local recipient table; to=<:> proto=SMTP helo=<192.168.0.1> + #TD NOQUEUE: reject_warning: VRFY from example.com[10.0.0.1]: 450 4.1.2 <<D0-1C7-1F41F6@BS>>: Recipient address rejected: Domain not found; to=<<D0-1C7-1F41F6@BS>> proto=SMTP helo=<friend> + #TD NOQUEUE: reject: VRFY from example.com[10.0.0.1]: 450 4.1.8 <[email protected]>: Sender address rejected: Domain not found; from=<[email protected]> to=<to> proto=SMTP + #TD NOQUEUE: reject: VRFY from example.com[10.0.0.1]: 554 5.7.1 Service unavailable; Client host [10.0.0.1] blocked using zen.spamhaus.org; http://www.spamhaus.org/query/bl?ip=10.0.0.1; to=<u> proto=SMTP + + if ( ($host,$hostip,$dsn,$reason) = ($p4 =~ /([^[]+)\[($re_IP)\]: ($re_DSN) (?:<.*>: )?([^;]*);/o )) { + $rej_action = "Temp$rej_action" if ($dsn =~ /^4/); + $Totals{"${rej_action}Verify"}++; + $Counts{"${rej_action}Verify"}{"\u$reason"}{formathost($hostip,$host)}++; -if (keys %UnknownUsers) { - $un=scalar(keys %UnknownUsers); - if ($Detail >= 10) { - print "\n\nUnknown users: $un Time(s)\n"; - foreach $ThisOne (sort {$a cmp $b} keys %UnknownUsers) { - print " $ThisOne : $UnknownUsers{$ThisOne} Time(s)\n"; - } - } - else { - $n=0; - foreach $ThisOne (keys %UnknownUsers) { - $n+=$UnknownUsers{$ThisOne}; + } else { + inc_unmatched('vrfyfrom', $OrigLine); + } + } + else { + inc_unmatched('rejectlast', $OrigLine); + } } - print "\n\nUnknown users: $un, $n Time(s)"; - } -} -if (keys %SaslAuthenticationFail) { - if ($Detail >= 5) { - print "\n\nSASL Authentication failed from:\n"; - foreach $Host (sort {$a cmp $b} keys %SaslAuthenticationFail) { - print " $Host : $SaslAuthenticationFail{$Host} Time(s)\n"; - } - } - else { - $n=0; - $hn=scalar(keys %SaslAuthenticationFail); - foreach $Host (keys %SaslAuthenticationFail) { - $n+=$SaslAuthenticationFail{$Host}; - } - print "\n\nSASL Authentication failed from: $hn Host(s), $n Time(s)"; - } -} + # ^$re_QID: ... (not rejects) + elsif ( my ($bytes,$nrcpt) = ($p2 =~ /^from=<[^>]*>, size=(\d+), nrcpt=(\d+).*$/o ) ) { + #TD 4AEFAF569C11: from=<FROM: SOME [email protected]>, size=4051, nrcpt=1 (queue active) + #TD12 2A535C2E01: from=<[email protected]>, size=25302, nrcpt=2 (queue active) + #TD F0EC9BBE2: from=<[email protected]>, size=5529, nrcpt=1 (queue active) + + # Distinguish bytes accepted vs. bytes delivered due to multiple recips + + #if (!exists $Qids{$qid}) { + # print "ERROR: no Qids{$qid} found\n"; + #} + if (!exists $Qids{$qid} and !exists $Qids{$qid}{'nrcpt'}) { + $Qids{$qid}{'nrcpt'} = $nrcpt; + $Qids{$qid}{'size'} = $bytes; + $Totals{'MsgsAccepted'}++; + $Totals{'BytesAccepted'} += $bytes; + } + #else { + # Occurs for each deferral + # print "DEBUG: RETRY($Qid) $p2\n"; + #} + } + + ### sent, forwarded, bounced, softbounce, deferred, (un)deliverable + elsif ( ($to,$origto,$relay,$DDD,$status,$reason) = ($p2 =~ /^to=<([^>]*)>,(?: orig_to=\<([^>]*)>,)? relay=([^ ]*).*, ($re_DDD), status=([^ ]+) (.*)$/o )) { + #TD 552B6C20E: to=<[email protected]>, relay=mail.example.net[10.0.0.1]:25, delay=1021, delays=1020/0.04/0.56/0.78, dsn=2.0.0, status=sent (250 Ok: queued as 6EAC4719EB) + #TD DD925BBE2: to=<[email protected]>, orig_to=<[email protected]>, relay=mail.example.net[2001:dead:beef::1], delay=2, status=sent (250 Ok: queued as 5221227246) + + $reason =~ s/\((.*)\)/$1/; # Makes capturing nested parens easier + $to = lc $to; + $origto = lc $origto; + my ($localpart, $domainpart) = split ('@', $to); + + # If recipient_delimiter is set, break localpart into user + extension + # and save localpart in origto if origto is empty + # + if ($Opts{'recipient_delimiter'} and $localpart =~ /\Q$Opts{'recipient_delimiter'}\E/o) { + + # special cases: never split mailer-daemon or double-bounce + # or owner- or -request if delim is "-" (dash). + unless ($localpart =~ /^(?:mailer-daemon|double-bounce)$/i or + ($Opts{'recipient_delimiter'} eq '-' and $localpart =~ /^owner-.|.-request$/i)) { + my ($user,$extension) = split (/$Opts{'recipient_delimiter'}/o, $localpart, 2); + $origto = $localpart if ($origto =~ /^$/); + $localpart = $user; + } + } + + unless (($dsn) = ($DDD =~ /dsn=(\d\.\d\.\d)/)) { + #$dsn = "X.X.X (DSN unavailable)"; + $dsn = ""; + } + + ### sent + if ($status =~ /^sent$/) { + if ($reason =~ /forwarded as /) { + $Totals{'MsgsForwarded'}++; + $Counts{'MsgsForwarded'}{$domainpart}{$localpart}{$origto}++; + } + else { + if ($postfix_svc =~ /^lmtp$/) { + $Totals{'MsgsSentLmtp'}++; + $Counts{'MsgsSentLmtp'}{$domainpart}{$localpart}{$origto}++; + } + elsif ($postfix_svc =~ /^smtp$/) { + $Totals{'MsgsSent'}++; + $Counts{'MsgsSent'}{$domainpart}{$localpart}{$origto}++; + } + # virtual, command, ... + else { + $Totals{'MsgsDelivered'}++; + $Counts{'MsgsDelivered'}{$domainpart}{$localpart}{$origto}++; + } + } + if (exists $Qids{$qid} and exists $Qids{$qid}{'size'}) { + $Totals{'BytesDelivered'} += $Qids{$qid}{'size'}; + } + } -if (keys %SaslAuth) { - if ($Detail >= 5) { - print "\n\nSASL Authenticated messages from:\n"; - foreach $Host (sort {$a cmp $b} keys %SaslAuth) { - if ($Detail >= 10) { - print " $Host:\n"; - foreach $User (sort {$a cmp $b} keys %{$SaslAuth{$Host}} ) { - print " sasluser $User : $SaslAuth{$Host}{$User} Times(s)\n"; + ### bounced + elsif ($status =~ /^(?:bounced|SOFTBOUNCE)$/) { + #TD 76EB0D13: to=<[email protected]>, relay=none, delay=1, status=bounced (mail for mail.example.com loops back to myself) + #TD C8103B94: to=<[email protected]>, relay=none, delay=0, status=bounced (Host or domain name not found. Name service error for name=unknown.com type=A: Host not found) + #TD C76431E2: to=<[email protected]>, relay=local, delay=2, status=SOFTBOUNCE (host sample.net[192.168.0.1] said: 450 <[email protected]>: User unknown in local recipient table (in reply to RCPT TO command)) + #TD EB0B8770: to=<[email protected]>, orig_to=<postmaster>, relay=none, delay=1, status=bounced (User unknown in virtual alias table) + #TD EB0B8770: to=<[email protected]>, orig_to=<postmaster>, relay=sample.net[192.168.0.1], delay=1.1, status=bounced (User unknown in relay recipient table) + #TD D8962E54: to=<[email protected]>, relay=local, conn_use=2 delay=0.21, delays=0.05/0.02/0/0.14, dsn=4.1.1, status=SOFTBOUNCE (unknown user: "to") + #TD F031C832: to=<[email protected]>, orig_to=<[email protected]>, relay=local, delay=0.17, delays=0.13/0.01/0/0.03, dsn=5.1.1, status=bounced (unknown user: "to") + #TD 04B0702E: to=<[email protected]>, relay=example.com[10.0.0.1]:25, delay=12, delays=6.5/0.01/0.03/5.1, dsn=5.1.1, status=bounced (host example.com[10.0.0.1] said: 550 5.1.1 User unknown (in reply to RCPT TO command)) + #TD 9DAC8B2D: to=<[email protected]>, relay=example.com[10.0.0.1]:25, delay=1.4, delays=0.04/0/0.27/1.1, dsn=5.0.0, status=bounced (host example.com[10.0.0.1] said: 511 sorry, no mailbox here by that name (#5.1.1 - chkuser) (in reply to RCPT TO command)) + #TD 79CB702D: to=<[email protected]>, relay=example.com[10.0.0.1]:25, delay=0.3, delays=0.04/0/0.61/0.8, dsn=5.0.0, status=bounced (host example.com[10.0.0.1] said: 550 <[email protected]>, Recipient unknown (in reply to RCPT TO command)) + #TD 88B7A079: to=<[email protected]>, relay=example.com[10.0.0.1]:25, delay=45, delays=0.03/0/5.1/40, dsn=5.0.0, status=bounced (host example.com[10.0.0.1] said: 550-"The recipient cannot be verified. Please check all recipients of this 550 message to verify they are valid." (in reply to RCPT TO command)) + #TD 47B7B074: to=<[email protected]>, relay=example.com[10.0.0.1]:25, delay=6.6, delays=6.5/0/0/0.11, dsn=5.1.1, status=bounced (host example.com[10.0.0.1] said: 550 5.1.1 <[email protected]> User unknown; rejecting (in reply to RCPT TO command)) + + # print "bounce message from " . $to . " msg : " . $relay . "\n"; + + ### local bounce + # XXX local v. remote bounce seems iffy, relative + if ($relay =~ /^(?:none|local|virtual|avcheck|maildrop|127\.0\.0\.1)/) { + $Totals{'BounceLocal'}++; + $Counts{'BounceLocal'}{get_dsn_msg($dsn)}{$to}{"\u$reason"}++; + + ### remote bounce + } else { + my ($reply,$fmtdhost) = cleanhostreply($reason,$relay,$to,$domainpart); + + $Totals{'BounceRemote'}++; + $Counts{'BounceRemote'}{get_dsn_msg($dsn)}{$domainpart}{$localpart}{$fmtdhost}{$reply}++; } } - else { - $n=0; - foreach $User (keys %{$SaslAuth{$Host}} ) { - $n+=$SaslAuth{$Host}{$User}; + + elsif ($status =~ /deferred/) { + + #TD DD4F2AC4D3: to=<[email protected]>, relay=none, delay=27077, delays=27077/0/0.57/0, dsn=4.4.3, status=deferred (Host or domain name not found. Name service error for name=example.com type=MX: Host not found, try again) + #TD E52A1F1B52: to=<[email protected]>, relay=none, delay=141602, status=deferred (connect to mx1.example.com[10.0.0.1]: Connection refused) + #TD E52A1F1B52: to=<[email protected]>, relay=none, delay=141602, status=deferred (delivery temporarily suspended: connect to example.com[192.168.0.1]: Connection refused) + #TD DB775D7035: to=<[email protected]>, relay=none, delay=306142, delays=306142/0.04/0.18/0, dsn=4.4.1, status=deferred (connect to example.com[10.0.0.1]: Connection refused) + #TD EEDC1F1AA6: to=<[email protected]>, relay=example.org[10.0.0.1], delay=48779, status=deferred (lost connection with mail.example.org[10.0.0.1] while sending MAIL FROM) + #TD 8E7A0575C3: to=<[email protected]>, relay=sample.net, delay=26541, status=deferred (conversation with mail.example.com timed out while sending end of data -- message may be sent more than once) + #TD 7CF61B7030: to=<[email protected]>, relay=sample.net[10.0.0.1]:25, delay=322, delays=0.04/0/322/0, dsn=4.4.2, status=deferred (conversation with example.com[10.0.0.01] timed out while receiving the initial server greeting) + #TD B8BF0AE331: to=<to@localhost>, orig_to=<toalias@localhost>, relay=none, delay=238024, status=deferred (delivery temporarily suspended: transport is unavailable) + + # XXX postfix reports dsn=5.0.0, host's reply may contain its own dsn's such as 511 and #5.1.1 + # XXX should these be used instead? + #TD 232EAC2E55: to=<[email protected]>, relay=sample.net[10.0.0.1]:25, delay=5.7, delays=0.05/0.02/5.3/0.3, dsn=4.7.1, status=deferred (host sample.net[10.0.0.1] said: 450 4.7.1 <[email protected]>: Recipient address rejected: Greylisted (in reply to RCPT TO command)) + #TD 11677B700D: to=<[email protected]>, relay=example.com[10.0.0.1]:25, delay=79799, delays=79797/0.02/0.4/1.3, dsn=4.0.0, status=deferred (host example.com[10.0.0.1] said: 450 <[email protected]>: User unknown in local recipient table (in reply to RCPT TO command)) + #TD 0DA72B7035: to=<[email protected]>, relay=example.com[10.0.0.1]:25, delay=97, delays=0.03/0/87/10, dsn=4.0.0, status=deferred (host example.com[10.0.0.1] said: 450 <[email protected]>: Recipient address rejected: undeliverable address: User unknown in virtual alias table (in reply to RCPT TO command)) + + my ($reply,$fmtdhost) = cleanhostreply($reason,$relay,$to,$domainpart); + + if ($DeferredByQid{$qid}++ == 0) { + $Totals{'MsgsDeferred'}++; } - print " $Host: $n Time(s)\n"; + $Totals{'Deferrals'}++; + $Counts{'Deferrals'}{get_dsn_msg($dsn)}{$reply}{$domainpart}{$localpart}{$fmtdhost}++; } - } - } - else { - $n=0; - $hn=scalar(keys %SaslAuth); - foreach $Host (keys %SaslAuth) { - foreach $User (keys %{$SaslAuth{$Host}} ) { - $n+=$SaslAuth{$Host}{$User}; + + elsif ($status =~ /^undeliverable$/) { + #TD B54D220BFC: to=<[email protected]>, relay=sample.com[10.0.0.1], delay=0, dsn=5.0.0, status=undeliverable (host sample.com[10.0.0.1] refused to talk to me: 554 5.7.1 example.com Connection not authorized) + #TD 8F699C2EA6: to=<[email protected]>, relay=virtual, delay=0.14, delays=0.06/0/0/0.08, dsn=5.1.1, status=undeliverable (unknown user: "[email protected]") + $Totals{'Undeliverable'}++; + $Counts{'Undeliverable'}{$reason}{$origto ? "$to ($origto)" : "$to"}++; + } + + elsif ($status =~ /^deliverable$/) { + # sendmail -bv style deliverable reports + #TD ED862C2EA6: to=<[email protected]>, relay=virtual, delay=0.09, delays=0.03/0/0/0.06, dsn=2.0.0, status=deliverable (delivers to maildir) + $Totals{'Deliverable'}++; + $Counts{'Deliverable'}{$reason}{$origto ? "$to ($origto)" : "$to"}++; } - } - print "\n\nSASL Authenticated messages from: $hn Host(s), $n Time(s)"; - } -} -if (keys %TLSconnectFrom) { - if ($Detail >= 5) { - print "\n\nTLS Connections from:\n"; - foreach $Host (sort {$a cmp $b} keys %TLSconnectFrom) { - print " $Host : $TLSconnectFrom{$Host} Time(s)\n"; - } - } - else { - $n=0; - $hn=scalar(keys %TLSconnectFrom); - foreach $Host (keys %TLSconnectFrom) { - $n+=$TLSconnectFrom{$Host}; + else { + # keep this as the last condition in this else clause + inc_unmatched('unknownstatus', $OrigLine); + } + } # end of sent, forwarded, bounced, softbounce, deferred, (un)deliverable + + # XXX don't care about this anymore; MsgsAccepted are counted with from= lines + elsif ( $p2 =~ /^uid=(?:[^ ]*) from=<(?:[^>]*)>/o ) { + #TD2 1DFE2C2E18: uid=0 from=<root> + #$Totals{'MsgsAccepted'}++; + } + + elsif ( ($from) = ($p2 =~ /^from=<([^>]*)>, status=expired, returned to sender$/o )) { + #TD 9294C8866: from=<[email protected]>, status=expired, returned to sender + $from = "<>" if ($from =~ /^$/); + $Totals{'ReturnedToSender'}++; + $Counts{'ReturnedToSender'}{$from}++; + + } elsif ( ($p2 =~ /^resent-message-id=<?(?:[^>]*)>?$/o )) { + #TD 52A49200E1: resent-message-id=4739073.1 + #TD DB2E3C2E0E: resent-message-id=<[email protected]> + $Totals{'MsgsResent'}++; + + # see also ConnectionLost elsewhere + } elsif (($host,$hostip,$reason) = ($p2 =~ /^lost connection with ([^[]*)\[($re_IP)\] (while .*)$/o )) { + #TD EB7D4341F0: lost connection with sample.net[10.0.0.1] while sending MAIL FROM + #TD 5F6C7C2E0F: lost connection with sample.net[10.0.0.2] while receiving the initial server greeting + $Totals{'ConnectionLost'}++; + $Counts{'ConnectionLost'}{"\u$reason"}{formathost($hostip,$host)}++; + } + + # see also TimeoutInbound elsewhere + elsif (($host,$hostip,$reason) = ($p2 =~ /^conversation with ([^[]*)\[($re_IP)\] timed out (while .*)$/o )) { + #TD C20574341F3: conversation with sample.net[10.0.0.1] timed out while receiving the initial SMTP greeting + $Totals{'TimeoutInbound'}++; + $Counts{'TimeoutInbound'}{"\u$reason"}{formathost($hostip,$host)}++; + } + + elsif ($p2 =~ /^sender delay notification: $re_QID$/o) { + #TD 8DB93C2FF2: sender delay notification: AA61EC2F9A + $Totals{'SenderDelayNotification'}++; + + } elsif ( ($warning,$host,$hostip,$to,$reason) = ($p2 =~ /^warning: header (.*) from ([^[]+)\[($re_IP)\]; from=<(?:[^ ]*)> to=<([^ ]*)>(?: proto=[^ ]* helo=<[^ ]*>)?(?:: (.*))?$/o )) { + $reason = 'Unknown Reason' if ($reason =~ /^$/); + $Totals{'WarningHeader'}++; + $Counts{'WarningHeader'}{$reason}{formathost($hostip,$host)}{$to}{$warning}++; + + ### filter messages + } elsif ( ($host,$hostip,$trigger,$reason,$filter,$from,$to) = ($p2 =~ /^filter: RCPT from ([^[]+)\[($re_IP)\]: <([^>]*)>: (.*) triggers FILTER ([^;]+); from=<([^>]*)> to=<([^>]+)> proto=\S+ helo=<[^>]+>$/o )) { + $from = "<>" if ($from =~ /^$/); + #TD NOQUEUE: filter: RCPT from example.com[10.0.0.1]: <>: Sender address triggers FILTER filter:somefilter; from=<> to=<[email protected]> proto=SMTP helo=<example.com> + #TD NOQUEUE: filter: RCPT from example.com[192.168.0.1]: <[email protected]>: Recipient address triggers FILTER smtp-amavis:[127.0.0.1]:10024; from=<[email protected]> to=<[email protected]> proto=SMTP helo=<sample.net> + $Totals{'Filtered' --- /root/logwatch/scripts/services/vsftpd 2008-07-15 16:57:32.000000000 +0200 +++ vsftpd 2008-09-14 12:21:00.000000000 +0200 @@ -83,7 +83,7 @@ } } -if ( (keys %AnonLogins) and ($Detail >= 5) ) { +if (keys %AnonLogins) { print "\nAnonymous FTP Logins:\n"; foreach $ThisOne (keys %AnonLogins) { print $ThisOne . $AnonLogins{$ThisOne} . " Time(s)\n"; @@ -111,11 +111,11 @@ if ( ( $#UploadedFiles >= 0 ) or ( $#FailedUploadedFiles >= 0 ) ) { - if ( $#UploadedFiles >= 0) { + if ( ( $#UploadedFiles >= 0) && ( $Detail >= 5) ) { print "\nIncoming FTP Files:\n"; print @UploadedFiles; } - if ( $#FailedUploadedFiles >= 0) { + if ( ( $#FailedUploadedFiles >= 0) && ( $Detail >= 5) ) { print "\nFailed Uploads\n"; print @FailedUploadedFiles; } @@ -124,11 +124,11 @@ if ( ( $#DownloadedFiles >= 0 ) or ( $#FailedDownloadedFiles >=0 ) ) { - if ( $#DownloadedFiles >= 0) { + if ( ( $#DownloadedFiles >= 0) && ( $Detail >= 5) ) { print "\nOutgoing FTP Files:\n"; print @DownloadedFiles; } - if ( $#FailedDownloadedFiles >= 0) { + if ( ( $#FailedDownloadedFiles >= 0) && ( $Detail >= 5) ) { print "\nFailed Downloads\n"; print @FailedDownloadedFiles; } --- /root/logwatch/scripts/services/amavis 2008-06-17 23:46:40.000000000 +0200 +++ amavis 2008-09-14 12:11:28.000000000 +0200 @@ -74,6 +74,12 @@ or ($ThisLine =~ /^Checking/) or ($ThisLine =~ /^(ESMTP|FWD|SEND) via/) or ($ThisLine =~ /^spam_scan/) + or ($ThisLine =~ /^virus_scan/) + or ($ThisLine =~ /^run_av/) + or ($ThisLine =~ /^check_header/) + or ($ThisLine =~ /^p.path/) + or ($ThisLine =~ /sender addr ignored/) + or ($ThisLine =~ /^smtp session rundown/) or ($ThisLine =~ /^Not-Delivered/) or ($ThisLine =~ /^SpamControl/) or ($ThisLine =~ /^SPAM-TAG/) @@ -94,6 +100,7 @@ or ($ThisLine =~ /^local delivery: /) or ($ThisLine =~ /^cached [a-zA-Z0-9]+ /) or ($ThisLine =~ /^loaded policy bank/) + or ($ThisLine =~ /smtp connection cache/) or ($ThisLine =~ /^wbl: soft-whitelisted/) or ($ThisLine =~ /^p\d+ \d+(\/\d+)* Content-Type: /) or ($ThisLine =~ /^Requesting (a |)process rundown after [0-9]+ tasks/) _______________________________________________ Logwatch-Devel mailing list [email protected] http://www2.list.logwatch.org:81/mailman/listinfo/logwatch-devel
dovecot.diff
(text/plain, 1.8 KB)
--- /root/logwatch/scripts/services/dovecot 2008-08-11 17:38:02.000000000 +0200
+++ dovecot 2008-09-14 11:57:57.000000000 +0200
@@ -130,7 +130,7 @@
$Disconnected{$Reason}++;
} elsif (($Reason, $Host) = ($ThisLine =~ /TLS initialization failed/) ) {
$TLSInitFail++;
- } elsif (($Host) = ($ThisLine =~ /Aborted login \[(.*)\]/) ) {
+ } elsif (($Host) = ($ThisLine =~ /^dovecot: imap-login: Aborted login/) ) {
$Aborted{$Host}++;
# This is for Dovecot 1.0 series
@@ -143,6 +143,8 @@
$Disconnected{"no reason"}++;
} elsif (($Reason) = ($ThisLine =~ /pop3-login: Disconnected: (.+)/) ) {
$Disconnected{"no reason"}++;
+ } elsif (($Reason) = ($ThisLine =~ /imap-login: Disconnected (.+)/) ) {
+ $Disconnected{"no reason"}++;
} elsif (($Reason) = ($ThisLine =~ /imap-login: Disconnected: (.+)/) ) {
$Disconnected{"no reason"}++;
} elsif (($Reason) = ($ThisLine =~ /IMAP.+: Disconnected: (.+)/) ) {
@@ -165,7 +167,7 @@
print "\nDovecot was killed, and not restarted afterwards.\n";
}
-if ( ( $Detail >=5 ) and $Restarts ) {
+if ( ( $Detail >=0 ) and $Restarts ) {
print "\nDovecot restarted $Restarts time(s).";
}
@@ -215,7 +217,7 @@
" |" . " " x $totalSpaceLength . $TotalCount . "\n";
}
-if ( ( $Detail >= 10 ) and (keys %Login)) {
+if ( ( $Detail >= 0 ) and (keys %Login)) {
print "\n\nDovecot IMAP and POP3 Successful Logins:";
$LoginCount = 0;
foreach my $User (keys %Login) {
@@ -245,7 +247,7 @@
print "\n\nTotal: $LoginCount successful logins";
}
-if (keys %Disconnected) {
+if ((keys %Disconnected) && ($Detail >= 10)) {
print "\n\nDovecot disconnects:";
foreach my $Reason (sort keys %Disconnected) {
print "\n $Reason: $Disconnected{$Reason} Time(s)";
emerge.diff
(text/plain, 417 B)
--- /root/logwatch/scripts/services/emerge 2008-07-01 01:07:51.000000000 +0200
+++ emerge 2008-09-14 12:13:28.000000000 +0200
@@ -49,6 +49,7 @@
($ThisLine =~ /Compiling/) or
($ThisLine =~ /=== sync/) or
($ThisLine =~ /Starting rsync with/i) or
+ ($ThisLine =~ /Starting retry/) or
($ThisLine =~ /Merging/) or
($ThisLine =~ /Unmerging./) or
($ThisLine =~ /AUTOCLEAN/) or
postfix.diff
(text/plain, 154.8 KB) - not displayed
vsftpd.diff
(text/plain, 1.2 KB)
--- /root/logwatch/scripts/services/vsftpd 2008-07-15 16:57:32.000000000 +0200
+++ vsftpd 2008-09-14 12:21:00.000000000 +0200
@@ -83,7 +83,7 @@
}
}
-if ( (keys %AnonLogins) and ($Detail >= 5) ) {
+if (keys %AnonLogins) {
print "\nAnonymous FTP Logins:\n";
foreach $ThisOne (keys %AnonLogins) {
print $ThisOne . $AnonLogins{$ThisOne} . " Time(s)\n";
@@ -111,11 +111,11 @@
if ( ( $#UploadedFiles >= 0 ) or
( $#FailedUploadedFiles >= 0 ) ) {
- if ( $#UploadedFiles >= 0) {
+ if ( ( $#UploadedFiles >= 0) && ( $Detail >= 5) ) {
print "\nIncoming FTP Files:\n";
print @UploadedFiles;
}
- if ( $#FailedUploadedFiles >= 0) {
+ if ( ( $#FailedUploadedFiles >= 0) && ( $Detail >= 5) ) {
print "\nFailed Uploads\n";
print @FailedUploadedFiles;
}
@@ -124,11 +124,11 @@
if ( ( $#DownloadedFiles >= 0 ) or
( $#FailedDownloadedFiles >=0 ) ) {
- if ( $#DownloadedFiles >= 0) {
+ if ( ( $#DownloadedFiles >= 0) && ( $Detail >= 5) ) {
print "\nOutgoing FTP Files:\n";
print @DownloadedFiles;
}
- if ( $#FailedDownloadedFiles >= 0) {
+ if ( ( $#FailedDownloadedFiles >= 0) && ( $Detail >= 5) ) {
print "\nFailed Downloads\n";
print @FailedDownloadedFiles;
}
amavis.diff
(text/plain, 1 KB)
--- /root/logwatch/scripts/services/amavis 2008-06-17 23:46:40.000000000 +0200
+++ amavis 2008-09-14 12:11:28.000000000 +0200
@@ -74,6 +74,12 @@
or ($ThisLine =~ /^Checking/)
or ($ThisLine =~ /^(ESMTP|FWD|SEND) via/)
or ($ThisLine =~ /^spam_scan/)
+ or ($ThisLine =~ /^virus_scan/)
+ or ($ThisLine =~ /^run_av/)
+ or ($ThisLine =~ /^check_header/)
+ or ($ThisLine =~ /^p.path/)
+ or ($ThisLine =~ /sender addr ignored/)
+ or ($ThisLine =~ /^smtp session rundown/)
or ($ThisLine =~ /^Not-Delivered/)
or ($ThisLine =~ /^SpamControl/)
or ($ThisLine =~ /^SPAM-TAG/)
@@ -94,6 +100,7 @@
or ($ThisLine =~ /^local delivery: /)
or ($ThisLine =~ /^cached [a-zA-Z0-9]+ /)
or ($ThisLine =~ /^loaded policy bank/)
+ or ($ThisLine =~ /smtp connection cache/)
or ($ThisLine =~ /^wbl: soft-whitelisted/)
or ($ThisLine =~ /^p\d+ \d+(\/\d+)* Content-Type: /)
or ($ThisLine =~ /^Requesting (a |)process rundown after [0-9]+ tasks/)