fix logrotate functionality
[logparse.git] / logparse / parsers / sshd.py
index 38b306443e3b5a16f5f0bffb9fed977cfc32787a..18b1799d86bd35a477c999f739dfca25a6f6b6f0 100644 (file)
@@ -1,7 +1,11 @@
 #
-#   sshd.py
+#   sshd_auth.py
 #   
-#   Find number of ssh logins and authorised users
+#   Find number of ssh logins and authorised users (uses /var/log/auth.log)
+#   
+#   NOTE: This file is now deprecated in favour of the newer journald mechanism
+#   used in sshd-journald.py. This parser is still functional but is slower and
+#   has less features. Please switch over if possible.
 #
 
 import re
@@ -14,15 +18,26 @@ import logging
 logger = logging.getLogger(__name__)
 
 def parse_log():
+
+    logger.warning("NOTE: This sshd parser is now deprecated. Please use sshd-journald if possible.")
+
     logger.debug("Starting sshd section")
     section = Section("ssh")
     logger.debug("Searching for matches in {0}".format(config.prefs['logs']['auth']))
     matches = re.findall('.*sshd.*Accepted publickey for .* from .*', readlog(config.prefs['logs']['auth']))    # get all logins
     logger.debug("Finished searching for logins")
+
+    logger.debug("Searching for matches in {0}".format(config.prefs['logs']['auth']))
+    authlog = readlog(config.prefs['logs']['auth'])
+   
+    matches = re.findall('.*sshd.*Accepted publickey for .* from .*', authlog)    # get all logins
+    invalid_matches = re.findall(".*sshd.*Invalid user .* from .*", authlog)
+    root_matches = re.findall("Disconnected from authenticating user root", authlog)
+    logger.debug("Finished searching for logins")
     
     users = []  # list of users with format [username, number of logins] for each item
     data = []
-    num = sum(1 for x in matches)     # total number of logins
+    num = len(matches)     # total number of logins
     for match in matches:
         entry = re.search('^.*publickey\sfor\s(\w*)\sfrom\s(\S*)', match)  # [('user', 'ip')]
 
@@ -30,24 +45,44 @@ def parse_log():
         ip = entry.group(2)
 
         userhost = user + '@' + resolve(ip, fqdn=config.prefs['sshd']['resolve-domains'])
-        exists = [i for i, item in enumerate(users) if re.search(userhost, item[0])]
-        if (exists == []):
-            users.append([userhost, 1])
-        else:
-            users[exists[0]][1] += 1
+        users.append(userhost)
     logger.debug("Parsed list of authorised users")
 
-    auth_data = Data(subtitle=plural('login', num) + ' from')
-
-    if (len(users) == 1):             # if only one user, do not display no of logins for this user
-        logger.debug("found " + str(len(matches)) + " ssh logins for user " + users[0][0])
-        auth_data.subtitle += ' ' + users[0][0]
-    else:
-        for user in users:
-            auth_data.items.append(user[0] + ' (' + str(user[1]) + ')')
-            auth_data.orderbyfreq()
-            auth_data.truncl(config.prefs['maxlist'])
-        logger.debug("found " + str(len(matches)) + " ssh logins for users " + str(data))
+    auth_data = Data(subtitle=plural('login', num) + ' from', items=users)
+
+    if (len(auth_data.items) == 1):             # if only one user, do not display no of logins for this user
+        logger.debug("found " + str(len(matches)) + " ssh logins for user " + users[0])
+        auth_data.subtitle += ' ' + auth_data.items[0]
+    auth_data.orderbyfreq()
+    auth_data.truncl(config.prefs['maxlist'])
+    logger.debug("Found " + str(len(matches)) + " ssh logins for users " + str(data))
     section.append_data(auth_data)
+
+    invalid_users = []
+    for match in invalid_matches:
+        entry = re.search('^.*Invalid user (\S+) from (\S+).*', match)  # [('user', 'ip')]
+
+        try:
+            user = entry.group(1)
+            ip = entry.group(2)
+        except:     # blank user field
+            continue
+
+        userhost = user + '@' + ip
+        invalid_users.append(userhost)
+    logger.debug("Parsed list of invalid users")
+    invalid_data = Data(subtitle=plural("attempted login", len(invalid_matches)) + " from " + plural("invalid user", len(invalid_users), print_quantity=False), items=invalid_users)
+    if (len(invalid_data.items) == 1):             # if only one user, do not display no of logins for this user
+        logger.debug("Found " + str(len(invalid_matches)) + " SSH login attempts for invalid user " + invalid_users[0])
+        invalid_data.subtitle += ' ' + invalid_data.items[0]
+    invalid_data.orderbyfreq()
+    invalid_data.truncl(config.prefs['maxlist'])
+    logger.debug("Found " + str(len(invalid_matches)) + " SSH login attempts for invalid users " + str(data))
+    section.append_data(invalid_data)
+
+    logger.debug("Found {0} attempted logins for root".format(str(len(root_matches))))
+
+    section.append_data(Data(subtitle=plural("attempted login", str(len(root_matches))) + " for root"))
+
     logger.info("Finished sshd section")
     return section