commit e92cade1139f6e74bda15d961ff722cc05115f4b
Author: Konstantin Ryabitsev <mricon(a)kernel.org>
Date: Wed Apr 18 11:07:22 2012 -0400
Add "failed_summary_only" option.
Systems with publicly accessible services that don't use things like
fail2ban or denyhosts tend to have a long list of failed attempts
in each report. This option lists summary of all failed attempts per
service, making the report much more palatable. I leave this option
off by default, following the principle of least change.
Also, sanitize the username before putting it into the report,
as some enteprising souls have apparently tried using "<!--" as the
username.
etc/modules.d/logins.conf.in | 6 ++++++
modules/logins_mod.py | 21 +++++++++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
---
diff --git a/etc/modules.d/logins.conf.in b/etc/modules.d/logins.conf.in
index fa5867d..ad35f48 100644
--- a/etc/modules.d/logins.conf.in
+++ b/etc/modules.d/logins.conf.in
@@ -37,3 +37,9 @@ safe_domains = .*
# If you have too many systems, wide-scale probing may turn ugly. This
# will collapse the reports.
systems_collapse = 10
+##
+# Failed logins reports tend to be long on systems with publicly listening
+# services. If you want to see only a summary of failed logins, then
+# set this option to 1:
+#
+failed_summary_only = 0
diff --git a/modules/logins_mod.py b/modules/logins_mod.py
index 15d4264..2d2b8a8 100644
--- a/modules/logins_mod.py
+++ b/modules/logins_mod.py
@@ -176,6 +176,8 @@ class logins_mod(InternalModule):
logger.put(0, 'Error compiling domain regex: %s' % domain)
logger.put(0, 'Check config for Logins module!')
+ self.failed_summary_only = opts.get('failed_summary_only', '0')
+
self.regex_map = regex_map
self.pam_service_re = rc('(\S+)\(pam_unix\)')
@@ -636,7 +638,12 @@ class logins_mod(InternalModule):
if user == 'root' or user == 'ROOT':
action += 10
remote = self._mk_userat(byuser, rhost)
- restuple = (action, system, service, remote)
+
+ if self.failed_summary_only != '0':
+ restuple = (action, service, 'total failed',
+ '%s%s' % (system, remote))
+ else:
+ restuple = (action, system, service, remote)
else:
if rhost:
match = 0
@@ -647,7 +654,17 @@ class logins_mod(InternalModule):
if not match:
tmp = {'system': system, 'rhost': rhost}
system = self.untrusted_host % tmp
- restuple = (action, user, service, system)
+
+ if self.failed_summary_only != '0':
+ restuple = (action, service, 'total failed', system)
+ else:
+ # Sanitize user
+ user = user.replace('&', '&')
+ user = user.replace('<', '<')
+ user = user.replace('>', '>')
+
+ restuple = (action, user, service, system)
+
return restuple
def _mk_dots(self, str, lim):