Ejemplo n.º 1
0
        def overwrite_or_create_files(filename: str, data: Dict):
            """
            Updates a file coming from the master
            :param filename: Filename to update
            :param data: File metadata such as modification time, whether it's a merged file or not, etc.
            :return: None
            """
            full_filename_path = common.ossec_path + filename
            if os.path.basename(filename) == 'client.keys':
                self._check_removed_agents("{}{}".format(zip_path, filename), logger)

            if data['merged']:  # worker nodes can only receive agent-groups files
                if data['merge-type'] == 'agent-info':
                    logger.warning("Agent status received in a worker node")
                    raise WazuhInternalError(3011)

                for name, content, _ in wazuh.core.cluster.cluster.unmerge_agent_info('agent-groups', zip_path, filename):
                    full_unmerged_name = os.path.join(common.ossec_path, name)
                    tmp_unmerged_path = full_unmerged_name + '.tmp'
                    with open(tmp_unmerged_path, 'wb') as f:
                        f.write(content)
                    safe_move(tmp_unmerged_path, full_unmerged_name,
                              permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions'],
                              ownership=(common.ossec_uid(), common.ossec_gid())
                              )
            else:
                if not os.path.exists(os.path.dirname(full_filename_path)):
                    utils.mkdir_with_mode(os.path.dirname(full_filename_path))
                safe_move("{}{}".format(zip_path, filename), full_filename_path,
                          permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions'],
                          ownership=(common.ossec_uid(), common.ossec_gid())
                          )
Ejemplo n.º 2
0
def create_group(group_id):
    """Creates a group.

    :param group_id: Group ID.
    :return: Confirmation message.
    """
    # Input Validation of group_id
    if not InputValidator().group(group_id):
        raise WazuhError(1722)

    group_path = path.join(common.shared_path, group_id)

    if group_id.lower() == "default" or path.exists(group_path):
        raise WazuhError(1711, extra_message=group_id)

    # Create group in /etc/shared
    group_def_path = path.join(common.shared_path, 'agent-template.conf')
    try:
        mkdir_with_mode(group_path)
        copyfile(group_def_path, path.join(group_path, 'agent.conf'))
        chown_r(group_path, common.ossec_uid(), common.ossec_gid())
        chmod_r(group_path, 0o660)
        chmod(group_path, 0o770)
        msg = f"Group '{group_id}' created."
    except Exception as e:
        raise WazuhInternalError(1005, extra_message=str(e))

    return WazuhResult({'message': msg})
Ejemplo n.º 3
0
        def overwrite_or_create_files(filename: str, data: Dict):
            """Update a file coming from the master.

            Move a file which is inside the unzipped directory that comes from master to the path
            specified in 'filename'. If the file is 'merged' type, it is first split into files
            and then moved to their final directory.

            Parameters
            ----------
            filename : str
                Filename inside unzipped dir to update.
            data : dict
                File metadata such as modification time, whether it's a merged file or not, etc.
            """
            full_filename_path = os.path.join(common.wazuh_path, filename)
            if os.path.basename(filename) == 'client.keys':
                self._check_removed_agents(os.path.join(zip_path, filename),
                                           logger)

            if data['merged']:  # worker nodes can only receive agent-groups files
                # Split merged file into individual files inside zipdir (directory containing unzipped files),
                # and then move each one to the destination directory (<ossec_path>/filename).
                for name, content, _ in wazuh.core.cluster.cluster.unmerge_info(
                        'agent-groups', zip_path, filename):
                    full_unmerged_name = os.path.join(common.wazuh_path, name)
                    tmp_unmerged_path = full_unmerged_name + '.tmp'
                    with open(tmp_unmerged_path, 'wb') as f:
                        f.write(content)
                    safe_move(tmp_unmerged_path,
                              full_unmerged_name,
                              permissions=self.cluster_items['files'][
                                  data['cluster_item_key']]['permissions'],
                              ownership=(common.ossec_uid(),
                                         common.ossec_gid()))
            else:
                # Create destination dir if it doesn't exist.
                if not os.path.exists(os.path.dirname(full_filename_path)):
                    utils.mkdir_with_mode(os.path.dirname(full_filename_path))
                # Move the file from zipdir (directory containing unzipped files) to <ossec_path>/filename.
                safe_move(os.path.join(zip_path, filename),
                          full_filename_path,
                          permissions=self.cluster_items['files'][
                              data['cluster_item_key']]['permissions'],
                          ownership=(common.ossec_uid(), common.ossec_gid()))
Ejemplo n.º 4
0
def write_into_yaml_file(config: Dict):
    """
    Writes old configuration into a YAML file
    :param config: Dictionary with old configuration values
    """
    json_config = json.dumps(config)
    try:
        with open(CONFIG_FILE_PATH, 'w') as output_file:
            yaml.dump(json.loads(json_config),
                      output_file,
                      default_flow_style=False,
                      allow_unicode=True)
        # change group and permissions from config.yml file
        os.chown(CONFIG_FILE_PATH, common.ossec_uid(), common.ossec_gid())
        os.chmod(CONFIG_FILE_PATH, 0o660)
    except IOError as e:
        raise APIException(
            2002,
            details='API configuration could not be written into '
            f'{to_relative_path(CONFIG_FILE_PATH)} file: '
            f'{e.strerror}')
Ejemplo n.º 5
0
def start(foreground, root, config_file):
    """Run the Wazuh API.

    If another Wazuh API is running, this function fails.
    This function exits with 0 if successful or 1 if failed because the API was already running.

    Arguments
    ---------
    foreground : bool
        If the API must be daemonized or not
    root : bool
        If true, the daemon is run as root. Normally not recommended for security reasons
    config_file : str
        Path to the API config file
    """
    import asyncio
    import logging
    import os
    import ssl

    import connexion
    import uvloop
    from aiohttp_cache import setup_cache

    import wazuh.security
    from api import __path__ as api_path
    # noinspection PyUnresolvedReferences
    from api import validator
    from api.api_exception import APIError
    from api.constants import CONFIG_FILE_PATH
    from api.middlewares import set_user_name, security_middleware, response_postprocessing, request_logging, \
        set_secure_headers
    from api.uri_parser import APIUriParser
    from api.util import to_relative_path
    from wazuh.core import pyDaemonModule

    configuration.api_conf.update(configuration.read_yaml_config(config_file=config_file))
    api_conf = configuration.api_conf
    security_conf = configuration.security_conf
    log_path = api_conf['logs']['path']

    # Set up logger
    set_logging(log_path=log_path, debug_mode=api_conf['logs']['level'], foreground_mode=foreground)
    logger = logging.getLogger('wazuh-api')

    # Set correct permissions on api.log file
    if os.path.exists(os.path.join(common.ossec_path, log_path)):
        os.chown(os.path.join(common.ossec_path, log_path), common.ossec_uid(), common.ossec_gid())
        os.chmod(os.path.join(common.ossec_path, log_path), 0o660)

    # Configure https
    ssl_context = None
    if api_conf['https']['enabled']:
        try:
            # Generate SSL if it does not exist and HTTPS is enabled
            if not os.path.exists(api_conf['https']['key']) or not os.path.exists(api_conf['https']['cert']):
                logger.info('HTTPS is enabled but cannot find the private key and/or certificate. '
                            'Attempting to generate them')
                private_key = configuration.generate_private_key(api_conf['https']['key'])
                logger.info(f"Generated private key file in WAZUH_PATH/{to_relative_path(api_conf['https']['key'])}")
                configuration.generate_self_signed_certificate(private_key, api_conf['https']['cert'])
                logger.info(f"Generated certificate file in WAZUH_PATH/{to_relative_path(api_conf['https']['cert'])}")

            # Load SSL context
            allowed_ssl_ciphers = {
                'tls': ssl.PROTOCOL_TLS,
                'tlsv1': ssl.PROTOCOL_TLSv1,
                'tlsv1.1': ssl.PROTOCOL_TLSv1_1,
                'tlsv1.2': ssl.PROTOCOL_TLSv1_2
            }
            try:
                ssl_cipher = allowed_ssl_ciphers[api_conf['https']['ssl_cipher'].lower()]
            except (KeyError, AttributeError):
                # KeyError: invalid string value
                # AttributeError: invalid boolean value
                logger.error(str(APIError(2003, details='SSL cipher is not valid. Allowed values: '
                                                        'TLS, TLSv1, TLSv1.1, TLSv1.2')))
                sys.exit(1)
            ssl_context = ssl.SSLContext(protocol=ssl_cipher)
            if api_conf['https']['use_ca']:
                ssl_context.verify_mode = ssl.CERT_REQUIRED
                ssl_context.load_verify_locations(api_conf['https']['ca'])
            ssl_context.load_cert_chain(certfile=api_conf['https']['cert'],
                                        keyfile=api_conf['https']['key'])
        except ssl.SSLError:
            logger.error(str(APIError(2003, details='Private key does not match with the certificate')))
            sys.exit(1)
        except IOError as e:
            if e.errno == 22:
                logger.error(str(APIError(2003, details='PEM phrase is not correct')))
            elif e.errno == 13:
                logger.error(str(APIError(2003, details='Ensure the certificates have the correct permissions')))
            else:
                print('Wazuh API SSL ERROR. Please, ensure if path to certificates is correct in the configuration '
                      f'file WAZUH_PATH/{to_relative_path(CONFIG_FILE_PATH)}')
            sys.exit(1)

    # Drop privileges to ossec
    if not root:
        if api_conf['drop_privileges']:
            os.setgid(common.ossec_gid())
            os.setuid(common.ossec_uid())
    else:
        print(f"Starting API as root")

    # Foreground/Daemon
    if not foreground:
        pyDaemonModule.pyDaemon()
        pyDaemonModule.create_pid('wazuh-apid', os.getpid())
    else:
        print(f"Starting API in foreground")

    # Load the SPEC file into memory to use as a reference for future calls
    wazuh.security.load_spec()

    # Set up API
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    app = connexion.AioHttpApp(__name__, host=api_conf['host'],
                               port=api_conf['port'],
                               specification_dir=os.path.join(api_path[0], 'spec'),
                               options={"swagger_ui": False, 'uri_parser_class': APIUriParser},
                               only_one_api=True
                               )
    app.add_api('spec.yaml',
                arguments={'title': 'Wazuh API',
                           'protocol': 'https' if api_conf['https']['enabled'] else 'http',
                           'host': api_conf['host'],
                           'port': api_conf['port']
                           },
                strict_validation=True,
                validate_responses=False,
                pass_context_arg_name='request',
                options={"middlewares": [response_postprocessing, set_user_name, security_middleware, request_logging,
                                         set_secure_headers]})

    # Enable CORS
    if api_conf['cors']['enabled']:
        import aiohttp_cors
        cors = aiohttp_cors.setup(app.app, defaults={
            api_conf['cors']['source_route']: aiohttp_cors.ResourceOptions(
                expose_headers=api_conf['cors']['expose_headers'],
                allow_headers=api_conf['cors']['allow_headers'],
                allow_credentials=api_conf['cors']['allow_credentials']
            )
        })
        # Configure CORS on all endpoints.
        for route in list(app.app.router.routes()):
            cors.add(route)

    # Enable cache plugin
    if api_conf['cache']['enabled']:
        setup_cache(app.app)

    # API configuration logging
    logger.debug(f'Loaded API configuration: {api_conf}')
    logger.debug(f'Loaded security API configuration: {security_conf}')

    # Start API
    app.run(port=api_conf['port'],
            host=api_conf['host'],
            ssl_context=ssl_context,
            access_log_class=alogging.AccessLogger,
            use_default_access_log=True
            )
Ejemplo n.º 6
0
        async def update_file(name: str, data: Dict):
            """Update a local file with one received from a worker.

            The modification date is checked to decide whether to update ir or not.

            Parameters
            ----------
            name : str
                Relative path of the file.
            data : dict
                Metadata of the file (MD5, merged, etc).
            """
            # Full path
            full_path, error_updating_file = os.path.join(
                common.wazuh_path, name), False

            try:
                # Only valid client.keys is the local one (master).
                if os.path.basename(name) == 'client.keys':
                    self.logger.warning(
                        "Client.keys received in a master node")
                    raise exception.WazuhClusterError(3007)

                # If the file is merged, create individual files from it.
                if data['merged']:
                    for file_path, file_data, file_time in wazuh.core.cluster.cluster.unmerge_info(
                            data['merge_type'], decompressed_files_path,
                            data['merge_name']):
                        # Destination path.
                        full_unmerged_name = os.path.join(
                            common.wazuh_path, file_path)
                        # Path where to create the file before moving it to the destination path (with safe_move).
                        tmp_unmerged_path = os.path.join(
                            common.wazuh_path, 'queue', 'cluster', self.name,
                            os.path.basename(file_path))

                        try:
                            agent_id = os.path.basename(file_path)
                            # If the agent does not exist on the master, do not copy its file from the worker.
                            if agent_id not in agent_ids:
                                n_errors['warnings'][data['cluster_item_key']] = 1 \
                                    if n_errors['warnings'].get(data['cluster_item_key']) is None \
                                    else n_errors['warnings'][data['cluster_item_key']] + 1

                                self.logger.debug2(
                                    f"Received group of an non-existent agent '{agent_id}'"
                                )
                                continue

                            # Format the file_data specified inside the merged file.
                            try:
                                mtime = datetime.strptime(
                                    file_time, '%Y-%m-%d %H:%M:%S.%f')
                            except ValueError:
                                mtime = datetime.strptime(
                                    file_time, '%Y-%m-%d %H:%M:%S')

                            # If the file already existed, check if it is older than the one to be copied from worker.
                            if os.path.isfile(full_unmerged_name):
                                local_mtime = datetime.utcfromtimestamp(
                                    int(os.stat(full_unmerged_name).st_mtime))
                                if local_mtime > mtime:
                                    logger.debug2(
                                        f"Receiving an old file ({file_path})")
                                    continue

                            # Create file in temporal path and safe move it to the destination path.
                            with open(tmp_unmerged_path, 'wb') as f:
                                f.write(file_data)

                            mtime_epoch = timegm(mtime.timetuple())
                            utils.safe_move(
                                tmp_unmerged_path,
                                full_unmerged_name,
                                ownership=(common.ossec_uid(),
                                           common.ossec_gid()),
                                permissions=self.cluster_items['files'][
                                    data['cluster_item_key']]['permissions'],
                                time=(mtime_epoch, mtime_epoch))
                            self.integrity_sync_status[
                                'total_extra_valid'] += 1
                        except Exception as e:
                            self.logger.error(
                                f"Error updating agent group/status ({tmp_unmerged_path}): {e}"
                            )

                            n_errors['errors'][data['cluster_item_key']] = 1 \
                                if n_errors['errors'].get(data['cluster_item_key']) is None \
                                else n_errors['errors'][data['cluster_item_key']] + 1
                        await asyncio.sleep(0.0001)

                # If the file is not merged, move it directly to the destination path.
                else:
                    zip_path = os.path.join(decompressed_files_path, name)
                    utils.safe_move(zip_path,
                                    full_path,
                                    ownership=(common.ossec_uid(),
                                               common.ossec_gid()),
                                    permissions=self.cluster_items['files']
                                    [data['cluster_item_key']]['permissions'])

            except exception.WazuhException as e:
                logger.debug2(f"Warning updating file '{name}': {e}")
                error_tag = 'warnings'
                error_updating_file = True
            except Exception as e:
                logger.debug2(f"Error updating file '{name}': {e}")
                error_tag = 'errors'
                error_updating_file = True

            if error_updating_file:
                n_errors[error_tag][data['cluster_item_key']] = 1 if not n_errors[error_tag].get(
                    data['cluster_item_key']) \
                    else n_errors[error_tag][data['cluster_item_key']] + 1
Ejemplo n.º 7
0
        async def update_file(name: str, data: Dict):
            """
            Updates a file from the worker. It checks the modification date to decide whether to update it or not.
            If it's a merged file, it unmerges it.
            :param name: Filename to update
            :param data: File metadata
            :return: None
            """
            # Full path
            full_path, error_updating_file, n_merged_files = common.ossec_path + name, False, 0

            # Cluster items information: write mode and permissions
            lock_full_path = "{}/queue/cluster/lockdir/{}.lock".format(common.ossec_path, os.path.basename(full_path))
            lock_file = open(lock_full_path, 'a+')
            try:
                fcntl.lockf(lock_file, fcntl.LOCK_EX)
                if os.path.basename(name) == 'client.keys':
                    self.logger.warning("Client.keys received in a master node")
                    raise exception.WazuhClusterError(3007)
                if data['merged']:
                    self.sync_extra_valid_status['total_extra_valid'] = len(agent_ids)
                    for file_path, file_data, file_time in wazuh.core.cluster.cluster.unmerge_info(data['merge_type'],
                                                                                                   decompressed_files_path,
                                                                                                   data['merge_name']):
                        full_unmerged_name = os.path.join(common.ossec_path, file_path)
                        tmp_unmerged_path = os.path.join(common.ossec_path, 'queue/cluster', self.name, os.path.basename(file_path))
                        try:
                            agent_id = os.path.basename(file_path)
                            if agent_id not in agent_ids:
                                n_errors['warnings'][data['cluster_item_key']] = 1 \
                                    if n_errors['warnings'].get(data['cluster_item_key']) is None \
                                    else n_errors['warnings'][data['cluster_item_key']] + 1

                                self.logger.debug2("Received group of an non-existent agent '{}'".format(agent_id))
                                continue

                            try:
                                mtime = datetime.strptime(file_time, '%Y-%m-%d %H:%M:%S.%f')
                            except ValueError:
                                mtime = datetime.strptime(file_time, '%Y-%m-%d %H:%M:%S')

                            if os.path.isfile(full_unmerged_name):

                                local_mtime = datetime.utcfromtimestamp(int(os.stat(full_unmerged_name).st_mtime))
                                # check if the date is older than the manager's date
                                if local_mtime > mtime:
                                    logger.debug2("Receiving an old file ({})".format(file_path))
                                    continue

                            with open(tmp_unmerged_path, 'wb') as f:
                                f.write(file_data)

                            mtime_epoch = timegm(mtime.timetuple())
                            utils.safe_move(tmp_unmerged_path, full_unmerged_name,
                                            ownership=(common.ossec_uid(), common.ossec_gid()),
                                            permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions'],
                                            time=(mtime_epoch, mtime_epoch)
                                            )
                        except Exception as e:
                            self.logger.error("Error updating agent group/status ({}): {}".format(tmp_unmerged_path, e))
                            self.sync_extra_valid_status['total_extra_valid'] -= 1

                            n_errors['errors'][data['cluster_item_key']] = 1 \
                                if n_errors['errors'].get(data['cluster_item_key']) is None \
                                else n_errors['errors'][data['cluster_item_key']] + 1
                        await asyncio.sleep(0.0001)

                else:
                    zip_path = "{}{}".format(decompressed_files_path, name)
                    utils.safe_move(zip_path, full_path,
                                    ownership=(common.ossec_uid(), common.ossec_gid()),
                                    permissions=self.cluster_items['files'][data['cluster_item_key']]['permissions']
                                    )

            except exception.WazuhException as e:
                logger.debug2("Warning updating file '{}': {}".format(name, e))
                error_tag = 'warnings'
                error_updating_file = True
            except Exception as e:
                logger.debug2("Error updating file '{}': {}".format(name, e))
                error_tag = 'errors'
                error_updating_file = True

            if error_updating_file:
                n_errors[error_tag][data['cluster_item_key']] = 1 if not n_errors[error_tag].get(
                    data['cluster_item_key']) \
                    else n_errors[error_tag][data['cluster_item_key']] + 1

            fcntl.lockf(lock_file, fcntl.LOCK_UN)
            lock_file.close()
Ejemplo n.º 8
0
def test_ossec_uid():
    with patch('wazuh.core.common.getpwnam', return_value=getpwnam("root")):
        ossec_uid()
Ejemplo n.º 9
0
                        default=common.ossec_conf)
    args = parser.parse_args()

    if args.version:
        print_version()
        sys.exit(0)

    # Set logger
    try:
        debug_mode = configuration.get_internal_options_value('wazuh_clusterd', 'debug', 2, 0) or args.debug_level
    except Exception:
        debug_mode = 0

    # set correct permissions on cluster.log file
    if os.path.exists('{0}/logs/cluster.log'.format(common.wazuh_path)):
        os.chown('{0}/logs/cluster.log'.format(common.wazuh_path), common.ossec_uid(), common.ossec_gid())
        os.chmod('{0}/logs/cluster.log'.format(common.wazuh_path), 0o660)

    main_logger = set_logging(foreground_mode=args.foreground, debug_mode=debug_mode)

    cluster_configuration = cluster_utils.read_config(config_file=args.config_file)
    if cluster_configuration['disabled']:
        sys.exit(0)
    cluster_items = cluster_utils.get_cluster_items()
    try:
        wazuh.core.cluster.cluster.check_cluster_config(cluster_configuration)
    except Exception as e:
        main_logger.error(e)
        sys.exit(1)

    if args.test_config:
Ejemplo n.º 10
0
def start(foreground, root, config_file):
    """
    Run the Wazuh API.

    If another Wazuh API is running, this function fails. The `stop` command should be used first.
    This function exits with 0 if success or 2 if failed because the API was already running.

    Arguments
    ---------
    foreground : bool
        If the API must be daemonized or not
    root : bool
        If true, the daemon is run as root. Normally not recommended for security reasons
    config_file : str
        Path to the API config file
    """

    pids = get_wazuh_apid_pids()
    if pids:
        print(
            f"Cannot start API while other processes are running. Kill these before {pids}"
        )
        sys.exit(2)

    configuration.api_conf.update(
        configuration.read_yaml_config(config_file=args.config_file))
    api_conf = configuration.api_conf
    cors = api_conf['cors']
    log_path = api_conf['logs']['path']

    ssl_context = None
    if api_conf['https']['enabled'] and os.path.exists(api_conf['https']['key']) and \
            os.path.exists(api_conf['https']['cert']):
        try:
            ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS)
            if api_conf['https']['use_ca']:
                ssl_context.verify_mode = ssl.CERT_REQUIRED
                ssl_context.load_verify_locations(api_conf['https']['ca'])
            ssl_context.load_cert_chain(certfile=api_conf['https']['cert'],
                                        keyfile=api_conf['https']['key'])
        except ssl.SSLError as e:
            raise APIException(
                2003,
                details='Private key does not match with the certificate')
        except OSError as e:
            if e.errno == 22:
                raise APIException(2003, details='PEM phrase is not correct')

    # Foreground/Daemon
    if not foreground:
        print(f"Starting API in background")
        pyDaemonModule.pyDaemon()

    # Drop privileges to ossec
    if not root:
        if api_conf['drop_privileges']:
            os.setgid(common.ossec_gid())
            os.setuid(common.ossec_uid())

    set_logging(log_path=log_path,
                debug_mode=api_conf['logs']['level'],
                foreground_mode=args.foreground)

    # set correct permissions on api.log file
    if os.path.exists(os.path.join(common.ossec_path, log_path)):
        os.chown(os.path.join(common.ossec_path, log_path), common.ossec_uid(),
                 common.ossec_gid())
        os.chmod(os.path.join(common.ossec_path, log_path), 0o660)

    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    app = connexion.AioHttpApp(__name__,
                               host=api_conf['host'],
                               port=api_conf['port'],
                               specification_dir=os.path.join(
                                   api_path[0], 'spec'),
                               options={"swagger_ui": False})
    app.add_api('spec.yaml',
                arguments={
                    'title': 'Wazuh API',
                    'protocol':
                    'https' if api_conf['https']['enabled'] else 'http',
                    'host': api_conf['host'],
                    'port': api_conf['port']
                },
                strict_validation=True,
                validate_responses=True,
                pass_context_arg_name='request',
                options={"middlewares": [set_user_name, check_experimental]})

    # Enable CORS
    if cors['enabled']:
        cors = aiohttp_cors.setup(
            app.app,
            defaults={
                cors['source_route']:
                aiohttp_cors.ResourceOptions(
                    expose_headers=cors['expose_headers'],
                    allow_headers=cors['allow_headers'],
                    allow_credentials=cors['allow_credentials'])
            })
        # Configure CORS on all endpoints.
        for route in list(app.app.router.routes()):
            cors.add(route)

    # Enable cache plugin
    setup_cache(app.app)

    # Enable swagger UI plugin
    setup_swagger(app.app,
                  ui_version=3,
                  swagger_url='/ui',
                  swagger_from_file=os.path.join(app.specification_dir,
                                                 'spec.yaml'))

    # Configure https
    if api_conf['https']['enabled']:

        # Generate SSC if it does not exist and HTTPS is enabled
        if not os.path.exists(api_conf['https']['key']) or \
                not os.path.exists(api_conf['https']['cert']):
            logger = logging.getLogger('wazuh')
            logger.info(
                'HTTPS is enabled but cannot find the private key and/or certificate. '
                'Attempting to generate them.')
            private_key = generate_private_key(api_conf['https']['key'])
            logger.info(
                f"Generated private key file in WAZUH_PATH/{to_relative_path(api_conf['https']['key'])}."
            )
            generate_self_signed_certificate(private_key,
                                             api_conf['https']['cert'])
            logger.info(
                f"Generated certificate file in WAZUH_PATH/{to_relative_path(api_conf['https']['cert'])}."
            )

        if ssl_context is None:
            try:
                ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS)
                if api_conf['https']['use_ca']:
                    ssl_context.verify_mode = ssl.CERT_REQUIRED
                    ssl_context.load_verify_locations(api_conf['https']['ca'])
                ssl_context.load_cert_chain(certfile=api_conf['https']['cert'],
                                            keyfile=api_conf['https']['key'])
            except ssl.SSLError as e:
                raise APIException(
                    2003,
                    details='Private key does not match with the certificate')
            except IOError as e:
                raise APIException(
                    2003,
                    details=
                    'Please, ensure if path to certificates is correct in the configuration '
                    f'file WAZUH_PATH/{to_relative_path(CONFIG_FILE_PATH)}')

    app.run(port=api_conf['port'],
            host=api_conf['host'],
            ssl_context=ssl_context,
            access_log_class=alogging.AccessLogger,
            use_default_access_log=True)
Ejemplo n.º 11
0
    if args.version:
        print_version()
        sys.exit(0)

    # Set logger
    try:
        debug_mode = configuration.get_internal_options_value(
            'wazuh_clusterd', 'debug', 2, 0) or args.debug_level
    except Exception:
        debug_mode = 0

    # set correct permissions on cluster.log file
    if os.path.exists('{0}/logs/cluster.log'.format(common.ossec_path)):
        os.chown('{0}/logs/cluster.log'.format(common.ossec_path),
                 common.ossec_uid(), common.ossec_gid())
        os.chmod('{0}/logs/cluster.log'.format(common.ossec_path), 0o660)

    main_logger = set_logging(foreground_mode=args.foreground,
                              debug_mode=debug_mode)

    cluster_configuration = cluster_utils.read_config(
        config_file=args.config_file)
    if cluster_configuration['disabled']:
        sys.exit(0)
    cluster_items = cluster_utils.get_cluster_items()
    try:
        wazuh.core.cluster.cluster.check_cluster_config(cluster_configuration)
    except Exception as e:
        main_logger.error(e)
        sys.exit(1)