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