Пример #1
0
 def is_running(self):
     if self.elasticsearch_home:
         try:
             return elastic_process.ProcessManager().status()['running']
         except KeyError:
             return elastic_process.ProcessManager().status()['RUNNING']
     return False
Пример #2
0
 def invoke(self) -> Tuple[int, Dict]:
     es_url = f'https://{self.network_host}:{self.http_port}'
     es_cluster_data = {
         'persistent': {
             'script.max_compilations_rate': '1000/5m'
         },
         'transient': {
             'script.max_compilations_rate': '1000/5m'
         }
     }
     attempts = 0
     es_process_profile = profile.ProcessProfiler()
     if not es_process_profile.is_listening():
         process.ProcessManager().start()
     while not es_process_profile.is_listening(
     ) and attempts < self.max_attempts:
         attempts += 1
         sleep(10)
     r = requests.put(url=f'{es_url}/_cluster/settings',
                      data=json.dumps(es_cluster_data),
                      auth=('admin', 'admin'),
                      headers={'content-type': 'application/json'},
                      verify=False)
     if self.terminate_elasticsearch:
         process.ProcessManager().stop()
     if r.status_code != 200:
         return r.status_code, {'error': r.text}
     else:
         return r.status_code, r.json()
Пример #3
0
 def is_running(self) -> bool:
     """Check if Elasticsearch is running
     Returns:
         True, if running
     """
     if self.elasticsearch_home:
         try:
             return elastic_process.ProcessManager().status()['running']
         except KeyError:
             return elastic_process.ProcessManager().status()['RUNNING']
     return False
Пример #4
0
 def invoke(self, shell: Optional[bool] = False, cwd: Optional[str] = None) -> List[
     Tuple[List, bytes, bytes]]:
     utilities.set_permissions_of_file(file_path=self.opendistro_security_admin, unix_permissions_integer='+x')
     if not cwd:
         cwd = self.security_conf_directory
     attempts = 0
     es_process_profile = profile.ProcessProfiler()
     if not es_process_profile.is_listening():
         process.ProcessManager().start()
     while not es_process_profile.is_listening() and attempts < self.max_attempts:
         attempts += 1
         sleep(10)
     results = super().invoke(shell, cwd)
     if self.terminate_elasticsearch:
         process.ProcessManager().stop()
     return results
Пример #5
0
def change_elasticsearch_password(old_password, password='******', remote_host=None, remote_port=None,
                                  prompt_user=True, stdout=True, verbose=False):
    """
    Change the Elasticsearch password for all builtin users

    :param old_password: The old Elasticsearch password
    :param password: The new Elasticsearch password
    :param prompt_user: If True, warning prompt is displayed before proceeding
    :param stdout: Print status to stdout
    :param verbose: Include detailed debug messages
    """

    from dynamite_nsm.services.elasticsearch import process as elastic_process
    from dynamite_nsm.services.elasticsearch import profile as elastic_profile

    log_level = logging.INFO
    if verbose:
        log_level = logging.DEBUG
    logger = get_logger('ELASTICSEARCH', level=log_level, stdout=stdout)

    if prompt_user:
        resp = utilities.prompt_input(
            '\n\033[93m[-] WARNING! Changing the ElasticSearch password may result in connected components losing '
            'communication. Be sure to update Kibana/LogStash passwords.\n'
            '[?] Are you sure you wish to continue? [no]|yes):\033[0m ')
        while resp not in ['', 'no', 'yes']:
            resp = utilities.prompt_input('\033[93m[?] Are you sure you wish to continue? ([no]|yes):\033[0m ')
        if resp != 'yes':
            if stdout:
                sys.stdout.write('[+] Exiting\n')
            exit(0)
    if remote_host:
        logger.info("Resetting ElasticSearch password on remote host: {}:{}".format(remote_host, remote_port))
    else:
        logger.info("Resetting ElasticSearch password on localhost.")
        if elastic_profile.ProcessProfiler().is_installed():
            # If ElasticSearch is installed Locally.
            # Start the process, in order to perform a reset.
            if not elastic_process.ProcessManager().start():
                logger.error('Could not start ElasticSearch Process. Password reset failed.')
                raise general_exceptions.ResetPasswordError(
                    "ElasticSearch process was not able to start, check your ElasticSearch logs.")
            while not elastic_profile.ProcessProfiler().is_listening():
                logger.info('Waiting for ElasticSearch API to become accessible.')
                time.sleep(5)

            logger.info('ElasticSearch API is up.')
            logger.debug('Sleeping for 5 seconds, while ElasticSearch API finishes booting.')
            time.sleep(5)
        else:
            logger.error("ElasticSearch is not installed, and no remote ElasticSearch host was specified.")
            raise general_exceptions.ResetPasswordError(
                "ElasticSearch is not installed, and no remote ElasticSearch host was specified.")

    es_pw_config = PasswordConfigManager('elastic', current_password=old_password, remote_host=remote_host,
                                         remote_http_port=remote_port)
    logger.info("Attempting password reset.")
    es_pw_config.set_all_passwords(password)
Пример #6
0
 def _install_kibana_objects(self):
     self.logger.info('Installing Kibana Dashboards')
     self.logger.info('Waiting for ElasticSearch to become accessible.')
     # Start ElasticSearch if it is installed locally and is not running
     if self.elasticsearch_host in ['localhost', '127.0.0.1', '0.0.0.0', '::1', '::/128']:
         self.logger.info('Starting ElasticSearch.')
         elastic_process.ProcessManager().start()
         while not elastic_profile.ProcessProfiler().is_listening():
             self.logger.info('Waiting for ElasticSearch API to become accessible.')
             time.sleep(5)
         self.logger.info('ElasticSearch API is up.')
         self.logger.info('Sleeping for 5 seconds, while ElasticSearch API finishes booting.')
         time.sleep(5)
     try:
         kibana_proc = kibana_process.ProcessManager()
         kibana_proc.optimize()
         utilities.set_ownership_of_file(self.install_directory, user='******', group='dynamite')
         utilities.set_ownership_of_file(self.configuration_directory, user='******', group='dynamite')
         time.sleep(5)
         self.logger.info('Starting Kibana.')
         kibana_proc.start()
     except Exception as e:
         raise kibana_exceptions.InstallKibanaError("General error while starting Kibana process; {}".format(e))
     kibana_api_start_attempts = 0
     while not kibana_profile.ProcessProfiler().is_listening() and kibana_api_start_attempts != 5:
         self.logger.info('Waiting for Kibana API to become accessible.')
         kibana_api_start_attempts += 1
         time.sleep(5)
     if kibana_api_start_attempts == 5:
         self.logger.error('Kibana API could not be started after {} attempts.'.format(kibana_api_start_attempts))
         raise kibana_exceptions.InstallKibanaError(
             "Kibana API could not be started after {} attempts.".format(kibana_api_start_attempts))
     self.logger.info('Kibana API is up.')
     self.logger.info('Sleeping for 10 seconds, while Kibana API finishes booting.')
     time.sleep(10)
     api_config = kibana_configs.ApiConfigManager(self.configuration_directory)
     kibana_object_create_attempts = 1
     while kibana_object_create_attempts != 5:
         try:
             self.logger.info('[Attempt {}] Attempting to install dashboards/visualizations.'.format(
                 kibana_object_create_attempts))
             api_config.create_dynamite_kibana_objects()
             break
         except kibana_exceptions.CreateKibanaObjectsError:
             kibana_object_create_attempts += 1
             time.sleep(10)
     if kibana_object_create_attempts == 5:
         self.logger.error(
             "Kibana objects could not be created after {} attempts".format(kibana_object_create_attempts))
         raise kibana_exceptions.InstallKibanaError(
             "Kibana objects could not be created after {} attempts".format(kibana_object_create_attempts))
     self.logger.info('Successfully created dashboards/visualizations.')
     kibana_proc.stop()
Пример #7
0
 def stop(self) -> bool:
     """Stop the monitor services
     Returns:
         True, if successfully stopped
     """
     kibana_res, logstash_res, elasticsearch_res = True, True, True
     if not elasticsearch_profile.ProcessProfiler().is_installed():
         self.logger.error('You must install kibana to run this command.')
         return False
     elasticsearch_res = elasticsearch_process.ProcessManager().stop()
     if logstash_profile.ProcessProfiler().is_installed():
         logstash_res = logstash_process.ProcessManager().stop()
     if kibana_profile.ProcessProfiler().is_installed():
         kibana_res = kibana_process.ProcessManager().stop()
     return kibana_res and elasticsearch_res and logstash_res
Пример #8
0
def uninstall_elasticsearch(prompt_user=True, stdout=True, verbose=False):
    """
    Uninstall ElasticSearch

    :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('ELASTICSEARCH', level=log_level, stdout=stdout)

    env_file = os.path.join(const.CONFIG_PATH, 'environment')
    environment_variables = utilities.get_environment_file_dict()
    es_profiler = elastic_profile.ProcessProfiler()
    if not es_profiler.is_installed():
        logger.error('ElasticSearch is not installed.')
        raise elastic_exceptions.UninstallElasticsearchError(
            "ElasticSearch is not installed.")
    configuration_directory = environment_variables.get('ES_PATH_CONF')
    es_config = elastic_configs.ConfigManager(
        configuration_directory=configuration_directory)
    if prompt_user:
        sys.stderr.write(
            '\n\033[93m[-] WARNING! Removing ElasticSearch Will Delete All Data.'
            '\033[0m\n')
        resp = utilities.prompt_input(
            '\033[93m[?] Are you sure you wish to continue? ([no]|yes):\033[0m '
        )
        while resp not in ['', 'no', 'yes']:
            resp = utilities.prompt_input(
                '\n\033[93m[?] Are you sure you wish to continue? ([no]|yes):\033[0m '
            )
        if resp != 'yes':
            if stdout:
                sys.stdout.write('\n[+] Exiting\n')
            exit(0)
    if es_profiler.is_running():
        elastic_process.ProcessManager().stop()
    try:
        shutil.rmtree(es_config.configuration_directory)
        shutil.rmtree(es_config.es_home)
        shutil.rmtree(es_config.path_logs)
        shutil.rmtree(const.INSTALL_CACHE, ignore_errors=True)
        env_lines = ''
        with open(env_file) as env_fr:
            for line in env_fr.readlines():
                if 'ES_PATH_CONF' in line:
                    continue
                elif 'ES_HOME' in line:
                    continue
                elif 'ES_LOGS' 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)
    except Exception as e:
        logger.error(
            "General error occurred while attempting to uninstall ElasticSearch."
            .format(e))
        logger.debug(
            "General error occurred while attempting to uninstall ElasticSearch; {}"
            .format(e))
        raise elastic_exceptions.UninstallElasticsearchError(
            "General error occurred while attempting to uninstall ElasticSearch; {}"
            .format(e))
    try:
        sysctl = systemctl.SystemCtl()
    except general_exceptions.CallProcessError:
        raise elastic_exceptions.UninstallElasticsearchError(
            "Could not find systemctl.")
    sysctl.uninstall_and_disable('elasticsearch')
Пример #9
0
    def setup_passwords(self):
        env_dict = utilities.get_environment_file_dict()

        def setup_from_bootstrap(s):
            bootstrap_users_and_passwords = {}
            for line in s.split('\n'):
                if 'PASSWORD' in line:
                    _, user, _, password = line.split(' ')
                    if not isinstance(password, str):
                        password = password.decode()
                    bootstrap_users_and_passwords[user] = password
            es_pass_config = elastic_configs.PasswordConfigManager(
                auth_user='******',
                current_password=bootstrap_users_and_passwords['elastic'],
                stdout=self.stdout,
                verbose=self.verbose)
            es_pass_config.set_all_passwords(new_password=self.password)

        if not elastic_profile.ProcessProfiler().is_installed():
            self.logger.error(
                'ElasticSearch must be installed and running to bootstrap passwords.'
            )
            raise elastic_exceptions.InstallElasticsearchError(
                "ElasticSearch must be installed and running to bootstrap passwords."
            )
        self.logger.info('Creating certificate keystore.')
        es_config_path = os.path.join(self.configuration_directory, 'config')
        try:
            utilities.makedirs(es_config_path, exist_ok=True)
        except Exception as e:
            self.logger.error(
                "General error occurred while attempting to create {} directory."
                .format(es_config_path))
            self.logger.debug(
                "General error occurred while attempting to create {} directory; {}"
                .format(es_config_path, e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to create {} directory; {}"
                .format(es_config_path, e))
        es_cert_util = os.path.join(self.install_directory, 'bin',
                                    'elasticsearch-certutil')
        es_cert_keystore = os.path.join(self.configuration_directory, 'config',
                                        'elastic-certificates.p12')
        cert_p = subprocess.Popen(
            [es_cert_util, 'cert', '-out', es_cert_keystore, '-pass', ''],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            stdin=subprocess.PIPE,
            env=env_dict)
        try:
            cert_p_res = cert_p.communicate()
        except Exception as e:
            self.logger.error(
                "General error occurred while attempting to install SSL keystores."
            )
            self.logger.debug(
                "General error occurred while attempting to install SSL keystores; {}"
                .format(e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to install SSL keystores; {}"
                .format(e))
        if not os.path.exists(es_cert_keystore):
            self.logger.error(
                'Failed to setup SSL certificate keystore: \noutput: {}\n\t'.
                format(cert_p_res))
            raise elastic_exceptions.InstallElasticsearchError(
                "Failed to setup SSL keystore; {}".format(cert_p_res))
        keystore_config_path = os.path.join(self.configuration_directory,
                                            'config')
        try:
            utilities.set_ownership_of_file(keystore_config_path,
                                            user='******',
                                            group='dynamite')
        except Exception as e:
            self.logger.error(
                'General error occurred while attempting to set permissions for {}.'
                .format(keystore_config_path))
            self.logger.debug(
                "General error occurred while attempting to set permissions for {}; {}"
                .format(keystore_config_path, e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to set permissions for {}; {}"
                .format(keystore_config_path, e))
        if not elastic_profile.ProcessProfiler().is_running():
            elastic_process.ProcessManager().start()
            attempts = 0
            while not elastic_profile.ProcessProfiler().is_listening():
                self.logger.info(
                    'Waiting for ElasticSearch API to become accessible.')
                time.sleep(10)
                attempts += 1
                if attempts == 10:
                    self.logger.error(
                        "Failed to start ElasticSearch API after 10 attempts.")
                    raise elastic_exceptions.InstallElasticsearchError(
                        "Failed to start Elasticsearch API after 10 attempts.")
            self.logger.info('ElasticSearch API is up.')
            self.logger.debug(
                'Sleeping for 5 seconds, while ElasticSearch API finishes booting.'
            )
            time.sleep(5)
        self.logger.info('Bootstrapping passwords.')
        es_password_util = os.path.join(self.install_directory, 'bin',
                                        'elasticsearch-setup-passwords')
        bootstrap_p = subprocess.Popen([es_password_util, 'auto'],
                                       cwd=self.configuration_directory,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.STDOUT,
                                       stdin=subprocess.PIPE,
                                       env=env_dict)
        try:
            bootstrap_p_res = bootstrap_p.communicate(input=b'y\n')
            if not bootstrap_p_res:
                self.logger.error('Failed to setup new passwords.')
                raise elastic_exceptions.InstallElasticsearchError(
                    "Failed to bootstrap password.")
            try:
                if not isinstance(bootstrap_p_res[0], str):
                    setup_from_bootstrap(bootstrap_p_res[0].decode())
                else:
                    setup_from_bootstrap(bootstrap_p_res[0])
            except general_exceptions.ResetPasswordError:
                self.logger.error("Failed to bootstrap password.")
                raise elastic_exceptions.InstallElasticsearchError(
                    "Failed to bootstrap password.")
        except Exception as e:
            self.logger.error(
                "General error occurred while attempting to bootstrap ElasticSearch passwords."
            )
            self.logger.debug(
                "General error occurred while attempting to bootstrap ElasticSearch passwords {}"
                .format(e))
            raise elastic_exceptions.InstallElasticsearchError(
                "General error occurred while attempting to bootstrap ElasticSearch passwords {}"
                .format(e))
Пример #10
0
    def status(self) -> Optional[Union[Dict, str]]:
        """Get the statuses of monitor services
        Returns:
            The statuses of monitor services
        """
        agent_status = {}
        kibana_status, elasticsearch_status, logstash_status = {}, {}, {}
        if not elasticsearch_profile.ProcessProfiler().is_installed():
            self.logger.error(
                'You must install elasticsearch to run this command.')
            return None

        elasticsearch_status = elasticsearch_process.ProcessManager().status()
        agent_status.update({
            'elasticsearch': {
                'running':
                elasticsearch_status.get('running'),
                'enabled_on_startup':
                elasticsearch_status.get('enabled_on_startup')
            }
        })
        if logstash_profile.ProcessProfiler().is_installed():
            logstash_status = logstash_process.ProcessManager().status()
            agent_status.update({
                'logstash': {
                    'running': logstash_status.get('running'),
                    'enabled_on_startup':
                    logstash_status.get('enabled_on_startup')
                }
            })
        if kibana_profile.ProcessProfiler().is_installed():
            kibana_status = kibana_process.ProcessManager().status()
            agent_status.update({
                'kibana': {
                    'running': kibana_status.get('running'),
                    'enabled_on_startup':
                    kibana_status.get('enabled_on_startup')
                }
            })

        if self.pretty_print_status:
            colorize = utilities.PrintDecorations.colorize
            child_services = [
                ['Service', 'Running', 'Enabled on Startup'],
                [
                    'kibana',
                    colorize('yes', 'green')
                    if kibana_status.get('running') else colorize('no', 'red'),
                    colorize('yes', 'green')
                    if kibana_status.get('enabled_on_startup') else colorize(
                        'no', 'red')
                ]
            ]
            if elasticsearch_status:
                child_services.append([
                    'elasticsearch',
                    colorize('yes', 'green')
                    if elasticsearch_status.get('running') else colorize(
                        'no', 'red'),
                    colorize('yes', 'green')
                    if elasticsearch_status.get('enabled_on_startup') else
                    colorize('no', 'red')
                ])
            if logstash_status:
                child_services.append([
                    'logstash',
                    colorize('yes', 'green')
                    if elasticsearch_status.get('running') else colorize(
                        'no', 'red'),
                    colorize('yes', 'green')
                    if elasticsearch_status.get('enabled_on_startup') else
                    colorize('no', 'red')
                ])

            return tabulate.tabulate(child_services, tablefmt='fancy_grid')
        return agent_status
Пример #11
0
    def setup(self):
        """Setup Elasticsearch, Logstash, and Kibana
        Returns:
            None
        """

        if self.elasticsearch_install_directory or self.elasticsearch_configuration_directory or \
                self.elasticsearch_log_directory:
            if not (self.elasticsearch_install_directory
                    and self.elasticsearch_configuration_directory
                    and self.elasticsearch_log_directory):
                self.logger.error(
                    'You must specify elasticsearch-configuration-directory, elasticsearch-install-directory, '
                    'and elasticsearch-log-directory.')
                return None
            elasticsearch_install.InstallManager(
                configuration_directory=self.
                elasticsearch_configuration_directory,
                install_directory=self.elasticsearch_install_directory,
                log_directory=self.elasticsearch_log_directory,
                stdout=self.stdout,
                verbose=self.verbose).setup(
                    node_name=utilities.get_default_es_node_name(),
                    network_host=utilities.get_primary_ip_address(),
                    port=9200)
        if self.logstash_install_directory or self.logstash_configuration_directory or self.logstash_log_directory:
            if not (self.logstash_install_directory
                    and self.logstash_configuration_directory
                    and self.logstash_log_directory):
                self.logger.error(
                    'You must specify logstash-configuration-directory, logstash-install-directory, '
                    'and logstash-log-directory.')
                return None
            logstash_install.InstallManager(
                configuration_directory=self.logstash_configuration_directory,
                install_directory=self.logstash_install_directory,
                log_directory=self.logstash_log_directory,
                stdout=self.stdout,
                verbose=self.verbose).setup(
                    node_name=utilities.get_default_es_node_name().replace(
                        'es', 'ls'),
                    elasticsearch_host=utilities.get_primary_ip_address(),
                    elasticsearch_port=9200)
        if self.kibana_install_directory or self.kibana_configuration_directory or self.kibana_log_directory:
            from dynamite_nsm.services.elasticsearch import process as elasticsearch_process
            if not (self.kibana_install_directory
                    and self.kibana_configuration_directory
                    and self.kibana_log_directory):
                self.logger.error(
                    'You must specify kibana-configuration-directory, kibana-install-directory, '
                    'and kibana-log-directory.')
                return None
            self.logger.info('Starting Elasticsearch.')
            elasticsearch_process.ProcessManager().start()
            kibana_install.InstallManager(
                configuration_directory=self.kibana_configuration_directory,
                install_directory=self.kibana_install_directory,
                log_directory=self.kibana_log_directory,
                stdout=self.stdout,
                verbose=self.verbose).setup(
                    host=utilities.get_primary_ip_address(),
                    port=5601,
                    elasticsearch_targets=[
                        f'https://{utilities.get_primary_ip_address()}:9200'
                    ])