PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /opt/sharedrads/mitigatord/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //opt/sharedrads/mitigatord/mitigatord |
#!/opt/imh-python/bin/python3 import pdb import os import signal import time import datetime import re import argparse import threading from subprocess import check_output class Mitigator(): ''' currently has two main features: 1. watches for a queueprocd process related to jailshells, kills it 2. repeatedly attemps to clear virtfs if there are mounts ''' def __init__(self): self.log_file = '/var/log/mitigatord.log' self.virtfs_attempts = 0 self.log_level = 2 self.virt_check_interval = 3 self.thread_list = [] def get_args(self): ''' flags: -d makes logging to log_file instead of stdout ''' parser = argparse.ArgumentParser() parser.add_argument('-d', '--daemon', action='store_true', default=False, dest='daemon', help=('logs to log file instead of stdout')) self.args = parser.parse_args() # slows down process checking for daemon mode self.log(f'pid {os.getpid()} starting in daemon mode', 1) # convert minutes to seconds def proc_watcher(self): ''' function to check for and kill the process that spawns jailshells ''' search_str = re.compile( r'root\s+(\d+)[^\n]+queueprocd - process - update_users_jail\s*\n' ) ps_aux = check_output('ps -fu root | grep -F queueprocd', shell=True, timeout = 60).decode('utf-8') # lightest string comparison I think if 'update_users_jail' not in ps_aux: self.log('proc not found', 3) return # then gets pid with re proc_finder = re.search(search_str, ps_aux) if not proc_finder: self.log('re.search failed, looping', 3) return pid = int(proc_finder.group(1)) self.log(f'found:\n{proc_finder.group(0).strip()}', 1) try: os.kill(pid, signal.SIGKILL) except Exception as e: self.log(e, 1) return def clear_virt(self): ''' runs proc_watcher clears umounts all virtfs mounts + orphans ''' self.launch_thread('proc_watcher', self.proc_watcher) time.sleep(0.4) clear_cmd = ('grep -F " /home/virtfs/" /proc/mounts ' '''| awk '{print $2}' ''' '| xargs -I {} -P 5 umount -v {} &>/dev/null;' 'echo -n') self.log('clearing virtfs mounts', 1) check_output(clear_cmd, shell=True, timeout=3600) self.log('clearing orphan mounts', 1) check_output( '/scripts/clear_orphaned_virtfs_mounts --clearall &>/dev/null', timeout=3600, shell=True, ) self.log('done clearing virtfs mounts', 1) def check_virt(self): ''' checks for virtfs mounts returns False if there are no virtfs mounts runs clear_virt and returns True if mounts ''' count_cmd = ('grep -F " /home/virtfs/" /proc/mounts ' '''| awk '{print $2}' | wc -l 2>/dev/null''') virt_count = check_output(count_cmd, shell=True, timeout=60) virt_count = virt_count.decode('utf-8').strip() self.log(f'{virt_count} virtfs mounts', 2) if int(virt_count) == 0: self.log('no virt mounts found, looping', 2) return False else: self.log(f'{virt_count} virtfs mounts', 1) self.clear_virt() return True def virt_watcher(self): ''' function for virtfs mount clearing loop ''' while True: self.check_virt() time.sleep(self.virt_check_interval) def launch_thread(self, name, target): ''' uses daemon false so we dont need to join threads ''' t = threading.Thread( name=name, target=target, daemon = False ) t.start() self.thread_list.append(t) def log(self, log_str, lvl): ''' provides logging with modular verbosity see self.log_level in __init__ ''' if lvl >= self.log_level: return tstamp = datetime.datetime.now().replace(microsecond=0).isoformat() log_str = f'{tstamp}:{log_str}' if self.args.daemon: with open(self.log_file, 'a') as fh: if os.path.getsize(self.log_file) > 15000000: fh.truncate(10000000) print(log_str, file=fh) return print(log_str) def main(): ''' handles main thread launching ''' m = Mitigator() m.get_args() m.launch_thread('virt_watcher', m.virt_watcher) if __name__ == '__main__': main()