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.')
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) })
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
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
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)
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)
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()
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.")
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')
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)
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