{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at https://securityonion.net/license; you may not use this file except in compliance with the Elastic License 2.0. #} {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'soc/defaults.map.jinja' import SOCDEFAULTS with context %} {% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_NODES %} {% from 'manager/map.jinja' import MANAGERMERGED %} {% set DOCKER_EXTRA_HOSTS = ELASTICSEARCH_NODES %} {% do DOCKER_EXTRA_HOSTS.append({GLOBALS.influxdb_host:pillar.node_data[GLOBALS.influxdb_host].ip}) %} {% set SOCMERGED = salt['pillar.get']('soc', SOCDEFAULTS, merge=true) %} {% do SOCMERGED.config.server.update({'proxy': MANAGERMERGED.proxy}) %} {% do SOCMERGED.config.server.update({'additionalCA': MANAGERMERGED.additionalCA}) %} {% do SOCMERGED.config.server.update({'insecureSkipVerify': MANAGERMERGED.insecureSkipVerify}) %} {# if SOCMERGED.config.server.modules.cases == httpcase details come from the soc pillar #} {% if SOCMERGED.config.server.modules.cases != 'soc' %} {% do SOCMERGED.config.server.modules.elastic.update({'casesEnabled': false}) %} {% do SOCMERGED.config.server.client.update({'casesEnabled': false}) %} {% do SOCMERGED.config.server.client.hunt.update({'escalateRelatedEventsEnabled': false}) %} {% do SOCMERGED.config.server.client.alerts.update({'escalateRelatedEventsEnabled': false}) %} {% if SOCMERGED.config.server.modules.cases == 'elasticcases' %} {% do SOCMERGED.config.server.modules.update({ 'elasticcases': { 'hostUrl': 'https://' ~ GLOBALS.manager_ip ~ ':5601', 'username': GLOBALS.elasticsearch.auth.users.so_elastic_user.user, 'password': GLOBALS.elasticsearch.auth.users.so_elastic_user.pass, } }) %} {% endif %} {% endif %} {# since cases is not a valid soc config item and only used for the map files, remove it from being placed in the config #} {% do SOCMERGED.config.server.modules.pop('cases') %} {# set enabled Sigma rules based on role if defined and default if not #} {# this particular config is deprecated as of 2.4.120 - use enabledSigmaRules instead #} {% if GLOBALS.role in SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules %} {% do SOCMERGED.config.server.modules.elastalertengine.update({'autoEnabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules[GLOBALS.role]}) %} {% else %} {% do SOCMERGED.config.server.modules.elastalertengine.update({'autoEnabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.autoEnabledSigmaRules.default}) %} {% endif %} {# set enabled Sigma rules based on role if defined and default if not #} {% if GLOBALS.role in SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules %} {% do SOCMERGED.config.server.modules.elastalertengine.update({'enabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules[GLOBALS.role]}) %} {% else %} {% do SOCMERGED.config.server.modules.elastalertengine.update({'enabledSigmaRules': SOCMERGED.config.server.modules.elastalertengine.enabledSigmaRules.default}) %} {% endif %} {# set elastalertengine.rulesRepos, strelkaengine.rulesRepos, and suricataengine.rulesetSources based on airgap or not #} {% if GLOBALS.airgap %} {% do SOCMERGED.config.server.modules.elastalertengine.update({'rulesRepos': SOCMERGED.config.server.modules.elastalertengine.rulesRepos.airgap}) %} {% do SOCMERGED.config.server.modules.strelkaengine.update({'rulesRepos': SOCMERGED.config.server.modules.strelkaengine.rulesRepos.airgap}) %} {#% if SOCMERGED.config.server.modules.suricataengine.rulesetSources is mapping %#} {% do SOCMERGED.config.server.modules.suricataengine.update({'rulesetSources': SOCMERGED.config.server.modules.suricataengine.rulesetSources.airgap}) %} {#% endif %#} {% do SOCMERGED.config.server.update({'airgapEnabled': true}) %} {% else %} {% do SOCMERGED.config.server.modules.elastalertengine.update({'rulesRepos': SOCMERGED.config.server.modules.elastalertengine.rulesRepos.default}) %} {% do SOCMERGED.config.server.modules.strelkaengine.update({'rulesRepos': SOCMERGED.config.server.modules.strelkaengine.rulesRepos.default}) %} {#% if SOCMERGED.config.server.modules.suricataengine.rulesetSources is mapping %#} {% do SOCMERGED.config.server.modules.suricataengine.update({'rulesetSources': SOCMERGED.config.server.modules.suricataengine.rulesetSources.default}) %} {#% endif %#} {% do SOCMERGED.config.server.update({'airgapEnabled': false}) %} {% endif %} {# Define the Detections custom ruleset that should always be present #} {% set CUSTOM_RULESET = { 'name': '__custom__', 'description': 'User-created custom rules created via the Detections module in the SOC UI', 'sourceType': 'elasticsearch', 'sourcePath': 'so_detection.ruleset:__custom__', 'readOnly': false, 'deleteUnreferenced': false, 'license': 'Custom', 'enabled': true } %} {# Always append the custom ruleset to suricataengine.rulesetSources if not already present #} {% if SOCMERGED.config.server.modules.suricataengine is defined and SOCMERGED.config.server.modules.suricataengine.rulesetSources is defined %} {% if SOCMERGED.config.server.modules.suricataengine.rulesetSources is not mapping %} {% set custom_names = SOCMERGED.config.server.modules.suricataengine.rulesetSources | selectattr('name', 'equalto', '__custom__') | list %} {% if custom_names | length == 0 %} {% do SOCMERGED.config.server.modules.suricataengine.rulesetSources.append(CUSTOM_RULESET) %} {% endif %} {% endif %} {% endif %} {# Enable SO_FILTERS and SO_EXTRACTIONS when Suricata is the metadata engine #} {% if SOCMERGED.config.server.modules.suricataengine is defined and SOCMERGED.config.server.modules.suricataengine.rulesetSources is defined %} {% if SOCMERGED.config.server.modules.suricataengine.rulesetSources is not mapping %} {% for ruleset in SOCMERGED.config.server.modules.suricataengine.rulesetSources %} {% if ruleset.name in ['SO_FILTERS', 'SO_EXTRACTIONS'] and GLOBALS.md_engine == 'SURICATA' %} {% do ruleset.update({'enabled': true}) %} {% endif %} {% endfor %} {% endif %} {% endif %} {# Transform Emerging-Threats ruleset based on license key #} {% if SOCMERGED.config.server.modules.suricataengine is defined and SOCMERGED.config.server.modules.suricataengine.rulesetSources is defined %} {% if SOCMERGED.config.server.modules.suricataengine.rulesetSources is not mapping %} {% for ruleset in SOCMERGED.config.server.modules.suricataengine.rulesetSources %} {% if ruleset.name == 'Emerging-Threats' %} {% if ruleset.licenseKey and ruleset.licenseKey != '' %} {# License key is defined - transform to ETPRO #} {% if ruleset.sourceType == 'directory' %} {# Airgap mode - update directory path #} {% do ruleset.update({ 'name': 'ETPRO', 'sourcePath': '/nsm/rules/custom-local-repos/local-etpro-suricata/etpro.rules.tar.gz', 'license': 'Commercial' }) %} {% else %} {# Engine Version is hardcoded in the URL - this does not change often: https://community.emergingthreats.net/t/supported-engines/71 #} {% do ruleset.update({ 'name': 'ETPRO', 'sourcePath': 'https://rules.emergingthreatspro.com/' ~ ruleset.licenseKey ~ '/suricata-7.0.3/etpro.rules.tar.gz', 'urlHash': 'https://rules.emergingthreatspro.com/' ~ ruleset.licenseKey ~ '/suricata-7.0.3/etpro.rules.tar.gz.md5', 'license': 'Commercial' }) %} {% endif %} {% else %} {# No license key - explicitly set to ETOPEN #} {% if ruleset.sourceType == 'directory' %} {# Airgap mode - update directory path #} {% do ruleset.update({ 'name': 'ETOPEN', 'sourcePath': '/nsm/rules/suricata/etopen/', 'license': 'BSD' }) %} {% else %} {% do ruleset.update({ 'name': 'ETOPEN', 'sourcePath': 'https://rules.emergingthreats.net/open/suricata-7.0.3/emerging.rules.tar.gz', 'urlHash': 'https://rules.emergingthreats.net/open/suricata-7.0.3/emerging.rules.tar.gz.md5', 'license': 'BSD' }) %} {% endif %} {% endif %} {% endif %} {% endfor %} {% endif %} {% endif %} {# set playbookRepos based on airgap or not #} {% if GLOBALS.airgap %} {% do SOCMERGED.config.server.modules.playbook.update({'playbookRepos': SOCMERGED.config.server.modules.playbook.playbookRepos.airgap}) %} {% else %} {% do SOCMERGED.config.server.modules.playbook.update({'playbookRepos': SOCMERGED.config.server.modules.playbook.playbookRepos.default}) %} {% endif %} {# remove these modules if detections is disabled #} {% if not SOCMERGED.config.server.client.detectionsEnabled %} {% do SOCMERGED.config.server.modules.pop('elastalertengine') %} {% do SOCMERGED.config.server.modules.pop('strelkaengine') %} {% do SOCMERGED.config.server.modules.pop('suricataengine') %} {% elif pillar.global.airgap %} {# if system is Airgap, don't autoupdate Yara & Sigma rules #} {% do SOCMERGED.config.server.modules.elastalertengine.update({'autoUpdateEnabled': false}) %} {% do SOCMERGED.config.server.modules.strelkaengine.update({'autoUpdateEnabled': false}) %} {% endif %} {% set standard_actions = SOCMERGED.config.pop('actions') %} {% if pillar.global.endgamehost != '' %} {# this is added to prevent endgame_dict from being added to standard_actions for each time this file is rendered #} {# since this map file is rendered 3 times, it causes endgame_dict to appened 3 times if custom actions are defined in the pillar #} {% set endgame = namespace(add=true) %} {% for d in standard_actions %} {% if d.name is defined %} {% if d.name == 'Endgame' %} {% set endgame.add = false %} {% endif %} {% endif %} {% endfor %} {% set endgame_dict = { "name": "Endgame", "description": "Endgame Endpoint Investigation and Response", "icon": "fa-external-link-alt", "target": "_blank", "links": ["https://" ~ pillar.global.endgamehost ~ "/endpoints/{:agent.id}"] } %} {% if endgame.add %} {% do standard_actions.append(endgame_dict) %} {% endif %} {% endif %} {% do SOCMERGED.config.server.client.hunt.update({'actions': standard_actions}) %} {% do SOCMERGED.config.server.client.dashboards.update({'actions': standard_actions}) %} {% do SOCMERGED.config.server.client.update({'job': {'actions': standard_actions}}) %} {% do SOCMERGED.config.server.client.alerts.update({'actions': standard_actions}) %} {% do SOCMERGED.config.server.client.cases.update({'actions': standard_actions}) %} {% do SOCMERGED.config.server.client.detections.update({'actions': standard_actions}) %} {# replace the _x_ with . for soc ui to config conversion #} {% do SOCMERGED.config.eventFields.update({':endpoint:events.api': SOCMERGED.config.eventFields.pop(':endpoint:events_x_api') }) %} {% do SOCMERGED.config.eventFields.update({':endpoint:events.file': SOCMERGED.config.eventFields.pop(':endpoint:events_x_file') }) %} {% do SOCMERGED.config.eventFields.update({':endpoint:events.library': SOCMERGED.config.eventFields.pop(':endpoint:events_x_library') }) %} {% do SOCMERGED.config.eventFields.update({':endpoint:events.network': SOCMERGED.config.eventFields.pop(':endpoint:events_x_network') }) %} {% do SOCMERGED.config.eventFields.update({':endpoint:events.process': SOCMERGED.config.eventFields.pop(':endpoint:events_x_process') }) %} {% do SOCMERGED.config.eventFields.update({':endpoint:events.registry': SOCMERGED.config.eventFields.pop(':endpoint:events_x_registry') }) %} {% do SOCMERGED.config.eventFields.update({':endpoint:events.security': SOCMERGED.config.eventFields.pop(':endpoint:events_x_security') }) %} {% set standard_eventFields = SOCMERGED.config.pop('eventFields') %} {% do SOCMERGED.config.server.client.hunt.update({'eventFields': standard_eventFields}) %} {% do SOCMERGED.config.server.client.dashboards.update({'eventFields': standard_eventFields}) %}