예제 #1
0
    def __init__(self,
                 stdout: Optional[bool] = True,
                 verbose: Optional[bool] = False,
                 pretty_print_status: Optional[bool] = False):
        """Manage Filebeat Process
        Args:
            stdout: Print output to console
            verbose: Include detailed debug messages
            pretty_print_status: If enabled, status will be printed in a tabulated style
        Returns:
            None
        """
        process.BaseProcessManager.__init__(
            self,
            'filebeat.service',
            'filebeat.process',
            log_path=None,
            stdout=stdout,
            verbose=verbose,
            pretty_print_status=pretty_print_status)

        if not profile.ProcessProfiler().is_installed():
            self.logger.error(
                "Filebeat is not installed. Install it with 'dynamite filebeat install -h'"
            )
            raise CallFilebeatProcessError('Filebeat is not installed.')
예제 #2
0
 def __init__(self, prompt_user, stdout, verbose):
     execution_strategy.BaseExecStrategy.__init__(
         self,
         strategy_name="agent_uninstall",
         strategy_description="Uninstall Agent.",
         functions=(
             utilities.create_dynamite_environment_file,
             prompt_agent_uninstall,
         ),
         arguments=(
             # utilities.create_dynamite_environment_file
             {},
             # prompt_user
             {
                 "prompt_user": bool(prompt_user),
                 "stdout": bool(stdout),
             },
         ),
         return_formats=(
             None,
             None,
         ))
     if filebeat_profile.ProcessProfiler().is_installed():
         self.add_function(func=filebeat_install.uninstall_filebeat,
                           argument_dict={
                               'prompt_user': False,
                               'stdout': bool(stdout),
                               'verbose': bool(verbose)
                           })
     if zeek_profile.ProcessProfiler().is_installed():
         self.add_function(func=zeek_install.uninstall_zeek,
                           argument_dict={
                               'prompt_user': False,
                               'stdout': bool(stdout),
                               'verbose': bool(verbose)
                           })
     if suricata_profile.ProcessProfiler().is_installed():
         self.add_function(func=suricata_install.uninstall_suricata,
                           argument_dict={
                               'prompt_user': False,
                               'stdout': bool(stdout),
                               'verbose': bool(verbose)
                           })
     if get_installed_agent_analyzers():
         self.add_function(func=log_message,
                           argument_dict={
                               "msg":
                               '*** Agent uninstalled successfully. ***',
                               'stdout': bool(stdout),
                               'verbose': bool(verbose)
                           })
     else:
         self.add_function(func=log_message,
                           argument_dict={
                               "msg": '*** Agent is not installed. ***',
                               'stdout': bool(stdout),
                               'verbose': bool(verbose)
                           })
예제 #3
0
def get_installed_agent_analyzers():
    zeek_profiler = zeek_profile.ProcessProfiler()
    suricata_profiler = suricata_profile.ProcessProfiler()
    filebeat_profiler = filebeat_profile.ProcessProfiler()

    agent_analyzers = []
    if zeek_profiler.is_installed():
        agent_analyzers.append('Zeek')
    if suricata_profiler.is_installed():
        agent_analyzers.append('Suricata')
    if filebeat_profiler.is_installed():
        agent_analyzers.append('Filebeat')
    return agent_analyzers
예제 #4
0
 def stop(self) -> bool:
     """Stop agent processes
     Returns:
         True, if successful
     """
     filebeat_res, suricata_res, zeek_res = True, True, True
     if not filebeat_profile.ProcessProfiler().is_installed():
         self.logger.error('You must install Filebeat to run this command.')
         return False
     filebeat_res = filebeat_process.ProcessManager().stop()
     if suricata_profile.ProcessProfiler().is_installed():
         suricata_res = suricata_process.ProcessManager().stop()
     if zeek_profile.ProcessProfiler().is_installed():
         zeek_res = zeek_process.ProcessManager().stop()
     return filebeat_res and zeek_res and suricata_res
예제 #5
0
    def actionHighlighted(self, act_on_this, keypress):
        zeek_installed, suricata_installed, filebeat_installed = zeek_profile.ProcessProfiler().is_installed(), \
                                                                 suricata_profile.ProcessProfiler().is_installed(), \
                                                                 filebeat_profile.ProcessProfiler().is_installed()
        app_mapping = {}
        if filebeat_installed:
            if zeek_installed and suricata_installed:
                app_mapping = zeek_and_suricata_mapping
            elif zeek_installed:
                app_mapping = zeek_only_mapping
            elif suricata_installed:
                app_mapping = suricata_only_mapping

        npyscreen.notify_wait(act_on_this, form_color='GOODHL')
        app_mapping[act_on_this]().run()
        exit(0)
예제 #6
0
    def create(self):

        zeek_installed, suricata_installed, filebeat_installed = zeek_profile.ProcessProfiler().is_installed(), \
                                                                 suricata_profile.ProcessProfiler().is_installed(), \
                                                                 filebeat_profile.ProcessProfiler().is_installed()
        app_mapping = {}
        if filebeat_installed:
            if zeek_installed and suricata_installed:
                app_mapping = zeek_and_suricata_mapping
            elif zeek_installed:
                app_mapping = zeek_only_mapping
            elif suricata_installed:
                app_mapping = suricata_only_mapping

        self.add(AgentConfigMultiSelect,
                 values=sorted(app_mapping.keys()),
                 max_height=5)
예제 #7
0
def install_filebeat(install_directory,
                     monitor_log_paths,
                     targets,
                     kafka_topic=None,
                     kafka_username=None,
                     kafka_password=None,
                     agent_tag=None,
                     download_filebeat_archive=True,
                     stdout=True,
                     verbose=False):
    """
    Install Filebeat

    :param install_directory: The installation directory (E.G /opt/dynamite/filebeat/)
    :param monitor_log_paths: A tuple of log paths to monitor
    :param targets: A tuple of Logstash/Kafka targets to forward events to (E.G ["192.168.0.9:5044", ...])
    :param kafka_topic: A string representing the name of the Kafka topic to write messages too
    :param kafka_username: The username for connecting to Kafka
    :param kafka_password: The password for connecting to Kafka
    :param agent_tag: A friendly name for the agent (defaults to the hostname with no spaces and _agt suffix)
    :param download_filebeat_archive: If True, download the Filebeat archive from a mirror
    :param stdout: Print the output to console
    :param verbose: Include detailed debug messages
    """
    log_level = logging.INFO
    if verbose:
        log_level = logging.DEBUG
    logger = get_logger('FILEBEAT', level=log_level, stdout=stdout)

    filebeat_profiler = filebeat_profile.ProcessProfiler()
    if filebeat_profiler.is_installed():
        logger.error('FileBeat is already installed.')
        raise filebeat_exceptions.AlreadyInstalledFilebeatError()
    filebeat_installer = InstallManager(
        install_directory,
        monitor_log_paths=monitor_log_paths,
        targets=targets,
        kafka_topic=kafka_topic,
        kafka_username=kafka_username,
        kafka_password=kafka_password,
        agent_tag=agent_tag,
        download_filebeat_archive=download_filebeat_archive,
        stdout=stdout,
        verbose=verbose)
    filebeat_installer.setup_filebeat()
예제 #8
0
 def __init__(self, stdout=True, verbose=False, pretty_print_status=False):
     try:
         process.BaseProcessManager.__init__(
             self,
             'filebeat.service',
             'filebeat',
             log_path=None,
             pid_file=os.path.join(PID_DIRECTORY, 'filebeat.pid'),
             stdout=stdout,
             verbose=verbose,
             pretty_print_status=pretty_print_status)
     except general_exceptions.CallProcessError:
         self.logger.error("Could not find systemctl on this system.")
         raise filebeat_exceptions.CallFilebeatProcessError(
             "Could not find systemctl.")
     if not filebeat_profile.ProcessProfiler().is_installed():
         self.logger.error(
             "FileBeat is not installed. Install it with 'dynamite agent install -h'"
         )
         raise filebeat_exceptions.CallFilebeatProcessError(
             "FileBeat is not installed.")
예제 #9
0
def uninstall_filebeat(prompt_user=True, stdout=True, verbose=False):
    """
    Uninstall Filebeat

    :param prompt_user: Print a warning before continuing
    :param stdout: Print the output to console
    :param verbose: Include detailed debug messages
    """

    log_level = logging.INFO
    if verbose:
        log_level = logging.DEBUG
    logger = get_logger('FILEBEAT', level=log_level, stdout=stdout)
    logger.info("Uninstalling FileBeat.")
    env_file = os.path.join(const.CONFIG_PATH, 'environment')
    environment_variables = utilities.get_environment_file_dict()
    filebeat_profiler = filebeat_profile.ProcessProfiler()
    if prompt_user:
        sys.stderr.write(
            '\n[-] WARNING! Removing Filebeat Will Remove Critical Agent Functionality.\n'
        )
        resp = utilities.prompt_input(
            '[?] Are you sure you wish to continue? ([no]|yes): ')
        while resp not in ['', 'no', 'yes']:
            resp = utilities.prompt_input(
                '[?] Are you sure you wish to continue? ([no]|yes): ')
        if resp != 'yes':
            if stdout:
                sys.stdout.write('\n[+] Exiting\n')
            exit(0)
    if filebeat_profiler.is_running():
        try:
            filebeat_process.ProcessManager().stop()
        except filebeat_exceptions.CallFilebeatProcessError as e:
            logger.error("Could not kill Filebeat process. Cannot uninstall.")
            logger.debug(
                "Could not kill Filebeat process. Cannot uninstall; {}".format(
                    e))
            raise filebeat_exceptions.UninstallFilebeatError(
                'Could not kill Filebeat process; {}'.format(e))
    install_directory = environment_variables.get('FILEBEAT_HOME')
    try:
        with open(env_file) as env_fr:
            env_lines = ''
            for line in env_fr.readlines():
                if 'FILEBEAT_HOME' in line:
                    continue
                elif line.strip() == '':
                    continue
                env_lines += line.strip() + '\n'
        with open(env_file, 'w') as env_fw:
            env_fw.write(env_lines)
        if filebeat_profiler.is_installed():
            shutil.rmtree(install_directory, ignore_errors=True)
    except Exception as e:
        logger.error(
            "General error occurred while attempting to uninstall Filebeat.")
        logger.debug(
            "General error occurred while attempting to uninstall Filebeat; {}"
            .format(e))
        raise filebeat_exceptions.UninstallFilebeatError(
            "General error occurred while attempting to uninstall Filebeat; {}"
            .format(e))
    try:
        sysctl = systemctl.SystemCtl()
    except general_exceptions.CallProcessError:
        raise filebeat_exceptions.UninstallFilebeatError(
            "Could not find systemctl.")
    sysctl.uninstall_and_disable('filebeat')
    sysctl.uninstall_and_disable('dynamite-agent')
예제 #10
0
 def __init__(self,
              capture_network_interfaces,
              targets,
              kafka_topic=None,
              kafka_username=None,
              kafka_password=None,
              agent_analyzers=('zeek', 'suricata'),
              tag=None,
              stdout=True,
              verbose=False):
     execution_strategy.BaseExecStrategy.__init__(
         self,
         strategy_name="agent_install",
         strategy_description=
         "Install Zeek and/or Suricata along with FileBeat.",
         functions=(utilities.create_dynamite_environment_file, ),
         arguments=({}, ),
         return_formats=(None, ))
     if not zeek_profile.ProcessProfiler().is_installed(
     ) and 'zeek' in agent_analyzers:
         self.add_function(func=zeek_install.install_zeek,
                           argument_dict={
                               'configuration_directory':
                               '/etc/dynamite/zeek/',
                               'install_directory':
                               '/opt/dynamite/zeek',
                               'capture_network_interfaces':
                               list(capture_network_interfaces),
                               'download_zeek_archive':
                               True,
                               'stdout':
                               bool(stdout),
                               'verbose':
                               bool(verbose)
                           })
     else:
         self.add_function(func=log_message,
                           argument_dict={
                               "msg": 'Skipping Zeek installation.',
                               'stdout': bool(stdout),
                               'verbose': bool(verbose)
                           },
                           return_format=None)
     if not suricata_profile.ProcessProfiler().is_installed(
     ) and 'suricata' in agent_analyzers:
         self.add_function(func=suricata_install.install_suricata,
                           argument_dict={
                               'configuration_directory':
                               '/etc/dynamite/suricata/',
                               'install_directory':
                               '/opt/dynamite/suricata/',
                               'log_directory':
                               '/opt/dynamite/suricata/logs/',
                               'capture_network_interfaces':
                               list(capture_network_interfaces),
                               'download_suricata_archive':
                               True,
                               'stdout':
                               bool(stdout),
                               'verbose':
                               bool(verbose)
                           })
     else:
         self.add_function(func=log_message,
                           argument_dict={
                               "msg": 'Skipping Suricata installation.',
                               'stdout': bool(stdout),
                               'verbose': bool(verbose)
                           },
                           return_format=None)
     if not filebeat_profile.ProcessProfiler().is_installed():
         filebeat_args = {
             'targets': list(targets),
             'kafka_topic': kafka_topic,
             'kafka_username': kafka_username,
             'kafka_password': kafka_password,
             'agent_tag': tag,
             'install_directory': '/opt/dynamite/filebeat/',
             'download_filebeat_archive': True,
             'stdout': bool(stdout)
         }
         monitor_log_paths = []
         if 'zeek' in agent_analyzers:
             monitor_log_paths.append(
                 "/opt/dynamite/zeek/logs/current/*.log")
         if 'suricata' in agent_analyzers:
             monitor_log_paths.append(
                 '/opt/dynamite/suricata/logs/eve.json')
         filebeat_args.update({'monitor_log_paths': monitor_log_paths})
         self.add_function(func=filebeat_install.install_filebeat,
                           argument_dict=filebeat_args)
     else:
         self.add_function(
             func=log_message,
             argument_dict={
                 "msg": 'Skipping Filebeat installation; already installed',
                 'stdout': bool(stdout),
                 'verbose': bool(verbose)
             },
             return_format=None)
     self.add_function(func=log_message,
                       argument_dict={
                           "msg": '*** Agent installed successfully. ***',
                           'verbose': bool(verbose)
                       })
     self.add_function(func=log_message,
                       argument_dict={
                           "msg": 'Next, Start your agent: '
                           '\'dynamite agent start\'.',
                           'stdout': bool(stdout),
                           'verbose': bool(verbose)
                       },
                       return_format=None)
예제 #11
0
    def status(self) -> Optional[Union[Dict, str]]:
        """Get the status of a processes
        Returns:
            A dictionary containing process status or a tabulated string if `pretty_print` is True.
        """
        if not filebeat_profile.ProcessProfiler().is_installed():
            self.logger.error('You must install filebeat to run this command.')
            return None
        agent_status = {}
        filebeat_status, zeek_status, suricata_status = {}, {}, {}
        filebeat_status = filebeat_process.ProcessManager().status()
        agent_status.update({
            'filebeat': {
                'running': filebeat_status.get('running'),
                'enabled_on_startup': filebeat_status.get('enabled_on_startup')
            }
        })
        if zeek_profile.ProcessProfiler().is_installed():
            zeek_status = zeek_process.ProcessManager().status()
            agent_status.update({
                'zeek': {
                    'running': zeek_status.get('running'),
                    'enabled_on_startup': zeek_status.get('enabled_on_startup')
                }
            })
        if suricata_profile.ProcessProfiler().is_installed():
            suricata_status = suricata_process.ProcessManager().status()
            agent_status.update({
                'suricata': {
                    'running': suricata_status.get('running'),
                    'enabled_on_startup':
                    suricata_status.get('enabled_on_startup')
                }
            })
        if self.pretty_print_status:
            colorize = utilities.PrintDecorations.colorize
            child_services = [
                ['Service', 'Running', 'Enabled on Startup'],
                [
                    'filebeat',
                    colorize('yes', 'green') if filebeat_status.get('running')
                    else colorize('no', 'red'),
                    colorize('yes', 'green')
                    if filebeat_status.get('enabled_on_startup') else colorize(
                        'no', 'red')
                ]
            ]
            if zeek_status:
                child_services.append([
                    'zeek',
                    colorize('yes', 'green')
                    if zeek_status.get('running') else colorize('no', 'red'),
                    colorize('yes', 'green')
                    if zeek_status.get('enabled_on_startup') else colorize(
                        'no', 'red')
                ])
            if suricata_status:
                child_services.append([
                    'suricata',
                    colorize('yes', 'green')
                    if zeek_status.get('running') else colorize('no', 'red'),
                    colorize('yes', 'green')
                    if zeek_status.get('enabled_on_startup') else colorize(
                        'no', 'red')
                ])

            return tabulate.tabulate(child_services, tablefmt='fancy_grid')
        return agent_status