def checkIPenabled(ip): _prefs = Prefs() _deny = _prefs.getGeneralPref('HOSTS_DENY').split(",") _allow = _prefs.getGeneralPref('HOSTS_ALLOW').split(",") # HOSTS_ALLOW is privileged to HOSTS_DENY for net in _allow: if ipaddress.ip_address(ip) in ipaddress.ip_network(net): #print("IP apriori allowed -> {}".format(ip)) return 1 for net in _deny: if ipaddress.ip_address(ip) in ipaddress.ip_network(net): #print("IP apriori denied -> {}".format(ip)) return 0 return 2
def __init__(self, q = queue.Queue(10), loop_time = 1.0/60): print("DB Watcher initialized") super(DbWatcher, self).__init__() self.name = "DB Watcher" self.q = q self.db = Database() self.timeout = loop_time # Get DB_EVENT_CHECK_SLEEP value from config file self._sleeptime = Prefs().getGeneralPref('DB_EVENT_CHECK_SLEEP') self.isTimed = False pass
def __init__(self, rule_list, name = "", retroactive = False, q = queue.Queue(10), loop_time = 1.0/60): print("Journald watcher [{}] initialized".format(name)) super(Journald_watcher, self).__init__() self._prefs = Prefs() self.db = Database() self.name = name self.q = q self.rules = rule_list #print(self.rules) self.retroactive = retroactive self.j = journal.Reader() self.j.log_level(journal.LOG_INFO) try: self.j.add_match(_SYSTEMD_UNIT="{}.service".format(rule_list[0].getNameOfBelongService())) except: return if self.retroactive == False: self.j.seek_tail() self.j.get_previous() pass
def stop(self, removeLogfile=False, removeSocketFile=True): # Remove logfile if removeLogfile == True: try: os.remove(logfile) except: pass if removeSocketFile == True: try: sock_path = Prefs().getGeneralPref('SOCKET_PATH') os.remove(sock_path) except Exception: pass # get the pid from the pidfile try: pf = open(self.pidfile, 'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None #return 1 if not pid: message = "pidfile %s does not exist. GGH not running?\n" message += "Start GGH first with `{} --start`".format(sys.argv[0]) sys.stderr.write(message % self.pidfile) return 1# not an error in a restart # Try to kill the daemon process try: while 1: os.kill(pid, SIGTERM) print("Trying to SIGTERM pid {}".format(pid)) time.sleep(0.1) except OSError as err: err = str(err) if err.find("No such process") > 0: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: print(str(err)) sys.exit(1)
def run(self): print(datetime.datetime.today()) print("GoofyGoHome - launching") sock_path = Prefs().getGeneralPref('SOCKET_PATH') # start DB watcher thread dbWatcher = DbWatcher() dbWatcher.start() #dbWatcher.onThread(dbWatcher.checkEventsNow) # start communication server commServer = comm_server.CommunicationServer(Daemon.getInstance(), dbWatcher) t = threading.Thread(target=commServer.start, args=(sock_path, True), name="comm_server") t.start() # We don't start this immediately (with value 0) # in order to prevent a havoc s = sched.scheduler(time.time, time.sleep) s.enter(2, 1, watchJournalFiles, (s,)) s.run()
class Journald_watcher(Thread): def __init__(self, rule_list, name = "", retroactive = False, q = queue.Queue(10), loop_time = 1.0/60): print("Journald watcher [{}] initialized".format(name)) super(Journald_watcher, self).__init__() self._prefs = Prefs() self.db = Database() self.name = name self.q = q self.rules = rule_list #print(self.rules) self.retroactive = retroactive self.j = journal.Reader() self.j.log_level(journal.LOG_INFO) try: self.j.add_match(_SYSTEMD_UNIT="{}.service".format(rule_list[0].getNameOfBelongService())) except: return if self.retroactive == False: self.j.seek_tail() self.j.get_previous() pass def run(self): #rule = None if self.rules == [] or self.rules == None: return #for rule in self.rules: #print(rule) #break #print("Journald_watcher.run -> {}".format(rule.getRulename())) #print("Processing {}".format(rule.getNameOfBelongService())) p = select.poll() p.register(self.j, self.j.get_events()) if self.retroactive == True: # Send a message to journald to generate a I/O traffic # so that poll catches events in the past without having # to wait for journal.APPEND to occur naturally. journal.send("GGH") # Inspiration taken from https://yalis.fr/git/yves/pyruse/src/branch/master/pyruse/main.py # In accordance with § 31 odst. 1 písm. a) zákona č. 121/2000 Sb., autorský zákon while p.poll(): #print(self.j.process()) if self.j.process() != journal.APPEND: continue for entry in self.j: if entry['MESSAGE'] != "": # Print SYSTEMD messages for debugging #print(str(entry['__REALTIME_TIMESTAMP'])+ ' ' + entry['MESSAGE']) #print() for rule in self.rules: self.processRule(rule, entry['MESSAGE']) pass def processRule(self, rule, message): #print("{} - Processing the message for the rule {} ...".format(self.name, rule.getRulename())) regexyolo = re.compile(rule.getRegex()) r1 = regexyolo.search(message) if r1 is not None: print("Rule {} -> {} triggered".format(rule.getNameOfBelongService(), rule.getRulename())) try: ipaddr = r1.group(rule.getCriteriaToDistinguish()) if checkIPenabled(ipaddr) == 1: return dictx = rule.getIpXoccurDict() ipcnt = dictx.get(ipaddr, 0) # 0 is the default value if key does not exist #print("ipaddr {} / {}".format(ipaddr, ipcnt)) rule.updateIpXoccur(ipaddr, ipcnt + 1) except: pass # Sanction maybe? self.sanctionner(rule) def sanctionner(self, rule): threshold_count = rule.getThresholdCount() if rule.getThresholdCount() != None else self._prefs.getGeneralPref('THRESHOLDCOUNT') tempAction = rule.getAction() tempAntiaction = rule.getAntiaction() for element, cnt in rule.getIpXoccurDict().items(): if checkIPenabled(element) == 0 or cnt >= int(threshold_count): #print("Threshold count -> {}".format(threshold_count)) #print("OccurenceCount after this read -> {}".format(cnt)) # Replace CRITERIA_TO_DISTINGUISH group placeholder in Regex if tempAction != None: replaced1 = re.sub(rule.getCriteriaToDistinguish(), str(element), tempAction) rule.setAction(replaced1) # check if such a tuple (rule,distingueur) is already in database # if it is, we do not want to apply ACTION and ANTIACTION again # nor we want to log this event to events table, only eventlog if self._prefs.getGeneralPref('DO_NOT_DUPLICATE').lower() == 'true': if self.db.checkDistingueurDetectedForRule(element, rule.getRulename()) == False: # Run the action, let it roll baby print("FIRST TIME") print("Executing ACTION -> {}".format(rule.getAction())) Utils.execute_action(rule.getAction()) else: print("DO_NOT_DUPLICATE is ON -> skipping ACTION") else: # Run the action, let it roll baby print("Executing ACTION -> {}".format(rule.getAction())) Utils.execute_action(rule.getAction()) if tempAntiaction != None: replaced2 = re.sub(rule.getCriteriaToDistinguish(), str(element), tempAntiaction) rule.setAntiaction(replaced2) #print(rule.getAntiaction()) # Add event to DB # Here is important if Antiaction is set. If that is the case, the event is added both to events and eventlog tables # In events table are stored only events with antiaction if self._prefs.getGeneralPref('DO_NOT_DUPLICATE').lower() == 'true': if self.db.checkDistingueurDetectedForRule(element, rule.getRulename()) == False: print("FIRST TIME") # Add event to DB events table if rule.getAntiaction() != None: self.db.addEvent(rule.getNameOfBelongService(), rule.getRulename(), element, time.asctime(), rule.getJailtime() if rule.getJailtime() != None else self._prefs.getGeneralPref('JAILTIME'), rule.getAntiaction()) else: print("DO_NOT_DUPLICATE is ON -> skipping DB store to events.") # Add event to DB eventlog table self.db.addEventlog(rule.getNameOfBelongService(), rule.getRulename(), element, time.asctime()) # We imposed the sanction, now we reset the counter # Die Strafe wird getilgt, nehehe rule.updateIpXoccur(element, 0) print("{} : OCCURCNT DICT -> {}".format(rule.getRulename(), rule.getIpXoccurDict()))
def watchJournalFiles(sch): ruleExecutor = RuleExecutor(prefs=prefs) # run self again / recursion sch.enter(Prefs().getGeneralPref('DAEMON_SLEEP'), 1, watchJournalFiles, (sch,))
try: os.mkdir(DATADIR_ABS) except OSError: pass logfile = DATADIR_ABS + LOGFILENAME pidfile = DATADIR_ABS + PIDFILENAME daemon = Daemon(pidfile, stdout=logfile, stderr=logfile) #'/dev/stderr' module_path = os.path.dirname(__file__) confFile = os.path.join(module_path, CONFDIR + CONFFILENAME) if '--start' == sys.argv[1]: prefs = Prefs(confFile) # create the logfile f = open(logfile, 'w') f.close() if len(sys.argv) >= 3 and sys.argv[2] == '-d': daemon.start(daemon=False) else: daemon.start(daemon=True) elif '--stop' == sys.argv[1]: daemon.stop(removeLogfile=False) elif '--restart' == sys.argv[1]: