The logwatch output regarding exim on Debian 13 contained a number of unsummarised entries:
Didn't Summarize: 2026-02-10 00:17:41 plain_server authenticator failed for host59.sub-63-47-149.myvzw.com [63.47.149.59]: 535 Incorrect authentication data (set_id=postmaster)
Didn't Summarize: 2026-02-10 00:22:26 SMTP command timeout on TLS connection from 111-70-32-126.emome-ip.hinet.net [111.70.32.126] D=5m5s
and some unmatched entries, for example:
2026-02-10 05:17:01 SMTP call from scan-62-0.shadowserver.org [64.62.156.38] dropped: too many unrecognized commands (last was "Accept: */*"): 1 Time(s)
The pattern matching and summarisation code is in the file
/usr/share/logwatch/scripts/services/exim. Rather than modify this
file directly, it can be overridden by a version in
/etc/logwatch/scripts/services/exim. I already had a copy of the
scripts/services/exim file in /etc/logwatch, modified to handle
high bad recipients counts.
Note that there are two places where exim log messages are recognised; the first collects the messages of interest from the exim log file, the second handles the reporting.
The unmatched entries issue was easy; the exim log message now used unrecognized in place of nonmail.
The authenticator failed message required changes to an existing regex, while the command timeout on TLS was a completely new message.
The complete diff is shown below:
--- /usr/share/logwatch/scripts/services/exim 2025-02-25 05:38:03.000000000 +0000
+++ exim 2026-02-11 15:54:36.863341010 +0000
@@ -167,6 +167,9 @@
elsif ( $ThisLine =~ /unqualified (sender|recipient) rejected/ ) {
$DontAccept{$ThisLine}++;
}
+ elsif ( $ThisLine =~ /bad recipient count high/ ) {
+ $DontAccept{$ThisLine}++;
+ }
elsif ( $ThisLine =~ /do not accept mail / ) {
$DontAccept{$ThisLine}++;
}
@@ -244,7 +247,7 @@
# Spammer who does not read protocol
$Proto{$ThisLine}++;
}
- elsif ( $ThisLine =~ /dropped: too many nonmail commands/ ) {
+ elsif ( $ThisLine =~ /dropped: too many unrecognized commands/ ) {
# Often someone who tries lots of transactions
$Proto{$ThisLine}++;
}
@@ -260,6 +263,9 @@
# Various TLS errrors
$Proto{$ThisLine}++;
}
+ elsif ( $ThisLine =~ /command timeout on TLS connection from/ ) {
+ $Proto{$ThisLine}++;
+ }
elsif ( $ThisLine =~ /authenticator failed for/ ) {
$Proto{$ThisLine}++;
}
@@ -521,6 +527,10 @@
$cc = "Unqualified Receipient";
$bb = "$1";
}
+ elsif ( $ThisOne =~ m/bad recipient count high/ ) {
+ $cc = "Blocked Host";
+ ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/);
+ }
elsif ( $ThisOne =~ m/not accept Windows executables/ ) {
$cc = "Blocked Attachment";
( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/);
@@ -655,8 +665,8 @@
$bb = "SMTP protocol synchronization error";
$SmtpConnection{$bb}++;
}
- elsif ( $ThisOne =~ /dropped: too many nonmail commands/ ) {
- $bb = "Connection dropped after too many nonmail SMTP commands";
+ elsif ( $ThisOne =~ /dropped: too many unrecognized commands/ ) {
+ $bb = "Connection dropped after too many unrecognized SMTP commands";
$SmtpConnection{$bb}++;
}
elsif ( $ThisOne =~ /dropped: too many syntax or protocol errors/ ) {
@@ -673,13 +683,17 @@
$SmtpProblemHosts{$key}++;
$SmtpConnection{$bb}++;
}
- elsif ( $ThisOne =~ /authenticator failed for (?:\S+ |)\([^)]*\) \[($IPAddress)\](?::\d+ |)(?:I=\[$IPAddress\]:\d+|): ([^(]*)/ ) {
+ elsif ( $ThisOne =~ /authenticator failed for (?:\S+ |)(?:\([^)]*\) |)\[($IPAddress)\](?:: \d+ |)([^(]*)/ ) {
my $key = $1;
$bb = $2;
$bb =~ s/\s+$//;
$SmtpProblemHosts{$key}++;
$SmtpConnection{$bb}++;
}
+ elsif ( $ThisOne =~ /command timeout on TLS connection from/ ) {
+ $bb = "TLS timeout";
+ $SmtpConnection{$bb}++;
+ }
elsif ( $ThisOne =~ /TLS error on connection from (?:(\S+) |)(?:\(([^)]*)\) |)\[($IPAddress)\](?::\d+|) (?:I=\[$IPAddress\](?::\d+|) |)\(([^)]+)\): (.*)/ ) {
my ($reverseHost, $hostLabel, $hostAddress, $action, $message) = ($1, $2, $3, $4, $5);
$message =~ s/\.$//;
Logwatch on Oracle Linux
While I’m on logwatch, the logwatch reports from the Oracle clould instance I run had these entries:
--------------------- Sudo (secure-log) Begin ------------------------
**Unmatched Entries**
oracle-cloud-agent : PWD=/var/lib/oracle-cloud-agent ; USER=root ; COMMAND=/bin/systemctl is-active unified-monitoring-agent_config_downloader.timer: 288 Time(s)
oracle-cloud-agent : PWD=/var/lib/oracle-cloud-agent ; USER=root ; COMMAND=/bin/systemctl is-active unified-monitoring-agent.service: 288 Time(s)
oracle-cloud-agent : PWD=/var/lib/oracle-cloud-agent ; USER=root ; COMMAND=/bin/systemctl cat unified-monitoring-agent.service: 288 Time(s)
To match these entries, I created a localised version of the
sudo script in /etc/logwatch/scripts/services and made the
following changes:
--- /usr/share/logwatch/scripts/services/sudo 2025-09-12 20:10:44.000000000 +0100
+++ /etc/logwatch/scripts/services/sudo 2026-02-17 19:12:36.376955569 +0000
@@ -49,6 +49,7 @@
my (%ConFailed);
my $contlines = 0;
my $argsprinted = 0;
+my (%OracleAgent);
if (defined($ENV{'ignore_commands'})) {
foreach my $entry (split(',',$ENV{'ignore_commands'})) {
@@ -87,9 +88,13 @@
push @{$byUser{$user}{$euser . " (No such user)"}}, ["No password entry"];
} elsif ( ($user, $error, $tty, $dir, $euser, $cmd, $args) = $ThisLine =~ m/^\s*\S+ : \(command continued\)/) {
$contlines++;
- } else {
- chomp($ThisLine);
- $OtherList{$ThisLine}++;
+ } elsif ( $ThisLine =~ /oracle-cloud-agent.*?COMMAND=(.*)$/ ) {
+ my @tokens = split(" ", $1);
+ $OracleAgent{$tokens[$#tokens]}++;
+ }
+ else {
+ chomp($ThisLine);
+ $OtherList{$ThisLine}++;
}
}
@@ -119,6 +124,14 @@
} # foreach $euser
} # foreach $user
+if (keys %OracleAgent) {
+ print "\nOracle Cloud Agent:";
+ print "\n-------------------\n";
+ foreach my $Agent (keys %OracleAgent) {
+ print " $Agent : $OracleAgent{$Agent} Times(s)\n";
+ }
+}
+
if (keys %ConFailed) {
print "\nConversation failed with:";
print "\n-------------------------";
While I was in the area, I thought I’d add some logwatch reporting for OpenSMTPD, the mail server I use. However, it turns out that someone has already done that. And it works very well.