summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2023-10-01 10:20:06 +0200
committerErich Eckner <git@eckner.net>2023-10-01 10:20:06 +0200
commit014cd416c259897189ebabf471840e26ee873603 (patch)
tree3590209591cffb0852a5fcea2d05f9ea335f6b8b
parentfc9d0012656cb8be235ac42638fa3569c0d3574b (diff)
downloadlogwatch-overrides-014cd416c259897189ebabf471840e26ee873603.tar.xz
sshd: revert to arch default
-rw-r--r--sshd484
1 files changed, 198 insertions, 286 deletions
diff --git a/sshd b/sshd
index 47d32a2..c41be67 100644
--- a/sshd
+++ b/sshd
@@ -1,165 +1,11 @@
-##########################################################################
-# $Id$
-##########################################################################
-# $Log: sshd,v $
-# Revision 1.79 2011/01/05 10:49:03 stefan
-# ignoring PAM 2 more authentication failures
-#
-# Revision 1.78 2010/05/10 10:49:03 stefan
-# ignoring nasty PTR records
-#
-# Revision 1.77 2009/02/20 17:49:03 mike
-# pam_winbind ignores from JT Moree -mgt
-#
-# Revision 1.76 2009/02/20 17:39:15 mike
-# Added pam_chroot from Alan Brenner -mgt
-#
-# Revision 1.75 2008/05/12 21:44:26 mike
-# One more Solaris 10 filter -mgt
-#
-# Revision 1.74 2008/05/12 21:35:19 mike
-# Solaris 10 cleanups pam_unix_auth and <invalid username> -mgt
-#
-# Revision 1.73 2008/05/03 16:15:22 mike
-# Added debug1 line from Fedora patch tree -mgt
-#
-# Revision 1.72 2008/03/24 23:31:27 kirk
-# added copyright/license notice to each script
-#
-# Revision 1.71 2007/11/25 20:20:05 bjorn
-# Modified regexp of AllowUsers to allow for host names.
-#
-# Revision 1.70 2007/11/25 20:02:57 bjorn
-# Handling chmod, chown errors, by Ivana Varekova.
-#
-# Revision 1.69 2007/09/20 00:00:15 bjorn
-# Corrected handling of invalid logins, by Dan Wallis.
-#
-# Revision 1.68 2007/07/14 14:21:22 mike
-# Added chan_read_failed ignore -mgt
-#
-# Revision 1.67 2007/06/18 03:53:25 bjorn
-# Counting of some "not allowed" statements, by Jesus de Santos García.
-#
-# Revision 1.66 2007/04/15 20:59:02 bjorn
-# Added support for refused_connections_threshold, by JT Moree.
-#
-#
-# Revision 1.65 2007/01/29 20:09:17 bjorn
-# Improved filtering, by Ivana Varekova.
-#
-# Revision 1.64 2006/11/12 20:59:31 bjorn
-# Additional 'illegal user' processing, by Ivana Varekova.
-#
-# Revision 1.63 2006/09/15 15:40:58 bjorn
-# Additional filtering by Ivana Varekova.
-#
-# Revision 1.62 2006/07/28 17:44:04 bjorn
-# Filtering postponed with publickey, by Markus Lude.
-#
-# Revision 1.61 2006/03/20 20:42:57 bjorn
-# Additional filtering, by Ivana Varekova.
-#
-# Revision 1.60 2006/03/08 04:29:34 bjorn
-# Filter pam_krb5 message, by Markus Lude.
-#
-# Revision 1.59 2006/01/20 22:31:04 bjorn
-# Handle new pam_unix format, by Ivana Varekova.
-#
-# Revision 1.58 2005/12/01 04:13:47 bjorn
-# Removed extraneous 'these' sprinkled in output.
-#
-# Revision 1.57 2005/11/24 16:47:09 bjorn
-# Count unknowns, by David Baldwin.
-#
-# Revision 1.56 2005/11/22 18:38:30 bjorn
-# Filtering additional pam messages, by Ivana Varekova.
-#
-# Revision 1.55 2005/11/16 19:56:51 bjorn
-# Filtering forced-command-only string.
-#
-# Revision 1.54 2005/10/19 05:48:39 bjorn
-# Added name/IP mismatch detection, and filtering redundant entries, by
-# Gilles Detillieux
-#
-# Revision 1.53 2005/10/01 18:59:48 bjorn
-# Corrected patch from rev. 1.51
-#
-# Revision 1.52 2005/10/01 18:28:12 bjorn
-# Modified to 'use strict', and added more filtering, by David Baldwin
-#
-# Revision 1.51 2005/09/29 15:06:55 bjorn
-# Filtering failed bind on 0.0.0.0, by Ivana Varekova.
-#
-# Revision 1.50 2005/09/28 18:49:19 mike
-# Ignore channel_lookup and server_input_channel_req from David Baldwin -mgt
-#
-# Revision 1.49 2005/09/28 18:28:52 mike
-# Patch for no route read error -mgt
-#
-# Revision 1.48 2005/09/27 21:03:20 bjorn
-# Allow filtering by host/network address
-#
-# Revision 1.47 2005/09/13 18:52:37 mike
-# Patch from David Baldwin, ldap and key ignores, improved reset and timeout regex -mgt
-#
-# Revision 1.46 2005/08/31 23:19:38 bjorn
-# LookupIP needs to be done after sorting by IP address, not before
-#
-# Revision 1.45 2005/07/21 05:56:59 bjorn
-# Allow non-space chars for username
-#
-# Revision 1.44 2005/05/21 22:47:48 bjorn
-# Provide summary per IP address, cleaned up "illegal" vs. "invalid"
-# usage, removed duplicate code, all submitted by Gilles Detillieux
-#
-# Revision 1.43 2005/04/20 17:19:32 bjorn
-# Remove pam_unix, for Debian
-#
-# Revision 1.42 2005/04/17 23:29:23 bjorn
-# Reporting changes and pam filtering from Paweł Gołaszewski and Willi Mann
-#
-# Revision 1.41 2005/02/24 17:08:05 kirk
-# Applying consolidated patches from Mike Tremaine
-#
-# Revision 1.9 2005/02/13 22:50:46 mgt
-# patches from Pawel -mgt
-#
-# Revision 1.8 2005/02/13 21:26:13 mgt
-# patches from Michael Weiser -mgt
-#
-# Revision 1.7 2005/02/13 21:03:40 mgt
-# Patch from Jeffery ? -mgt
-#
-# Revision 1.6 2004/10/06 21:40:44 mgt
-# Patches from Kenneth -mgt
-#
-# Revision 1.5 2004/07/29 19:33:29 mgt
-# Chmod and removed perl call -mgt
-#
-# Revision 1.4 2004/07/27 00:23:07 mgt
-# Suse 9.1 fix -mgt
-#
-# Revision 1.3 2004/07/10 01:54:36 mgt
-# sync with kirk -mgt
-#
-# Revision 1.38 2004/06/23 15:01:17 kirk
-# - Added more patches from blues@ds.pg.gda.pl
-#
-# Revision 1.37 2004/02/03 19:13:14 kirk
-# More Solaris patches from Sean Boran <sean@boran.com>
-#
-# Revision 1.36 2004/02/03 18:39:34 kirk
-# Patches from [ISO-8859-2] Pawe? Go?aszewski" <blues@ds.pg.gda.pl>
-#
-# Revision 1.35 2004/02/03 03:52:20 kirk
-# Added mailscanner filter and more Solaris support from Mike Tremaine <mgt@stellarcore.net>
-#
-# Revision 1.34 2004/02/03 02:45:26 kirk
-# Tons of patches, and new 'oidentd' and 'shaperd' filters from
-# Pawe? Go?aszewski" <blues@ds.pg.gda.pl>
-#
-##########################################################################
+
+########################################################
+# Please file all bug reports, patches, and feature
+# requests under:
+# https://sourceforge.net/p/logwatch/_list/tickets
+# Help requests and discusion can be filed under:
+# https://sourceforge.net/p/logwatch/discussion/
+########################################################
#######################################################
## Copyright (c) 2008 Kirk Bauer
@@ -184,8 +30,28 @@ my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0;
my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
my $IgnoreHost = $ENV{'sshd_ignore_host'} || "";
my $RefusedConnectionsThreshold = $ENV{'refused_connections_threshold'} || 0;
+my $IllegalUsersThreshold = $ENV{'illegal_users_threshold'} || 0;
+DoLookup( $ENV{'sshd_ip_lookup'} );
my $DebugCounter = 0;
+#Init String Containers
+my (
+$Action, $Address, $Addresses,
+$BytesRead, $BytesWritten, $ClientVer,
+$Code, $Dir, $EmptyUser,
+$Error, $File, $FingerP,
+$Flags, $From, $Host,
+$IP, $IlegUser, $InvaUser,
+$Key, $Line, $Method,
+$Mode, $Modtime, $Offer,
+$Option, $Perm, $Pom,
+$Pom1, $Pom2, $Port,
+$Prio, $Reason, $Received,
+$Sent, $To, $User,
+$Why, $realm, $user,
+$hr, $min, $sec,
+$conn,
+);
# No sense in running if 'sshd' doesn't even exist on this system...
#unless (( -f "/usr/sbin/sshd" ) or ( -f "/usr/local/sbin/sshd") or ( -f "/usr/lib/ssh/sshd")) {
# exit (0);
@@ -193,7 +59,6 @@ my $DebugCounter = 0;
my %Users = ();
my %IllegalUsers = ();
-my %PotentialIllegalUsers = ();
my %TooManyFailures = ();
my %NoIdent = ();
my %BindFailed = ();
@@ -246,10 +111,16 @@ my $sftpRequests = 0;
my $NetworkErrors = 0;
my $Kills = 0;
my $Starts = 0;
-my $NetworkErrors = 0;
my $StatusNoSuchFile = 0;
my $BytesSent = 0;
my $BytesReceived = 0;
+my $NoCipher = 0;
+my $MaxStartupsThrottling = 0;
+my $MaxStartupsDrops = 0;
+my $MaxStartupsTime = 0;
+my %MaxStartupsIPs = ();
+
+my $multiline = 0;
if ( $Debug >= 5 ) {
print STDERR "\n\nDEBUG: Inside SSHD Filter \n\n";
@@ -262,8 +133,20 @@ while (defined(my $ThisLine = <STDIN>)) {
$DebugCounter++;
}
chomp($ThisLine);
+
+ if ( $multiline ) {
+ if ( ($Host) = ($ThisLine =~ /^banner exchange: Connection from ([^ ]+)(?: port \d+)?:/) ) {
+ $NegotiationFailed{$Reason}{$Host}{$Offer}++;
+ } elsif ( ($Host) = ($ThisLine =~ /^Connection reset by ([^ ]+)(?: port \d+)?/) ) {
+ $NegotiationFailed{$Reason}{$Host}{$Offer}++;
+ }
+ }
+
+ $multiline = 0;
+
if (
($ThisLine =~ /^pam_succeed_if: requirement "uid < 100" (not|was) met by user /) or
+ ($ThisLine =~ /^pam_succeed_if\(.*?\): requirement "uid >= 1000" (not|was) met by user /) or
($ThisLine =~ m/^(log: )?$/ ) or
($ThisLine =~ m/^(log: )?\^\[\[60G/ ) or
($ThisLine =~ m/^(log: )? succeeded$/ ) or
@@ -292,6 +175,8 @@ while (defined(my $ThisLine = <STDIN>)) {
# usually followed by a session opened for user
($ThisLine =~ m/^pam_krb5\[\d+\]: authentication succeeds for /) or
($ThisLine =~ m/^nss_ldap: reconnect/) or
+ ($ThisLine =~ /gkr-pam: gnome-keyring-daemon started properly/) or
+ ($ThisLine =~ /gkr-pam: unable to locate daemon control file/) or
($ThisLine =~ m/^pam_ldap: error trying to bind as user "[^"]+" \(Invalid credentials\)/) or
($ThisLine =~ m/^pam_ldap: ldap_starttls_s: Can't contact LDAP server/) or
($ThisLine =~ m/^pam_sss\(sshd:.*\)/) or
@@ -305,6 +190,7 @@ while (defined(my $ThisLine = <STDIN>)) {
($ThisLine =~ /pam_winbind\(sshd:account\): user .* OK/) or
($ThisLine =~ /pam_systemd\(sshd:session\): Moving/) or
($ThisLine =~ /pam_systemd\(sshd:session\): .*: Connection reset by peer/) or
+ ($ThisLine =~ /userauth_finish: .*: Connection reset by peer/) or
($ThisLine =~ /PAM \d+ more authentication failures?;/) or
($ThisLine =~ /^PAM service\(sshd\) ignoring max retries;/) or
($ThisLine =~ /^Failed keyboard-interactive for <invalid username> from/ ) or
@@ -314,19 +200,24 @@ while (defined(my $ThisLine = <STDIN>)) {
($ThisLine =~ /Starting session: (forced-command|subsystem|shell|command)/ ) or
($ThisLine =~ /Found matching \w+ key:/ ) or
($ThisLine =~ /User child is on pid \d/ ) or
- ($ThisLine =~ /Nasty PTR record .* is set up for [\da-fA-F.:]+, ignoring/) or
+ ($ThisLine =~ /Nasty PTR record .* is set up for [\da-fA-F.:]+(?:%\S+)?, ignoring/) or
($ThisLine =~ /Exiting on signal / ) or
- ($ThisLine =~ /Disconnected from [\da-fA-F.:]* port \d*/ ) or
- ($ThisLine =~ /Disconnected from user \S+ [\da-fA-F.:]* port \d*/ ) or
- ($ThisLine =~ /Disconnected from (authenticating|invalid) user \S+ [\da-fA-F.:]* port \d*/ ) or
+ ($ThisLine =~ /Disconnected from [\da-fA-F.:]*(?:%\S+)? port \d*/ ) or
+ ($ThisLine =~ /Disconnected from user \S+ [\da-fA-F.:]*(?:%\S+)? port \d*/ ) or
+ ($ThisLine =~ /Disconnected from (authenticating|invalid) user \S+ [\da-fA-F.:]*(?:%\S+)? port \d*/ ) or
($ThisLine =~ /Disconnecting( (authenticating|invalid) user .* port \d+)?: Too many authentication failures \[preauth\]/ ) or
($ThisLine =~ /Disconnecting( (authenticating|invalid) user .* port \d+)?: Change of username or service not allowed: .* \[preauth\]/ ) or
($ThisLine =~ /Failed to release session: Interrupted system call/) or
($ThisLine =~ /Close session: user /) or
+ #($ThisLine =~ /error: .*: banner line contains invalid characters/) or
+ #($ThisLine =~ /past MaxStartups/) or
+ #($ThisLine =~ /exited MaxStartups throttling/) or
+ # user already accounted for in other statement
+ ($ThisLine =~ /^input_userauth_request: (illegal|invalid) user (.*)(?: \[preauth\])?$/ ) or
0 # This line prevents blame shifting as lines are added above
) {
# Ignore these
- } elsif ( my ($Method,$User,$Host,$Port,$Key,$FingerP) = ($ThisLine =~ /^Accepted (\S+) for ((?:invalid user )?\S+) from ([\d\.:a-f]+)(?:%\w+)? port (\d+) ssh[12](?:: (\w+) (.+))?/) ) {
+ } elsif ( ($Method,$User,$Host,$Port,$Key,$FingerP) = ($ThisLine =~ /^Accepted (\S+) for ((?:invalid user )?\S+) from ([\d\.:a-f]+)(?:%\w+)? port (\d+) ssh[12](?:: (\w+) (.+))?/) ) {
if ($Debug >= 5) {
print STDERR "DEBUG: Found -$User logged in from $Host using $Method ($Key)\n";
}
@@ -339,23 +230,24 @@ while (defined(my $ThisLine = <STDIN>)) {
$Users{$User}{$Host}{"(all)"}++;
}
}
- } elsif ( my ($Method, undef,$User,$Host,$Port) = ($ThisLine =~ m/^Failed (\S+) for (illegal|invalid) user (.*) from ([^ ]+) port (\d+)/ ) ) { #openssh
+ } elsif ( ($Method, undef,$User,$Host,$Port) = ($ThisLine =~ m/^Failed (\S+) for (illegal|invalid) user (.*) from ([^ ]+) port (\d+)/ ) ) { #openssh
$IllegalUsers{$Host}{$User}++;
- } elsif ( my ($User) = ( $ThisLine =~ /Disconnecting: Too many authentication failures for ([^ ]+)/)) {
+ } elsif ( ($User) = ( $ThisLine =~ /Disconnecting: Too many authentication failures for ([^ ]+)/)) {
$TooManyFailures{$User}++;
- } elsif ( my ($User) = ( $ThisLine =~ /error: maximum authentication attempts exceeded for ([^ ]+) from [^ ]+ port \d+ ssh2 \[preauth\]/)) {
+ } elsif ( ($User) = ( $ThisLine =~ /error: maximum authentication attempts exceeded for ([^ ]+) from [^ ]+ port \d+ ssh2 \[preauth\]/)) {
$TooManyFailures{$User}++;
- } elsif ( my ($User,$Host) = ( $ThisLine =~ /error: maximum authentication attempts exceeded for invalid user ([^ ]+) from ([^ ]+) port \d+ ssh2 \[preauth\]/)) {
+ } elsif ( ($User,$Host) = ( $ThisLine =~ /error: maximum authentication attempts exceeded for invalid user ([^ ]+) from ([^ ]+) port \d+ ssh2 \[preauth\]/)) {
$IllegalUsers{$Host}{$User}++;
} elsif ( $ThisLine =~ m/^(fatal: )?Did not receive ident(ification)? string from (\S+)/ ) { # ssh/openssh
my $name = LookupIP($3);
$NoIdent{$name}++;
- } elsif ( my ($Host) = ($ThisLine =~ /Could not write ident string to ([^ ]+)$/ )) {
+ } elsif ( ($Host) = ($ThisLine =~ /Could not write ident string to ([^ ]+)$/ )) {
my $name = LookupIP($Host);
$NoIdent{$name}++;
} elsif (
- ($ThisLine =~ m/^fatal: Connection closed by remote host\./ ) or
+ ($ThisLine =~ m/^(?:error:.*|fatal:) Connection closed by remote host/ ) or
($ThisLine =~ m/^(|fatal: )Read error from remote host(| [^ ]+): Connection reset by peer/ ) or
+ ($ThisLine =~ m/^error: .*: read: Connection reset by peer/ ) or
($ThisLine =~ m/^Read error from remote host [^ ]+: (Connection timed out|No route to host)/ ) or
($ThisLine =~ m/^fatal: Read from socket failed: No route to host/) or
($ThisLine =~ m/^fatal: Write failed: Network is unreachable/ ) or
@@ -377,7 +269,7 @@ while (defined(my $ThisLine = <STDIN>)) {
if ( $Debug >= 5 ) {
print STDERR "DEBUG: Found -Listening on port 22- line\n";
}
- } elsif ( my ($Port,$Address,$Reason) = ($ThisLine =~ /^error: Bind to port ([^ ]+) on ([^ ]+) failed: (.+).$/ )) {
+ } elsif ( ($Port,$Address,$Reason) = ($ThisLine =~ /^error: Bind to port ([^ ]+) on ([^ ]+) failed: (.+).$/ )) {
my $Temp = "$Address port $Port ($Reason)";
# Failed to bind on 0.0.0.0 likely due to configured "ListenAddress"
# on both IPv4 and IPv6
@@ -398,7 +290,7 @@ while (defined(my $ThisLine = <STDIN>)) {
if ( $Debug >= 5 ) {
print STDERR "DEBUG: Found -Keygen complete- line\n";
}
- } elsif ( my ($Method,$User,$Host,undef) = ( $ThisLine =~ m/^Failed (\S+) for (\S+) from ([^ ]+) port (\d+)/ ) ) { #openssh
+ } elsif ( ($Method,$User,$Host,undef) = ( $ThisLine =~ m/^Failed (\S+) for (\S+) from ([^ ]+) port (\d+)/ ) ) { #openssh
# depending on log mode, openssh may not report these in connection context.
if ( $Debug >= 5 ) {
print STDERR "DEBUG: Found -Failed login- line\n";
@@ -406,122 +298,135 @@ while (defined(my $ThisLine = <STDIN>)) {
$BadLogins{$Host}{"$User/$Method"}++;
} elsif ($ThisLine =~ s/^(log: )?Could not reverse map address ([^ ]*).*$/$2/) {
$NoRevMap{$ThisLine}++;
- } elsif ( my ($Address) = ($ThisLine =~ /^reverse mapping checking getaddrinfo for (\S+( \[\S+\])?) failed - POSSIBLE BREAK-IN ATTEMPT!/)) {
+ } elsif ( ($Address) = ($ThisLine =~ /^reverse mapping checking getaddrinfo for (\S+( \[\S+\])?) failed - POSSIBLE BREAK-IN ATTEMPT!/)) {
$NoRevMap{$Address}++;
- } elsif ( my ($IP,$Address) = ($ThisLine =~ /^Address ([^ ]*) maps to ([^ ]*), but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!/)) {
+ } elsif ( ($IP,$Address) = ($ThisLine =~ /^Address ([^ ]*) maps to ([^ ]*), but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!/)) {
$NoRevMap{"$Address($IP)"}++;
- } elsif ( my (undef,$Address) = ($ThisLine =~ /^warning: ([^ ]*), line \d+: can't verify hostname: getaddrinfo\(([^ ]*), AF_INET\) failed$/)) {
+ } elsif ( (undef,$Address) = ($ThisLine =~ /^warning: ([^ ]*), line \d+: can't verify hostname: getaddrinfo\(([^ ]*), AF_INET\) failed$/)) {
$NoRevMap{$Address}++;
- } elsif ( my (undef,$Addresses) = ($ThisLine =~ /^warning: ([^ ]*), line \d+: host [^ ]* mismatch: (.*)$/)) {
+ } elsif ( (undef,$Addresses) = ($ThisLine =~ /^warning: ([^ ]*), line \d+: host [^ ]* mismatch: (.*)$/)) {
$MisMatch{$Addresses}++;
} elsif ( $ThisLine =~ m/subsystem request for sftp/ ) {
$sftpRequests++;
} elsif ( $ThisLine =~ m/refused connect from (.*)$/ ) {
$RefusedConnections{$1}++;
- } elsif ( my ($Reason) = ($ThisLine =~ /^Authentication refused: (.*)$/ ) ) {
+ } elsif ( ($Reason) = ($ThisLine =~ /^Authentication refused: (.*)$/ ) ) {
$RefusedAuthentication{$Reason}++;
- } elsif ( my (undef,$Host,$Port,$Reason,$Offer) = ($ThisLine =~ /^(fatal: )?Unable to negotiate with ([^ ]+)( port \d+)?: (.*)\. Their offer: (.*) \[preauth\]$/) ) {
+ } elsif ( (undef,$Host,$Port,$Reason,$Offer) = ($ThisLine =~ /^(fatal: )?Unable to negotiate with ([^ ]+)( port \d+)?: (.*)\. Their offer: (.*) \[preauth\]$/) ) {
$NegotiationFailed{$Reason}{$Host}{$Offer}++;
- } elsif ( my ($Reason,$Host,$Offer) = ($ThisLine =~ /^(Protocol major versions differ) for ([^ ]+)(?: port \d+): (.*)$/) ) {
+ } elsif ( ($Reason,$Host,$Offer) = ($ThisLine =~ /^(Protocol major versions differ) for ([^ ]+)(?: port \d+)?: (.*)$/) ) {
$NegotiationFailed{$Reason}{$Host}{$Offer}++;
- } elsif ( my ($Prio,$Host,$Port,$Code,$Reason) = ($ThisLine =~ /^(error: )?Received disconnect from ([^ ]*)( port \d+)?: ?(\d+): (.*)$/)) {
+ } elsif ( ($Reason,$Offer) = ($ThisLine =~ /^error: (Protocol major versions differ): (.*)$/) ) {
+ $multiline++;
+ } elsif ( ($Reason,$Offer) = ($ThisLine =~ /^error: (kex_exchange_identification): (.*)$/) ) {
+ $multiline++;
+ } elsif ( ($Reason,$Offer) = ($ThisLine =~ /^error: (kex protocol error): (.*)$/) ) {
+ $multiline++;
+ } elsif ( ($Prio,$Host,$Port,$Code,$Reason) = ($ThisLine =~ /^(error: )?Received disconnect from ([^ ]*)( port \d+)?: ?(\d+): (.*)$/)) {
# Reason 11 ({SSH,SSH2}_DISCONNECT_BY_APPLICATION) is expected, and logged at severity level INFO
if (($Reason =~ /preauth/) || ($Code != 11) || ($Detail >= 30)) {
$DisconnectReceived{$Reason}{$Host}++;
}
- } elsif ( my ($Host) = ($ThisLine =~ /^ROOT LOGIN REFUSED FROM ([^ ]*)$/)) {
+ } elsif ( ($Host) = ($ThisLine =~ /^ROOT LOGIN REFUSED FROM ([^ ]*)$/)) {
$RootLogin{$Host}++;
- } elsif ( my ($Error) = ($ThisLine =~ /^Cannot release PAM authentication\[\d\]: (.*)$/)) {
+ } elsif ( ($Error) = ($ThisLine =~ /^Cannot release PAM authentication\[\d\]: (.*)$/)) {
$PamReleaseFail{$Error}++;
- } elsif ( my ($Error) = ($ThisLine =~ /^pam_systemd\(sshd:session\): Failed to release session: (.*)$/)) {
+ } elsif ( ($Error) = ($ThisLine =~ /^pam_systemd\(sshd:session\): Failed to release session: (.*)$/)) {
$PamReleaseFail{$Error}++;
- } elsif ( my ($Error) = ( $ThisLine =~ m/^error: PAM: (.*)$/)) {
+ } elsif ( ($Error) = ( $ThisLine =~ m/^error: PAM: (.*)$/)) {
$PamError{$Error}++;
- } elsif ( my ($Error) = ( $ThisLine =~ m/pam_systemd\(sshd:session\): (Failed to create session: .*)$/)) {
+ } elsif ( ($Error) = ( $ThisLine =~ m/pam_systemd\(sshd:session\): (Failed to create session: .*)$/)) {
$PamError{$Error}++;
- } elsif ( my ($Reason) = ( $ThisLine =~ m/pam_chroot\(.+\):\s+([^:])/)) {
+ } elsif ( ($Reason) = ( $ThisLine =~ m/pam_chroot\(.+\):\s+([^:])/)) {
$PamChroot{$Reason}++;
- } elsif ( my ($Error) = ( $ThisLine =~ m/^error: Could not get shadow information for (.*)$/)) {
+ } elsif ( ($Error) = ( $ThisLine =~ m/^error: Could not get shadow information for (.*)$/)) {
$ShadowInfo{$Error}++;
- } elsif ( my ($Reason) = ($ThisLine =~ /^Setting tty modes failed: (.*)$/)) {
+ } elsif ( ($Reason) = ($ThisLine =~ /^Setting tty modes failed: (.*)$/)) {
$TTYModesFail{$Reason}++;
- } elsif ( my ($User,undef) = ($ThisLine =~ /^User ([^ ]*) not allowed because ([^ ]*) exists$/)) {
+ } elsif ( ($User,undef) = ($ThisLine =~ /^User ([^ ]*) not allowed because ([^ ]*) exists$/)) {
$LoginLock{$User}++;
- } elsif ( my ($Method,$InvaUser,$IlegUser,$EmptyUser,$User,$Host) = ($ThisLine =~ /^Postponed ([^ ]*) for ((invalid user) [^ ]*|(illegal user) [^ ]*|([^ ]*)) from ([^ ]*) port \d+ ssh/)) {
+ } elsif ( ($Method,$InvaUser,$IlegUser,$EmptyUser,$User,$Host) = ($ThisLine =~ /^Postponed ([^ ]*) for ((invalid user) [^ ]*|(illegal user) [^ ]*|([^ ]*)) from ([^ ]*) port \d+ ssh/)) {
$PostPonedAuth{"$User/$Method"}{$Host}++;
if ($IlegUser =~ /illegal user/) {$IllegalUsers{$Host}{$User}++;}
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because account is locked/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because account is locked/)) {
$LockedAccount{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) from (?:[^ ]*) not allowed because not listed in AllowUsers/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) from (?:[^ ]*) not allowed because not listed in AllowUsers/)) {
$AllowUsers{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*)( from [0-9.]*)? not allowed because listed in DenyUsers/)){
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*)( from [0-9.]*)? not allowed because listed in DenyUsers/)){
$DenyUsers{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*)( from [0-9.]*)? not allowed because not in any group/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*)( from [0-9.]*)? not allowed because not in any group/)) {
$NoGroups{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*)( from [^ ]*)? not allowed because a group is listed in DenyGroups/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*)( from [^ ]*)? not allowed because a group is listed in DenyGroups/)) {
$DenyGroups{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) from ([^ ]*) not allowed because none of user's groups are listed in AllowGroups/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) from ([^ ]*) not allowed because none of user's groups are listed in AllowGroups/)) {
$AllowGroups{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because shell (\S+) does not exist/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because shell (\S+) does not exist/)) {
$NoShellUsers{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because shell (\S+) is not executable/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because shell (\S+) is not executable/)) {
$ShellNotExecutableUsers{$User}++;
- } elsif ( my ($User) = ($ThisLine =~ /^fatal: Access denied for user ([^ ]+) by PAM account configuration \[preauth\]/)) {
+ } elsif ( ($User) = ($ThisLine =~ /^fatal: Access denied for user ([^ ]+) by PAM account configuration \[preauth\]/)) {
$PamDeny{$User}++;
- } elsif ( my ($IP) = ($ThisLine =~ /^scanned from ([^ ]*)/) ) {
+ } elsif ( ($IP) = ($ThisLine =~ /^scanned from ([^ ]*)/) ) {
push @Scanned, $IP;
- } elsif ( my (undef,$Line,$Option) = ($ThisLine =~ /^re(xec|process config) line (\d+): Deprecated option (.*)$/)) {
+ } elsif ( (undef,$Line,$Option) = ($ThisLine =~ /^re(xec|process config) line (\d+): Deprecated option (.*)$/)) {
$DeprecatedOption{"$Option - line $Line"}++;
- } elsif ( my ($Pom1,$Pom2,$User) = ($ThisLine =~ /pam_krb5(\[\d*\])?: authentication fails for (`|')([^ ]*)'/)) {
+ } elsif ( ($Pom1,$Pom2,$User) = ($ThisLine =~ /pam_krb5(\[\d*\])?: authentication fails for (`|')([^ ]*)'/)) {
$KrbAutFail{$User}++;
- } elsif ( my ($Error) = ($ThisLine =~ /pam_krb5: authenticate error: (.*)$/)) {
+ } elsif ( ($Error) = ($ThisLine =~ /pam_krb5: authenticate error: (.*)$/)) {
$KrbAutErr{$Error}++;
} elsif ( ($ThisLine =~ /pam_krb5: unable to determine uid\/gid for user$/)) {
$KrbAutErr{"unable to determine uid/gid for user"}++;
- } elsif ( my ($Error) = ($ThisLine =~ /pam_krb5: error removing file (.*)$/)) {
+ } elsif ( ($Error) = ($ThisLine =~ /pam_krb5: error removing file (.*)$/)) {
$KrbErr{"error removing file " . $Error}++;
- } elsif ( my ($Pom,$Error) = ($ThisLine =~ /pam_krb5(\[\d*\]): error resolving user name '[^ ]*' to uid\/gid pai/)) {
+ } elsif ( ($Pom,$Error) = ($ThisLine =~ /pam_krb5(\[\d*\]): error resolving user name '[^ ]*' to uid\/gid pai/)) {
$KrbErr{"error resolving user name '$Error' to uid\/gid pai"}++;
- } elsif ( my (undef,$User,$Host) = ($ThisLine =~ m/^(Illegal|Invalid) user (.*) from ([^ ]+)/ )) {
- $PotentialIllegalUsers{$Host}{$User}++;
- } elsif ( my (undef,$User) = ($ThisLine =~ /^input_userauth_request: (illegal|invalid) user (.*)$/ )) {
- if ($User =~ m/(.*) \[preauth\]/) {
- $User = $1;
+ } elsif ( (undef,$User,$Host) = ($ThisLine =~ m/^(Illegal|Invalid) user (.*) from ([^ ]+)/ )) {
+ if ($User eq "") {
+ $User = "{undefined}";
}
- $PotentialIllegalUsers{"undef"}{$User}++;
- } elsif (my ($File,$Perm,$Why) = ($ThisLine =~ /error: chmod (.*) (.*) failed: (.*)/)) {
+ $IllegalUsers{$Host}{$User}++;
+ } elsif (($File,$Perm,$Why) = ($ThisLine =~ /error: chmod (.*) (.*) failed: (.*)/)) {
$ChmodErr{"$File,$Perm,$Why"}++;
- } elsif (my ($File,$From,$To,$Why) = ($ThisLine =~ /error: chown (.*) (.*) (.*) failed: (.*)/)) {
+ } elsif (($File,$From,$To,$Why) = ($ThisLine =~ /error: chown (.*) (.*) (.*) failed: (.*)/)) {
$ChownErr{"$File,$From,$To,$Why"}++;
- } elsif (my ($user,$realm) = ($ThisLine =~ /Authorized to ([^ ]+), krb5 principal \1@([^ ]+) \((?:krb5_kuserok|ssh_gssapi_krb5_cmdok)\)/)) {
+ } elsif (($user,$realm) = ($ThisLine =~ /Authorized to ([^ ]+), krb5 principal \1@([^ ]+) \((?:krb5_kuserok|ssh_gssapi_krb5_cmdok)\)/)) {
$Krb_realm{$realm}{$user}++;
- } elsif (my ($Action,$User) = ($ThisLine =~ /^session ((?:open|clos)ed) for local user (\S+) from /)) {
+ } elsif (($Action,$User) = ($ThisLine =~ /^session ((?:open|clos)ed) for local user (\S+) from /)) {
$Session{"Action,$User"}++;
} elsif ($ThisLine =~ /^sent status No such file$/) {
$StatusNoSuchFile++;
- } elsif (my ($File,$Flags,$Mode) = ($ThisLine =~ /^open "(.*)" flags (\S+) mode (\d+)/ )) {
+ } elsif (($File,$Flags,$Mode) = ($ThisLine =~ /^open "(.*)" flags (\S+) mode (\d+)/ )) {
$OpenFile{"$File:$Flags:$Mode"}++;
- } elsif (my ($File,$BytesRead,$BytesWritten) = ($ThisLine =~ /^close "(.*)" bytes read (\d+) written (\d+)/ )) {
+ } elsif (($File,$BytesRead,$BytesWritten) = ($ThisLine =~ /^close "(.*)" bytes read (\d+) written (\d+)/ )) {
$CloseFileReadWrite{"$File,$BytesRead,$BytesWritten"}++;
- } elsif (my ($Sent,$Received) = ($ThisLine =~ /^Transferred: sent (\d+), received (\d+) bytes$/ )) {
+ } elsif (($Sent,$Received) = ($ThisLine =~ /^Transferred: sent (\d+), received (\d+) bytes$/ )) {
$BytesSent += $Sent;
$BytesReceived += $Received;
- } elsif (my ($File,$Modtime) = ($ThisLine =~ /^set "(.*)" modtime (\d+-\d+:\d+:\d+)$/ )) {
+ } elsif (($File,$Modtime) = ($ThisLine =~ /^set "(.*)" modtime (\d+-\d+:\d+:\d+)$/ )) {
$SetModtime{"$Modtime,$File"}++;
- } elsif (my ($Dir) = ($ThisLine =~ /^opendir "(.*)"$/ )) {
+ } elsif (($Dir) = ($ThisLine =~ /^opendir "(.*)"$/ )) {
$OpenDir{$Dir}++;
- } elsif (my ($Dir) = ($ThisLine =~ /^closedir "(.*)"$/ )) {
+ } elsif (($Dir) = ($ThisLine =~ /^closedir "(.*)"$/ )) {
$CloseDir{$Dir}++;
- } elsif (my ($File) = ($ThisLine =~ /^realpath "(.*)"$/ )) {
+ } elsif (($File) = ($ThisLine =~ /^realpath "(.*)"$/ )) {
$RealPath{$File}++;
- } elsif (my ($File) = ($ThisLine =~ /^stat name "(.*)"$/ )) {
+ } elsif (($File) = ($ThisLine =~ /^stat name "(.*)"$/ )) {
$Stat{$File}++;
- } elsif (my ($Dir) = ($ThisLine =~ /^Changed root directory to "(.*)"/ )) {
+ } elsif (($Dir) = ($ThisLine =~ /^Changed root directory to "(.*)"/ )) {
$Chroot{$Dir}++;
- } elsif (my ($ClientVer) = ($ThisLine =~ /^received client version (\S+)/ )) {
+ } elsif (($ClientVer) = ($ThisLine =~ /^received client version (\S+)/ )) {
$ClientVers{$ClientVer}++;
- } elsif (my ($Host,$Port) = ($ThisLine =~ /^error: connect_to (\S+) port (\d+): failed\.$/)) {
+ } elsif (($Host,$Port) = ($ThisLine =~ /^error: connect_to (\S+) port (\d+): failed\.$/)) {
$ConnectFailed{"$Host port $Port"}++;
+ } elsif ($ThisLine =~ /^fatal: no matching cipher found: /) {
+ $NoCipher++;
+ } elsif ($ThisLine =~ /beginning MaxStartups throttling/) {
+ $MaxStartupsThrottling++;
+ } elsif (($IP) = ($ThisLine =~ /drop connection #\d+ from \[(\S+)\]:\d+ on \[\S+\]:\d+ past MaxStartups/)) {
+ $MaxStartupsIPs{$IP}++;
+ } elsif (($hr, $min, $sec, $conn) = ($ThisLine =~ /exited MaxStartups throttling after (\d\d):(\d\d):(\d\d), (\d+) connections dropped/)) {
+ $MaxStartupsTime += (((($hr * 60) + $min) * 60) + $sec);
+ $MaxStartupsDrops += $conn;
} else {
# Report any unmatched entries...
unless ($ThisLine =~ /fwd X11 connect/) {
@@ -532,26 +437,6 @@ while (defined(my $ThisLine = <STDIN>)) {
###########################################################
-foreach my $Host (sort keys %PotentialIllegalUsers) {
- foreach my $User (sort keys %{$PotentialIllegalUsers{$Host}}) {
- my @user_hosts = grep { $PotentialIllegalUsers{$_}{$User} } keys %PotentialIllegalUsers;
-
- if ($Host eq "undef") {
- if ((scalar @user_hosts) == 1 && $user_hosts[0] == "undef") {
- # Report illegal user from "undef" only if there are no other hosts
- # for the given user
- $IllegalUsers{"undef"}{$User}++;
- }
- }
- else {
- while ($IllegalUsers{$Host}{$User} < $PotentialIllegalUsers{$Host}{$User}) {
- $IllegalUsers{$Host}{$User}++;
- }
- }
- }
-}
-
-###########################################################
sub timesplural {
my ($count) = @_;
@@ -587,7 +472,7 @@ if (keys %RootLogin) {
if (keys %BindFailed) {
print "\nFailed to bind:\n";
foreach my $ThisOne (sort {$a cmp $b} keys %BindFailed) {
- print " $ThisOne : " . timesplural($BindFailed{$ThisOne});
+ print " $ThisOne : " . timesplural($BindFailed{$ThisOne});
}
}
@@ -595,7 +480,7 @@ if ($Detail >= 30 && keys %ConnectFailed) {
# SSH Socks Forwarding
print "\nFailed to connect to:\n";
foreach my $ThisOne (sort {$a cmp $b} keys %ConnectFailed) {
- print " $ThisOne : " . timesplural($ConnectFailed{$ThisOne});
+ print " $ThisOne : " . timesplural($ConnectFailed{$ThisOne});
}
}
@@ -650,6 +535,10 @@ if (keys %NegotiationFailed) {
}
}
+if ($NoCipher && $Detail > 0) {
+ print "\nNo matching cipher offered: " . timesplural($NoCipher);
+}
+
if (keys %TooManyFailures) {
print "\nDisconnecting after too many authentication failures for user:\n";
foreach my $User (sort {$a cmp $b} keys %TooManyFailures) {
@@ -677,19 +566,25 @@ if (keys %BadLogins) {
}
if (keys %IllegalUsers) {
- print "\nIllegal users from:\n";
+ print "\nIllegal users from";
+ if ($IllegalUsersThreshold) {
+ print " (with threshold >= $IllegalUsersThreshold)";
+ }
+ print ":\n";
foreach my $ip (sort SortIP keys %IllegalUsers) {
my $name = LookupIP($ip);
my $totcount = 0;
foreach my $user (keys %{$IllegalUsers{$ip}}) {
$totcount += $IllegalUsers{$ip}{$user};
}
- print " $name: " . timesplural($totcount);
- if ($Detail >= 5) {
- my $sort = CountOrder(%{$IllegalUsers{$ip}});
- foreach my $user (sort $sort keys %{$IllegalUsers{$ip}}) {
- my $val = $IllegalUsers{$ip}{$user};
- print " $user: " . timesplural($val);
+ if ($IllegalUsersThreshold == 0 || $totcount >= $IllegalUsersThreshold) {
+ print " $name: " . timesplural($totcount);
+ if ($Detail >= 5) {
+ my $sort = CountOrder(%{$IllegalUsers{$ip}});
+ foreach my $user (sort $sort keys %{$IllegalUsers{$ip}}) {
+ my $val = $IllegalUsers{$ip}{$user};
+ print " $user: " . timesplural($val);
+ }
}
}
}
@@ -828,14 +723,14 @@ if (keys %RefusedAuthentication) {
}
if (keys %KrbAutFail) {
- print "\n\Failed pam_krb5 authentication:\n";
+ print "\n Failed pam_krb5 authentication:\n";
foreach my $User (sort keys %KrbAutFail) {
print " $User: " . timesplural($KrbAutFail{$User});
}
}
if (keys %KrbAutErr) {
- print "\n\pam_krb5 authentication errors:\n";
+ print "\n pam_krb5 authentication errors:\n";
foreach my $Error (sort keys %KrbAutErr) {
print " $Error: " . timesplural($KrbAutErr{$Error});
}
@@ -857,9 +752,9 @@ if (keys %DisconnectReceived) {
print " $Reason";
foreach my $Host (sort {$a cmp $b} keys %{$DisconnectReceived{$Reason}}) {
$Total += $DisconnectReceived{$Reason}{$Host};
- if( $Detail > 0 ) {
+ if( $Detail > 0 ) {
print "\n $Host : $DisconnectReceived{$Reason}{$Host} Time(s)";
- }
+ }
}
if( $Detail > 0 ) {
print "\n";
@@ -880,7 +775,7 @@ if (keys %RefusedConnections) {
my $output;
foreach my $badguy (sort {$a cmp $b} keys %RefusedConnections ) {
if ($RefusedConnectionsThreshold == 0 || $Detail > 5 || $RefusedConnections{$badguy} >= $RefusedConnectionsThreshold) {
- $output .= " $badguy: " . timesplural($RefusedConnections{$badguy});
+ $output .= " $badguy: " . timesplural($RefusedConnections{$badguy});
}
}
if ($output ne '') {
@@ -889,6 +784,23 @@ if (keys %RefusedConnections) {
}
}
+if ($MaxStartupsThrottling) {
+ print "\nMaxStartups throttling begins: " . timesplural($MaxStartupsThrottling);
+ if ($Detail >= 5) {
+ print " Dropped connections total: " . timesplural($MaxStartupsDrops);
+ my $hr = $MaxStartupsTime / 3600;
+ my $min = ($MaxStartupsTime / 60) % 60;
+ my $sec = $MaxStartupsTime % 60;
+ printf " Throttling time total: %02d:%02d:%02d\n", $hr, $min, $sec;
+ }
+ if ($Detail >= 10) {
+ print " Initial dropped IP:\n";
+ foreach my $ThisOne (sort SortIP keys %MaxStartupsIPs) {
+ print " " . LookupIP($ThisOne) . " : " . timesplural($MaxStartupsIPs{$ThisOne});
+ }
+ }
+}
+
if (keys %PamReleaseFail) {
print "\nCannot release PAM authentication:\n";
foreach my $Error (sort {$a cmp $b} keys %PamReleaseFail) {
@@ -990,33 +902,33 @@ if ($sftpRequests > 0) {
}
if (keys %ChmodErr) {
- print "\nChmod errors:\n";
- foreach (sort keys %ChmodErr) {
- my ($File,$Perm,$Why)= split ",";
- print " " . $File . " " . $Perm . " failed(" . $Why . "): " . timesplural($ChmodErr{"$File,$Perm,$Why"});
- }
+ print "\nChmod errors:\n";
+ foreach (sort keys %ChmodErr) {
+ my ($File,$Perm,$Why)= split ",";
+ print " " . $File . " " . $Perm . " failed(" . $Why . "): " . timesplural($ChmodErr{"$File,$Perm,$Why"});
+ }
}
if (keys %ChownErr) {
- print "\nChown errors:\n";
- foreach (keys %ChownErr) {
- my ($File,$From,$To,$Why)= split ",";
- print " " . $File . " " . $From . " " .$To . " failed(" . $Why . "): " . timesplural($ChmodErr{"$File,$From,$To,$Why"});
- }
+ print "\nChown errors:\n";
+ foreach (keys %ChownErr) {
+ my ($File,$From,$To,$Why)= split ",";
+ print " " . $File . " " . $From . " " .$To . " failed(" . $Why . "): " . timesplural($ChmodErr{"$File,$From,$To,$Why"});
+ }
}
-if ( ($Detail == 7 && keys %Krb_realm > 1) || ($Detail > 8 && keys %Krb_realm) ){
- print "\nSuccessful Kerberos Authentication from ",(scalar keys %Krb_realm)," realm:\n";
- foreach my $realm (sort keys %Krb_realm) {
- if($Detail > 9){
- print " ",$realm,":\n";
- foreach my $user(sort keys %{$Krb_realm{$realm}}){
- print " ",$user,": " . timesplural($Krb_realm{$realm}{$user});
+if ( ($Detail == 7 && keys %Krb_realm > 1) || ($Detail > 7 && keys %Krb_realm) ){
+ print "\nSuccessful Kerberos Authentication from ",(scalar keys %Krb_realm)," realm:\n";
+ foreach my $realm (sort keys %Krb_realm) {
+ if($Detail > 9){
+ print " ",$realm,":\n";
+ foreach my $user(sort keys %{$Krb_realm{$realm}}) {
+ print " ",$user,": " . timesplural($Krb_realm{$realm}{$user});
+ }
+ } else {
+ print " ",$realm,": ". (scalar keys %{$Krb_realm{$realm}}) . " User(s)\n";
}
- }else{
- print " ",$realm,": ". (scalar keys %{$Krb_realm{$realm}}) . " User(s)\n";
- }
- }
+ }
}
if (keys %OtherList) {