#
-# 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
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')]
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