Mercurial > repos > other > Puppet
changeset 345:bad68f1b6467
Add updated Dovecot script to Logwatch
This now handles "logged out" lines
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Mon, 20 Jul 2020 09:56:09 +0100 |
parents | 3a104df81e44 |
children | 61be075c5a68 |
files | common/logwatch/dovecot manifests/templates.pp |
diffstat | 2 files changed, 698 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/logwatch/dovecot Mon Jul 20 09:56:09 2020 +0100 @@ -0,0 +1,693 @@ +######################################################## +# $Id$ +######################################################## +# $Log: dovecot,v $ +# Revision 1.18 2010/09/18 17:41:00 stefan +# ignore: ssl-build-param +# +# Revision 1.17 2009/06/02 14:48:06 mike +# Removed some periods that were in the Fedora patch and broke the file -mgt +# +# Revision 1.16 2009/06/02 14:45:48 mike +# Patch from Fedora (Ivana Hutarova Varekova) -mgt +# +# Revision 1.15 2008/11/18 06:02:49 mike +# Rolled back..that was wrong. -mgt +# +# Revision 1.14 2008/11/18 06:00:34 mike +# Removed a space should be better -mgt +# +# Revision 1.13 2008/11/18 04:32:49 mike +# Added bytes detected to IMAP disconnect match expect more issues -mgt +# +# Revision 1.12 2008/08/11 15:38:02 mike +# Connection closed patch from Niels Baggesen -mgt +# +# Revision 1.11 2008/06/30 23:07:51 kirk +# fixed copyright holders for files where I know who they should be +# +# Revision 1.10 2008/03/24 23:31:26 kirk +# added copyright/license notice to each script +# +# Revision 1.9 2008/02/14 18:19:51 mike +# Patch from Gilles Detillieux summarize pop3/imap -mgt +# +# Revision 1.8 2008/01/16 20:11:04 bjorn +# Filtering dovecot start-up message, by Gilles Detillieux. +# +# Revision 1.7 2007/06/18 03:54:45 bjorn +# Better printing of IPv6 addresses, by Patrick Vande Walle. +# +# Revision 1.6 2007/03/17 19:13:13 bjorn +# Now handling dovecot starts/kills. +# +# Revision 1.5 2006/12/20 15:25:09 bjorn +# Additional filtering, by Ivana Varekova. +# +# Revision 1.4 2006/08/13 22:02:31 bjorn +# IPv4 addresses displayed in native format, and don't display user totals +# if user connects from only one IP address; changes by Patrick Vande Walle. +# +# Revision 1.3 2006/08/13 21:06:33 bjorn +# Added support for Dovecot 1.0 based on patches from Mark Nienberg, and +# IP addresses displayed without brackets for consistency across versions; +# modifications by Patrick Vande Walle. +# +# Revision 1.2 2005/12/07 04:31:44 bjorn +# Added $dovecot_ignore_host. +# +# Revision 1.1 2005/09/18 17:01:05 bjorn +# Dovecot filters written by Patrick Vande Walle. +# +######################################################## +# Please send all comments, suggestions, bug reports, +# etc, to logwatch-devel@lists.sourceforge.net +######################################################## +# The Dovecot script was written by: +# Patrick Vande Walle <patrick@isoc.lu> +# Based on previous work by +# Pawel Golaszewski <blues@gda.pl> +# +# TODO: +# - use printf features to align text in table +# +######################################################## + +######################################################## +## Copyright (c) 2008 Patrick Vande Walle +## 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 logwatch-devel@lists.sourceforge.net. +######################################################### + +use strict; + +my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; +my $Detail = $ENV{'dovecot_detail'} || $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; +my $IgnoreHost = $ENV{'dovecot_ignore_host'} || ""; + +my $Restarts = 0; +my $End = 0; +my $TLSInitFail = 0; +my %Aborted; +my %AuthDisconnectedWithPending; +my %AuthTimedOut; +my %AuthUsernameChars; +my %ChildErr; +my %Connection; +my %ConnectionClosed; +my %ConnectionIMAP; +my %ConnectionPOP3; +my %ConnectionSieve; +my %Disconnected; +my %DiskQuotaExceed; +my %Deliver; +my %DeliverUserCount; +my %Error; +my %Fatal; +my %Forwarded; +my %LimitExceeded; +my %Login; +my %LoginIMAP; +my %LoginPOP3; +my %MUAList; +my %OtherList; +my %ProxyConnection; +my %ProxyConnectionIMAP; +my %ProxyConnectionPOP3; +my %ProxyDisconnected; +my %ProxyLogin; +my %ProxyLoginIMAP; +my %ProxyLoginPOP3; +my %SieveLogin; +my %VacationDup; +my %VacationResponse; + +if ( $Debug >= 5 ) { + print STDERR "\n\nDEBUG \n\n"; +} + +use Socket; +my %rdns; +sub hostName { + (my $ipaddr) = @_; + + if ($ENV{'LOGWATCH_NUMERIC'} || $ENV{'dovecot_numeric'}) { + return $ipaddr; + } + + if (exists $rdns{ $ipaddr }) { + return $rdns{ $ipaddr }; + } + $rdns{ $ipaddr } = $ipaddr; + + my $iaddr = inet_aton($ipaddr); + if (defined $iaddr) { + my $host = gethostbyaddr($iaddr, AF_INET); + if (defined $host) { + my $iaddrcheck = gethostbyname($host); + if (defined $iaddrcheck) { + if ($iaddr eq $iaddrcheck) { + $rdns{ $ipaddr } = $host; + } + } + } + } + return $rdns{ $ipaddr }; +} + +# Handle "dovecot: <svc>" and "dovecot: [ID yyyyy mail.info] <svc" +my $dovecottag = qr/dovecot(?:\[\d+\])?:(?:\s*\[[^]]+\])?/; + +while (defined(my $ThisLine = <STDIN>)) { + # remove timestamp. We can't use *RemoveHeaders because we need the + # service name + #$ThisLine =~ s/^\w{3} .\d \d\d:\d\d:\d\d (?:[^\s:]* |)//; + if ( ($ThisLine =~ /(?:ssl-build-param|ssl-params): SSL parameters regeneration completed/) or + ($ThisLine =~ /ssl-params: Generating SSL parameters/) or + ($ThisLine =~ /auth-worker/) or + ($ThisLine =~ /auth:.*: Connected to/) or + ($ThisLine =~ /Connection closed/) or + ($ThisLine =~ /IMAP.*: Connection closed bytes/) or + ($ThisLine =~ /IMAP.* failed with mbox file/) or + ($ThisLine =~ /discarded duplicate forward to/) or + ($ThisLine =~ /discarding vacation response/) or + ($ThisLine =~ /discarded vacation reply to/) or + ($ThisLine =~ /Debug:/) or + 0 # This line prevents blame shifting as lines are added above + ) + { + # We don't care about these + } elsif ( $ThisLine =~ /Killed with signal /) { + $End++; + } elsif ( $ThisLine =~ /Dovecot (v\d[^ ]* |)(\([0-9a-fA-F]+\) )?starting up/) { + $Restarts++; + $End = 0; + } elsif ( (my ($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?pop3-login: Login: (.*?) \[(.*)\]/ ) ) or + (my ($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?pop3-login: (?:Info: )?Login: user=\<(.*?)\>.*rip=(.*), lip=/ ) ) ) { + if ($Host !~ /$IgnoreHost/) { + $Host = hostName($Host); + $Login{$User}{$Host}++; + $LoginPOP3{$User}++; + $ConnectionPOP3{$Host}++; + $Connection{$Host}++; + } + } elsif ( (my ($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?imap-login: Login: (.*?) \[(.*)\]/ ) ) or + (my ($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?imap-login: (?:Info: )?Login: user=\<(.*?)\>.*rip=(.*), lip=/ ) ) ) { + if ($Host !~ /$IgnoreHost/) { + $Host = hostName($Host); + $Login{$User}{$Host}++; + $LoginIMAP{$User}++; + $ConnectionIMAP{$Host}++; + $Connection{$Host}++; + } + } elsif (my ($User, $Host) = ( $ThisLine =~ /managesieve-login: Login: user=\<(.*?)\>.*rip=(.*), lip=/ ) ) { + if ($Host !~ /$IgnoreHost/) { + $Host = hostName($Host); + $SieveLogin{$User}{$Host}++; + $ConnectionSieve{$Host}++; + $Connection{$Host}++; + } + +# 'lda' for dovecot 2.0, 'deliver' for earlier versions + } elsif (my ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag (?:lda|deliver)\((.*)\): msgid=.*: saved mail to (.*)/ ) ) { + $Deliver{$User}{$Mailbox}++; + } elsif ( ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag service=lda, user=(.*), .* msgid=.*: saved mail to (.*)/ ) ) { + $Deliver{$User}{$Mailbox}++; +# For Sieve-based delivery + } elsif (my ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag (?:lda|deliver)\((.*)\): sieve: msgid=.*: stored mail into mailbox '(.*)'/ ) ) { + $Deliver{$User}{$Mailbox}++; + +# LMTP-based delivery + } elsif (my ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag lmtp\((?:\d+, )?(.*?)\): .*msgid=.*: saved mail to (.*)/ ) ) { + # dovecot: [ID 583609 mail.info] lmtp(12782, cloyce@headgear.org): jBt1EfjCMk3uMQAAm9eMBA: msgid=<4D32DB1F.3080707@c-dot.co.uk>: saved mail to INBOX + $Deliver{$User}{$Mailbox}++; + +# LMTP-based Sieve delivery + } elsif (my ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag lmtp\((?:\d+, )?(.*?)\): .*: sieve: msgid=.*: stored mail into mailbox '(.*)'/ ) ) { + $Deliver{$User}{$Mailbox}++; + +# sieve forward + } elsif (my ($User, $Recip) = ($ThisLine =~ /^$dovecottag (?:lda|deliver|lmtp)\((?:\d+, )?(.*?)\):(?: [^:]+:)? sieve: msgid=.* forwarded to \<(.*)\>/)) { + $Forwarded{$User}{$Recip}++; + +# sieve vacation + } elsif (my ($User, $Recip) = ($ThisLine =~ /^$dovecottag (?:lda|deliver|lmtp)\((?:\d+, )?(.*)\):(?: .*:)? sieve: msgid=.* sent vacation response to \<(.*)\>/)) { + $VacationResponse{$User}{$Recip}++; + + } elsif (my ($User, $Recip) = ($ThisLine =~ /^$dovecottag (?:lda|deliver|lmtp)\((?:\d+, )?(.*)\):(?: .*:)? sieve: msgid=.* discarded duplicate vacation response to \<(.*)\>/ )) { + $VacationDup{$User}{$Recip}++; + + } elsif ( $ThisLine =~ /^$dovecottag (?:lda|deliver|lmtp)\(.*\): .*sieve: msgid=.* marked message to be discarded if not explicitly delivered/ ) { + # dovecot: lda(joe): sieve: msgid=<m$01$@com>: marked message to be discarded if not explicitly delivered (discard action) + # IGNORE + } elsif ( $ThisLine =~ /^$dovecottag lmtp\(.*\): Connect from/ ) { + # dovecot: [ID 583609 mail.info] lmtp(12782): Connect from local: 1 Time(s) + # IGNORE + + } elsif ( $ThisLine =~ /^$dovecottag lmtp\(.*\): Disconnect from/ ) { + # dovecot: [ID 583609 mail.info] lmtp(12782): Disconnect from local: Client quit: 1 Time(s) + # IGNORE + + # Dovecot 2.0 proxy + } elsif (my ($User, $Host) = ( $ThisLine =~ /^$dovecottag pop3-login: proxy\((.*)\): started proxying to .*: user=<.*>, method=.*, rip=(.*), lip=/ ) ) { + if ($Host !~ /$IgnoreHost/) { + $ProxyLogin{$User}{$Host}++; + $ProxyLoginPOP3{$User}++; + $ProxyConnectionPOP3{$Host}++; + $ProxyConnection{$Host}++; + } + } elsif (my ($User, $Host) = ( $ThisLine =~ /^$dovecottag imap-login: proxy\((.*)\): started proxying to .*: user=<.*>, method=.*, rip=(.*), lip=/ ) ) { + if ($Host !~ /$IgnoreHost/) { + $ProxyLogin{$User}{$Host}++; + $ProxyLoginIMAP{$User}++; + $ProxyConnectionIMAP{$Host}++; + $ProxyConnection{$Host}++; + } + } elsif (my ($Reason) = ( $ThisLine =~ /proxy\(.*\): disconnecting .* \(Disconnected (.*)\)/ ) ) { + $ProxyDisconnected{$Reason}++; + + } elsif ($ThisLine =~ /Disconnected (\[|bytes|top)/) { + $Disconnected{"No reason"}++; + } elsif (my ($Reason) = ($ThisLine =~ /Disconnected: (.*) \[/) ) { + $Disconnected{$Reason}++; + } elsif (my ($Reason) = ($ThisLine =~ /Disconnected: (.*) (bytes|top|in)=.*/) ) { + $Disconnected{$Reason}++; + } elsif ($ThisLine =~ /Logged out (rcvd|bytes|top|in)=.*/) { + $Disconnected{"Logged out"}++; + } elsif (my ($Reason) = ($ThisLine =~ /Disconnected \((.*)\):/) ) { + $Reason =~ s/ in \d+ secs//; + $Disconnected{$Reason}++; + } elsif ($ThisLine =~ /Server shutting down./) { + $ConnectionClosed{"Server shutting down"}++; + } elsif (my ($Reason, $Host) = ($ThisLine =~ /TLS initialization failed/) ) { + $TLSInitFail++; + } elsif (my ($Host) = ($ThisLine =~ /Aborted login:.* rip=(.*),/) ) { + $Host = hostName($Host); + $Aborted{$Host}++; + } elsif (my ($Host) = ($ThisLine =~ /Aborted login \[(.*)\]/) ) { + $Host = hostName($Host); + $Aborted{$Host}++; + } elsif (my ($Reason) = ($ThisLine =~ /Aborted login \((.*)\):/)) { + $Aborted{$Reason}++; + } elsif (my ($User,$IP) = ($ThisLine =~ /auth: (?:LOGIN|login)\((.*),(\d+\.\d+\.\d+\.\d+)\): Request timed out waiting for client to continue authentication/) ) { + $AuthTimedOut{$User}{$IP}++; + } elsif (my ($Reason) = ($ThisLine =~ /auth: Warning: auth client \d+ disconnected with \d+ pending requests: (.*)/) ) { + $AuthDisconnectedWithPending{$Reason}++; + } elsif (my ($IP) = ($ThisLine =~ /auth: login\(.*,(\d+\.\d+\.\d+\.\d+)\): Username character disallowed by auth_username_chars: .* \(username: .*\)/) ) { + $AuthUsernameChars{$IP}++; + } elsif (my ($user, $rip, $lip) = ($ThisLine =~ /Maximum number of connections.* exceeded.* user=<([^>]+)>.*rip=([^,]+), lip=([^,]+)/)) { + # dovecot: [ID 583609 mail.info] imap-login: Maximum number of connections from user+IP exceeded (mail_max_userip_connections=10): user=<cloyce@headgear.org>, method=CRAM-MD5, rip=102.225.17.52, lip=14.105.322.67, TLS + $LimitExceeded{"max_userip_connections: $user from $rip to $lip"}++; + +# This is for Dovecot 1.0 series +# Overly general matches in this section -mgt + } elsif ($ThisLine =~ /Disconnected for inactivity/) { + $Disconnected{"Inactivity"}++; + } elsif ($ThisLine =~ /Disconnected in IDLE/) { + $Disconnected{"in IDLE"}++; + } elsif ($ThisLine =~ /Disconnected in APPEND/) { + $Disconnected{"in APPEND"}++; + } elsif (($ThisLine =~ /Disconnected$/) or + ($ThisLine =~ /(IMAP|POP3)\(.+\): Disconnected (bytes|top|rip|user|method)=/) or + ($ThisLine =~ /(imap\-login|pop3\-login): Disconnected: (bytes|top|rip|user|method)=/) ) { + $Disconnected{"No reason"}++; + } elsif ( (my ($Reason) = ($ThisLine =~ /(?:IMAP|POP3).+: Disconnected: (.+) (bytes|top)=/i)) or + (my ($Reason) = ($ThisLine =~ /(?:imap\-login|pop3\-login): Disconnected: \(?(.+)\)?: /)) or + #This one should go away also -mgt + (my ($Reason) = ($ThisLine =~ /IMAP.+: Disconnected: (.+)/i)) ) { + $Disconnected{$Reason}++; + } elsif ($ThisLine =~ /(IMAP|POP3).+: Connection closed (top|bytes)=/i) { + $ConnectionClosed{"No reason"}++; + } elsif (my ($Reason) = ($ThisLine =~ /(?:IMAP|POP3).+: Connection closed: (.*) (?:bytes|method|top|rip|user)=/i) ) { + $ConnectionClosed{$Reason}++; + } elsif ($ThisLine =~ /(IMAP|POP3).+: (Connection closed.*)/) { + $Disconnected{$2}++; + } elsif (my ($Host) = ($ThisLine =~ /(?:imap\-login|pop3\-login): Aborted login: .*rip=(?:::ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) ) { + $Aborted{$Host}++; + } elsif (my ($Error) = ($ThisLine =~ /child \d* (?:\(login\) )?returned error (.*)/)) { + # dovecot: child 23747 (login) returned error 89 + # dovecot: log: Error: service(auth): child 19654 returned error 89 (Fatal failure) + $ChildErr{$Error}++; + } elsif (my ($Name) = ($ThisLine =~ /$dovecottag IMAP\((.*)\): .*(.*) failed: Disk quota exceeded/i)) { + # dovecot: IMAP(podracka): mkdir(/home/LF/KLINIKY/podracka/mail/.imap/saved-messages) failed: Disk quota exceeded + $DiskQuotaExceed{$Name}++; + # This is with imap_id_log = * enabled + } elsif (my ($User,$MUA) = ($ThisLine =~ /imap\((.*)\): ID sent: name=(.*)/)) { + $MUAList{$MUA}{$User}++; + # These are failed connections with imap_id_log = * enabled + } elsif ($ThisLine =~ /imap-login: ID sent: (?:name|vendor)=/) { + # Ignore + } elsif (my ($Fatal) = ($ThisLine =~ /^(?:$dovecottag )?(.* Fatal:.*)/)) { + $Fatal{$Fatal}++; + } elsif (my ($Error) = ($ThisLine =~ /^(?:$dovecottag )?(.* Error:.*)/)) { + $Error{$Error}++; + } else { + # Report any unmatched entries... + chomp($ThisLine); + $OtherList{$ThisLine}++; + } +} + +################################################ + +if ( $End ) { + print "\nDovecot was killed, and not restarted afterwards.\n"; +} + +if ( keys %Fatal ) { + print "\nDovecot Fatal Errors:\n"; + foreach my $Fatal (sort keys %Fatal) { + print " ${Fatal}: $Fatal{$Fatal} Time(s)\n"; + } +} + +if ( keys %Error ) { + print "\nDovecot Errors:\n"; + foreach my $Error (sort keys %Error) { + print " ${Error}: $Error{$Error} Time(s)\n"; + } +} + +if ( ( $Detail >=5 ) and $Restarts ) { + print "\nDovecot restarted $Restarts time(s).\n"; +} + +if ( ( $Detail >= 5 ) and (keys %Connection)) { + print "\n[Dovecot IMAP and POP3] Connections:". + "\n====================================". + "\nPOP3 IMAP Total Host". + "\n" . "-" x 72; + + $TLSInitFail = 0; + my $IMAPCount = 0; + my $POP3Count = 0; + my $TotalCount = 0; + foreach my $Host (sort { $Connection{$b} <=> $Connection{$a} } + keys %Connection) { + my $Total = $Connection{$Host}; + my $Conns = 0; + my $IMAP = 0; + if (defined ($ConnectionPOP3{$Host})) { + $Conns = $ConnectionPOP3{$Host}; + } + if (defined ($ConnectionIMAP{$Host})) { + $IMAP = $ConnectionIMAP{$Host}; + } +# Cleanly display IPv4 addresses + $Host=~ s/::ffff://; + printf "\n%4s %4s %5s %s", $Conns, $IMAP, $Total, $Host; + $POP3Count += $Conns; + $IMAPCount += $IMAP; + $TotalCount += $Total; + } + print "\n" . "-" x 72; + printf "\n%4s %4s %5s %s", $POP3Count, $IMAPCount, $TotalCount, "Total"; +} + +if (keys %Deliver) { + my $DeliverCount = 0; + my $DeliverUserCount; + foreach my $User (keys %Deliver) { + foreach my $Mailbox (keys %{$Deliver{$User}}) { + $DeliverUserCount{$User} += $Deliver{$User}{$Mailbox}; + } + $DeliverCount += $DeliverUserCount{$User}; + } + printf "\n" if ($Detail >= 5); + printf "\nDovecot Deliveries: %s", $DeliverCount; + if ($Detail >= 5) { + foreach my $User (sort { $DeliverUserCount{$b} <=> $DeliverUserCount{$a} } + keys %DeliverUserCount) { + printf "\n %4s %s", $DeliverUserCount{$User}, $User; + if ($Detail >= 10) { + foreach my $Mailbox (sort { + $Deliver{$User}{$b} <=> $Deliver{$User}{$a} + } keys %{$Deliver{$User}}) { + printf "\n %4s %s", $Deliver{$User}{$Mailbox}, $Mailbox; + } + } + } + } +} + +if (($Detail >= 10) and (keys %Forwarded)) { + my $TotalForwarded = 0; + + print "\n\nDovecot LDA sieve forwards:"; + foreach my $User (sort keys %Forwarded) { + print "\n\n User $User"; + foreach my $Recip (sort keys %{$Forwarded{$User}}) { + print "\n To $Recip: $Forwarded{$User}{$Recip} time(s)"; + $TotalForwarded += $Forwarded{$User}{$Recip}; + } + } + print "\n\n Total: $TotalForwarded Time(s)"; +} + +if (($Detail >= 10) and (keys %VacationResponse)) { + my $TotalVacResp = 0; + print "\n\nDovecot LDA sieve vacation responses:"; + foreach my $User (sort keys %VacationResponse) { + print "\n\n User $User"; + foreach my $Recip (sort keys %{$VacationResponse{$User}}) { + print "\n To $Recip: $VacationResponse{$User}{$Recip} time(s)"; + $TotalVacResp += $VacationResponse{$User}{$Recip}; + } + } + print "\n\n Total: $TotalVacResp Time(s)"; +} + +if (($Detail >= 10) and (keys %VacationDup)) { + my $TotalVacDup = 0; + print "\n\nDovecot LDA sieve duplicate vacation responses not sent:"; + foreach my $User (sort keys %VacationDup) { + print "\n User $User"; + foreach my $Recip (sort keys %{$VacationDup{$User}}) { + print "\n To $Recip: $VacationDup{$User}{$Recip} time(s)"; + $TotalVacDup += $VacationDup{$User}{$Recip}; + } + } + print "\n\n Total: $TotalVacDup Time(s)"; +} + +if (keys %Login) { + my $LoginCount = 0; + my %LoginUserCount; + foreach my $User (keys %Login) { + foreach my $Host (keys %{$Login{$User}}) { + $LoginUserCount{$User} += $Login{$User}{$Host}; + } + $LoginCount += $LoginUserCount{$User}; + $LoginPOP3{$User} = 0 if $LoginPOP3{$User} <= 0; + $LoginIMAP{$User} = 0 if $LoginIMAP{$User} <= 0; + } + printf "\n" if ($Detail >= 5); + printf "\nDovecot IMAP and POP3 Successful Logins: %s", $LoginCount; + if ($Detail >= 5) { + foreach my $User (sort { $LoginUserCount{$b} <=> $LoginUserCount{$a} } + keys %LoginUserCount) { + printf("\n %4s %s", $LoginUserCount{$User}, $User); + if ($Detail >= 10) { + print " ("; + if ($LoginPOP3{$User} > 0) { print "$LoginPOP3{$User} POP3"; }; + if ($LoginPOP3{$User} > 0 && $LoginIMAP{$User} > 0) { print ", "; }; + if ($LoginIMAP{$User} > 0) { print "$LoginIMAP{$User} IMAP"; }; + print ")"; + foreach my $Host (sort { $Login{$User}{$b} <=> $Login{$User}{$a} } + keys %{$Login{$User}}) { + # Cleanly display IPv4 addresses + $Host=~ s/::ffff://; + printf "\n %4s %s", $Login{$User}{$Host}, $Host; + } + } + } + } +} + +if ( ( $Detail >= 10 ) and (keys %SieveLogin)) { + print "\n\nDovecot ManageSieve Successful Logins:"; + my $LoginCount = 0; + foreach my $User (sort keys %SieveLogin) { + print "\n\n User $User:"; + my $UserCount = 0; + my $NumHosts = 0; + foreach my $Host (sort keys %{$SieveLogin{$User}}) { + $NumHosts++; + my $HostCount = $SieveLogin{$User}{$Host}; +# Cleanly display IPv4 addresses + $Host=~ s/::ffff://; + print "\n From $Host: $HostCount Time(s)"; + $UserCount += $HostCount; + } + $LoginCount += $UserCount; + if ($NumHosts > 1) { + print "\n Total: $UserCount Time(s)"; + } + } + print "\n\nTotal: $LoginCount successful ManageSieve logins"; +} + +if (keys %LimitExceeded) { + print "\n\nDovecot limits exceeded:"; + foreach my $Reason (sort keys %LimitExceeded) { + print "\n $Reason: $LimitExceeded{$Reason} Time(s)"; + } +} + +if ( ( $Detail >= 10 ) and (keys %AuthDisconnectedWithPending)) { + print "\n\nAuth client disconnected with pending requests:"; + foreach my $Reason (sort keys %AuthDisconnectedWithPending) { + print "\n $Reason: $AuthDisconnectedWithPending{$Reason} Time(s)"; + } +} + +if ( ( $Detail >= 10 ) and (keys %AuthTimedOut)) { + print "\n\nRequest timed out waiting for client to continue authentication:"; + foreach my $User (sort(keys %AuthTimedOut)) { + print "\n User: $User (IPs: "; + print join(", ",sort(keys %{$AuthTimedOut{$User}})); + my $Total = 0; + foreach my $IP (keys %{$AuthTimedOut{$User}}) { + $Total += $AuthTimedOut{$User}{$IP}; + } + print ") $Total Time(s)"; + } +} + +if ( ( $Detail >= 10 ) and (keys %AuthUsernameChars)) { + print "\n\nUsername character disallowed by auth_username_chars:"; + foreach my $IP (sort keys %AuthUsernameChars) { + print "\n $IP: $AuthUsernameChars{$IP} Time(s)"; + } +} + +if (keys %Disconnected) { + my $Disconnects = 0; + foreach my $Reason (%Disconnected) { + $Disconnects += $Disconnected{$Reason}; + } + printf "\n\nDovecot disconnects: %s Total", $Disconnects; + if ($Detail >= 5) { + foreach my $Reason (sort { $Disconnected{$b} <=> $Disconnected{$a} } + keys %Disconnected) { + printf "\n %4s %s", $Disconnected{$Reason}, $Reason; + } + } +} + +if (keys %ConnectionClosed) { + print "\n\nDovecot connections closed:"; + foreach my $Reason (sort keys %ConnectionClosed) { + print "\n $Reason: $ConnectionClosed{$Reason} Time(s)"; + } +} + +if (keys %ChildErr) { + print "\n\nDovecot child error:"; + foreach my $Error (sort keys %ChildErr) { + print "\n error number ". $Error . ": ". $ChildErr{$Error} ." Time(s)"; + } +} + +if ((keys %Aborted) && ($Detail >= 10)) { + print "\n\nLogout/aborts:"; + foreach my $Host (sort keys %Aborted) { + print "\n $Host: $Aborted{$Host} Time(s)"; + } +} + +if ($TLSInitFail > 0) { + print "\n\nTLS Initialization failed $TLSInitFail Time(s)"; +} + +if (keys %DiskQuotaExceed) { + print "\n\nDisk quota exceeded:"; + foreach my $Name (sort keys %DiskQuotaExceed) { + print "\n disk quota for user '". $Name . "' exceeded: ". $DiskQuotaExceed{$Name} ." Time(s)"; + } +} + +# This has to be explicitly enabled in dovecot config to log this, +# so we'll assume people want it if enabled +if (keys %MUAList) { + print "\n\nIMAP Mail User Agent Strings:"; + foreach my $MUA (sort(keys %MUAList)) { + print "\n $MUA: (Users: "; + print join(", ",sort(keys %{$MUAList{$MUA}})); + my $Total = 0; + foreach my $User (keys %{$MUAList{$MUA}}) { + $Total += $MUAList{$MUA}{$User}; + } + print ") $Total Time(s)"; + } +} + +if ( ( $Detail >= 5 ) and (keys %ProxyLogin)) { + print "\n\nDovecot Proxy IMAP and POP3 Successful Logins:"; + my $LoginCount = 0; + foreach my $User (sort keys %ProxyLogin) { + print "\n User $User:"; + if ( ($Detail >= 10) and ($ProxyLoginPOP3{$User} > 0 || $ProxyLoginIMAP{$User} > 0) ) { + print " ("; + if ($ProxyLoginPOP3{$User} > 0) { print "$ProxyLoginPOP3{$User} POP3"; }; + if ($ProxyLoginPOP3{$User} > 0 && $ProxyLoginIMAP{$User} > 0) { print ", "; }; + if ($ProxyLoginIMAP{$User} > 0) { print "$ProxyLoginIMAP{$User} IMAP"; }; + print ")"; + } + my $UserCount = 0; + my $NumHosts = 0; + foreach my $Host (sort keys %{$ProxyLogin{$User}}) { + $NumHosts++; + my $HostCount = $ProxyLogin{$User}{$Host}; +# Cleanly display IPv4 addresses + $Host=~ s/::ffff://; + print "\n From $Host: $HostCount Time(s)" if ($Detail >= 10); + $UserCount += $HostCount; + } + $LoginCount += $UserCount; + if ($Detail >= 10) { + if ($NumHosts > 1) { + print "\n Total: $UserCount Time(s)\n"; + } else { + print "\n"; + } + } elsif ($Detail >= 5) { + print " $UserCount Time(s)"; + } + } + print "\nTotal: $LoginCount successful logins"; +} + +if (keys %ProxyDisconnected) { + print "\n\nDovecot Proxy disconnects:\n"; + foreach my $Reason (sort keys %ProxyDisconnected) { + print " $Reason: $ProxyDisconnected{$Reason} Time(s)\n"; + } +} + +if (keys %OtherList) { + print "\n\n**Unmatched Entries**\n"; + foreach my $line (sort {$a cmp $b} keys %OtherList) { + print " $line: $OtherList{$line} Time(s)\n"; + } +} + +exit(0); + + +# vi: shiftwidth=3 tabstop=3 syntax=perl et +# Local Variables: +# mode: perl +# perl-indent-level: 3 +# indent-tabs-mode: nil +# End:
--- a/manifests/templates.pp Sun Jul 12 19:54:02 2020 +0100 +++ b/manifests/templates.pp Mon Jul 20 09:56:09 2020 +0100 @@ -302,6 +302,8 @@ '/etc/logwatch/conf/', '/etc/logwatch/conf/logfiles/', '/etc/logwatch/conf/services/', + '/etc/logwatch/scripts/', + '/etc/logwatch/scripts/services/', ] file { $logwatch_dirs: ensure => directory, @@ -324,6 +326,9 @@ file { '/etc/logwatch/conf/services/php.conf': source => 'puppet:///common/logwatch/services_php.conf', } + file { '/etc/logwatch/scripts/services/dovecot': + source => 'puppet:///common/logwatch/dovecot', + } } #Our web server with our configs, not just a stock one