logparse / parsers / sshd_journald.pyon commit rename parsers, better journald integration (e1f7605)
   1"""
   2Find number of ssh logins and authorised users (uses journald)
   3"""
   4
   5import re
   6from systemd import journal
   7
   8from logparse import config
   9from logparse.formatting import *
  10from logparse.load_parsers import Parser
  11from logparse.util import resole
  12
  13class SshdJournald(Parser):
  14
  15    def __init__(self):
  16        super().__init__()
  17        self.name = "sshd_journald"
  18        self.info = "Find number of ssh logins and authorised users "
  19                "(uses journald)"
  20
  21    def parse_log(self):
  22
  23        logger.debug("Starting sshd section")
  24        section = Section("ssh")
  25
  26        j = journal.Reader()
  27        j.this_machine()
  28        j.log_level(journal.LOG_INFO)
  29        j.add_match(_COMM="sshd")
  30        j.seek_realtime(section.period.startdate)
  31        
  32        messages = [entry["MESSAGE"] for entry in j if "MESSAGE" in entry]
  33
  34        login_data = Data("successful", [])
  35        invalid_data = Data("invalid", [])
  36        failed_data = Data("failed", [])
  37
  38        for msg in messages:
  39
  40            if "Accepted publickey" in msg:
  41                # [('user', 'ip')]
  42                entry = re.search('^.*publickey\sfor\s(\w*)\sfrom\s(\S*)', msg)
  43                user = entry.group(1)
  44                ip = entry.group(2)
  45
  46                userhost = user + '@' + resolve(ip,
  47                        fqdn=config.prefs.get("sshd", "sshd-resolve-domains"))
  48                login_data.items.append(userhost)
  49
  50            elif "Connection closed by authenticating user root" in msg:
  51                entry = re.search('^.*Connection closed by authenticating user"
  52                        " (\S+) (\S+)', msg)  # [('user', 'ip')]
  53                user = entry.group(1)
  54                ip = entry.group(2)
  55
  56                userhost = user + '@' + resolve(ip, 
  57                        fqdn=config.prefs.get("sshd", "sshd-resolve-domains"))
  58                failed_data.items.append(userhost)
  59
  60            elif "Invalid user" in msg:
  61                # [('user', 'ip')]
  62                entry = re.search('^.*Invalid user (\S+) from (\S+).*', msg)
  63                user = entry.group(1)
  64                ip = entry.group(2)
  65
  66                userhost = user + '@' + resolve(ip, 
  67                        fqdn=config.prefs.get("sshd", "sshd-resolve-domains"))
  68                invalid_data.items.append(userhost)
  69
  70        login_data.subtitle = plural("successful login", 
  71                len(login_data.items)) + " from"
  72        login_data.orderbyfreq()
  73        login_data.truncl(config.prefs.getint("logparse", "maxlist"))
  74        
  75        invalid_data.subtitle = plural("attempted login", len(invalid_data.items))
  76        invalid_data.orderbyfreq()
  77        invalid_data.subtitle +=  plural(" from invalid user", 
  78                len(invalid_data.items), False)
  79        invalid_data.truncl(config.prefs.getint("logparse", "maxlist"))
  80
  81        failed_data.subtitle = plural("failed login", 
  82                len(failed_data.items)) + " from"
  83        failed_data.orderbyfreq()
  84        failed_data.truncl(config.prefs.getint("logparse", "maxlist"))
  85
  86        section.append_data(login_data)
  87        section.append_data(invalid_data)
  88        section.append_data(failed_data)
  89
  90        logger.info("Finished sshd section")
  91        return section