Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
 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)
Esempio n. 5
0
 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)
Esempio n. 6
0
    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)