def run(self): if not InternalServer.is_external_falco(): self.running_container_id = self._start_container( 'falco -pc -o json_output=true -o file_output.enabled=true ' + '-o file_output.filename=/host' + SysdigFalcoMonitor._falco_output_filename + self.falco_rules) # Wait 3 seconds for sysdig/falco start up and creates the output file time.sleep(3) # Check output file and running docker container if not os.path.isfile(SysdigFalcoMonitor._falco_output_filename) or \ (not InternalServer.is_external_falco() and \ len(self.docker_driver.get_docker_container_ids_by_image_name('falcosecurity/falco:0.18.0')) == 0): raise DagdaError('Falcosecurity/falco output file not found.') # Review sysdig/falco logs after rules parser if not InternalServer.is_external_falco(): sysdig_falco_logs = self.docker_driver.docker_logs( self.running_container_id, True, True, False) if "Rule " in sysdig_falco_logs: SysdigFalcoMonitor._parse_log_and_show_dagda_warnings( sysdig_falco_logs) # Read file with open(SysdigFalcoMonitor._falco_output_filename, 'rb') as f: last_file_position = 0 fbuf = io.BufferedReader(f) while True: fbuf.seek(last_file_position) content = fbuf.readlines() sysdig_falco_events = [] for line in content: line = line.decode('utf-8').replace("\n", "") json_data = json.loads(line) container_id = json_data['output_fields']['container.id'] if container_id != 'host': try: json_data['container_id'] = container_id json_data['image_name'] = json_data[ 'output_fields']['container.image.repository'] if 'container.image.tag' in json_data[ 'output_fields']: json_data['image_name'] += ":" + json_data[ 'output_fields']['container.image.tag'] sysdig_falco_events.append(json_data) except IndexError: # The /tmp/falco_output.json file had information about ancient events, so nothing to do pass except KeyError: # The /tmp/falco_output.json file had information about ancient events, so nothing to do pass last_file_position = fbuf.tell() if len(sysdig_falco_events) > 0: self.mongodb_driver.bulk_insert_sysdig_falco_events( sysdig_falco_events) time.sleep(2)
def run(self): if not InternalServer.is_external_falco(): self.running_container_id = self._start_container('falco -pc -o json_output=true -o file_output.enabled=true ' + '-o file_output.filename=/host' + SysdigFalcoMonitor._falco_output_filename + self.falco_rules) # Wait 3 seconds for sysdig/falco start up and creates the output file time.sleep(3) # Check output file and running docker container if not os.path.isfile(SysdigFalcoMonitor._falco_output_filename) or \ (not InternalServer.is_external_falco() and \ len(self.docker_driver.get_docker_container_ids_by_image_name('sysdig/falco')) == 0): raise DagdaError('Sysdig/falco output file not found.') # Review sysdig/falco logs after rules parser if not InternalServer.is_external_falco(): sysdig_falco_logs = self.docker_driver.docker_logs(self.running_container_id, True, True, False) if "Rule " in sysdig_falco_logs: SysdigFalcoMonitor._parse_log_and_show_dagda_warnings(sysdig_falco_logs) # Read file with open(SysdigFalcoMonitor._falco_output_filename, 'rb') as f: last_file_position = 0 fbuf = io.BufferedReader(f) while True: fbuf.seek(last_file_position) content = fbuf.readlines() sysdig_falco_events = [] for line in content: line = line.decode('utf-8').replace("\n", "") json_data = json.loads(line) container_id = json_data['output'].split(" (id=")[1].replace(")", "") if container_id != 'host': try: image_name = self.docker_driver.get_docker_image_name_by_container_id(container_id) json_data['container_id'] = container_id json_data['image_name'] = image_name sysdig_falco_events.append(json_data) except IndexError: # The /tmp/falco_output.json file had information about ancient events, so nothing to do pass last_file_position = fbuf.tell() if len(sysdig_falco_events) > 0: self.mongodb_driver.bulk_insert_sysdig_falco_events(sysdig_falco_events) time.sleep(2)
def pre_check(self): if not InternalServer.is_external_falco(): # Init linux_distro = SysdigFalcoMonitor._get_linux_distro() uname_r = os.uname().release # Check requirements if not os.path.isfile('/.dockerenv'): # I'm living in real world! if 'Red Hat' in linux_distro or 'CentOS' in linux_distro or 'Fedora' in linux_distro \ or 'openSUSE' in linux_distro: # Red Hat/CentOS/Fedora/openSUSE return_code = subprocess.call(["rpm", "-q", "kernel-devel-" + uname_r], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) elif 'Debian' in linux_distro or 'Ubuntu' in linux_distro: # Debian/Ubuntu return_code = subprocess.call(["dpkg", "-l", "linux-headers-" + uname_r], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) else: raise DagdaError('Linux distribution not supported yet.') if return_code != 0: raise DagdaError('The kernel headers are not installed in the host operating system.') else: # I'm running inside a docker container DagdaLogger.get_logger().warning("I'm running inside a docker container, so I can't check if the kernel " "headers are installed in the host operating system. Please, review it!!") # Check Docker driver if self.docker_driver.get_docker_client() is None: raise DagdaError('Error while fetching Docker server API version.') # Docker pull for ensuring the sysdig/falco image self.docker_driver.docker_pull('sysdig/falco') # Stops sysdig/falco containers if there are any container_ids = self.docker_driver.get_docker_container_ids_by_image_name('sysdig/falco') if len(container_ids) > 0: for container_id in container_ids: self.docker_driver.docker_stop(container_id) self.docker_driver.docker_remove_container(container_id) # Cleans mongodb falco_events collection self.mongodb_driver.delete_falco_events_collection() # Starts sysdig running container without custom entrypoint for avoiding: # --> Runtime error: error opening device /host/dev/sysdig0 self.running_container_id = self._start_container() time.sleep(30) logs = self.docker_driver.docker_logs(self.running_container_id, True, True, False) if "Runtime error: error opening device /host/dev/sysdig0" not in logs: self.docker_driver.docker_stop(self.running_container_id) else: raise DagdaError('Runtime error opening device /host/dev/sysdig0.') # Clean up self.docker_driver.docker_remove_container(self.running_container_id)
def run(self): edn_pid = os.fork() if edn_pid == 0: try: while True: item = InternalServer.get_dagda_edn().get() if item['msg'] == 'init_db': self._init_or_update_db() elif item['msg'] == 'check_image': self._check_docker_by_image_name(item) elif item['msg'] == 'check_container': self._check_docker_by_container_id(item) except KeyboardInterrupt: # Pressed CTRL+C to quit, so nothing to do pass else: docker_events_monitor_pid = os.fork() if docker_events_monitor_pid == 0: try: docker_daemon_events_monitor = DockerDaemonEventsMonitor( InternalServer.get_docker_driver(), InternalServer.get_mongodb_driver()) docker_daemon_events_monitor.run() except KeyboardInterrupt: # Pressed CTRL+C to quit, so nothing to do pass else: sysdig_falco_monitor_pid = os.fork() if sysdig_falco_monitor_pid == 0: try: self.sysdig_falco_monitor.pre_check() self.sysdig_falco_monitor.run() except DagdaError as e: DagdaLogger.get_logger().error(e.get_message()) DagdaLogger.get_logger().warning( 'Runtime behaviour monitor disabled.') except KeyboardInterrupt: # Pressed CTRL+C to quit if not InternalServer.is_external_falco(): InternalServer.get_docker_driver().docker_stop( self.sysdig_falco_monitor. get_running_container_id()) InternalServer.get_docker_driver( ).docker_remove_container( self.sysdig_falco_monitor. get_running_container_id()) else: serve(DagdaServer.app, host=self.dagda_server_host, port=self.dagda_server_port, ident=None)
def run(self): edn_pid = os.fork() if edn_pid == 0: try: while True: item = InternalServer.get_dagda_edn().get() if item['msg'] == 'init_db': self._init_or_update_db() elif item['msg'] == 'check_image': self._check_docker_by_image_name(item) elif item['msg'] == 'check_container': self._check_docker_by_container_id(item) except KeyboardInterrupt: # Pressed CTRL+C to quit, so nothing to do pass else: docker_events_monitor_pid = os.fork() if docker_events_monitor_pid == 0: try: docker_daemon_events_monitor = DockerDaemonEventsMonitor(InternalServer.get_docker_driver(), InternalServer.get_mongodb_driver()) docker_daemon_events_monitor.run() except KeyboardInterrupt: # Pressed CTRL+C to quit, so nothing to do pass else: sysdig_falco_monitor_pid = os.fork() if sysdig_falco_monitor_pid == 0: try: self.sysdig_falco_monitor.pre_check() self.sysdig_falco_monitor.run() except DagdaError as e: DagdaLogger.get_logger().error(e.get_message()) DagdaLogger.get_logger().warning('Runtime behaviour monitor disabled.') except KeyboardInterrupt: # Pressed CTRL+C to quit if not InternalServer.is_external_falco(): InternalServer.get_docker_driver().docker_stop(self.sysdig_falco_monitor.get_running_container_id()) InternalServer.get_docker_driver().docker_remove_container( self.sysdig_falco_monitor.get_running_container_id()) else: DagdaServer.app.run(debug=False, host=self.dagda_server_host, port=self.dagda_server_port)
def pre_check(self): if not InternalServer.is_external_falco(): # Init linux_distro = SysdigFalcoMonitor._get_linux_distro() uname_r = os.uname().release # Check requirements if not os.path.isfile('/.dockerenv'): # I'm living in real world! if 'Red Hat' in linux_distro or 'CentOS' in linux_distro or 'Fedora' in linux_distro \ or 'openSUSE' in linux_distro: # Red Hat/CentOS/Fedora/openSUSE return_code = subprocess.call( ["rpm", "-q", "kernel-devel-" + uname_r], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) elif 'Debian' in linux_distro or 'Ubuntu' in linux_distro: # Debian/Ubuntu return_code = subprocess.call( ["dpkg", "-l", "linux-headers-" + uname_r], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) else: raise DagdaError('Linux distribution not supported yet.') if return_code != 0: raise DagdaError( 'The kernel headers are not installed in the host operating system.' ) else: # I'm running inside a docker container DagdaLogger.get_logger().warning( "I'm running inside a docker container, so I can't check if the kernel " "headers are installed in the host operating system. Please, review it!!" ) # Check Docker driver if self.docker_driver.get_docker_client() is None: raise DagdaError( 'Error while fetching Docker server API version.') # Docker pull for ensuring the falcosecurity/falco image self.docker_driver.docker_pull('falcosecurity/falco', tag='0.18.0') # Stops sysdig/falco containers if there are any container_ids = self.docker_driver.get_docker_container_ids_by_image_name( 'falcosecurity/falco:0.18.0') if len(container_ids) > 0: for container_id in container_ids: self.docker_driver.docker_stop(container_id) self.docker_driver.docker_remove_container(container_id) # Cleans mongodb falco_events collection self.mongodb_driver.delete_falco_events_collection() # Starts sysdig running container without custom entrypoint for avoiding: # --> Runtime error: error opening device /host/dev/sysdig0 self.running_container_id = self._start_container() time.sleep(30) logs = self.docker_driver.docker_logs(self.running_container_id, True, True, False) if "Runtime error: error opening device /host/dev/sysdig0" not in logs: self.docker_driver.docker_stop(self.running_container_id) else: raise DagdaError( 'Runtime error opening device /host/dev/sysdig0.') # Clean up self.docker_driver.docker_remove_container( self.running_container_id)