def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger self.logger.put(3, 'initializing selinux') rc = re.compile self.ignore = 0 self.preventing = 1 selinux_map = { rc('.*setroubleshoot\: SELinux is preventing'): self.selinux } do_selinux = int(opts.get('enable_selinux', '1')) self.regex_map = {} if do_selinux: self.regex_map.update(selinux_map) self.selinux_message_re = rc('setroubleshoot: (.*). For complete SELinux') self.selinux_title = '<font color="blue">SELinux Report</font>' self.selinux_preventing_title = '<font color="blue">SELinux Prevention Report</font>' self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th colspan="2" align="left"><h3>%s</h3></th></tr>\n%s' self.line_rep = '<tr%s><td valign="top" width="25%%">%s</td><td valign="top" width="75%%">%s</td></tr>\n' self.flip = ' bgcolor="#dddddd"'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger self.critical = 1 self.normal = 0 self.regex_map = {} self.regex_dict = {} n_dist = opts.get('notice_dist', '/etc/epylog/notice_dist.xml') n_loc = opts.get('notice_local', '/etc/epylog/notice_local.xml') enables = opts.get('enable', 'ALL') if not enables: return enlist = [] for en in enables.split(','): enlist.append(en.strip()) notice_dict = self._parse_notices(n_dist, n_loc, enlist) if not notice_dict: return self._digest_notice_dict(notice_dict) self.ip_re = re.compile('\d+.\d+.\d+.\d+') self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>\n' self.subreport_wrap = '<tr><th colspan="2" align="left"><h3>%s</h3></th></tr>\n' self.critical_title = '<font color="red">CRITICAL Notices</font>' self.normal_title = '<font color="blue">General Notices</font>' self.report_line = '<tr><td valign="top">%s</td><td valign="top" width="90%%">%s</td></tr>\n'
def __init__(self, opts, logger): ## # Do a "super-init" so the class we are subclassing gets # instantiated. # InternalModule.__init__(self) self.logger = logger ## # Convenience # rc = re.compile self.regex_map = { rc('rsyncd\[\d+\]: rsync on'): self.rsync_hosts, rc('rsyncd\[\d+\]: (?:sent|wrote)\s\S*\sbytes'): self.rsync_results } self.topcount = int(opts.get( 'report_top', 5)) #get report_top, default to 5 if not set ig_s = opts.get('ignore_hosts', '') ig_s.replace(',', ' ') self.ignore_hosts = ig_s.split(' ') # dict to store all of our data self.rsync_pid_bytes = {} self.rsync_pid_host = {} self.rsync_host_loc = rc( 'rsyncd\[(\d+)\]: rsync\son\s(\S*)\sfrom\s.*\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\)' ) self.rsync_bytes = rc( 'rsyncd\[(\d+)\]: (?:sent|wrote)\s(\d+) bytes (?:read|received)\s(\d+) bytes total size (\d+)' )
def __init__(self, opts, logger): ## # Do a "super-init" so the class we are subclassing gets # instantiated. # InternalModule.__init__(self) self.logger = logger ## # Convenience # rc = re.compile self.regex_map = { rc('rsyncd\[\d+\]: rsync on'): self.rsync_hosts, rc('rsyncd\[\d+\]: (?:sent|wrote)\s\S*\sbytes'): self.rsync_results } self.topcount = int(opts.get('report_top', 5)) #get report_top, default to 5 if not set ig_s = opts.get('ignore_hosts', '') ig_s.replace(',',' ') self.ignore_hosts = ig_s.split(' ') # dict to store all of our data self.rsync_pid_bytes = {} self.rsync_pid_host = {} self.rsync_host_loc = rc('rsyncd\[(\d+)\]: rsync\son\s(\S*)\sfrom\s.*\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\)') self.rsync_bytes = rc('rsyncd\[(\d+)\]: (?:sent|wrote)\s(\d+) bytes (?:read|received)\s(\d+) bytes total size (\d+)')
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile iptables_map = { rc('IN=\S*\sOUT=\S*\sMAC=\S*\sSRC=\S*\sDST=\S*\s'): self.iptables } ipchains_map = { rc('Packet\slog:\s.*PROTO.*'): self.ipchains } ipfilter_map = { rc('ipmon\[\d+\]:'): self.ipfilter } self.regex_map = {} if opts.get('enable_iptables', '1') == '1': self.regex_map.update(iptables_map) if opts.get('enable_ipchains', '0') == '1': self.regex_map.update(ipchains_map) if opts.get('enable_ipfilter', '0') == '1': self.regex_map.update(ipfilter_map) self.sortby = opts.get('sortby', 'packets') self.comment_line_re = rc('^\s*#') self.empty_line_re = rc('^\s*$') self.iptables_logtype_re = rc(':\s.*?(\S+?):*\sIN=') self.iptables_re = rc('SRC=(\S*)\s.*PROTO=(\S*)\s.*DPT=(\S*)') self.ipchains_re = rc('\slog:\s\S+\s(\S*).*\sPROTO=(\d+)\s(\S*):\d*\s\S*:(\d+)') self.ipfilter_re = rc('ipmon\[\d+\]:.*\s(\S+),\d+\s->\s\S+,(\d+)\sPR\s(\S+)') self.etc_services_re = rc('^(\S*)\s+(\S*)') self.trojan_list_re = rc('^(\S*)\s+(.*)') self.etc_protocols_re = rc('^(\S*)\s+(\S*)') svcdict = self._parse_etc_services() trojans = opts.get('trojan_list', '') self.systems_collapse = int(opts.get('systems_collapse', '10')) self.ports_collapse = int(opts.get('ports_collapse', '10')) self.trojan_warning_wrap = '<font color="red">%s</font>' if trojans: svcdict = self._parse_trojan_list(trojans, svcdict) self.svcdict = svcdict self.protodict = self._parse_etc_protocols() self.collapsed_ports_rep = '<font color="red">[%d ports]</font>' self.collapsed_hosts_rep = '<font color="red">[%d hosts]</font>' self.report_wrap = '<table width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th align="left" colspan="5"><h3><font color="red">%s</font></h3></th></tr>\n%s\n' self.line_rep = '<tr%s><td valign="top" width="5%%">%d</td><td valign="top" width="50%%">%s</td><td valign="top" width="15%%">%s</td><td valign="top" width="15%%">%s</td><td valign="top" width="15%%">%s</td></tr>\n' self.flip = ' bgcolor="#dddddd"'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile self.match_percentage = int(opts.get('match_percentage', '95')) self.debug_dump = int(opts.get('debug_dump', '1')) self.regex_map = {rc('^.+$'):self.expand_out_line} self.tmpdir = tempfile.mkdtemp(prefix='epylog-common-unparsed', dir='/var/tmp') self.matchfile = self.tmpdir + '/match_limited' self.matchfile_f = open(self.matchfile, 'w') self.complete = self.tmpdir + '/complete' self.complete_f = open(self.complete, 'w')
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile weed_dist = opts.get('weed_dist', '/etc/epylog/weed_dist.cf') weed_local = opts.get('weed_local', '/etc/epylog/weed.local.cf') weed_dist = weed_dist.strip() weed_local = weed_local.strip() logger.put(5, 'weed_dist=%s' % weed_dist) logger.put(5, 'weed_local=%s' % weed_local) weed = {} self.regex_map = {} self.section_re = rc('^\s*\[(.*)\]\s*$') self.comment_re = rc('^\s*#') self.empty_re = rc('^\s*$') for weedfile in [weed_dist, weed_local]: try: weed = self._read_weed(open(weedfile), weed) except: logger.put(5, 'Error reading %s' % weedfile) if not weed: return if 'REMOVE' in weed: removes = weed['REMOVE'] del weed['REMOVE'] for remove in removes: for key in weed.keys(): if remove in weed[key]: regexes = weed[key] weed[key] = [] for regex in regexes: if regex != remove: weed[key].append(regex) enable = opts.get('enable', 'ALL').split(',') if 'ADD' in weed: enable.append('ADD') if enable[0] == 'ALL': enable = weed.keys() for key in enable: key = key.strip() regexes = weed.get(key, []) for regex in regexes: try: regex_re = rc(regex) except: logger.put(5, 'Error compiling regex "%s"' % regex) continue self.regex_map[regex_re] = self.do_weed
def __init__(self, opts, logger): ## # Do a "super-init" so the class we are subclassing gets # instantiated. # InternalModule.__init__(self) self.logger = logger ## # Convenience # rc = re.compile #kojiload: Load: 7.1 Total: 192.0 Use: 3.7% (Very Light Load) self.regex_map = {rc('kojiload: Load:.*'): self.load_results} # dict to store all of our data self.loads = [] # list of kojiload percentages self.kojiloads = rc('kojiload: Load: (.*) Total: (.*) Use: (.*)\%.*')
def __init__(self, opts, logger): """ Sets up the module, naturally. """ InternalModule.__init__(self) self.logger = logger # For this mod, we'll use 5 as the default log level for general debug # statements and the like logger.put(5, 'Mod instantiated!'); # Save this for use later. (Captures usernames for login failures) self.re_mix = re.compile(r'auth: error: userdb\((?P<user>\w*),(?P<ip>\d*\.\d*\.\d*\.\d*),(?:.*)\)', re.I) self.regex_map = { # Logins re.compile(r'imap-login:\slogin:'******'pop3-login:\slogin:'******'imap\(\w*\): disconnected: logged out', re.I) : self.logout_imap, re.compile(r'pop3\(\w*\): disconnected: logged out', re.I) : self.logout_pop, # Disconnects and closed connections re.compile(r'disconnected:?\s(?:for)?\sinactivity', re.I) : self.disc_inactivity, re.compile(r'disconnected:\sinternal\serror', re.I) : self.disc_interr, re.compile(r'disconnected\sby\sserver', re.I) : self.disc_server, re.compile(r'disconnected\sby\sclient', re.I) : self.disc_client, re.compile(r'disconnected\sin\sidle', re.I) : self.disc_idle, re.compile(r'disconnected\sin\sappend', re.I) : self.disc_append, re.compile(r'imap\(\w*\):\sconnection\sclosed', re.I) : self.close_imap, re.compile(r'pop3\(\w*\):\sconnection\sclosed', re.I) : self.close_pop, # Other things: failures, etc. re.compile(r'authenticated user not found', re.I) : self.user_notfound, self.re_mix : self.user_mixedcase, re.compile(r'auth\sfail(?:ed)?', re.I) : self.auth_fail, re.compile(r'no\sauth\sattempt', re.I) : self.no_auth_atmpt, re.compile(r'(?:too\smany)?\s?invalid\simap', re.I) : self.invalid_imap, re.compile(r'(?:disallowed)?\s?plaintext\sauth', re.I) : self.disallow_ptxt, re.compile(r'\seof\s', re.I) : self.unex_eof, # Lines we choose to forcefully ignore re.compile(r'director:\serror', re.I) : self.ignore }
def __init__(self, opts, logger): ## # Do a "super-init" so the class we are subclassing gets # instantiated. # InternalModule.__init__(self) self.logger = logger ## # Convenience # rc = re.compile #kojiload: Load: 7.1 Total: 192.0 Use: 3.7% (Very Light Load) self.regex_map = { rc('kojiload: Load:.*'): self.load_results } # dict to store all of our data self.loads = [] # list of kojiload percentages self.kojiloads = rc('kojiload: Load: (.*) Total: (.*) Use: (.*)\%.*')
def __init__(self, opts, logger): ## # Do a "super-init" so the class we are subclassing gets # instantiated. # InternalModule.__init__(self) self.logger = logger ## # Convenience # rc = re.compile ## # This map specifies the regexes and the handlers for them. # ===> THIS MAP MUST EXIST AND BE NAMED "regex_map" <== # The format is as follows: #self.regex_map = { # rc('STRING TO MATCH'): self.handler_func, # rc('ANOTHER STRING'): self.other_handler_func # } # self.regex_map = {}
def __init__(self, opts, logger): ## # Do a "super-init" so the class we are subclassing gets # instantiated. # InternalModule.__init__(self) self.logger = logger ## # Convenience # rc = re.compile ## # This map specifies the regexes and the handlers for them. # ===> THIS MAP MUST EXIST AND BE NAMED "regex_map" <== # The format is as follows: #self.regex_map = { # rc('STRING TO MATCH'): self.handler_func, # rc('ANOTHER STRING'): self.other_handler_func # } # self.regex_map = { }
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile self.msg = 1 self.error = 2 self.regex_map = { rc('ntpd.*:\ssynchronized\sto.*'): self.ntp_synchronized, rc('kernel time sync status change'): self.ntp_status_change } self.ntp_synchronized_re = rc('ntpd\[\d+\]:\ssynchronized\sto\s*(\S*),\s*(.*)') self.ntp_status_change_re = rc('ntpd\[\d+\]:\skernel\stime\ssync\sstatus\schange\s(\d+)') self.ntp_message_title = '<font color="blue">Message</font>' self.report_wrap = '<table width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th align="left" colspan="3"><h3>%s</h3></th></tr>\n%s\n' self.line_rep = '<tr%s><td valign="top" width="15%%">%s</td><td valign="top" width="15%%">%s</td><td width="70%%">%s</td></tr>\n' self.flip = ' bgcolor="#dddddd"'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile self.prefailure = 2 self.usage = 1 self.regex_map = { rc('smartd\[.*\]: Device:.*, SMART Usage Attribute:'): self.usage_attribute, rc('smartd\[.*\]: Device:.*, SMART Prefailure Attribute:'): self.prefailure_attribute } self.prefailure_attribute_re = rc('smartd\[.*\]:\s*Device:\s*(.*),\s*SMART\s*Prefailure\s*Attribute:\s*\d+\s*(\S+)\s*changed\s*from') self.usage_attribute_re = rc('smartd\[.*\]:\s*Device:\s*(.*),\s*SMART\s*Usage\s*Attribute:\s*\d+\s*(\S+)\s*changed\s*from') self.smart_prefailure_title = '<font color=#FF9900>Prefailure Message</font>' self.smart_usage_title = '<font color="blue">Usage Message</font>' self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>\n' self.subreport_wrap = '<tr><th colspan="2" align="left"><h3>%s</h3></th></tr>\n' self.report_line = '<tr><td valign="top">%s</td><td valign="top" width="90%%">%s</td></tr>\n'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger self.logger.put(2, 'initializing sudo') rc = re.compile self.ignore = 0 self.open = 1 self.not_allowed = 2 sudo_map = { rc('.*sudo\:\s+\S+\s\:\sTTY'): self.sudo, rc('.*sudo:'): self.sudo_na } do_sudo = int(opts.get('enable_sudo', '1')) self.regex_map = {} if do_sudo: self.regex_map.update(sudo_map) self.sudo_user_name_re = rc('sudo:\s*(\S*)') self.sudo_as_user_re = rc('.*USER=(\S*)\s\;\sCOMMAND') self.sudo_command_name_re = rc('.*COMMAND=(.*)') self.sudo_error_message_re = rc('sudo:\s*\S*\s+:\s+(.*)\s+;\s+TTY') self.sudo_title = '<font color="blue">User Sudo Report</font>' self.sudo_open_title = '<font color="blue">User Sudo Report</font>' self.sudo_not_allowed_title = '<font color="red">Disallowed Sudo Commands</font>' self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th colspan="5" align="left"><h3>%s</h3></th></tr>\n%s' self.subreport_na_wrap = '<tr><th colspan="5" align="left"><h3>%s</h3></th></tr>\n%s' self.line_rep = '<tr%s><td valign="top" width="15%%">%s</td><td valign="top" width="45%%" colspan="2">%s</td><td width="25%%">%s</td><td width="15%%">%s</td></tr>\n' self.line_rep_na = '<tr%s><td valign="top" width="15%%">%s</td><td valign="top" width="30%%">%s</td><td valign="top" width="15%%">%s</td><td width="25%%">%s</td><td width="15%%">%s</td></tr>\n' self.flip = ' bgcolor="#dddddd"'
def __init__(self, opts): InternalModule.__init__(self) logger.debug('initializing sudo') rc = re.compile self.ignore = 0 self.open = 1 self.not_allowed = 2 sudo_map = { rc('.*sudo\:\s+\S+\s\:\sTTY'): self.sudo, rc('.*sudo:'): self.sudo_na } do_sudo = int(opts.get('enable_sudo', '1')) self.regex_map = {} if do_sudo: self.regex_map.update(sudo_map) self.sudo_user_name_re = rc('sudo:\s*(\S*)') self.sudo_as_user_re = rc('.*USER=(\S*)\s\;\sCOMMAND') self.sudo_command_name_re = rc('.*COMMAND=(.*)') self.sudo_error_message_re = rc('sudo:\s*\S*\s+:\s+(.*)\s+;\s+TTY') self.sudo_title = '<font color="blue">User Sudo Report</font>' self.sudo_open_title = '<font color="blue">User Sudo Report</font>' self.sudo_not_allowed_title = '<font color="red">Disallowed Sudo Commands</font>' self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th colspan="5" align="left"><h3>%s</h3></th></tr>\n%s' self.subreport_na_wrap = '<tr><th colspan="5" align="left"><h3>%s</h3></th></tr>\n%s' self.line_rep = '<tr%s><td valign="top" width="15%%">%s</td><td valign="top" width="45%%" colspan="2">%s</td><td width="25%%">%s</td><td width="15%%">%s</td></tr>\n' self.line_rep_na = '<tr%s><td valign="top" width="15%%">%s</td><td valign="top" width="30%%">%s</td><td valign="top" width="15%%">%s</td><td width="25%%">%s</td><td width="15%%">%s</td></tr>\n' self.flip = ' bgcolor="#dddddd"'
def __init__(self, opts): InternalModule.__init__(self) rc = re.compile self.ignore = 0 self.installed = 1 self.updated = 2 self.erased = 3 yum_map = { rc('yum\S+: Installed:'): self.pkg_installed, rc('yum\S+: Updated:'): self.pkg_updated, rc('yum\S+: Erased:'): self.pkg_erased } do_yum = int(opts.get('enable_yum', '1')) self.regex_map = {} if do_yum: self.regex_map.update(yum_map) self.name_re = rc('profile\: \[(.*)\]') self.installed_name_re = rc('Installed\: (.*)') self.updated_name_re = rc('Updated\: (.*)') self.erased_name_re = rc('Erased\: (.*)') self.yum_title = '<font color="blue">Yum Changes Report</font>' self.yum_installed_title = '<font color="blue">Packages Installed</font>' self.yum_updated_title = '<font color="blue">Packages Updated</font>' self.yum_erased_title = '<font color="blue">Packages Erased</font>' self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th colspan="2" align="left"><h3>%s</h3></th></tr>\n%s' self.line_rep = '<tr%s><td valign="top" width="25%%">%s</td><td valign="top" width="75%%">%s</td></tr>\n' self.flip = ' bgcolor="#dddddd"'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile self.regex_map = { rc('spamd\[\d+\]: clean message'): self.spamd, rc('spamd\[\d+\]: identified spam'): self.spamd } self.top = int(opts.get('report_top', '10')) self.thold = int(opts.get('spam_threshold', '5')) sort_by = opts.get('sort_by', 'most spammed') if sort_by == 'most spammed': self.sort = 'spammed' else: self.sort = 'messages' self.spamd_re = rc('\s\((.*?)/.*for (\S*?):.*in (\S*).*, (\d+) bytes') self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>\n' self.subreport_wrap = '<tr><th colspan="4" align="left"><h3>%s</h3></th></tr>\n' self.total_title = '<font color="blue">Total stats</font>' self.users_title = '<font color="blue">Top %d ranking users</font>' % self.top self.score_rep = '%.1f (%d/%d)' self.report_line = '<tr%s><td valign="top">%s</td><td valign="top">%s</td><td valign="top">%s</td><td valign="top">%s</td></tr>\n' self.flip = ' bgcolor="#dddddd"'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile postfix_map = { rc('postfix/smtpd\[\d+\]:\s\S*:'): self.postfix_smtpd, rc('postfix/.*qmgr\[\d+\]:\s\S*:'): self.postfix_qmgr, rc('postfix/local\[\d+\]:\s\S*:'): self.postfix_local, rc('postfix/smtp\[\d+\]:\s\S*:\sto='): self.postfix_smtp } sendmail_map = { rc('sendmail\['): self.sendmail } qmail_map = { rc('qmail:\s\d+.\d+\sinfo\smsg'): self.qmail_infomsg, rc('qmail:\s\d+.\d+\sstarting\sdelivery'): self.qmail_startdev, rc('qmail:\s\d+.\d+\sdelivery'): self.qmail_delivery, rc('qmail:\s\d+.\d+\sbounce\smsg\s\d+'): self.qmail_bounce } ssmtp_map = { rc('sSMTP\[\d+\]:\sSent\smail'): self.ssmtp_sent } do_postfix = int(opts.get('enable_postfix', '0')) do_sendmail = int(opts.get('enable_sendmail', '1')) do_qmail = int(opts.get('enable_qmail', '0')) do_ssmtp = int(opts.get('enable_ssmtp', '1')) self.regex_map = {} if do_postfix: self.regex_map.update(postfix_map) if do_sendmail: self.regex_map.update(sendmail_map) if do_qmail: self.regex_map.update(qmail_map) if do_ssmtp: self.regex_map.update(ssmtp_map) self.toplim = int(opts.get('top_report_limit', '5')) self.postfix_ident_re = rc('\[\d+\]:\s*([A-Z0-9]*):') self.postfix_smtpd_re = rc('client=\S*\[(\S*)\]') self.postfix_qmgr_re = rc('from=(\S*),.*size=(\d*),.*nrcpt=(\d*)') self.postfix_local_re = rc('to=(\S*),.*status=(\S*)\s\((.*)\)') self.postfix_smtp_re = rc('to=(\S*),.*status=(\S*)') self.sendmail_ident_re = rc('sendmail\[\d+\]:\s(.*?):') self.sendmail_fromline_re = rc('from=(.*?),.*size=(\d+),.*relay=(.*)') self.sendmail_ctladdr_re = rc('to=(\"\|.*?),\sctladdr=(\S+).*stat=(\w+)') self.sendmail_toline_re = rc('to=(.*?),.*stat=(\w+)') self.sendmail_from_re = rc('(<.*?>)') self.sendmail_relay_re = rc('(.*?)\s\[(\S*)\]') self.qmail_ident_re = rc('qmail:\s(\d+)') self.qmail_delid_re = rc('delivery\s(\d+):') self.qmail_infoline_re = rc('bytes\s(\d+)\sfrom\s(<.*?>)') self.qmail_startdev_re = rc('to\s\S+\s(\S+)') self.qmail_delivery_re = rc('delivery\s\d+:\s(\S+):') self.ssmtp_sent_re = rc('sSMTP\[\d+\]:\sSent\smail\sfor\s(\S+)\s\((\d+).*\)\suid=(\d+)\susername=(\S+)\soutbytes=(\d+)') self.procmail_re = rc('/procmail') self.bounce = 0 self.success = 1 self.warning = 2 self.procmail = 3 self.delidref = 4 self.delidid = 5 self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th colspan="2" align="left"><h3><font color="blue">%s</font></h3></th></tr>\n' self.report_line = '<tr><td valign="top" align="right">%s</td><td valign="top" width="90%%">%s</td></tr>\n'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger self.opts = opts rc = re.compile self.ignore = 0 self.open = 1 self.failure = 2 self.root_open = 11 self.root_failure = 12 ## # Ignore crond(pam_unix), to lessen the noise # self.pam_ignore = ['crond'] self.xinetd_ignore = [] ## # PAM reports # pam_map = { rc('\(pam_unix\)\S*:.*authentication\s*failure'): self.pam_failure, rc('\(pam_unix\)\S*:\ssession\sopened\sfor'): self.pam_open, rc('\(pam_unix\)\S*:\sbad\susername'): self.pam_baduser, rc('\(pam_unix\)\S*:\sauth\scould\snot'): self.pam_chelper_failure, rc('pam_krb5\S*:\s\S+\ssucceeds\sfor'): self.pam_krb5_open, rc('pam_krb5\S*:\s\S+\sfails\sfor'): self.pam_krb5_failure } ## # XINETD reports # xinetd_map = { rc('xinetd\S*: START:'): self.xinetd_start } ## # SSH reports # sshd_map = { rc('sshd\[\S*: Accepted'): self.sshd_open, rc('sshd\[\S*: Failed'): self.sshd_failure } ## # IMAPD and IPOP3D # uw_imap_map = { rc('imapd\[\S*: Login\sfail'): self.uw_imap_failure, rc('imapd\[\S*: Authenticated\suser'): self.uw_imap_open, rc('imapd\[\S*: Login\suser'): self.uw_imap_open, rc('ipop3d\[\S*: Login\sfail'): self.uw_imap_failure, rc('ipop3d\[\S*: Login\suser'): self.uw_imap_open, rc('ipop3d\[\S*: Auth\suser'): self.uw_imap_open } ## # IMP # imp_map = { rc('IMP\[\S*: Login'): self.imp2_open, rc('IMP\[\S*: FAILED'): self.imp2_failure, rc('HORDE\[\S*\s*\[imp\] Login'): self.imp3_open, rc('HORDE\[\S*\s*\[imp\] FAILED'): self.imp3_failure } ## # DOVECOT # dovecot_map = { rc('imap-login:\sLogin:\s'): self.dovecot_open, rc('imap-login:\sAborted\slogin\s'): self.dovecot_failure } ## # Courier-IMAP # courier_map = { rc('\sLOGIN,\suser=\S+,\sip=\[\S+\]'): self.courier_open, rc('\sLOGIN FAILED,\sip=\[\S+\]'): self.courier_failure } ## # Cyrus-IMAP # cyrus_map = { rc('imapd\[\S*: login:'******'pop3d\[\S*: login:'******'imapd\[\S*: badlogin:'******'pop3d\[\S*: badlogin:'******'apop\[\S*:\s\S+\sat\s.*\s\(\S*\):\s-ERR\s\[AUTH\]'): self.qpopper_failure, rc('apop\[\S*:\s\S+\sat\s.*\s\(\S*\):\s-ERR\s\[IN-USE\]'): self.qpopper_failure, rc('apop\[\S*:\s\(\S*\)\sPOP\slogin'): self.qpopper_open } ## # ProFTPD # proftpd_map = { rc('proftpd\[\S*:.*USER.*Login successful'): self.proftpd_open, rc('proftpd\[\S*:.*no such user found'): self.proftpd_failure, rc('proftpd\[\S*:.*Login failed'): self.proftpd_failure } ## # Systemd-Logind # systemd_map = { rc('systemd-logind\[\S*: New user \S+ logged in'): self.systemd_open, rc('systemd-logind\[\S*: New session \d+ of user \S'): self.systemd_open } regex_map = {} if opts.get('enable_pam', "1") != "0": regex_map.update(pam_map) if opts.get('enable_xinetd', "1") != "0": regex_map.update(xinetd_map) if opts.get('enable_sshd', "1") != "0": regex_map.update(sshd_map) self.pam_ignore.append('sshd') if opts.get('enable_uw_imap', "0") != "0": regex_map.update(uw_imap_map) self.xinetd_ignore.append('imaps') if opts.get('enable_imp', "0") != "0": regex_map.update(imp_map) if opts.get('enable_dovecot',"0") != "0": regex_map.update(dovecot_map) if opts.get('enable_courier',"0") != "0": regex_map.update(courier_map) if opts.get('enable_cyrus', "0") != "0": regex_map.update(cyrus_map) if opts.get('enable_qpopper',"0") != "0": regex_map.update(qpopper_map) if opts.get('enable_proftpd',"0") != "0": regex_map.update(proftpd_map) self.pam_ignore.append('ftp') self.xinetd_ignore.append('ftp') if opts.get('enable_systemd', "1") != "0": regex_map.update(systemd_map) self.safe_domains = [] safe_domains = opts.get('safe_domains', '.*') self.systems_collapse = int(opts.get('systems_collapse', '10')) for domain in safe_domains.split(','): domain = domain.strip() if domain: try: domain_re = rc(domain) self.safe_domains.append(domain_re) except: 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\)') self.pam_failure_re = rc('.*\slogname=(\S*).*\srhost=(\S*)') self.pam_failure_user_re = rc('\suser=(\S*)') self.pam_open_re = rc('.*for user (\S+) by\s(\S*)\s*\(uid=(\S+)\)') self.pam_failure_more_re = rc('(\S+)\smore\sauthentication\sfailures') self.pam_baduser_re = rc('\sbad\susername\s\[(.*)\]') self.pam_chelper_re = rc('password\sfor\s\[(.*)\]') self.pam_krb5_re = rc("^(\S+?)\[*\d*\]*:\spam_krb5\S*:\sauth.*\sfor\s`(\S+)'") self.xinetd_start_re = rc('START:\s*(\S*)\s') self.sshd_open_ruser_re = rc('Accepted\s(\S*)\sfor\s(\S*)\sfrom\s(\S*)\sport\s\d*\sruser\s(\S*)\s*(\S*)') self.sshd_open_re = rc('Accepted\s(\S*)\sfor\s(\S*)\sfrom\s(\S*)\sport\s\d+\s*(\S*)') self.sshd_fail_re = rc('Failed\s(\S*)\sfor.*\s(\S+)\sfrom\s(\S*)\sport\s\d*\s*(\S*)') self.uw_imap_fail_re = rc('auth=(.*)\shost=.*\[(\S*)\]') self.uw_imap_open_re = rc('user=(.*)\shost=.*\[(\S*)\]') self.uw_imap_service_re = rc('^(\S*)\[\d*\]:') self.dovecot_open_re = rc('Login:\s(\S+)\s\[(\S+)\]') self.dovecot_failure_re = rc('Aborted\slogin\s\[(\S+)\]') self.courier_open_re = rc('^(\S+?):.*\suser=(\S+),\sip=\[(\S+)\]') self.courier_failure_re = rc('^(\S+?):.*,\sip=\[(\S+)\]') self.imp2_open_re = rc('Login\s(\S*)\sto\s(\S*):\S*\sas\s(\S*)') self.imp2_fail_re = rc('FAILED\s(\S*)\sto\s(\S*):\S*\sas\s(\S*)') self.imp3_open_re = rc('success\sfor\s(\S*)\s\[(\S*)\]\sto\s\{(\S*):') self.imp3_fail_re = rc('LOGIN\s(\S*)\sto\s(\S*):\S*\sas\s(\S*)') self.proftpd_open_re = rc('proftpd\[\S*:.*\[(\S+)\].*USER\s(.*):\sLogin\ssuccessful') self.proftpd_failure_re = rc('proftpd\[\S*:.*\[(\S+)\].*USER\s([^:\s]*)') self.qpopper_open_re = rc('user "(.*)" at \(.*\)\s(\S*)') self.qpopper_fail_re = rc(':\s(.*)\sat\s(\S*)') self.cyrus_open_re = rc('login:.*\[(\S*)\]\s(\S*)\s') self.cyrus_fail_re = rc('badlogin:.*\[(\S*)\]\s\S\s(\S*)\sSASL') self.cyrus_service_re = rc('^(\S*)\[\d*\]:') self.systemd_new_user_re = rc('New\suser\s(\S+)\slogged\sin\.') self.systemd_new_session_re = rc('New\ssession\s\d+\sof\suser\s(\S+)\.') self.sshd_methods = {'password': '******', 'publickey': 'pk', 'rhosts-rsa': 'rsa', 'rsa': 'rsa', 'hostbased': 'host', 'none': 'none'} self.report_wrap = '<table width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th align="left" colspan="3"><h3>%s</h3></th></tr>\n%s\n' self.root_failures_title = '<font color="red">ROOT FAILURES</font>' self.root_logins_title = '<font color="blue">ROOT Logins</font>' self.user_failures_title = '<font color="red">User Failures</font>' self.user_logins_title = '<font color="blue">User Logins</font>' self.untrusted_host = '%(system)s::<font color="red">%(rhost)s</font>' self.flip = ' bgcolor="#dddddd"' self.line_rep = '<tr%s><td valign="top" width="15%%">%s</td><td valign="top" width="15%%">%s</td><td width="70%%">%s</td></tr>\n' self.collapsed_rep = '%s <font color="red">[%s more skipped]</font>'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger self.opts = opts rc = re.compile self.ignore = 0 self.open = 1 self.failure = 2 self.root_open = 11 self.root_failure = 12 self.pam_ignore = [] self.xinetd_ignore = [] self.logins_db = opts.get('loginsdb_path', '/var/lib/epylog/logins_db.sqlite') # where to keep the loginsdb self.time_fuzz = int(opts.get('time_fuzz', 60)) # how much to fuzz the time in minutes (default 60m) remove_older_than = int(opts.get('remove_older_than', 14)) # time in days to start remove from the db self.oldest_to_keep = time.time() - (remove_older_than*86400) if remove_older_than == '0': # if it is zero then don't delete any, ever - hah your funeral self.oldest_to_keep = None ig_users = opts.get('ignore_users', '') ig_users.replace(',',' ') self.ignore_users = ig_users.split(' ') self.db_cx = None ## # PAM reports # pam_map = { rc('\(pam_unix\)\S*:.*authentication\s*failure'): self.pam_failure, rc('\(pam_unix\)\S*:\ssession\sopened\sfor'): self.pam_open, rc('\(pam_unix\)\S*:\sbad\susername'): self.pam_baduser, rc('\(pam_unix\)\S*:\sauth\scould\snot'): self.pam_chelper_failure, rc('pam_krb5\S*:\s\S+\ssucceeds\sfor'): self.pam_krb5_open, rc('pam_krb5\S*:\s\S+\sfails\sfor'): self.pam_krb5_failure } ## # XINETD reports # xinetd_map = { rc('xinetd\S*: START:'): self.xinetd_start } ## # SSH reports # sshd_map = { rc('sshd\[\S*: Accepted'): self.sshd_open, rc('sshd\[\S*: Failed'): self.sshd_failure } ## # IMAPD and IPOP3D # uw_imap_map = { rc('imapd\[\S*: Login\sfail'): self.uw_imap_failure, rc('imapd\[\S*: Authenticated\suser'): self.uw_imap_open, rc('imapd\[\S*: Login\suser'): self.uw_imap_open, rc('ipop3d\[\S*: Login\sfail'): self.uw_imap_failure, rc('ipop3d\[\S*: Login\suser'): self.uw_imap_open, rc('ipop3d\[\S*: Auth\suser'): self.uw_imap_open } ## # IMP # imp_map = { rc('IMP\[\S*: Login'): self.imp2_open, rc('IMP\[\S*: FAILED'): self.imp2_failure, rc('HORDE\[\S*\s*\[imp\] Login'): self.imp3_open, rc('HORDE\[\S*\s*\[imp\] FAILED'): self.imp3_failure } ## # DOVECOT # dovecot_map = { rc('imap-login:\sLogin:\s'): self.dovecot_open, rc('imap-login:\sAborted\slogin\s'): self.dovecot_failure } ## # Courier-IMAP # courier_map = { rc('\sLOGIN,\suser=\S+,\sip=\[\S+\]'): self.courier_open, rc('\sLOGIN FAILED,\sip=\[\S+\]'): self.courier_failure } ## # Cyrus-IMAP # cyrus_map = { rc('imapd\[\S*: login:'******'pop3d\[\S*: login:'******'imapd\[\S*: badlogin:'******'pop3d\[\S*: badlogin:'******'apop\[\S*:\s\S+\sat\s.*\s\(\S*\):\s-ERR\s\[AUTH\]'): self.qpopper_failure, rc('apop\[\S*:\s\S+\sat\s.*\s\(\S*\):\s-ERR\s\[IN-USE\]'): self.qpopper_failure, rc('apop\[\S*:\s\(\S*\)\sPOP\slogin'): self.qpopper_open } ## # ProFTPD # proftpd_map = { rc('proftpd\[\S*:.*USER.*Login successful'): self.proftpd_open, rc('proftpd\[\S*:.*no such user found'): self.proftpd_failure, rc('proftpd\[\S*:.*Login failed'): self.proftpd_failure } regex_map = {} if opts.get('enable_pam', "1") != "0": regex_map.update(pam_map) if opts.get('enable_xinetd', "1") != "0": regex_map.update(xinetd_map) if opts.get('enable_sshd', "1") != "0": regex_map.update(sshd_map) self.pam_ignore.append('sshd') if opts.get('enable_uw_imap', "0") != "0": regex_map.update(uw_imap_map) self.xinetd_ignore.append('imaps') if opts.get('enable_imp', "0") != "0": regex_map.update(imp_map) if opts.get('enable_dovecot',"0") != "0": regex_map.update(dovecot_map) if opts.get('enable_courier',"0") != "0": regex_map.update(courier_map) if opts.get('enable_cyrus', "0") != "0": regex_map.update(cyrus_map) if opts.get('enable_qpopper',"0") != "0": regex_map.update(qpopper_map) if opts.get('enable_proftpd',"0") != "0": regex_map.update(proftpd_map) self.pam_ignore.append('ftp') self.xinetd_ignore.append('ftp') self.safe_domains = [] safe_domains = opts.get('safe_domains', '.*') for domain in safe_domains.split(','): domain = domain.strip() if domain: try: domain_re = rc(domain) self.safe_domains.append(domain_re) except: logger.put(0, 'Error compiling domain regex: %s' % domain) logger.put(0, 'Check config for Logins module!') self.regex_map = regex_map self.pam_service_re = rc('(\S+)\(pam_unix\)') self.pam_failure_re = rc('.*\slogname=(\S*).*\srhost=(\S*)') self.pam_failure_user_re = rc('\suser=(\S*)') self.pam_open_re = rc('.*for user (\S+) by\s(\S*)\s*\(uid=(\S+)\)') self.pam_failure_more_re = rc('(\S+)\smore\sauthentication\sfailures') self.pam_baduser_re = rc('\sbad\susername\s\[(.*)\]') self.pam_chelper_re = rc('password\sfor\s\[(.*)\]') self.pam_krb5_re = rc("^(\S+?)\[*\d*\]*:\spam_krb5\S*:\sauth.*\sfor\s`(\S+)'") self.xinetd_start_re = rc('START:\s*(\S*)\s') self.sshd_open_ruser_re = rc('Accepted\s(\S*)\sfor\s(\S*)\sfrom\s(\S*)\sport\s\d*\sruser\s(\S*)\s*(\S*)') self.sshd_open_re = rc('Accepted\s(\S*)\sfor\s(\S*)\sfrom\s(\S*)\sport\s\d+\s*(\S*)') self.sshd_fail_re = rc('Failed\s(\S*)\sfor.*\s(\S+)\sfrom\s(\S*)\sport\s\d*\s*(\S*)') self.uw_imap_fail_re = rc('auth=(.*)\shost=.*\[(\S*)\]') self.uw_imap_open_re = rc('user=(.*)\shost=.*\[(\S*)\]') self.uw_imap_service_re = rc('^(\S*)\[\d*\]:') self.dovecot_open_re = rc('Login:\s(\S+)\s\[(\S+)\]') self.dovecot_failure_re = rc('Aborted\slogin\s\[(\S+)\]') self.courier_open_re = rc('^(\S+?):.*\suser=(\S+),\sip=\[(\S+)\]') self.courier_failure_re = rc('^(\S+?):.*,\sip=\[(\S+)\]') self.imp2_open_re = rc('Login\s(\S*)\sto\s(\S*):\S*\sas\s(\S*)') self.imp2_fail_re = rc('FAILED\s(\S*)\sto\s(\S*):\S*\sas\s(\S*)') self.imp3_open_re = rc('success\sfor\s(\S*)\s\[(\S*)\]\sto\s\{(\S*):') self.imp3_fail_re = rc('LOGIN\s(\S*)\sto\s(\S*):\S*\sas\s(\S*)') self.proftpd_open_re = rc('proftpd\[\S*:.*\[(\S+)\].*USER\s(.*):\sLogin\ssuccessful') self.proftpd_failure_re = rc('proftpd\[\S*:.*\[(\S+)\].*USER\s([^:\s]*)') self.qpopper_open_re = rc('user "(.*)" at \(.*\)\s(\S*)') self.qpopper_fail_re = rc(':\s(.*)\sat\s(\S*)') self.cyrus_open_re = rc('login:.*\[(\S*)\]\s(\S*)\s') self.cyrus_fail_re = rc('badlogin:.*\[(\S*)\]\s\S\s(\S*)\sSASL') self.cyrus_service_re = rc('^(\S*)\[\d*\]:') self.sshd_methods = {'password': '******', 'publickey': 'pk', 'rhosts-rsa': 'rsa', 'rsa': 'rsa', 'hostbased': 'host', 'none': 'none'} self.report_wrap = '<table width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th align="left" colspan="3"><h3>%s</h3></th></tr>\n%s\n' self.root_failures_title = '<font color="red">ROOT FAILURES</font>' self.root_logins_title = '<font color="blue">ROOT Logins</font>' self.user_failures_title = '<font color="red">User Failures</font>' self.user_logins_title = '<font color="blue">User Logins</font>' self.untrusted_host = '%(system)s::<font color="red">%(rhost)s</font>' self.flip = ' bgcolor="#dddddd"' self.line_rep = '<tr%s><td valign="top" width="15%%">%s</td><td valign="top" width="15%%">%s</td><td width="70%%">%s</td></tr>\n'
def __init__(self, opts, logger): InternalModule.__init__(self) self.logger = logger rc = re.compile postfix_map = { rc('postfix/smtpd\[\d+\]:\s\S*:'): self.postfix_smtpd, rc('postfix/n*qmgr\[\d+\]:\s\S*:'): self.postfix_qmgr, rc('postfix/local\[\d+\]:\s\S*:'): self.postfix_local, rc('postfix/smtp\[\d+\]:\s\S*:\sto='): self.postfix_smtp } sendmail_map = { rc('sendmail\['): self.sendmail } qmail_map = { rc('qmail:\s\d+.\d+\sinfo\smsg'): self.qmail_infomsg, rc('qmail:\s\d+.\d+\sstarting\sdelivery'): self.qmail_startdev, rc('qmail:\s\d+.\d+\sdelivery'): self.qmail_delivery, rc('qmail:\s\d+.\d+\sbounce\smsg\s\d+'): self.qmail_bounce } do_postfix = int(opts.get('enable_postfix', '0')) do_sendmail = int(opts.get('enable_sendmail', '1')) do_qmail = int(opts.get('enable_qmail', '0')) self.regex_map = {} if do_postfix: self.regex_map.update(postfix_map) if do_sendmail: self.regex_map.update(sendmail_map) if do_qmail: self.regex_map.update(qmail_map) self.toplim = int(opts.get('top_report_limit', '5')) self.postfix_ident_re = rc('\[\d+\]:\s*([A-Z0-9]*):') self.postfix_smtpd_re = rc('client=\S*\[(\S*)\]') self.postfix_qmgr_re = rc('from=(\S*),.*size=(\d*)') self.postfix_local_re = rc('to=(\S*),.*status=(\S*)\s\((.*)\)') self.postfix_smtp_re = rc('to=(\S*),.*status=(\S*)') self.sendmail_ident_re = rc('sendmail\[\d+\]:\s(.*?):') self.sendmail_fromline_re = rc('from=(.*?),.*size=(\d+),.*relay=(.*)') self.sendmail_ctladdr_re = rc('to=(\"\|.*?),\sctladdr=(\S+).*stat=(\w+)') self.sendmail_toline_re = rc('to=(.*?),.*stat=(\w+)') self.sendmail_from_re = rc('(<.*?>)') self.sendmail_relay_re = rc('(.*?)\s\[(\S*)\]') self.qmail_ident_re = rc('qmail:\s(\d+)') self.qmail_delid_re = rc('delivery\s(\d+):') self.qmail_infoline_re = rc('bytes\s(\d+)\sfrom\s(<.*?>)') self.qmail_startdev_re = rc('to\s\S+\s(\S+)') self.qmail_delivery_re = rc('delivery\s\d+:\s(\S+):') self.procmail_re = rc('/procmail') self.bounce = 0 self.success = 1 self.warning = 2 self.procmail = 3 self.delidref = 4 self.delidid = 5 self.report_wrap = '<table border="0" width="100%%" rules="cols" cellpadding="2">%s</table>' self.subreport_wrap = '<tr><th colspan="2" align="left"><h3><font color="blue">%s</font></h3></th></tr>\n' self.report_line = '<tr><td valign="top" align="right">%s</td><td valign="top" width="90%%">%s</td></tr>\n'