Compare commits

..

7 Commits

Author SHA1 Message Date
Mike Reeves
acc9b8062e Remove Strelka container infrastructure
Removes all Strelka container salt states and infrastructure references,
replaced by the native fileanalyze module in sensoroni.

Removed:
- salt/strelka/ directory (all container states, configs, tools)
- Docker container definitions for 6 Strelka containers
- Firewall rules for strelka_frontend
- Container references in containers.map.jinja
- top.sls and allowed_states references to strelka/strelka.manager
- so-minion add_strelka_to_minion() function and call sites
- so-deny strelka_frontend entry
- Logstash strelka bind mount
- Logrotate strelka config
- Telegraf strelka file monitoring
- so-sensor-clean strelka cleanup
- so-image-common strelka container images

Kept (still needed):
- Elasticsearch index/ingest pipeline (ingests fileanalyze output)
- Elastic agent/fleet log collection config
- SOC strelkaengine (YARA rule management)
- Kibana saved objects (dashboards)
2026-04-06 14:57:22 -04:00
Mike Reeves
c6c538363d Add fileanalyze module salt configuration
Adds sensoroni agent configuration for the new fileanalyze module
that replaces the Strelka file analysis containers:
- defaults.yaml: default config values (watchDirs, concurrency, dedup, etc.)
- sensoroni.json: Jinja2 template to render module config when enabled
- soc_sensoroni.yaml: SOC config schema with descriptions for all settings
2026-04-06 14:12:48 -04:00
Mike Reeves
88de246ce3 Merge pull request #15725 from Security-Onion-Solutions/3/main
License Link to dev
2026-04-06 10:59:22 -04:00
Mike Reeves
3643b57167 Merge pull request #15724 from Security-Onion-Solutions/TOoSmOotH-patch-2
Fix JA4+ license link in soc_zeek.yaml
2026-04-06 10:24:04 -04:00
Mike Reeves
5b3ca98b80 Fix JA4+ license link in soc_zeek.yaml
Updated the license link in the JA4+ fingerprinting description.
2026-04-06 10:12:37 -04:00
Jason Ertel
76f4ccf8c8 Merge pull request #15705 from Security-Onion-Solutions/3/main
Merge pr/workflow changes back to dev
2026-04-01 10:57:34 -04:00
Mike Reeves
3dec6986b6 Merge pull request #15702 from Security-Onion-Solutions/3/main
soup fix
2026-03-31 15:12:01 -04:00
105 changed files with 452 additions and 4694 deletions

View File

@@ -1 +1 @@
3.0.0-foxtrot
3.1.0

View File

@@ -0,0 +1,2 @@
elasticsearch:
index_settings:

View File

@@ -97,6 +97,7 @@ base:
- node_data.ips
- secrets
- healthcheck.eval
- elasticsearch.index_templates
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
- elasticsearch.auth
{% endif %}
@@ -141,6 +142,7 @@ base:
- logstash.nodes
- logstash.soc_logstash
- logstash.adv_logstash
- elasticsearch.index_templates
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
- elasticsearch.auth
{% endif %}
@@ -254,6 +256,7 @@ base:
'*_import':
- node_data.ips
- secrets
- elasticsearch.index_templates
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
- elasticsearch.auth
{% endif %}

View File

@@ -41,8 +41,7 @@
'suricata',
'healthcheck',
'tcpreplay',
'zeek',
'strelka'
'zeek'
] %}
{% set kafka_states = [
@@ -84,26 +83,26 @@
),
'so-import': (
manager_states +
sensor_states | reject('equalto', 'strelka') | reject('equalto', 'healthcheck') | list +
['elasticsearch', 'elasticsearch.auth', 'kibana', 'kibana.secrets', 'logstash.ssl', 'strelka.manager']
sensor_states | reject('equalto', 'healthcheck') | list +
['elasticsearch', 'elasticsearch.auth', 'kibana', 'kibana.secrets', 'logstash.ssl']
),
'so-manager': (
manager_states +
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] +
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users'] +
stig_states +
kafka_states +
elastic_stack_states
),
'so-managerhype': (
manager_states +
['salt.cloud', 'strelka.manager', 'hypervisor', 'libvirt'] +
['salt.cloud', 'hypervisor', 'libvirt'] +
stig_states +
kafka_states +
elastic_stack_states
),
'so-managersearch': (
manager_states +
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] +
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users'] +
stig_states +
kafka_states +
elastic_stack_states

View File

@@ -57,8 +57,6 @@ container_list() {
"so-pcaptools"
"so-redis"
"so-soc"
"so-strelka-backend"
"so-strelka-manager"
"so-suricata"
"so-telegraf"
"so-zeek"

View File

@@ -42,21 +42,6 @@ clean() {
# done
#fi
## Clean up Zeek extracted files processed by Strelka
STRELKA_FILES='/nsm/strelka/processed'
OLDEST_STRELKA=$(find $STRELKA_FILES -type f -printf '%T+ %p\n' | sort -n | head -n 1)
if [ -z "$OLDEST_STRELKA" -o "$OLDEST_STRELKA" == ".." -o "$OLDEST_STRELKA" == "." ]; then
echo "$(date) - No old files available to clean up in $STRELKA_FILES" >>$LOG
else
OLDEST_STRELKA_DATE=$(echo $OLDEST_STRELKA | awk '{print $1}' | cut -d+ -f1)
OLDEST_STRELKA_FILE=$(echo $OLDEST_STRELKA | awk '{print $2}')
echo "$(date) - Removing extracted files for $OLDEST_STRELKA_DATE" >>$LOG
find $STRELKA_FILES -type f -printf '%T+ %p\n' | grep $OLDEST_STRELKA_DATE | awk '{print $2}' | while read FILE; do
echo "$(date) - Removing file: $FILE" >>$LOG
rm -f "$FILE"
done
fi
## Clean up Suricata log files
SURICATA_LOGS='/nsm/suricata'
OLDEST_SURICATA=$(find $SURICATA_LOGS -type f -printf '%T+ %p\n' | sort -n | head -n 1)

View File

@@ -134,48 +134,6 @@ docker:
extra_hosts: []
extra_env: []
ulimits: []
'so-strelka-backend':
final_octet: 36
custom_bind_mounts: []
extra_hosts: []
extra_env: []
ulimits: []
'so-strelka-filestream':
final_octet: 37
custom_bind_mounts: []
extra_hosts: []
extra_env: []
ulimits: []
'so-strelka-frontend':
final_octet: 38
port_bindings:
- 0.0.0.0:57314:57314
custom_bind_mounts: []
extra_hosts: []
extra_env: []
ulimits: []
'so-strelka-manager':
final_octet: 39
custom_bind_mounts: []
extra_hosts: []
extra_env: []
ulimits: []
'so-strelka-gatekeeper':
final_octet: 40
port_bindings:
- 0.0.0.0:6381:6379
custom_bind_mounts: []
extra_hosts: []
extra_env: []
ulimits: []
'so-strelka-coordinator':
final_octet: 41
port_bindings:
- 0.0.0.0:6380:6379
custom_bind_mounts: []
extra_hosts: []
extra_env: []
ulimits: []
'so-elastalert':
final_octet: 42
custom_bind_mounts: []

View File

@@ -89,12 +89,6 @@ docker:
so-redis: *dockerOptions
so-sensoroni: *dockerOptions
so-soc: *dockerOptions
so-strelka-backend: *dockerOptions
so-strelka-filestream: *dockerOptions
so-strelka-frontend: *dockerOptions
so-strelka-manager: *dockerOptions
so-strelka-gatekeeper: *dockerOptions
so-strelka-coordinator: *dockerOptions
so-elastalert: *dockerOptions
so-elastic-fleet-package-registry: *dockerOptions
so-idh: *dockerOptions

View File

@@ -1,123 +0,0 @@
{# 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; you may not use
this file except in compliance with the Elastic License 2.0. #}
{% import_json '/opt/so/state/esfleet_content_package_components.json' as ADDON_CONTENT_PACKAGE_COMPONENTS %}
{% import_json '/opt/so/state/esfleet_component_templates.json' as INSTALLED_COMPONENT_TEMPLATES %}
{% import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %}
{% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %}
{% set ADDON_CONTENT_INTEGRATION_DEFAULTS = {} %}
{% set DEBUG_STUFF = {} %}
{% for pkg in ADDON_CONTENT_PACKAGE_COMPONENTS %}
{% if pkg.name in CORE_ESFLEET_PACKAGES %}
{# skip core content packages #}
{% elif pkg.name not in CORE_ESFLEET_PACKAGES %}
{# generate defaults for each content package #}
{% if pkg.dataStreams is defined and pkg.dataStreams is not none and pkg.dataStreams | length > 0%}
{% for pattern in pkg.dataStreams %}
{# in ES 9.3.2 'input' type integrations no longer create default component templates and instead they wait for user input during 'integration' setup (fleet ui config)
title: generic is an artifact of that and is not in use #}
{% if pattern.title == "generic" %}
{% continue %}
{% endif %}
{% if "metrics-" in pattern.name %}
{% set integration_type = "metrics-" %}
{% elif "logs-" in pattern.name %}
{% set integration_type = "logs-" %}
{% else %}
{% set integration_type = "" %}
{% endif %}
{# on content integrations the component name is user defined at the time it is added to an agent policy #}
{% set component_name = pattern.title %}
{% set index_pattern = pattern.name %}
{# component_name_x maintains the functionality of merging local pillar changes with generated 'defaults' via SOC UI #}
{% set component_name_x = component_name.replace(".","_x_") %}
{# pillar overrides/merge expects the key names to follow the naming in elasticsearch/defaults.yaml eg. so-logs-1password_x_item_usages . The _x_ is replaced later on in elasticsearch/template.map.jinja #}
{% set integration_key = "so-" ~ integration_type ~ pkg.name + '_x_' ~ component_name_x %}
{# Default integration settings #}
{% set integration_defaults = {
"index_sorting": false,
"index_template": {
"composed_of": [integration_type ~ component_name ~ "@package", integration_type ~ component_name ~ "@custom", "so-fleet_integrations.ip_mappings-1", "so-fleet_globals-1", "so-fleet_agent_id_verification-1"],
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"ignore_missing_component_templates": [integration_type ~ component_name ~ "@custom"],
"index_patterns": [index_pattern],
"priority": 501,
"template": {
"settings": {
"index": {
"lifecycle": {"name": "so-" ~ integration_type ~ component_name ~ "-logs"},
"number_of_replicas": 0
}
}
}
},
"policy": {
"phases": {
"cold": {
"actions": {
"allocate":{
"number_of_replicas": ""
},
"set_priority": {"priority": 0}
},
"min_age": "60d"
},
"delete": {
"actions": {
"delete": {}
},
"min_age": "365d"
},
"hot": {
"actions": {
"rollover": {
"max_age": "30d",
"max_primary_shard_size": "50gb"
},
"forcemerge":{
"max_num_segments": ""
},
"shrink":{
"max_primary_shard_size": "",
"method": "COUNT",
"number_of_shards": ""
},
"set_priority": {"priority": 100}
},
"min_age": "0ms"
},
"warm": {
"actions": {
"allocate": {
"number_of_replicas": ""
},
"forcemerge": {
"max_num_segments": ""
},
"shrink":{
"max_primary_shard_size": "",
"method": "COUNT",
"number_of_shards": ""
},
"set_priority": {"priority": 50}
},
"min_age": "30d"
}
}
}
} %}
{% do ADDON_CONTENT_INTEGRATION_DEFAULTS.update({integration_key: integration_defaults}) %}
{% endfor %}
{% else %}
{% endif %}
{% endif %}
{% endfor %}

View File

@@ -9,22 +9,16 @@
"namespace": "so",
"description": "Zeek Import logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/import/*/zeek/logs/*.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "import",
"pipeline": "",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -40,8 +34,7 @@
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -15,25 +15,19 @@
"version": ""
},
"name": "kratos-logs",
"namespace": "so",
"description": "Kratos logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/kratos/kratos.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "kratos",
"pipeline": "kratos",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -54,10 +48,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -9,22 +9,16 @@
"namespace": "so",
"description": "Zeek logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/zeek/logs/current/*.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "zeek",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
"exclude_files": ["({%- endraw -%}{{ ELASTICFLEETMERGED.logging.zeek.excluded | join('|') }}{%- raw -%})(\\..+)?\\.log$"],
@@ -36,10 +30,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -5,7 +5,7 @@
"package": {
"name": "endpoint",
"title": "Elastic Defend",
"version": "9.3.0",
"version": "9.0.2",
"requires_root": true
},
"enabled": true,

View File

@@ -6,23 +6,21 @@
"name": "agent-monitor",
"namespace": "",
"description": "",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"output_id": null,
"vars": {},
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/agents/agent-monitor.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "agentmonitor",
"pipeline": "elasticagent.monitor",
"parsers": "",
@@ -36,16 +34,15 @@
"ignore_older": "72h",
"clean_inactive": -1,
"harvester_limit": 0,
"fingerprint": false,
"fingerprint": true,
"fingerprint_offset": 0,
"file_identity_native": true,
"fingerprint_length": 64,
"file_identity_native": false,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}
}
},
"force": true
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "hydra-logs",
"namespace": "so",
"description": "Hydra logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/hydra/hydra.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "hydra",
"pipeline": "hydra",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -40,10 +34,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "idh-logs",
"namespace": "so",
"description": "IDH integration",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/idh/opencanary.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "idh",
"pipeline": "common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -37,10 +31,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,32 +4,26 @@
"version": ""
},
"name": "import-evtx-logs",
"namespace": "so",
"description": "Import Windows EVTX logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/import/*/evtx/*.json"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "import",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
"exclude_files": [
"\\.gz$"
],
"include_files": [],
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- drop_fields:\n fields: [\"host\"]\n ignore_missing: true\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: system.security\n- add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.security-2.13.0\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.sysmon_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.sysmon_operational-3.6.0\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.application\n - add_fields:\n target: event\n fields:\n dataset: system.application\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.application-2.13.0\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.system\n - add_fields:\n target: event\n fields:\n dataset: system.system\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.system-2.13.0\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.powershell_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.powershell_operational-3.6.0\n- add_fields:\n target: data_stream\n fields:\n dataset: import",
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- drop_fields:\n fields: [\"host\"]\n ignore_missing: true\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: system.security\n- add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.security-2.6.1\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.sysmon_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.sysmon_operational-3.1.2\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.application\n - add_fields:\n target: event\n fields:\n dataset: system.application\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.application-2.6.1\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.system\n - add_fields:\n target: event\n fields:\n dataset: system.system\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.system-2.6.1\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.powershell_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.powershell_operational-3.1.2\n- add_fields:\n target: data_stream\n fields:\n dataset: import",
"tags": [
"import"
],
@@ -39,10 +33,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "import-suricata-logs",
"namespace": "so",
"description": "Import Suricata logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/import/*/suricata/eve*.json"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "import",
"pipeline": "suricata.common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -38,10 +32,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,18 +4,14 @@
"version": ""
},
"name": "rita-logs",
"namespace": "so",
"description": "RITA Logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
@@ -23,8 +19,6 @@
"/nsm/rita/exploded-dns.csv",
"/nsm/rita/long-connections.csv"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "rita",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
"exclude_files": [
@@ -39,10 +33,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "so-ip-mappings",
"namespace": "so",
"description": "IP Description mappings",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/custom-mappings/ip-descriptions.csv"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "hostnamemappings",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
"exclude_files": [
@@ -38,10 +32,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "soc-auth-sync-logs",
"namespace": "so",
"description": "Security Onion - Elastic Auth Sync - Logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/soc/sync.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "soc",
"pipeline": "common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -37,10 +31,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,26 +4,20 @@
"version": ""
},
"name": "soc-detections-logs",
"namespace": "so",
"description": "Security Onion Console - Detections Logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/soc/detections_runtime-status_sigma.log",
"/opt/so/log/soc/detections_runtime-status_yara.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "soc",
"pipeline": "common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -41,10 +35,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "soc-salt-relay-logs",
"namespace": "so",
"description": "Security Onion - Salt Relay - Logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/soc/salt-relay.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "soc",
"pipeline": "common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -39,10 +33,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "soc-sensoroni-logs",
"namespace": "so",
"description": "Security Onion - Sensoroni - Logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/sensoroni/sensoroni.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "soc",
"pipeline": "common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -37,10 +31,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "soc-server-logs",
"namespace": "so",
"description": "Security Onion Console Logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/opt/so/log/soc/sensoroni-server.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "soc",
"pipeline": "common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -39,10 +33,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "strelka-logs",
"namespace": "so",
"description": "Strelka Logs",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/strelka/log/strelka.log"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "strelka",
"pipeline": "strelka.file",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -37,10 +31,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -4,25 +4,19 @@
"version": ""
},
"name": "suricata-logs",
"namespace": "so",
"description": "Suricata integration",
"policy_id": "so-grid-nodes_general",
"policy_ids": [
"so-grid-nodes_general"
],
"vars": {},
"namespace": "so",
"inputs": {
"filestream-filestream": {
"enabled": true,
"streams": {
"filestream.filestream": {
"filestream.generic": {
"enabled": true,
"vars": {
"paths": [
"/nsm/suricata/eve*.json"
],
"compression_gzip": false,
"use_logs_stream": false,
"data_stream.dataset": "suricata",
"pipeline": "suricata.common",
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
@@ -37,10 +31,10 @@
"harvester_limit": 0,
"fingerprint": false,
"fingerprint_offset": 0,
"fingerprint_length": "64",
"file_identity_native": true,
"exclude_lines": [],
"include_lines": [],
"delete_enabled": false
"include_lines": []
}
}
}

View File

@@ -1,123 +0,0 @@
{# 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; you may not use
this file except in compliance with the Elastic License 2.0. #}
{% import_json '/opt/so/state/esfleet_input_package_components.json' as ADDON_INPUT_PACKAGE_COMPONENTS %}
{% import_json '/opt/so/state/esfleet_component_templates.json' as INSTALLED_COMPONENT_TEMPLATES %}
{% import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %}
{% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %}
{% set ADDON_INPUT_INTEGRATION_DEFAULTS = {} %}
{% set DEBUG_STUFF = {} %}
{% for pkg in ADDON_INPUT_PACKAGE_COMPONENTS %}
{% if pkg.name in CORE_ESFLEET_PACKAGES %}
{# skip core input packages #}
{% elif pkg.name not in CORE_ESFLEET_PACKAGES %}
{# generate defaults for each input package #}
{% if pkg.dataStreams is defined and pkg.dataStreams is not none and pkg.dataStreams | length > 0 %}
{% for pattern in pkg.dataStreams %}
{# in ES 9.3.2 'input' type integrations no longer create default component templates and instead they wait for user input during 'integration' setup (fleet ui config)
title: generic is an artifact of that and is not in use #}
{% if pattern.title == "generic" %}
{% continue %}
{% endif %}
{% if "metrics-" in pattern.name %}
{% set integration_type = "metrics-" %}
{% elif "logs-" in pattern.name %}
{% set integration_type = "logs-" %}
{% else %}
{% set integration_type = "" %}
{% endif %}
{# on input integrations the component name is user defined at the time it is added to an agent policy #}
{% set component_name = pattern.title %}
{% set index_pattern = pattern.name %}
{# component_name_x maintains the functionality of merging local pillar changes with generated 'defaults' via SOC UI #}
{% set component_name_x = component_name.replace(".","_x_") %}
{# pillar overrides/merge expects the key names to follow the naming in elasticsearch/defaults.yaml eg. so-logs-1password_x_item_usages . The _x_ is replaced later on in elasticsearch/template.map.jinja #}
{% set integration_key = "so-" ~ integration_type ~ pkg.name + '_x_' ~ component_name_x %}
{# Default integration settings #}
{% set integration_defaults = {
"index_sorting": false,
"index_template": {
"composed_of": [integration_type ~ component_name ~ "@package", integration_type ~ component_name ~ "@custom", "so-fleet_integrations.ip_mappings-1", "so-fleet_globals-1", "so-fleet_agent_id_verification-1"],
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"ignore_missing_component_templates": [integration_type ~ component_name ~ "@custom"],
"index_patterns": [index_pattern],
"priority": 501,
"template": {
"settings": {
"index": {
"lifecycle": {"name": "so-" ~ integration_type ~ component_name ~ "-logs"},
"number_of_replicas": 0
}
}
}
},
"policy": {
"phases": {
"cold": {
"actions": {
"allocate":{
"number_of_replicas": ""
},
"set_priority": {"priority": 0}
},
"min_age": "60d"
},
"delete": {
"actions": {
"delete": {}
},
"min_age": "365d"
},
"hot": {
"actions": {
"rollover": {
"max_age": "30d",
"max_primary_shard_size": "50gb"
},
"forcemerge":{
"max_num_segments": ""
},
"shrink":{
"max_primary_shard_size": "",
"method": "COUNT",
"number_of_shards": ""
},
"set_priority": {"priority": 100}
},
"min_age": "0ms"
},
"warm": {
"actions": {
"allocate": {
"number_of_replicas": ""
},
"forcemerge": {
"max_num_segments": ""
},
"shrink":{
"max_primary_shard_size": "",
"method": "COUNT",
"number_of_shards": ""
},
"set_priority": {"priority": 50}
},
"min_age": "30d"
}
}
}
} %}
{% do ADDON_INPUT_INTEGRATION_DEFAULTS.update({integration_key: integration_defaults}) %}
{% do DEBUG_STUFF.update({integration_key: "Generating defaults for "+ pkg.name })%}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}

View File

@@ -59,8 +59,8 @@
{# skip core integrations #}
{% elif pkg.name not in CORE_ESFLEET_PACKAGES %}
{# generate defaults for each integration #}
{% if pkg.dataStreams is defined and pkg.dataStreams is not none and pkg.dataStreams | length > 0 %}
{% for pattern in pkg.dataStreams %}
{% if pkg.es_index_patterns is defined and pkg.es_index_patterns is not none %}
{% for pattern in pkg.es_index_patterns %}
{% if "metrics-" in pattern.name %}
{% set integration_type = "metrics-" %}
{% elif "logs-" in pattern.name %}
@@ -75,27 +75,44 @@
{% if component_name in WEIRD_INTEGRATIONS %}
{% set component_name = WEIRD_INTEGRATIONS[component_name] %}
{% endif %}
{# create duplicate of component_name, so we can split generics from @custom component templates in the index template below and overwrite the default @package when needed
eg. having to replace unifiedlogs.generic@package with filestream.generic@package, but keep the ability to customize unifiedlogs.generic@custom and its ILM policy #}
{% set custom_component_name = component_name %}
{# duplicate integration_type to assist with sometimes needing to overwrite component templates with 'logs-filestream.generic@package' (there is no metrics-filestream.generic@package) #}
{% set generic_integration_type = integration_type %}
{# component_name_x maintains the functionality of merging local pillar changes with generated 'defaults' via SOC UI #}
{% set component_name_x = component_name.replace(".","_x_") %}
{# pillar overrides/merge expects the key names to follow the naming in elasticsearch/defaults.yaml eg. so-logs-1password_x_item_usages . The _x_ is replaced later on in elasticsearch/template.map.jinja #}
{% set integration_key = "so-" ~ integration_type ~ component_name_x %}
{# if its a .generic template make sure that a .generic@package for the integration exists. Else default to logs-filestream.generic@package #}
{% if ".generic" in component_name and integration_type ~ component_name ~ "@package" not in INSTALLED_COMPONENT_TEMPLATES %}
{# these generic templates by default are directed to index_pattern of 'logs-generic-*', overwrite that here to point to eg gcp_pubsub.generic-* #}
{% set index_pattern = integration_type ~ component_name ~ "-*" %}
{# includes use of .generic component template, but it doesn't exist in installed component templates. Redirect it to filestream.generic@package #}
{% set component_name = "filestream.generic" %}
{% set generic_integration_type = "logs-" %}
{% endif %}
{# Default integration settings #}
{% set integration_defaults = {
"index_sorting": false,
"index_template": {
"composed_of": [integration_type ~ component_name ~ "@package", integration_type ~ component_name ~ "@custom", "so-fleet_integrations.ip_mappings-1", "so-fleet_globals-1", "so-fleet_agent_id_verification-1"],
"composed_of": [generic_integration_type ~ component_name ~ "@package", integration_type ~ custom_component_name ~ "@custom", "so-fleet_integrations.ip_mappings-1", "so-fleet_globals-1", "so-fleet_agent_id_verification-1"],
"data_stream": {
"allow_custom_routing": false,
"hidden": false
},
"ignore_missing_component_templates": [integration_type ~ component_name ~ "@custom"],
"ignore_missing_component_templates": [integration_type ~ custom_component_name ~ "@custom"],
"index_patterns": [index_pattern],
"priority": 501,
"template": {
"settings": {
"index": {
"lifecycle": {"name": "so-" ~ integration_type ~ component_name ~ "-logs"},
"lifecycle": {"name": "so-" ~ integration_type ~ custom_component_name ~ "-logs"},
"number_of_replicas": 0
}
}

View File

@@ -135,33 +135,9 @@ elastic_fleet_bulk_package_install() {
fi
}
elastic_fleet_get_package_list_by_type() {
if ! output=$(fleet_api "epm/packages"); then
elastic_fleet_installed_packages() {
if ! fleet_api "epm/packages/installed?perPage=500"; then
return 1
else
is_integration=$(jq '[.items[] | select(.type=="integration") | .name ]' <<< "$output")
is_input=$(jq '[.items[] | select(.type=="input") | .name ]' <<< "$output")
is_content=$(jq '[.items[] | select(.type=="content") | .name ]' <<< "$output")
jq -n --argjson is_integration "${is_integration:-[]}" \
--argjson is_input "${is_input:-[]}" \
--argjson is_content "${is_content:-[]}" \
'{"integration": $is_integration,"input": $is_input, "content": $is_content}'
fi
}
elastic_fleet_installed_packages_components() {
package_type=${1,,}
if [[ "$package_type" != "integration" && "$package_type" != "input" && "$package_type" != "content" ]]; then
echo "Error: Invalid package type ${package_type}. Valid types are 'integration', 'input', or 'content'."
return 1
fi
packages_by_type=$(elastic_fleet_get_package_list_by_type)
packages=$(jq --arg package_type "$package_type" '.[$package_type]' <<< "$packages_by_type")
if ! output=$(fleet_api "epm/packages/installed?perPage=500"); then
return 1
else
jq -c --argjson packages "$packages" '[.items[] | select(.name | IN($packages[])) | {name: .name, dataStreams: .dataStreams}]' <<< "$output"
fi
}

View File

@@ -18,9 +18,7 @@ INSTALLED_PACKAGE_LIST=/tmp/esfleet_installed_packages.json
BULK_INSTALL_PACKAGE_LIST=/tmp/esfleet_bulk_install.json
BULK_INSTALL_PACKAGE_TMP=/tmp/esfleet_bulk_install_tmp.json
BULK_INSTALL_OUTPUT=/opt/so/state/esfleet_bulk_install_results.json
INTEGRATION_PACKAGE_COMPONENTS=/opt/so/state/esfleet_package_components.json
INPUT_PACKAGE_COMPONENTS=/opt/so/state/esfleet_input_package_components.json
CONTENT_PACKAGE_COMPONENTS=/opt/so/state/esfleet_content_package_components.json
PACKAGE_COMPONENTS=/opt/so/state/esfleet_package_components.json
COMPONENT_TEMPLATES=/opt/so/state/esfleet_component_templates.json
PENDING_UPDATE=false
@@ -181,13 +179,10 @@ if [[ -f $STATE_FILE_SUCCESS ]]; then
else
echo "Elastic integrations don't appear to need installation/updating..."
fi
# Write out file for generating index/component/ilm templates, keeping each package type separate
for package_type in "INTEGRATION" "INPUT" "CONTENT"; do
if latest_installed_package_list=$(elastic_fleet_installed_packages_components "$package_type"); then
outfile="${package_type}_PACKAGE_COMPONENTS"
echo $latest_installed_package_list > "${!outfile}"
fi
done
# Write out file for generating index/component/ilm templates
if latest_installed_package_list=$(elastic_fleet_installed_packages); then
echo $latest_installed_package_list | jq '[.items[] | {name: .name, es_index_patterns: .dataStreams}]' > $PACKAGE_COMPONENTS
fi
if retry 3 1 "so-elasticsearch-query / --fail --output /dev/null"; then
# Refresh installed component template list
latest_component_templates_list=$(so-elasticsearch-query _component_template | jq '.component_templates[] | .name' | jq -s '.')

View File

@@ -91,13 +91,6 @@ estemplatedir:
- group: 939
- makedirs: True
esaddontemplatedir:
file.directory:
- name: /opt/so/conf/elasticsearch/templates/addon-index
- user: 930
- group: 939
- makedirs: True
esrolesdir:
file.directory:
- name: /opt/so/conf/elasticsearch/roles

View File

@@ -1,6 +1,6 @@
elasticsearch:
enabled: false
version: 9.3.2
version: 9.0.8
index_clean: true
vm:
max_map_count: 1048576

View File

@@ -10,10 +10,8 @@
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_NODES %}
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_SEED_HOSTS %}
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %}
{% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS, SO_MANAGED_INDICES %}
{% if GLOBALS.role != 'so-heavynode' %}
{% from 'elasticsearch/template.map.jinja' import ALL_ADDON_SETTINGS %}
{% endif %}
{% set TEMPLATES = salt['pillar.get']('elasticsearch:templates', {}) %}
{% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %}
include:
- ca
@@ -119,52 +117,40 @@ escomponenttemplates:
- onchanges_in:
- file: so-elasticsearch-templates-reload
- show_changes: False
# Clean up legacy and non-SO managed templates from the elasticsearch/templates/index/ directory
so_index_template_dir:
file.directory:
- name: /opt/so/conf/elasticsearch/templates/index
- clean: True
{%- if SO_MANAGED_INDICES %}
- require:
{%- for index in SO_MANAGED_INDICES %}
- file: so_index_template_{{index}}
{%- endfor %}
{%- endif %}
# Auto-generate index templates for SO managed indices (directly defined in elasticsearch/defaults.yaml)
# These index templates are for the core SO datasets and are always required
# Auto-generate templates from defaults file
{% for index, settings in ES_INDEX_SETTINGS.items() %}
{% if settings.index_template is defined %}
so_index_template_{{index}}:
{% if settings.index_template is defined %}
es_index_template_{{index}}:
file.managed:
- name: /opt/so/conf/elasticsearch/templates/index/{{ index }}-template.json
- source: salt://elasticsearch/base-template.json.jinja
- defaults:
TEMPLATE_CONFIG: {{ settings.index_template }}
TEMPLATE_CONFIG: {{ settings.index_template }}
- template: jinja
- show_changes: False
- onchanges_in:
- file: so-elasticsearch-templates-reload
{% endif %}
{% endfor %}
{% if GLOBALS.role != "so-heavynode" %}
# Auto-generate optional index templates for integration | input | content packages
# These index templates are not used by default (until user adds package to an agent policy).
# Pre-configured with standard defaults, and incorporated into SOC configuration for user customization.
{% for index,settings in ALL_ADDON_SETTINGS.items() %}
{% if settings.index_template is defined %}
addon_index_template_{{index}}:
{% if TEMPLATES %}
# Sync custom templates to /opt/so/conf/elasticsearch/templates
{% for TEMPLATE in TEMPLATES %}
es_template_{{TEMPLATE.split('.')[0] | replace("/","_") }}:
file.managed:
- name: /opt/so/conf/elasticsearch/templates/addon-index/{{ index }}-template.json
- source: salt://elasticsearch/base-template.json.jinja
- defaults:
TEMPLATE_CONFIG: {{ settings.index_template }}
- source: salt://elasticsearch/templates/index/{{TEMPLATE}}
{% if 'jinja' in TEMPLATE.split('.')[-1] %}
- name: /opt/so/conf/elasticsearch/templates/index/{{TEMPLATE.split('/')[1] | replace(".jinja", "")}}
- template: jinja
{% else %}
- name: /opt/so/conf/elasticsearch/templates/index/{{TEMPLATE.split('/')[1]}}
{% endif %}
- user: 930
- group: 939
- show_changes: False
- onchanges_in:
- file: addon-elasticsearch-templates-reload
{% endif %}
- file: so-elasticsearch-templates-reload
{% endfor %}
{% endif %}
@@ -193,17 +179,9 @@ so-elasticsearch-templates-reload:
file.absent:
- name: /opt/so/state/estemplates.txt
addon-elasticsearch-templates-reload:
file.absent:
- name: /opt/so/state/addon_estemplates.txt
so-elasticsearch-templates:
cmd.run:
{%- if GLOBALS.role == "so-heavynode" %}
- name: /usr/sbin/so-elasticsearch-templates-load --heavynode
{%- else %}
- name: /usr/sbin/so-elasticsearch-templates-load
{%- endif %}
- cwd: /opt/so
- template: jinja
- require:

View File

@@ -10,28 +10,24 @@
"processors": [
{
"set": {
"tag": "set_ecs_version_f5923549",
"field": "ecs.version",
"value": "8.17.0"
}
},
{
"set": {
"tag": "set_observer_vendor_ad9d35cc",
"field": "observer.vendor",
"value": "netgate"
}
},
{
"set": {
"tag": "set_observer_type_5dddf3ba",
"field": "observer.type",
"value": "firewall"
}
},
{
"rename": {
"tag": "rename_message_to_event_original_56a77271",
"field": "message",
"target_field": "event.original",
"ignore_missing": true,
@@ -40,14 +36,12 @@
},
{
"set": {
"tag": "set_event_kind_de80643c",
"field": "event.kind",
"value": "event"
}
},
{
"set": {
"tag": "set_event_timezone_4ca44cac",
"field": "event.timezone",
"value": "{{{_tmp.tz_offset}}}",
"if": "ctx._tmp?.tz_offset != null && ctx._tmp?.tz_offset != 'local'"
@@ -55,7 +49,6 @@
},
{
"grok": {
"tag": "grok_event_original_27d9c8c7",
"description": "Parse syslog header",
"field": "event.original",
"patterns": [
@@ -79,7 +72,6 @@
},
{
"date": {
"tag": "date__tmp_timestamp8601_to_timestamp_6ac9d3ce",
"if": "ctx._tmp.timestamp8601 != null",
"field": "_tmp.timestamp8601",
"target_field": "@timestamp",
@@ -90,7 +82,6 @@
},
{
"date": {
"tag": "date__tmp_timestamp_to_timestamp_f21e536e",
"if": "ctx.event?.timezone != null && ctx._tmp?.timestamp != null",
"field": "_tmp.timestamp",
"target_field": "@timestamp",
@@ -104,7 +95,6 @@
},
{
"grok": {
"tag": "grok_process_name_cef3d489",
"description": "Set Event Provider",
"field": "process.name",
"patterns": [
@@ -117,83 +107,71 @@
},
{
"pipeline": {
"tag": "pipeline_e16851a7",
"name": "logs-pfsense.log-1.25.1-firewall",
"name": "logs-pfsense.log-1.23.1-firewall",
"if": "ctx.event.provider == 'filterlog'"
}
},
{
"pipeline": {
"tag": "pipeline_828590b5",
"name": "logs-pfsense.log-1.25.1-openvpn",
"name": "logs-pfsense.log-1.23.1-openvpn",
"if": "ctx.event.provider == 'openvpn'"
}
},
{
"pipeline": {
"tag": "pipeline_9d37039c",
"name": "logs-pfsense.log-1.25.1-ipsec",
"name": "logs-pfsense.log-1.23.1-ipsec",
"if": "ctx.event.provider == 'charon'"
}
},
{
"pipeline": {
"tag": "pipeline_ad56bbca",
"name": "logs-pfsense.log-1.25.1-dhcp",
"name": "logs-pfsense.log-1.23.1-dhcp",
"if": "[\"dhcpd\", \"dhclient\", \"dhcp6c\"].contains(ctx.event.provider)"
}
},
{
"pipeline": {
"tag": "pipeline_dd85553d",
"name": "logs-pfsense.log-1.25.1-unbound",
"name": "logs-pfsense.log-1.23.1-unbound",
"if": "ctx.event.provider == 'unbound'"
}
},
{
"pipeline": {
"tag": "pipeline_720ed255",
"name": "logs-pfsense.log-1.25.1-haproxy",
"name": "logs-pfsense.log-1.23.1-haproxy",
"if": "ctx.event.provider == 'haproxy'"
}
},
{
"pipeline": {
"tag": "pipeline_456beba5",
"name": "logs-pfsense.log-1.25.1-php-fpm",
"name": "logs-pfsense.log-1.23.1-php-fpm",
"if": "ctx.event.provider == 'php-fpm'"
}
},
{
"pipeline": {
"tag": "pipeline_a0d89375",
"name": "logs-pfsense.log-1.25.1-squid",
"name": "logs-pfsense.log-1.23.1-squid",
"if": "ctx.event.provider == 'squid'"
}
},
{
"pipeline": {
"tag": "pipeline_c2f1ed55",
"name": "logs-pfsense.log-1.25.1-snort",
"name": "logs-pfsense.log-1.23.1-snort",
"if": "ctx.event.provider == 'snort'"
}
},
{
"pipeline": {
"tag":"pipeline_33db1c9e",
"name": "logs-pfsense.log-1.25.1-suricata",
"name": "logs-pfsense.log-1.23.1-suricata",
"if": "ctx.event.provider == 'suricata'"
}
},
{
"drop": {
"tag": "drop_9d7c46f8",
"if": "![\"filterlog\", \"openvpn\", \"charon\", \"dhcpd\", \"dhclient\", \"dhcp6c\", \"unbound\", \"haproxy\", \"php-fpm\", \"squid\", \"snort\", \"suricata\"].contains(ctx.event?.provider)"
}
},
{
"append": {
"tag": "append_event_category_4780a983",
"field": "event.category",
"value": "network",
"if": "ctx.network != null"
@@ -201,7 +179,6 @@
},
{
"convert": {
"tag": "convert_source_address_to_source_ip_f5632a20",
"field": "source.address",
"target_field": "source.ip",
"type": "ip",
@@ -211,7 +188,6 @@
},
{
"convert": {
"tag": "convert_destination_address_to_destination_ip_f1388f0c",
"field": "destination.address",
"target_field": "destination.ip",
"type": "ip",
@@ -221,7 +197,6 @@
},
{
"set": {
"tag": "set_network_type_1f1d940a",
"field": "network.type",
"value": "ipv6",
"if": "ctx.source?.ip != null && ctx.source.ip.contains(\":\")"
@@ -229,7 +204,6 @@
},
{
"set": {
"tag": "set_network_type_69deca38",
"field": "network.type",
"value": "ipv4",
"if": "ctx.source?.ip != null && ctx.source.ip.contains(\".\")"
@@ -237,7 +211,6 @@
},
{
"geoip": {
"tag": "geoip_source_ip_to_source_geo_da2e41b2",
"field": "source.ip",
"target_field": "source.geo",
"ignore_missing": true
@@ -245,7 +218,6 @@
},
{
"geoip": {
"tag": "geoip_destination_ip_to_destination_geo_ab5e2968",
"field": "destination.ip",
"target_field": "destination.geo",
"ignore_missing": true
@@ -253,7 +225,6 @@
},
{
"geoip": {
"tag": "geoip_source_ip_to_source_as_28d69883",
"ignore_missing": true,
"database_file": "GeoLite2-ASN.mmdb",
"field": "source.ip",
@@ -266,7 +237,6 @@
},
{
"geoip": {
"tag": "geoip_destination_ip_to_destination_as_8a007787",
"database_file": "GeoLite2-ASN.mmdb",
"field": "destination.ip",
"target_field": "destination.as",
@@ -279,7 +249,6 @@
},
{
"rename": {
"tag": "rename_source_as_asn_to_source_as_number_a917047d",
"field": "source.as.asn",
"target_field": "source.as.number",
"ignore_missing": true
@@ -287,7 +256,6 @@
},
{
"rename": {
"tag": "rename_source_as_organization_name_to_source_as_organization_name_f1362d0b",
"field": "source.as.organization_name",
"target_field": "source.as.organization.name",
"ignore_missing": true
@@ -295,7 +263,6 @@
},
{
"rename": {
"tag": "rename_destination_as_asn_to_destination_as_number_3b459fcd",
"field": "destination.as.asn",
"target_field": "destination.as.number",
"ignore_missing": true
@@ -303,7 +270,6 @@
},
{
"rename": {
"tag": "rename_destination_as_organization_name_to_destination_as_organization_name_814bd459",
"field": "destination.as.organization_name",
"target_field": "destination.as.organization.name",
"ignore_missing": true
@@ -311,14 +277,12 @@
},
{
"community_id": {
"tag": "community_id_d2308e7a",
"target_field": "network.community_id",
"ignore_failure": true
}
},
{
"grok": {
"tag": "grok_observer_ingress_interface_name_968018d3",
"field": "observer.ingress.interface.name",
"patterns": [
"%{DATA}.%{NONNEGINT:observer.ingress.vlan.id}"
@@ -329,7 +293,6 @@
},
{
"set": {
"tag": "set_network_vlan_id_efd4d96a",
"field": "network.vlan.id",
"copy_from": "observer.ingress.vlan.id",
"ignore_empty_value": true
@@ -337,7 +300,6 @@
},
{
"append": {
"tag": "append_related_ip_c1a6356b",
"field": "related.ip",
"value": "{{{destination.ip}}}",
"allow_duplicates": false,
@@ -346,7 +308,6 @@
},
{
"append": {
"tag": "append_related_ip_8121c591",
"field": "related.ip",
"value": "{{{source.ip}}}",
"allow_duplicates": false,
@@ -355,7 +316,6 @@
},
{
"append": {
"tag": "append_related_ip_53b62ed8",
"field": "related.ip",
"value": "{{{source.nat.ip}}}",
"allow_duplicates": false,
@@ -364,7 +324,6 @@
},
{
"append": {
"tag": "append_related_hosts_6f162628",
"field": "related.hosts",
"value": "{{{destination.domain}}}",
"if": "ctx.destination?.domain != null"
@@ -372,7 +331,6 @@
},
{
"append": {
"tag": "append_related_user_c036eec2",
"field": "related.user",
"value": "{{{user.name}}}",
"if": "ctx.user?.name != null"
@@ -380,7 +338,6 @@
},
{
"set": {
"tag": "set_network_direction_cb1e3125",
"field": "network.direction",
"value": "{{{network.direction}}}bound",
"if": "ctx.network?.direction != null && ctx.network?.direction =~ /^(in|out)$/"
@@ -388,7 +345,6 @@
},
{
"remove": {
"tag": "remove_a82e20f2",
"field": [
"_tmp"
],
@@ -397,21 +353,11 @@
},
{
"script": {
"tag": "script_a7f2c062",
"lang": "painless",
"description": "This script processor iterates over the whole document to remove fields with null values.",
"source": "void handleMap(Map map) {\n for (def x : map.values()) {\n if (x instanceof Map) {\n handleMap(x);\n } else if (x instanceof List) {\n handleList(x);\n }\n }\n map.values().removeIf(v -> v == null || (v instanceof String && v == \"-\"));\n}\nvoid handleList(List list) {\n for (def x : list) {\n if (x instanceof Map) {\n handleMap(x);\n } else if (x instanceof List) {\n handleList(x);\n }\n }\n}\nhandleMap(ctx);\n"
}
},
{
"append": {
"tag": "append_preserve_original_event_on_error",
"field": "tags",
"value": "preserve_original_event",
"allow_duplicates": false,
"if": "ctx.error?.message != null"
}
},
{
"pipeline": {
"name": "global@custom",
@@ -459,14 +405,7 @@
{
"append": {
"field": "error.message",
"value": "Processor '{{{ _ingest.on_failure_processor_type }}}' {{#_ingest.on_failure_processor_tag}}with tag '{{{ _ingest.on_failure_processor_tag }}}' {{/_ingest.on_failure_processor_tag}}in pipeline '{{{ _ingest.pipeline }}}' failed with message '{{{ _ingest.on_failure_message }}}'"
}
},
{
"append": {
"field": "tags",
"value": "preserve_original_event",
"allow_duplicates": false
"value": "{{{ _ingest.on_failure_message }}}"
}
}
]

View File

@@ -14,42 +14,15 @@
{% set ES_INDEX_SETTINGS_ORIG = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings %}
{% set ALL_ADDON_INTEGRATION_DEFAULTS = {} %}
{% set ALL_ADDON_SETTINGS_ORIG = {} %}
{% set ALL_ADDON_SETTINGS_GLOBAL_OVERRIDES = {} %}
{% set ALL_ADDON_SETTINGS = {} %}
{# start generation of integration default index_settings #}
{% if salt['file.file_exists']('/opt/so/state/esfleet_component_templates.json') %}
{# import integration type defaults #}
{% if salt['file.file_exists']('/opt/so/state/esfleet_integration_package_components.json') %}
{% set check_integration_package_components = salt['file.stats']('/opt/so/state/esfleet_integration_package_components.json') %}
{% if check_integration_package_components.size > 1 %}
{% from 'elasticfleet/integration-defaults.map.jinja' import ADDON_INTEGRATION_DEFAULTS %}
{% do ALL_ADDON_INTEGRATION_DEFAULTS.update(ADDON_INTEGRATION_DEFAULTS) %}
{% endif %}
{% endif %}
{# import input type defaults #}
{% if salt['file.file_exists']('/opt/so/state/esfleet_input_package_components.json') %}
{% set check_input_package_components = salt['file.stats']('/opt/so/state/esfleet_input_package_components.json') %}
{% if check_input_package_components.size > 1 %}
{% from 'elasticfleet/input-defaults.map.jinja' import ADDON_INPUT_INTEGRATION_DEFAULTS %}
{% do ALL_ADDON_INTEGRATION_DEFAULTS.update(ADDON_INPUT_INTEGRATION_DEFAULTS) %}
{% endif %}
{% endif %}
{# import content type defaults #}
{% if salt['file.file_exists']('/opt/so/state/esfleet_content_package_components.json') %}
{% set check_content_package_components = salt['file.stats']('/opt/so/state/esfleet_content_package_components.json') %}
{% if check_content_package_components.size > 1 %}
{% from 'elasticfleet/content-defaults.map.jinja' import ADDON_CONTENT_INTEGRATION_DEFAULTS %}
{% do ALL_ADDON_INTEGRATION_DEFAULTS.update(ADDON_CONTENT_INTEGRATION_DEFAULTS) %}
{% endif %}
{% endif %}
{% for index, settings in ALL_ADDON_INTEGRATION_DEFAULTS.items() %}
{% do ALL_ADDON_SETTINGS_ORIG.update({index: settings}) %}
{% endfor %}
{% if salt['file.file_exists']('/opt/so/state/esfleet_package_components.json') and salt['file.file_exists']('/opt/so/state/esfleet_component_templates.json') %}
{% set check_package_components = salt['file.stats']('/opt/so/state/esfleet_package_components.json') %}
{% if check_package_components.size > 1 %}
{% from 'elasticfleet/integration-defaults.map.jinja' import ADDON_INTEGRATION_DEFAULTS %}
{% for index, settings in ADDON_INTEGRATION_DEFAULTS.items() %}
{% do ES_INDEX_SETTINGS_ORIG.update({index: settings}) %}
{% endfor %}
{% endif%}
{% endif %}
{# end generation of integration default index_settings #}
@@ -58,33 +31,25 @@
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.update({index: salt['defaults.merge'](ELASTICSEARCHDEFAULTS.elasticsearch.index_settings[index], PILLAR_GLOBAL_OVERRIDES, in_place=False)}) %}
{% endfor %}
{% if ALL_ADDON_SETTINGS_ORIG.keys() | length > 0 %}
{% for index in ALL_ADDON_SETTINGS_ORIG.keys() %}
{% do ALL_ADDON_SETTINGS_GLOBAL_OVERRIDES.update({index: salt['defaults.merge'](ALL_ADDON_SETTINGS_ORIG[index], PILLAR_GLOBAL_OVERRIDES, in_place=False)}) %}
{% endfor %}
{% endif %}
{% set ES_INDEX_SETTINGS = {} %}
{% macro create_final_index_template(DEFINED_SETTINGS, GLOBAL_OVERRIDES, FINAL_INDEX_SETTINGS) %}
{% do GLOBAL_OVERRIDES.update(salt['defaults.merge'](GLOBAL_OVERRIDES, ES_INDEX_PILLAR, in_place=False)) %}
{% for index, settings in GLOBAL_OVERRIDES.items() %}
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.update(salt['defaults.merge'](ES_INDEX_SETTINGS_GLOBAL_OVERRIDES, ES_INDEX_PILLAR, in_place=False)) %}
{% for index, settings in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.items() %}
{# prevent this action from being performed on custom defined indices. #}
{# the custom defined index is not present in either of the dictionaries and fails to reder. #}
{% if index in DEFINED_SETTINGS and index in GLOBAL_OVERRIDES %}
{% if index in ES_INDEX_SETTINGS_ORIG and index in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES %}
{# dont merge policy from the global_overrides if policy isn't defined in the original index settingss #}
{# this will prevent so-elasticsearch-ilm-policy-load from trying to load policy on non ILM manged indices #}
{% if not DEFINED_SETTINGS[index].policy is defined and GLOBAL_OVERRIDES[index].policy is defined %}
{% do GLOBAL_OVERRIDES[index].pop('policy') %}
{% if not ES_INDEX_SETTINGS_ORIG[index].policy is defined and ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %}
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].pop('policy') %}
{% endif %}
{# this prevents and index from inderiting a policy phase from global overrides if it wasnt defined in the defaults. #}
{% if GLOBAL_OVERRIDES[index].policy is defined %}
{% for phase in GLOBAL_OVERRIDES[index].policy.phases.copy() %}
{% if DEFINED_SETTINGS[index].policy.phases[phase] is not defined %}
{% do GLOBAL_OVERRIDES[index].policy.phases.pop(phase) %}
{% if ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %}
{% for phase in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy.phases.copy() %}
{% if ES_INDEX_SETTINGS_ORIG[index].policy.phases[phase] is not defined %}
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy.phases.pop(phase) %}
{% endif %}
{% endfor %}
{% endif %}
@@ -146,14 +111,5 @@
{% endfor %}
{% endif %}
{% do FINAL_INDEX_SETTINGS.update({index | replace("_x_", "."): GLOBAL_OVERRIDES[index]}) %}
{% do ES_INDEX_SETTINGS.update({index | replace("_x_", "."): ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index]}) %}
{% endfor %}
{% endmacro %}
{{ create_final_index_template(ES_INDEX_SETTINGS_ORIG, ES_INDEX_SETTINGS_GLOBAL_OVERRIDES, ES_INDEX_SETTINGS) }}
{{ create_final_index_template(ALL_ADDON_SETTINGS_ORIG, ALL_ADDON_SETTINGS_GLOBAL_OVERRIDES, ALL_ADDON_SETTINGS) }}
{% set SO_MANAGED_INDICES = [] %}
{% for index, settings in ES_INDEX_SETTINGS.items() %}
{% do SO_MANAGED_INDICES.append(index) %}
{% endfor %}

View File

@@ -6,19 +6,8 @@
# Elastic License 2.0.
. /usr/sbin/so-common
if [[ -z "$1" ]]; then
if output=$(so-elasticsearch-query "_component_template" --retry 3 --retry-delay 1 --fail); then
jq '[.component_templates[] | .name] | sort' <<< "$output"
else
echo "Failed to retrieve component templates from Elasticsearch."
exit 1
fi
if [ "$1" == "" ]; then
curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L https://localhost:9200/_component_template | jq '.component_templates[] |.name'| sort
else
if output=$(so-elasticsearch-query "_component_template/$1" --retry 3 --retry-delay 1 --fail); then
jq <<< "$output"
else
echo "Failed to retrieve component template '$1' from Elasticsearch."
exit 1
fi
fi
curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L https://localhost:9200/_component_template/$1 | jq
fi

View File

@@ -1,190 +0,0 @@
#!/bin/bash
# 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.
. /usr/sbin/so-common
SO_STATE_FILE_SUCCESS=/opt/so/state/estemplates.txt
ADDON_STATE_FILE_SUCCESS=/opt/so/state/addon-estemplates.txt
ELASTICSEARCH_TEMPLATES_DIR="/opt/so/conf/elasticsearch/templates"
SO_TEMPLATES_DIR="${ELASTICSEARCH_TEMPLATES_DIR}/index"
ADDON_TEMPLATES_DIR="${ELASTICSEARCH_TEMPLATES_DIR}/addon-index"
LOAD_FAILURES=0
LOAD_FAILURES_NAMES=()
IS_HEAVYNODE="false"
FORCE="false"
VERBOSE="false"
# If soup is running, ignore errors
pgrep soup >/dev/null && should_exit_on_failure=0
while [[ $# -gt 0 ]]; do
case "$1" in
--heavynode)
IS_HEAVYNODE="true"
;;
--force)
FORCE="true"
;;
--verbose)
VERBOSE="true"
;;
*)
echo "Usage: $0 [options]"
echo "Options:"
echo " --heavynode Only loads index templates specific to heavynodes"
echo " --force Force reload all templates regardless of state file (default: false)"
echo " --verbose Enable verbose output"
exit 1
;;
esac
shift
done
load_template() {
local uri="$1"
local file="$2"
echo "Loading template file $file"
if ! output=$(retry 3 3 "so-elasticsearch-query $uri -d@$file -XPUT" "{\"acknowledged\":true}"); then
echo "$output"
return 1
elif [[ "$VERBOSE" == "true" ]]; then
echo "$output"
fi
}
check_required_component_template_exists() {
local required
local missing
local file=$1
required=$(jq '[((.composed_of //[]) - (.ignore_missing_component_templates // []))[]]' "$file")
missing=$(jq -n --argjson required "$required" --argjson component_templates "$component_templates" '(($required) - ($component_templates))')
if [[ $(jq length <<<"$missing") -gt 0 ]]; then
return 1
fi
}
check_heavynode_compatiable_index_template() {
# The only templates that are relevant to heavynodes are from datasets defined in elasticagent/files/elastic-agent.yml.jinja.
# Heavynodes do not have fleet server packages installed and do not support elastic agents reporting directly to them.
local -A heavynode_index_templates=(
["so-import"]=1
["so-syslog"]=1
["so-logs-soc"]=1
["so-suricata"]=1
["so-suricata.alerts"]=1
["so-zeek"]=1
["so-strelka"]=1
)
local template_name="$1"
if [[ ! -v heavynode_index_templates["$template_name"] ]]; then
return 1
fi
}
load_component_templates() {
local printed_name="$1"
local pattern="${ELASTICSEARCH_TEMPLATES_DIR}/component/$2"
# current state of nullglob shell option
shopt -q nullglob && nullglob_set=1 || nullglob_set=0
shopt -s nullglob
echo -e "\nLoading $printed_name component templates...\n"
for component in "$pattern"/*.json; do
tmpl_name=$(basename "${component%.json}")
if ! load_template "_component_template/${tmpl_name}-mappings" "$component"; then
LOAD_FAILURES=$((LOAD_FAILURES + 1))
LOAD_FAILURES_NAMES+=("$component")
fi
done
# restore nullglob shell option if needed
if [[ $nullglob_set -eq 1 ]]; then
shopt -u nullglob
fi
}
if [[ "$FORCE" == "true" || ! -f "$SO_STATE_FILE_SUCCESS" ]]; then
# Cannot load templates if Elasticsearch is not responding.
# NOTE: Slightly faster exit w/ failure than previous "retry 240 1" if there is a problem with Elasticsearch the
# script should exit sooner rather than hang at the 'so-elasticsearch-templates' salt state.
retry 3 15 "so-elasticsearch-query / --output /dev/null --fail" ||
fail "Elasticsearch is not responding. Please review Elasticsearch logs /opt/so/log/elasticsearch/securityonion.log for more details. Additionally, consider running so-elasticsearch-troubleshoot."
if [[ "$IS_HEAVYNODE" == "false" ]]; then
# TODO: Better way to check if fleet server is installed vs checking for Elastic Defend component template.
fleet_check="logs-endpoint.alerts@package"
if ! so-elasticsearch-query "_component_template/$fleet_check" --output /dev/null --retry 5 --retry-delay 3 --fail; then
echo -e "\nPackage $fleet_check not yet installed. Fleet Server may not be fully configured yet."
# Fleet Server is required because some SO index templates depend on components installed via
# specific integrations eg Elastic Defend. These are components that we do not manually create / manage
# via /opt/so/saltstack/salt/elasticsearch/templates/component/
exit 0
fi
fi
load_component_templates "ECS" "ecs"
load_component_templates "Elastic Agent" "elastic-agent"
load_component_templates "Security Onion" "securityonion"
component_templates=$(so-elasticsearch-component-templates-list)
echo -e "Loading Security Onion index templates...\n"
for so_idx_tmpl in "${SO_TEMPLATES_DIR}"/*.json; do
tmpl_name=$(basename "${so_idx_tmpl%-template.json}")
if [[ "$IS_HEAVYNODE" == "true" ]]; then
# TODO: Better way to load only heavynode specific templates
if ! check_heavynode_compatiable_index_template "$tmpl_name"; then
if [[ "$VERBOSE" == "true" ]]; then
echo "Skipping over $so_idx_tmpl, template is not a heavynode specific index template."
fi
continue
fi
fi
if check_required_component_template_exists "$so_idx_tmpl"; then
if ! load_template "_index_template/$tmpl_name" "$so_idx_tmpl"; then
LOAD_FAILURES=$((LOAD_FAILURES + 1))
LOAD_FAILURES_NAMES+=("$so_idx_tmpl")
fi
else
echo "Skipping over $so_idx_tmpl due to missing required component template(s)."
LOAD_FAILURES=$((LOAD_FAILURES + 1))
LOAD_FAILURES_NAMES+=("$so_idx_tmpl")
continue
fi
done
if [[ $LOAD_FAILURES -eq 0 ]]; then
echo "All templates loaded successfully."
touch "$SO_STATE_FILE_SUCCESS"
else
echo "Encountered $LOAD_FAILURES failure(s) loading templates:"
for failed_template in "${LOAD_FAILURES_NAMES[@]}"; do
echo " - $failed_template"
done
fi
else
echo "Templates already loaded"
fi

View File

@@ -0,0 +1,165 @@
#!/bin/bash
# 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.
{%- import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
STATE_FILE_INITIAL=/opt/so/state/estemplates_initial_load_attempt.txt
STATE_FILE_SUCCESS=/opt/so/state/estemplates.txt
if [[ -f $STATE_FILE_INITIAL ]]; then
# The initial template load has already run. As this is a subsequent load, all dependencies should
# already be satisified. Therefore, immediately exit/abort this script upon any template load failure
# since this is an unrecoverable failure.
should_exit_on_failure=1
else
# This is the initial template load, and there likely are some components not yet setup in Elasticsearch.
# Therefore load as many templates as possible at this time and if an error occurs proceed to the next
# template. But if at least one template fails to load do not mark the templates as having been loaded.
# This will allow the next load to resume the load of the templates that failed to load initially.
should_exit_on_failure=0
echo "This is the initial template load"
fi
# If soup is running, ignore errors
pgrep soup > /dev/null && should_exit_on_failure=0
load_failures=0
load_template() {
uri=$1
file=$2
echo "Loading template file $i"
if ! retry 3 1 "so-elasticsearch-query $uri -d@$file -XPUT" "{\"acknowledged\":true}"; then
if [[ $should_exit_on_failure -eq 1 ]]; then
fail "Could not load template file: $file"
else
load_failures=$((load_failures+1))
echo "Incremented load failure counter: $load_failures"
fi
fi
}
if [ ! -f $STATE_FILE_SUCCESS ]; then
echo "State file $STATE_FILE_SUCCESS not found. Running so-elasticsearch-templates-load."
. /usr/sbin/so-common
{% if GLOBALS.role != 'so-heavynode' %}
if [ -f /usr/sbin/so-elastic-fleet-common ]; then
. /usr/sbin/so-elastic-fleet-common
fi
{% endif %}
default_conf_dir=/opt/so/conf
# Define a default directory to load pipelines from
ELASTICSEARCH_TEMPLATES="$default_conf_dir/elasticsearch/templates/"
{% if GLOBALS.role == 'so-heavynode' %}
file="/opt/so/conf/elasticsearch/templates/index/so-common-template.json"
{% else %}
file="/usr/sbin/so-elastic-fleet-common"
{% endif %}
if [ -f "$file" ]; then
# Wait for ElasticSearch to initialize
echo -n "Waiting for ElasticSearch..."
retry 240 1 "so-elasticsearch-query / -k --output /dev/null --silent --head --fail" || fail "Connection attempt timed out. Unable to connect to ElasticSearch. \nPlease try: \n -checking log(s) in /var/log/elasticsearch/\n -running 'sudo docker ps' \n -running 'sudo so-elastic-restart'"
{% if GLOBALS.role != 'so-heavynode' %}
TEMPLATE="logs-endpoint.alerts@package"
INSTALLED=$(so-elasticsearch-query _component_template/$TEMPLATE | jq -r .component_templates[0].name)
if [ "$INSTALLED" != "$TEMPLATE" ]; then
echo
echo "Packages not yet installed."
echo
exit 0
fi
{% endif %}
touch $STATE_FILE_INITIAL
cd ${ELASTICSEARCH_TEMPLATES}/component/ecs
echo "Loading ECS component templates..."
for i in *; do
TEMPLATE=$(echo $i | cut -d '.' -f1)
load_template "_component_template/${TEMPLATE}-mappings" "$i"
done
echo
cd ${ELASTICSEARCH_TEMPLATES}/component/elastic-agent
echo "Loading Elastic Agent component templates..."
{% if GLOBALS.role == 'so-heavynode' %}
component_pattern="so-*"
{% else %}
component_pattern="*"
{% endif %}
for i in $component_pattern; do
TEMPLATE=${i::-5}
load_template "_component_template/$TEMPLATE" "$i"
done
echo
# Load SO-specific component templates
cd ${ELASTICSEARCH_TEMPLATES}/component/so
echo "Loading Security Onion component templates..."
for i in *; do
TEMPLATE=$(echo $i | cut -d '.' -f1);
load_template "_component_template/$TEMPLATE" "$i"
done
echo
# Load SO index templates
cd ${ELASTICSEARCH_TEMPLATES}/index
echo "Loading Security Onion index templates..."
shopt -s extglob
{% if GLOBALS.role == 'so-heavynode' %}
pattern="!(*1password*|*aws*|*azure*|*cloudflare*|*elastic_agent*|*fim*|*github*|*google*|*osquery*|*system*|*windows*|*endpoint*|*elasticsearch*|*generic*|*fleet_server*|*soc*)"
{% else %}
pattern="*"
{% endif %}
# Index templates will be skipped if the following conditions are met:
# 1. The template is part of the "so-logs-" template group
# 2. The template name does not correlate to at least one existing component template
# In this situation, the script will treat the skipped template as a temporary failure
# and allow the templates to be loaded again on the next run or highstate, whichever
# comes first.
COMPONENT_LIST=$(so-elasticsearch-component-templates-list)
for i in $pattern; do
TEMPLATE=${i::-14}
COMPONENT_PATTERN=${TEMPLATE:3}
MATCH=$(echo "$TEMPLATE" | grep -E "^so-logs-|^so-metrics" | grep -vE "detections|osquery")
if [[ -n "$MATCH" && ! "$COMPONENT_LIST" =~ "$COMPONENT_PATTERN" && ! "$COMPONENT_PATTERN" =~ \.generic|logs-winlog\.winlog ]]; then
load_failures=$((load_failures+1))
echo "Component template does not exist for $COMPONENT_PATTERN. The index template will not be loaded. Load failures: $load_failures"
else
load_template "_index_template/$TEMPLATE" "$i"
fi
done
else
{% if GLOBALS.role == 'so-heavynode' %}
echo "Common template does not exist. Exiting..."
{% else %}
echo "Elastic Fleet not configured. Exiting..."
{% endif %}
exit 0
fi
cd - >/dev/null
if [[ $load_failures -eq 0 ]]; then
echo "All templates loaded successfully"
touch $STATE_FILE_SUCCESS
else
echo "Encountered $load_failures templates that were unable to load, likely due to missing dependencies that will be available later; will retry on next highstate"
fi
else
echo "Templates already loaded"
fi

View File

@@ -13,12 +13,6 @@
'so-nginx',
'so-redis',
'so-soc',
'so-strelka-coordinator',
'so-strelka-gatekeeper',
'so-strelka-frontend',
'so-strelka-backend',
'so-strelka-manager',
'so-strelka-filestream'
] %}
{% elif GLOBALS.role in ['so-manager', 'so-standalone','so-managersearch', 'so-managerhype'] %}
@@ -36,12 +30,6 @@
'so-nginx',
'so-redis',
'so-soc',
'so-strelka-coordinator',
'so-strelka-gatekeeper',
'so-strelka-frontend',
'so-strelka-backend',
'so-strelka-manager',
'so-strelka-filestream'
] %}
{% elif GLOBALS.role == 'so-searchnode' %}
@@ -58,12 +46,6 @@
'so-logstash',
'so-nginx',
'so-redis',
'so-strelka-coordinator',
'so-strelka-gatekeeper',
'so-strelka-frontend',
'so-strelka-backend',
'so-strelka-manager',
'so-strelka-filestream'
] %}
{% elif GLOBALS.role == 'so-import' %}

View File

@@ -27,7 +27,6 @@ firewall:
self: []
sensor: []
standalone: []
strelka_frontend: []
syslog: []
desktop: []
customhostgroup0: []
@@ -140,10 +139,6 @@ firewall:
tcp:
- 22
udp: []
strelka_frontend:
tcp:
- 57314
udp: []
syslog:
tcp:
- 514
@@ -222,9 +217,6 @@ firewall:
- elastic_agent_control
- elastic_agent_data
- elastic_agent_update
strelka_frontend:
portgroups:
- strelka_frontend
analyst:
portgroups:
- nginx
@@ -1024,7 +1016,6 @@ firewall:
- elastic_agent_data
- elastic_agent_update
- endgame
- strelka_frontend
- localrules
fleet:
portgroups:
@@ -1113,9 +1104,6 @@ firewall:
- external_suricata
external_kafka:
portgroups: []
strelka_frontend:
portgroups:
- strelka_frontend
desktop:
portgroups:
- docker_registry
@@ -1309,9 +1297,6 @@ firewall:
chain:
DOCKER-USER:
hostgroups:
strelka_frontend:
portgroups:
- strelka_frontend
customhostgroup0:
portgroups: []
customhostgroup1:
@@ -1401,9 +1386,6 @@ firewall:
- syslog
- elasticsearch_node
- elasticsearch_rest
strelka_frontend:
portgroups:
- strelka_frontend
syslog:
portgroups:
- syslog

View File

@@ -47,7 +47,6 @@ firewall:
self: *ROhostgroupsettingsadv
sensor: *hostgroupsettings
standalone: *hostgroupsettings
strelka_frontend: *hostgroupsettings
syslog: *hostgroupsettings
desktop: *hostgroupsettings
customhostgroup0: &customhostgroupsettings
@@ -156,9 +155,6 @@ firewall:
ssh:
tcp: *tcpsettings
udp: *udpsettings
strelka_frontend:
tcp: *tcpsettings
udp: *udpsettings
syslog:
tcp: *tcpsettings
udp: *udpsettings
@@ -224,9 +220,7 @@ firewall:
portgroups: *portgroupsdocker
elastic_agent_endpoint:
portgroups: *portgroupsdocker
external_suricata:
portgroups: *portgroupsdocker
strelka_frontend:
external_suricata:
portgroups: *portgroupsdocker
syslog:
portgroups: *portgroupsdocker
@@ -236,24 +230,24 @@ firewall:
portgroups: *portgroupsdocker
customhostgroup0:
portgroups: *portgroupsdocker
customhostgroup1:
customhostgroup1:
portgroups: *portgroupsdocker
customhostgroup2:
customhostgroup2:
portgroups: *portgroupsdocker
customhostgroup3:
customhostgroup3:
portgroups: *portgroupsdocker
customhostgroup4:
customhostgroup4:
portgroups: *portgroupsdocker
customhostgroup5:
customhostgroup5:
portgroups: *portgroupsdocker
customhostgroup6:
customhostgroup6:
portgroups: *portgroupsdocker
customhostgroup7:
customhostgroup7:
portgroups: *portgroupsdocker
customhostgroup8:
customhostgroup8:
portgroups: *portgroupsdocker
customhostgroup9:
portgroups: *portgroupsdocker
customhostgroup9:
portgroups: *portgroupsdocker
INPUT:
hostgroups:
anywhere:
@@ -569,9 +563,7 @@ firewall:
portgroups: *portgroupsdocker
endgame:
portgroups: *portgroupsdocker
external_suricata:
portgroups: *portgroupsdocker
strelka_frontend:
external_suricata:
portgroups: *portgroupsdocker
syslog:
portgroups: *portgroupsdocker
@@ -711,28 +703,26 @@ firewall:
hostgroups:
self:
portgroups: *portgroupsdocker
strelka_frontend:
portgroups: *portgroupsdocker
customhostgroup0:
portgroups: *portgroupsdocker
customhostgroup1:
customhostgroup1:
portgroups: *portgroupsdocker
customhostgroup2:
customhostgroup2:
portgroups: *portgroupsdocker
customhostgroup3:
customhostgroup3:
portgroups: *portgroupsdocker
customhostgroup4:
customhostgroup4:
portgroups: *portgroupsdocker
customhostgroup5:
customhostgroup5:
portgroups: *portgroupsdocker
customhostgroup6:
customhostgroup6:
portgroups: *portgroupsdocker
customhostgroup7:
customhostgroup7:
portgroups: *portgroupsdocker
customhostgroup8:
customhostgroup8:
portgroups: *portgroupsdocker
customhostgroup9:
portgroups: *portgroupsdocker
customhostgroup9:
portgroups: *portgroupsdocker
INPUT:
hostgroups:
anywhere:
@@ -743,23 +733,23 @@ firewall:
portgroups: *portgroupshost
customhostgroup0:
portgroups: *portgroupshost
customhostgroup1:
customhostgroup1:
portgroups: *portgroupshost
customhostgroup2:
customhostgroup2:
portgroups: *portgroupshost
customhostgroup3:
customhostgroup3:
portgroups: *portgroupshost
customhostgroup4:
customhostgroup4:
portgroups: *portgroupshost
customhostgroup5:
customhostgroup5:
portgroups: *portgroupshost
customhostgroup6:
customhostgroup6:
portgroups: *portgroupshost
customhostgroup7:
customhostgroup7:
portgroups: *portgroupshost
customhostgroup8:
customhostgroup8:
portgroups: *portgroupshost
customhostgroup9:
customhostgroup9:
portgroups: *portgroupshost
heavynode:
@@ -774,11 +764,9 @@ firewall:
portgroups: *portgroupsdocker
self:
portgroups: *portgroupsdocker
strelka_frontend:
portgroups: *portgroupsdocker
customhostgroup0:
portgroups: *portgroupsdocker
customhostgroup1:
customhostgroup1:
portgroups: *portgroupsdocker
customhostgroup2:
portgroups: *portgroupsdocker

View File

@@ -9,5 +9,5 @@ SESSIONCOOKIE=$(curl -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http:
# Disable certain Features from showing up in the Kibana UI
echo
echo "Setting up default Kibana Space:"
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X PUT "localhost:5601/api/spaces/space/default" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d' {"id":"default","name":"Default","disabledFeatures":["ml","enterpriseSearch","logs","infrastructure","apm","uptime","monitoring","stackAlerts","actions","securitySolutionCasesV3","inventory","dataQuality","searchSynonyms","searchQueryRules","enterpriseSearchApplications","enterpriseSearchAnalytics","securitySolutionTimeline","securitySolutionNotes","securitySolutionRulesV1","entityManager","streams","cloudConnect","slo"]} ' >> /opt/so/log/kibana/misc.log
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X PUT "localhost:5601/api/spaces/space/default" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d' {"id":"default","name":"Default","disabledFeatures":["ml","enterpriseSearch","logs","infrastructure","apm","uptime","monitoring","stackAlerts","actions","securitySolutionCasesV3","inventory","dataQuality","searchSynonyms","enterpriseSearchApplications","enterpriseSearchAnalytics","securitySolutionTimeline","securitySolutionNotes","entityManager"]} ' >> /opt/so/log/kibana/misc.log
echo

View File

@@ -231,16 +231,6 @@ logrotate:
- dateext
- dateyesterday
- su root socore
/nsm/strelka/log/strelka_x_log:
- daily
- rotate 14
- missingok
- copytruncate
- compress
- create
- extension .log
- dateext
- dateyesterday
/opt/so/log/sensor_clean_x_log:
- daily
- rotate 2

View File

@@ -147,13 +147,6 @@ logrotate:
multiline: True
global: True
forcedType: "[]string"
"/nsm/strelka/log/strelka_x_log":
description: List of logrotate options for this file.
title: /nsm/strelka/log/strelka.log
advanced: True
multiline: True
global: True
forcedType: "[]string"
"/opt/so/log/sensor_clean_x_log":
description: List of logrotate options for this file.
title: /opt/so/log/sensor_clean.log

View File

@@ -89,7 +89,6 @@ so-logstash:
- /nsm/zeek:/nsm/zeek:ro
- /nsm/suricata:/suricata:ro
- /opt/so/log/fleet/:/osquery/logs:ro
- /opt/so/log/strelka:/strelka:ro
{% endif %}
{% if DOCKERMERGED.containers['so-logstash'].custom_bind_mounts %}
{% for BIND in DOCKERMERGED.containers['so-logstash'].custom_bind_mounts %}

View File

@@ -23,7 +23,6 @@ VALID_ROLES = {
'a': { 'role': 'analyst','desc': 'Analyst - 80/tcp, 443/tcp' },
'b': { 'role': 'beats_endpoint', 'desc': 'Logstash Beat - 5044/tcp' },
'e': { 'role': 'elasticsearch_rest', 'desc': 'Elasticsearch REST API - 9200/tcp' },
'f': { 'role': 'strelka_frontend', 'desc': 'Strelka frontend - 57314/tcp' },
's': { 'role': 'syslog', 'desc': 'Syslog device - 514/tcp/udp' },
}
@@ -91,7 +90,6 @@ def main():
group.add_argument('-a', dest='roles', action='append_const', const=VALID_ROLES['a']['role'], help="Analyst - 80/tcp, 443/tcp")
group.add_argument('-b', dest='roles', action='append_const', const=VALID_ROLES['b']['role'], help="Logstash Beat - 5044/tcp")
group.add_argument('-e', dest='roles', action='append_const', const=VALID_ROLES['e']['role'], help="Elasticsearch REST API - 9200/tcp")
group.add_argument('-f', dest='roles', action='append_const', const=VALID_ROLES['f']['role'], help="Strelka frontend - 57314/tcp")
group.add_argument('-s', dest='roles', action='append_const', const=VALID_ROLES['s']['role'], help="Syslog device - 514/tcp/udp")
ip_g = main_parser.add_argument_group(title='allow')

View File

@@ -511,28 +511,6 @@ function add_redis_to_minion() {
fi
}
function add_strelka_to_minion() {
printf '%s\n'\
"strelka:"\
" backend:"\
" enabled: True"\
" filestream:"\
" enabled: True"\
" frontend:"\
" enabled: True"\
" manager:"\
" enabled: True"\
" coordinator:"\
" enabled: True"\
" gatekeeper:"\
" enabled: True"\
" " >> $PILLARFILE
if [ $? -ne 0 ]; then
log "ERROR" "Failed to add strelka configuration to $PILLARFILE"
return 1
fi
}
function add_telegraf_to_minion() {
printf '%s\n'\
"telegraf:"\
@@ -729,7 +707,6 @@ function createEVAL() {
pcapspace || return 1
add_elasticsearch_to_minion || return 1
add_sensor_to_minion || return 1
add_strelka_to_minion || return 1
add_elastalert_to_minion || return 1
add_kibana_to_minion || return 1
add_telegraf_to_minion || return 1
@@ -748,7 +725,6 @@ function createSTANDALONE() {
add_elasticsearch_to_minion || return 1
add_logstash_to_minion || return 1
add_sensor_to_minion || return 1
add_strelka_to_minion || return 1
add_elastalert_to_minion || return 1
add_kibana_to_minion || return 1
add_redis_to_minion || return 1
@@ -833,7 +809,6 @@ function createHEAVYNODE() {
add_elasticsearch_to_minion || return 1
add_elastic_agent_to_minion || return 1
add_sensor_to_minion || return 1
add_strelka_to_minion || return 1
add_telegraf_to_minion || return 1
}
@@ -844,7 +819,6 @@ function createSENSOR() {
PCAP_PERCENTAGE=3
pcapspace || return 1
add_sensor_to_minion || return 1
add_strelka_to_minion || return 1
add_telegraf_to_minion || return 1
}

View File

@@ -16,6 +16,21 @@ sensoroni:
soc_host:
suripcap:
pcapMaxCount: 100000
fileanalyze:
enabled: False
watchDirs:
- /nsm/zeek/extracted/complete
processedDir: /nsm/strelka/processed
historyDir: /nsm/strelka/history
logFile: /var/log/strelka/strelka.log
concurrency: 8
maxDepth: 15
recycleSeconds: 300
dedupMaxEntries: 100000
dedupTTLSeconds: 3600
yaraRulesPath: /opt/so/conf/strelka/rules/compiled/rules.compiled
passwordsPath: /etc/strelka/passwords.dat
scannerTimeout: 150
analyzers:
echotrail:
base_url: https://api.echotrail.io/insights/

View File

@@ -14,7 +14,7 @@
"serverUrl": "https://{{ GLOBALS.url_base }}/sensoroniagents",
"verifyCert": false,
"modules": {
{%- if SENSORONIMERGED.config.analyze.enabled %}
{%- if SENSORONIMERGED.config.analyze.enabled %}
"analyze": {
"timeoutMs": {{ SENSORONIMERGED.config.analyze.timeout_ms }},
"parallelLimit": {{ SENSORONIMERGED.config.analyze.parallel_limit }}
@@ -31,11 +31,27 @@
"statickeyauth": {
"apiKey": "{{ GLOBALS.sensoroni_key }}"
{% if GLOBALS.is_sensor %}
},
},
"suriquery": {
"pcapInputPath": "/nsm/suripcap",
"pcapOutputPath": "/nsm/pcapout",
"pcapMaxCount": {{ SENSORONIMERGED.config.suripcap.pcapMaxCount }}
{%- endif %}
{%- if SENSORONIMERGED.config.fileanalyze.enabled %}
},
"fileanalyze": {
"watchDirs": {{ SENSORONIMERGED.config.fileanalyze.watchDirs | tojson }},
"processedDir": "{{ SENSORONIMERGED.config.fileanalyze.processedDir }}",
"historyDir": "{{ SENSORONIMERGED.config.fileanalyze.historyDir }}",
"logFile": "{{ SENSORONIMERGED.config.fileanalyze.logFile }}",
"concurrency": {{ SENSORONIMERGED.config.fileanalyze.concurrency }},
"maxDepth": {{ SENSORONIMERGED.config.fileanalyze.maxDepth }},
"recycleSeconds": {{ SENSORONIMERGED.config.fileanalyze.recycleSeconds }},
"dedupMaxEntries": {{ SENSORONIMERGED.config.fileanalyze.dedupMaxEntries }},
"dedupTTLSeconds": {{ SENSORONIMERGED.config.fileanalyze.dedupTTLSeconds }},
"yaraRulesPath": "{{ SENSORONIMERGED.config.fileanalyze.yaraRulesPath }}",
"passwordsPath": "{{ SENSORONIMERGED.config.fileanalyze.passwordsPath }}",
"scannerTimeout": {{ SENSORONIMERGED.config.fileanalyze.scannerTimeout }}
{%- endif %}
}
}

View File

@@ -65,6 +65,60 @@ sensoroni:
description: The maximum number of PCAP packets to extract from eligible PCAP files, for PCAP jobs. If there are issues fetching excessively large packet streams consider lowering this value to reduce the number of collected packets returned to the user interface.
helpLink: pcap
advanced: True
fileanalyze:
enabled:
description: Enable or disable the file analysis module. When enabled, this replaces Strelka for file scanning on sensor nodes.
forcedType: bool
advanced: False
helpLink: strelka
watchDirs:
description: Directories to watch for new files to analyze. Typically the Zeek or Suricata extracted file directories.
advanced: True
helpLink: strelka
processedDir:
description: Directory to move files to after scanning is complete.
advanced: True
helpLink: strelka
historyDir:
description: Directory for on-disk deduplication history. Each scanned file hash is recorded here to survive restarts.
advanced: True
helpLink: strelka
logFile:
description: Path to the JSON log file where scan results are written. This file is picked up by the existing filebeat pipeline.
advanced: True
helpLink: strelka
concurrency:
description: Maximum number of files to scan concurrently.
advanced: True
helpLink: strelka
maxDepth:
description: Maximum recursive extraction depth for nested archives.
advanced: True
helpLink: strelka
recycleSeconds:
description: Interval in seconds to recycle the file watcher to pick up new subdirectories.
advanced: True
helpLink: strelka
dedupMaxEntries:
description: Maximum number of entries in the in-memory deduplication cache.
advanced: True
helpLink: strelka
dedupTTLSeconds:
description: Time-to-live in seconds for deduplication cache entries.
advanced: True
helpLink: strelka
yaraRulesPath:
description: Path to compiled YARA rules file.
advanced: True
helpLink: strelka
passwordsPath:
description: Path to password dictionary for encrypted file cracking attempts.
advanced: True
helpLink: strelka
scannerTimeout:
description: Timeout in seconds for individual scanner execution.
advanced: True
helpLink: strelka
analyzers:
echotrail:
api_key:

View File

@@ -1,59 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'strelka/map.jinja' import STRELKAMERGED %}
include:
- strelka.config
- strelka.backend.sostatus
backend_backend_config:
file.managed:
- name: /opt/so/conf/strelka/backend/backend.yaml
- source: salt://strelka/backend/files/backend.yaml.jinja
- template: jinja
- user: 939
- group: 939
- makedirs: True
- defaults:
BACKENDCONFIG: {{ STRELKAMERGED.backend.config.backend }}
backend_logging_config:
file.managed:
- name: /opt/so/conf/strelka/backend/logging.yaml
- source: salt://strelka/backend/files/logging.yaml.jinja
- template: jinja
- user: 939
- group: 939
- defaults:
LOGGINGCONFIG: {{ STRELKAMERGED.backend.config.logging }}
backend_passwords:
file.managed:
- name: /opt/so/conf/strelka/backend/passwords.dat
- source: salt://strelka/backend/files/passwords.dat.jinja
- template: jinja
- user: 939
- group: 939
- defaults:
PASSWORDS: {{ STRELKAMERGED.backend.config.passwords }}
backend_taste:
file.managed:
- name: /opt/so/conf/strelka/backend/taste/taste.yara
- source: salt://strelka/backend/files/taste/taste.yara
- makedirs: True
- user: 939
- group: 939
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,27 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.backend.sostatus
so-strelka-backend:
docker_container.absent:
- force: True
so-strelka-backend_so-status.disabled:
file.comment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-backend$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,69 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
include:
- strelka.backend.config
- strelka.backend.sostatus
strelka_backend:
docker_container.running:
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-backend:{{ GLOBALS.so_version }}
- binds:
- /opt/so/conf/strelka/backend/:/etc/strelka/:ro
- /opt/so/conf/strelka/rules/compiled/:/etc/yara/:ro
{% if DOCKERMERGED.containers['so-strelka-backend'].custom_bind_mounts %}
{% for BIND in DOCKERMERGED.containers['so-strelka-backend'].custom_bind_mounts %}
- {{ BIND }}
{% endfor %}
{% endif %}
- name: so-strelka-backend
- networks:
- sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-strelka-backend'].ip }}
- command: strelka-backend
- extra_hosts:
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
{% if DOCKERMERGED.containers['so-strelka-backend'].extra_hosts %}
{% for XTRAHOST in DOCKERMERGED.containers['so-strelka-backend'].extra_hosts %}
- {{ XTRAHOST }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-backend'].extra_env %}
- environment:
{% for XTRAENV in DOCKERMERGED.containers['so-strelka-backend'].extra_env %}
- {{ XTRAENV }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-backend'].ulimits %}
- ulimits:
{% for ULIMIT in DOCKERMERGED.containers['so-strelka-backend'].ulimits %}
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
{% endfor %}
{% endif %}
- restart_policy: on-failure
- watch:
- file: strelkasensorcompiledrules
- file: backend_backend_config
- file: backend_logging_config
- file: backend_passwords
- file: backend_taste
delete_so-strelka-backend_so-status.disabled:
file.uncomment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-backend$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1 +0,0 @@
{{ BACKENDCONFIG | yaml(false) }}

View File

@@ -1 +0,0 @@
{{ LOGGINGCONFIG | yaml(false) }}

View File

@@ -1 +0,0 @@
{{ PASSWORDS | join('\n') }}

View File

@@ -1,748 +0,0 @@
// Archive Files
rule _7zip_file
{
meta:
type = "archive"
strings:
$a = { 37 7A BC AF 27 1C }
condition:
$a at 0
}
rule arj_file
{
meta:
type = "archive"
condition:
uint16(0) == 0xEA60
}
rule cab_file
{
meta:
type = "archive"
strings:
$a = { 4D 53 43 46 00 00 00 00 }
condition:
$a at 0 or
( uint16(0) == 0x5A4D and $a )
}
rule cpio_file
{
meta:
type = "archive"
strings:
$a = { 30 37 30 37 30 31 }
condition:
$a at 0
}
rule iso_file
{
meta:
type = "archive"
strings:
$a = { 43 44 30 30 31 }
condition:
$a at 0x8001 and $a at 0x8801 and $a at 0x9001
}
rule mhtml_file
{
meta:
type = "archive"
strings:
$a = "MIME-Version: 1.0"
$b = "This document is a Single File Web Page, also known as a Web Archive file"
condition:
$a at 0 and $b
}
rule rar_file
{
meta:
type = "archive"
condition:
uint16(0) == 0x6152 and uint8(2) == 0x72 and uint16(3) == 0x1A21 and uint8(5) == 0x07
}
rule tar_file
{
meta:
type = "archive"
strings:
$a = { 75 73 74 61 72 }
condition:
uint16(0) == 0x9D1F or
uint16(0) == 0xA01F or
$a at 257
}
rule xar_file
{
meta:
type = "archive"
condition:
uint32(0) == 0x21726178
}
rule zip_file
{
meta:
type = "archive"
condition:
( uint32(0) == 0x04034B50 and not uint32(4) == 0x00060014 )
}
// Audio Files
rule mp3_file
{
meta:
type = "audio"
condition:
uint16(0) == 0x4449 and uint8(2) == 0x33
}
// Certificate Files
rule pkcs7_file
{
meta:
type = "certificate"
strings:
$a = "-----BEGIN PKCS7-----"
condition:
(uint16(0) == 0x8230 and uint16(4) == 0x0906) or
uint32(0) == 0x09068030 or
$a at 0
}
rule x509_der_file
{
meta:
type = "certificate"
condition:
uint16(0) == 0x8230 and ( uint16(4) == 0x8230 or uint16(4) == 0x8130 )
}
rule x509_pem_file
{
meta:
type = "certificate"
strings:
$a = "-----BEGIN CERTI"
condition:
$a at 0
}
// Compressed Files
rule bzip2_file
{
meta:
type = "compressed"
condition:
uint16(0) == 0x5A42 and uint8(2) == 0x68
}
rule gzip_file
{
meta:
type = "compressed"
condition:
uint16(0) == 0x8B1F and uint8(2) == 0x08
}
rule lzma_file
{
meta:
type = "compressed"
condition:
uint16(0) == 0x005D and uint8(2) == 0x00
}
rule xz_file
{
meta:
type = "compressed"
condition:
uint32(0) == 0x587A37FD and uint16(4) == 0x005A
}
// Document Files
rule doc_subheader_file
{
meta:
type = "document"
condition:
uint32(0) == 0x00C1A5EC
}
rule mso_file
{
meta:
type = "document"
strings:
$a = { 3C 3F 6D 73 6F 2D 61 70 70 6C 69 63 61 74 69 6F 6E 20 } // <?mso-application
$b = { 3C 3F 6D 73 6F 2D 63 6F 6E 74 65 6E 74 54 79 70 65 } // <?mso-contentType
condition:
$a at 0 or
$b at 0
}
rule olecf_file
{
meta:
description = "Object Linking and Embedding (OLE) Compound File (CF)"
type = "document"
condition:
uint32(0) == 0xE011CFD0 and uint32(4) == 0xE11AB1A1
}
rule ooxml_file
{
meta:
description = "Microsoft Office Open XML Format"
type = "document"
condition:
uint32(0) == 0x04034B50 and uint32(4) == 0x00060014
}
rule pdf_file
{
meta:
description = "Portable Document Format"
type = "document"
condition:
uint32(0) == 0x46445025
}
rule poi_hpbf_file
{
meta:
description = "https://poi.apache.org/components/hpbf/file-format.html"
type = "document"
strings:
$a = { 43 48 4E 4B 49 4E 4B } // CHNKINK
condition:
$a at 0
}
rule rtf_file
{
meta:
type = "document"
condition:
uint32(0) == 0x74725C7B
}
rule vbframe_file
{
meta:
type = "document"
strings:
$a = { 56 45 52 53 49 4F 4E 20 35 2E 30 30 0D 0A 42 65 67 69 6E } // VERSION 5.00\r\nBegin
condition:
$a at 0
}
rule wordml_file
{
meta:
description = "Microsoft Office Word 2003 XML format"
type = "document"
strings:
$a = { 3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D } // <?xml version=
$b = "http://schemas.microsoft.com/office/word/2003/wordml"
condition:
$a at 0 and $b
}
rule xfdf_file
{
meta:
description = "XML Forms Data Format"
type = "document"
strings:
$a = { 3C 78 66 64 66 20 78 6D 6C 6E 73 3D } // <xfdf xmlns=
condition:
$a at 0
}
// Email Files
rule email_file
{
meta:
type = "email"
strings:
$a = "\x0aReceived:" nocase fullword
$b = "\x0AReturn-Path:" nocase fullword
$c = "\x0aMessage-ID:" nocase fullword
$d = "\x0aReply-To:" nocase fullword
$e = "\x0aX-Mailer:" nocase fullword
condition:
$a in (0..2048) or
$b in (0..2048) or
$c in (0..2048) or
$d in (0..2048) or
$e in (0..2048)
}
rule tnef_file
{
meta:
description = "Transport Neutral Encapsulation Format"
type = "email"
condition:
uint32(0) == 0x223E9F78
}
// Encryption Files
rule pgp_file
{
meta:
type = "encryption"
strings:
$a = { ?? ?? 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 50 55 42 4C 49 43 20 4B 45 59 20 42 4C 4F 43 4B 2D } // (.{2})(\x2D\x2D\x2DBEGIN PGP PUBLIC KEY BLOCK\x2D)
$b = { ?? ?? 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 53 49 47 4E 41 54 55 52 45 2D } // (\x2D\x2D\x2D\x2D\x2DBEGIN PGP SIGNATURE\x2D)
$c = { ?? ?? 2D 2D 2D 42 45 47 49 4E 20 50 47 50 20 4D 45 53 53 41 47 45 2D } // (\x2D\x2D\x2D\x2D\x2DBEGIN PGP MESSAGE\x2D)
condition:
$a at 0 or
$b at 0 or
$c at 0
}
// Executable Files
rule elf_file
{
meta:
description = "Executable and Linkable Format"
type = "executable"
condition:
uint32(0) == 0x464C457F
}
rule lnk_file
{
meta:
description = "Windows Shortcut file"
type = "executable"
condition:
uint32(0) == 0x0000004C
}
rule macho_file
{
meta:
description = "Mach object"
type = "executable"
condition:
uint32(0) == 0xCEFAEDFE or
uint32(0) == 0xCFFAEDFE or
uint32(0) == 0xFEEDFACE or
uint32(0) == 0xFEEDFACF
}
rule mz_file
{
meta:
description = "DOS MZ executable"
type = "executable"
condition:
uint16(0) == 0x5A4D
}
// Image Files
rule bmp_file
{
meta:
type = "image"
strings:
$a = { 42 4D ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ( 0C | 28 | 40 | 6C | 7C | 80 ) 00 } // BM
condition:
$a at 0
}
rule cmap_file
{
meta:
type = "image"
strings:
$a = { 62 65 67 69 6E 63 6D 61 70 } // begincmap
condition:
$a at 0
}
rule gif_file
{
meta:
description = "Graphics Interchange Format"
type = "image"
condition:
uint32(0) == 0x38464947 and ( uint16(4) == 0x6137 or uint16(4) == 0x6139 )
}
rule jpeg_file
{
meta:
type = "image"
condition:
uint32(0) == 0xE0FFD8FF or
uint32(0) == 0xE1FFD8FF or
uint32(0) == 0xE2FFD8FF or
uint32(0) == 0xE8FFD8FF
}
rule postscript_file
{
meta:
type = "image"
strings:
$a = { 25 21 50 53 2D 41 64 6F 62 65 2D 33 2E 30 } // %!PS-Adobe-3.0
condition:
$a at 0
}
rule png_file
{
meta:
type = "image"
condition:
uint32(0) == 0x474E5089
}
rule psd_file
{
meta:
description = "Photoshop Document"
type = "image"
condition:
uint32(0) == 0x53504238
}
rule psd_image_file
{
meta:
description = "Photoshop Document image resource block"
type = "image"
condition:
uint32(0) == 0x4D494238
}
rule svg_file
{
meta:
type = "image"
strings:
$a = { 3C 73 76 67 20 } // <svg
condition:
$a at 0
}
rule xicc_file
{
meta:
type = "image"
strings:
$a = { 58 49 43 43 5F 50 52 4F 46 49 4C 45 } // XICC_PROFILE
condition:
$a at 0
}
rule xmp_file
{
meta:
type = "image"
strings:
$a = { 3C 3F 78 70 61 63 6B 65 74 20 62 65 67 69 6E 3D } // <?xpacket begin=
$b = { 3C 78 3A 78 6D 70 6D 65 74 61 20 78 6D 6C 6E 73 3A 78 3D } // <x:xmpmeta xmlns:x=
condition:
$a at 0 or $b at 0
}
// Metadata Files
rule jar_manifest_file
{
meta:
type = "metadata"
condition:
uint32(0) == 0x696E614D and uint32(4) == 0x74736566
}
rule bplist_file
{
meta:
description = "Binary Property List"
type = "metadata"
condition:
uint32(0) == 0x696C7062 and uint32(4) == 0x30307473
}
// Multimedia Files
rule fws_file
{
meta:
type = "multimedia"
condition:
uint16(0) == 0x5746 and uint8(2) == 0x53
}
rule cws_file
{
meta:
description = "zlib compressed Flash file"
type = "multimedia"
condition:
uint16(0) == 0x5743 and uint8(2) == 0x53
}
rule zws_file
{
meta:
description = "LZMA compressed Flash file"
type = "multimedia"
condition:
uint16(0) == 0x575A and uint8(2) == 0x53
}
// Package Files
rule debian_package_file
{
meta:
type = "package"
strings:
$a = { 21 3C 61 72 63 68 3E 0A 64 65 62 69 61 6E } // \x21\x3Carch\x3E\x0Adebian
condition:
$a at 0
}
rule rpm_file
{
meta:
type = "package"
condition:
uint32(0) == 0x6D707264 or uint32(0) == 0xDBEEABED
}
// Packer Files
rule upx_file
{
meta:
description = "Ultimate Packer for Executables"
type = "packer"
strings:
$a = {55505830000000}
$b = {55505831000000}
$c = "UPX!"
condition:
uint16(0) == 0x5A4D and
$a in (0..1024) and
$b in (0..1024) and
$c in (0..1024)
}
// Script Files
rule batch_file
{
meta:
type = "script"
strings:
$a = { ( 45 | 65 ) ( 43 | 63 ) ( 48 | 68 ) ( 4F | 6F ) 20 ( 4F | 6F) ( 46 | 66 ) ( 46 | 66 ) } // [Ee][Cc][Hh][Oo] [Oo][Ff][Ff]
condition:
$a at 0
}
rule javascript_file
{
meta:
type = "script"
strings:
$var = { 76 61 72 20 } // var
$function1 = { 66 75 6E 63 74 69 6F 6E } // function
$function2 = { 28 66 75 6E 63 74 69 6F 6E } // (function
$function3 = { 66 75 6E 63 74 69 6F 6E [0-1] 28 } // function[0-1](
$if = { 69 66 [0-1] 28 } // if[0-1](
$misc1 = { 24 28 } // $(
$misc2 = { 2F ( 2A | 2F ) } // \/(\/|\*)
$jquery = { 6A 51 75 65 72 79 } // jQuery
$try = { 74 72 79 [0-1] 7B } // try[0-1]{
$catch = { 63 61 74 63 68 28 } // catch(
$push = { 2E 70 75 73 68 28 } // .push(
$array = { 6E 65 77 20 41 72 72 61 79 28 } // new Array(
$document1 = { 64 6f 63 75 6d 65 6e 74 2e 63 72 65 61 74 65 } // document.create
$document2 = { 64 6F 63 75 6D 65 6E 74 2E 77 72 69 74 65 } // document.write
$window = { 77 69 6E 64 6F 77 ( 2E | 5B ) } // window[.\[]
$define = { 64 65 66 69 6E 65 28 } // define(
$eval = { 65 76 61 6C 28 } // eval(
$unescape = { 75 6E 65 73 63 61 70 65 28 } // unescape(
condition:
$var at 0 or
$function1 at 0 or
$function2 at 0 or
$if at 0 or
$jquery at 0 or
$function3 in (0..30) or
$push in (0..30) or
$array in (0..30) or
( $try at 0 and $catch in (5..5000) ) or
$document1 in (0..100) or
$document2 in (0..100) or
$window in (0..100) or
$define in (0..100) or
$eval in (0..100) or
$unescape in (0..100) or
( ( $misc1 at 0 or $misc2 at 0 ) and $var and $function1 and $if )
}
rule vb_file
{
meta:
type = "script"
strings:
$a = { 41 74 74 72 69 62 75 74 65 20 56 42 5F 4E 61 6D 65 20 3D } // Attribute VB_Name =
$b = { 4F 70 74 69 6F 6E 20 45 78 70 6C 69 63 69 74 } // Option Explicit
$c = { 44 69 6D 20 } // Dim
$d = { 50 75 62 6C 69 63 20 53 75 62 20 } // Public Sub
$e = { 50 72 69 76 61 74 65 20 53 75 62 20 } // Private Sub
condition:
$a at 0 or
$b at 0 or
$c at 0 or
$d at 0 or
$e at 0
}
// Text Files
rule hta_file
{
meta:
type = "text"
strings:
$a = { 3C 48 54 41 3A 41 50 50 4C 49 43 41 54 49 4F 4E 20 } // <HTA:APPLICATION
condition:
$a in (0..2000)
}
rule html_file
{
meta:
type = "text"
strings:
$a = { 3C 21 ( 64 | 44 ) ( 6F | 4F ) ( 63 |43 ) ( 74 | 54 ) ( 79 | 59 ) ( 70 | 50 ) ( 65 | 45 ) 20 ( 68 | 48 ) ( 74 | 54 ) ( 6D | 4D ) ( 6C | 4C ) } // <![Dd][Oo][Cc][Tt][Yy][Pp][Ee] [Hh][Tt][Mm][Ll]
$b = { 3C ( 68 | 48 ) ( 74 | 54 ) ( 6D | 4D ) ( 6C | 4C ) } // <[Hh][Tt][Mm][Ll]
$c = { 3C ( 62 | 42 ) ( 72 | 52 ) } // <br
$d = { 3C ( 44 | 64 ) ( 49 | 69 ) ( 56 | 76 ) } // <[Dd][Ii][Vv]
$e = { 3C ( 41 | 61 ) 20 ( 48 |68 ) ( 52 | 72 ) ( 45 | 65 ) ( 46 | 66 ) 3D } // <[Aa] [Hh][Rr][Ee][Ff]=
$f = { 3C ( 48 | 68 ) ( 45 | 65 ) ( 41 | 61 ) ( 44 | 64 ) } // <[Hh][Ee][Aa][Dd]
$g = { 3C ( 53 | 73 ) ( 43 | 63 ) ( 52 | 72 ) ( 49 | 69 ) ( 50 | 70 ) ( 54 | 74 ) } // <[Ss][Cc][Rr][Ii][Pp][Tt]
$h = { 3C ( 53 | 73 ) ( 54 | 74 ) ( 59 | 79 ) ( 4C | 6C ) ( 45 | 65 ) } // <[Ss][Tt][Yy][Ll][Ee]
$i = { 3C ( 54 | 74 ) ( 41 | 61 ) ( 42 | 62 ) ( 4C | 6C ) ( 45 | 65 ) } // <[Tt][Aa][Bb][Ll][Ee]
$j = { 3C ( 50 | 70 ) } // <[Pp]
$k = { 3C ( 49 | 69 ) ( 4D | 6D ) ( 47 | 67 ) } // <[Ii][Mm][Gg]
$l = { 3C ( 53 | 73 ) ( 50 |70 ) ( 41 | 61 ) ( 4E | 6E ) } // <[Ss][Pp][Aa][Nn]
$m = { 3C ( 48 | 68 ) ( 52 | 72 | 31 | 32 | 33 | 34 | 35 | 36 ) } // <[Hh][Rr] <[Hh][1-6]
$n = { 3C ( 54 | 74) ( 49 | 69 ) ( 54 | 74 ) ( 4C | 6C ) ( 45 | 65 ) 3E } // <[Tt][Ii][Tt][Ll][Ee]>
condition:
$a at 0 or
$b at 0 or
$c at 0 or
$d at 0 or
$e at 0 or
$f at 0 or
$g at 0 or
$h at 0 or
$i at 0 or
$j at 0 or
$k at 0 or
$l at 0 or
$m at 0 or
$n at 0
}
rule json_file
{
meta:
type = "text"
strings:
$a = { 7B [0-5] 22 }
condition:
$a at 0
}
rule php_file
{
meta:
type = "text"
strings:
$a = { 3c 3f 70 68 70 }
condition:
$a at 0
}
rule soap_file
{
meta:
description = "Simple Object Access Protocol"
type = "text"
strings:
$a = { 3C 73 6F 61 70 65 6E 76 3A 45 6E 76 65 6C 6F 70 65 } // <soapenv:Envelope xmlns
$b = { 3C 73 3A 45 6E 76 65 6C 6F 70 65 } // <s:Envelope
condition:
$a at 0 or
$b at 0
}
rule xml_file
{
meta:
type = "text"
strings:
$a = { 3C 3F ( 58 | 78) ( 4D | 6D ) ( 4C | 6C ) 20 76 65 72 73 69 6F 6E 3D } // <?[Xx][Mm][Ll] version=
$b = { 3C 3F 78 6D 6C 3F 3E } // <?xml?>
$c = { 3C 73 74 79 6C 65 53 68 65 65 74 20 78 6D 6C 6E 73 3D } // <styleSheet xmlns=
$d = { 3C 77 6F 72 6B 62 6F 6F 6B 20 78 6D 6C 6E 73 } // <workbook xmlns
$e = { 3C 78 6D 6C 20 78 6D 6C 6E 73 } // <xml xmlns
$f = { 3C 69 6E 74 20 78 6D 6C 6E 73 } // <int xmlns
condition:
$a at 0 or
$b at 0 or
$c at 0 or
$d at 0 or
$e at 0 or
$f at 0
}
// Video Files
rule avi_file
{
meta:
type = "video"
strings:
$a = { 52 49 46 46 ?? ?? ?? ?? 41 56 49 20 4C 49 53 54 }
condition:
$a at 0
}
rule wmv_file
{
meta:
type = "video"
condition:
uint32(0) == 0x75B22630 and uint32(4) == 0x11CF668E and uint32(8) == 0xAA00D9A6 and uint32(12) == 0x6CCE6200
}

View File

@@ -1,13 +0,0 @@
# 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 'strelka/map.jinja' import STRELKAMERGED %}
include:
{% if STRELKAMERGED.backend.enabled %}
- strelka.backend.enabled
{% else %}
- strelka.backend.disabled
{% endif %}

View File

@@ -1,21 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
append_so-strelka-backend_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-strelka-backend
- unless: grep -q so-strelka-backend /opt/so/conf/so-status/so-status.conf
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,99 +0,0 @@
# 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.
import argparse
import glob
import hashlib
import json
import os
import yara
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
def check_syntax(rule_file):
try:
# Testing if compilation throws a syntax error, don't save the result
yara.compile(filepath=rule_file)
return (True, rule_file, None)
except yara.SyntaxError as e:
# Return the error message for logging purposes
return (False, rule_file, str(e))
def compile_yara_rules(rules_dir):
compiled_dir = os.path.join(rules_dir, "compiled")
compiled_rules_path = "/opt/so/saltstack/local/salt/strelka/rules/compiled/rules.compiled"
rule_files = glob.glob(os.path.join(rules_dir, '**/*.yar'), recursive=True)
files_to_compile = {}
removed_count = 0
success_count = 0
# Use ThreadPoolExecutor to parallelize syntax checks
with ThreadPoolExecutor() as executor:
results = executor.map(check_syntax, rule_files)
# Collect yara files and prepare for batch compilation
ts = str(datetime.utcnow().isoformat())
failure_ids = []
success_ids = []
for success, rule_file, error_message in results:
rule_id = os.path.splitext(os.path.basename(rule_file))[0]
if success:
files_to_compile[os.path.basename(rule_file)] = rule_file
success_count += 1
success_ids.append(rule_id)
else:
failure_ids.append(rule_id)
# Extract just the UUID from the rule file name
log_entry = {
"event_module": "soc",
"event_dataset": "soc.detections",
"log.level": "error",
"error_message": error_message,
"error_analysis": "Syntax Error",
"detection_type": "YARA",
"rule_uuid": rule_id,
"error_type": "runtime_status"
}
with open('/opt/sensoroni/logs/detections_runtime-status_yara.log', 'a') as log_file:
json.dump(log_entry, log_file)
log_file.write('\n') # Ensure new entries start on new lines
os.remove(rule_file)
removed_count += 1
# Compile all remaining valid rules into a single file
compiled_sha256=""
if files_to_compile:
compiled_rules = yara.compile(filepaths=files_to_compile)
compiled_rules.save(compiled_rules_path)
print(f"All remaining rules compiled and saved into {compiled_rules_path}")
# Hash file
with open(compiled_rules_path, 'rb') as hash_file:
compiled_sha256=hashlib.sha256(hash_file.read()).hexdigest()
# Remove the rules.compiled if there aren't any files to be compiled
else:
if os.path.exists(compiled_rules_path):
os.remove(compiled_rules_path)
# Create compilation report
compilation_report = {
"timestamp": ts,
"compiled_sha256": compiled_sha256,
"failure": failure_ids,
"success": success_ids
}
# Write total
with open('/opt/so/state/detections_yara_compilation-total.log', 'w+') as report_file:
json.dump(compilation_report, report_file)
# Print summary of compilation results
print(f"Summary: {success_count} rules compiled successfully, {removed_count} rules removed due to errors.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Compile YARA rules from the specified directory")
parser.add_argument("rules_dir", help="Directory containing YARA rules to compile")
args = parser.parse_args()
compile_yara_rules(args.rules_dir)

View File

@@ -1,64 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% if GLOBALS.is_manager %}
include:
- strelka.manager
{% endif %}
# Strelka config
strelkasensorcompiledrules:
file.recurse:
- name: /opt/so/conf/strelka/rules/compiled/
- source: salt://strelka/rules/compiled/
- user: 939
- group: 939
- clean: True
- makedirs: True
strelkadatadir:
file.directory:
- name: /nsm/strelka
- user: 939
- group: 939
- makedirs: True
strelkalogdir:
file.directory:
- name: /nsm/strelka/log
- user: 939
- group: 939
strelkagkredisdatadir:
file.directory:
- name: /nsm/strelka/gk-redis-data
- user: 939
- group: 939
strelkacoordredisdatadir:
file.directory:
- name: /nsm/strelka/coord-redis-data
- user: 939
- group: 939
strelka_sbin:
file.recurse:
- name: /usr/sbin
- source: salt://strelka/tools/sbin
- user: 939
- group: 939
- file_mode: 755
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,19 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.config
- strelka.coordinator.sostatus
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,27 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.coordinator.sostatus
so-strelka-coordinator:
docker_container.absent:
- force: True
so-strelka-coordinator_so-status.disabled:
file.comment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-coordinator$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,64 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
include:
- strelka.coordinator.config
- strelka.coordinator.sostatus
strelka_coordinator:
docker_container.running:
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }}
- name: so-strelka-coordinator
- networks:
- sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-strelka-coordinator'].ip }}
- entrypoint: redis-server --save "" --appendonly no
- extra_hosts:
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
{% if DOCKERMERGED.containers['so-strelka-coordinator'].extra_hosts %}
{% for XTRAHOST in DOCKERMERGED.containers['so-strelka-coordinator'].extra_hosts %}
- {{ XTRAHOST }}
{% endfor %}
{% endif %}
- port_bindings:
{% for BINDING in DOCKERMERGED.containers['so-strelka-coordinator'].port_bindings %}
- {{ BINDING }}
{% endfor %}
{% if DOCKERMERGED.containers['so-strelka-coordinator'].extra_env %}
- environment:
{% for XTRAENV in DOCKERMERGED.containers['so-strelka-coordinator'].extra_env %}
- {{ XTRAENV }}
{% endfor %}
{% endif %}
- binds:
- /nsm/strelka/coord-redis-data:/data:rw
{% if DOCKERMERGED.containers['so-strelka-coordinator'].custom_bind_mounts %}
{% for BIND in DOCKERMERGED.containers['so-strelka-coordinator'].custom_bind_mounts %}
- {{ BIND }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-coordinator'].ulimits %}
- ulimits:
{% for ULIMIT in DOCKERMERGED.containers['so-strelka-coordinator'].ulimits %}
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
{% endfor %}
{% endif %}
delete_so-strelka-coordinator_so-status.disabled:
file.uncomment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-coordinator$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,13 +0,0 @@
# 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 'strelka/map.jinja' import STRELKAMERGED %}
include:
{% if STRELKAMERGED.coordinator.enabled %}
- strelka.coordinator.enabled
{% else %}
- strelka.coordinator.disabled
{% endif %}

View File

@@ -1,21 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
append_so-strelka-coordinator_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-strelka-coordinator
- unless: grep -q so-strelka-coordinator /opt/so/conf/so-status/so-status.conf
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,739 +0,0 @@
strelka:
backend:
enabled: False
config:
backend:
logging_cfg: '/etc/strelka/logging.yaml'
limits:
max_files: 0
time_to_live: 0
max_depth: 15
distribution: 600
scanner: 150
coordinator:
addr: 'HOST:6380'
db: 0
tasting:
mime_db: '/usr/lib/file/magic.mgc'
yara_rules: '/etc/strelka/taste/'
scanners:
'ScanBase64PE':
- positive:
flavors:
- 'base64_pe'
priority: 5
'ScanBatch':
- positive:
flavors:
- 'text/x-msdos-batch'
- 'batch_file'
priority: 5
'ScanBmpEof':
- positive:
flavors:
- 'image/x-ms-bmp'
- 'bmp_file'
negative:
source:
- 'ScanTranscode'
priority: 5
'ScanBzip2':
- positive:
flavors:
- 'application/x-bzip2'
- 'bzip2_file'
priority: 5
'ScanDmg':
- positive:
flavors:
- 'dmg_disk_image'
- 'hfsplus_disk_image'
priority: 5
'ScanDocx':
- positive:
flavors:
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
priority: 5
options:
extract_text: False
'ScanDonut':
- positive:
flavors:
- 'hacktool_win_shellcode_donut'
priority: 5
'ScanElf':
- positive:
flavors:
- 'application/x-object'
- 'application/x-executable'
- 'application/x-sharedlib'
- 'application/x-coredump'
- 'elf_file'
priority: 5
'ScanEmail':
- positive:
flavors:
- 'application/vnd.ms-outlook'
- 'message/rfc822'
- 'email_file'
priority: 5
'ScanEncryptedDoc':
- positive:
flavors:
- 'encrypted_word_document'
priority: 5
options:
max_length: 5
scanner_timeout: 150
log_pws: True
password_file: "/etc/strelka/passwords.dat"
'ScanEncryptedZip':
- positive:
flavors:
- 'encrypted_zip'
priority: 5
options:
max_length: 5
scanner_timeout: 150
log_pws: True
password_file: '/etc/strelka/passwords.dat'
'ScanEntropy':
- positive:
flavors:
- '*'
priority: 5
'ScanExiftool':
- positive:
flavors:
- 'application/msword'
- 'application/vnd.openxmlformats-officedocument'
- 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
- 'olecf_file'
- 'ooxml_file'
- 'audio/mpeg'
- 'mp3_file'
- 'mhtml_file'
- 'application/pdf'
- 'pdf_file'
- 'text/rtf'
- 'rtf_file'
- 'wordml_file'
- 'application/x-dosexec'
- 'mz_file'
- 'application/x-object'
- 'application/x-executable'
- 'application/x-sharedlib'
- 'application/x-coredump'
- 'elf_file'
- 'lnk_file'
- 'application/x-mach-binary'
- 'macho_file'
- 'image/gif'
- 'gif_file'
- 'image/jpeg'
- 'jpeg_file'
- 'image/png'
- 'png_file'
- 'image/tiff'
- 'type_is_tiff'
- 'image/x-ms-bmp'
- 'bmp_file'
- 'application/x-shockwave-flash'
- 'fws_file'
- 'psd_file'
- 'video/mp4'
- 'video/quicktime'
- 'video/x-msvideo'
- 'avi_file'
- 'video/x-ms-wmv'
- 'wmv_file'
priority: 5
options:
tmp_directory: '/dev/shm/'
'ScanFooter':
- positive:
flavors:
- '*'
priority: 5
options:
length: 50
encodings:
- classic
- backslash
'ScanGif':
- positive:
flavors:
- 'image/gif'
- 'gif_file'
priority: 5
'ScanGzip':
- positive:
flavors:
- 'application/gzip'
- 'application/x-gzip'
- 'gzip_file'
priority: 5
'ScanHash':
- positive:
flavors:
- '*'
priority: 5
'ScanHeader':
- positive:
flavors:
- '*'
priority: 5
options:
length: 50
'ScanHtml':
- positive:
flavors:
- 'hta_file'
- 'text/html'
- 'html_file'
priority: 5
options:
max_hyperlinks: 50
'ScanIqy':
- positive:
flavors:
- 'iqy_file'
priority: 5
'ScanIni':
- positive:
filename: '(\.([Cc][Ff][Gg]|[Ii][Nn][Ii])|PROJECT)$'
flavors:
- 'ini_file'
priority: 5
'ScanIso':
- positive:
flavors:
- 'application/x-iso9660-image'
priority: 5
options:
limit: 50
'ScanJarManifest':
- positive:
flavors:
- 'jar_manifest_file'
priority: 5
'ScanJavascript':
- negative:
flavors:
- 'text/html'
- 'html_file'
positive:
flavors:
- 'javascript_file'
- 'text/javascript'
priority: 5
options:
beautify: True
'ScanJpeg':
- positive:
flavors:
- 'image/jpeg'
- 'jpeg_file'
priority: 5
'ScanJson':
- positive:
flavors:
- 'application/json'
- 'json_file'
priority: 5
'ScanLibarchive':
- positive:
flavors:
- 'application/vnd.ms-cab-compressed'
- 'cab_file'
- 'application/x-7z-compressed'
- '_7zip_file'
- 'application/x-cpio'
- 'cpio_file'
- 'application/x-xar'
- 'xar_file'
- 'arj_file'
- 'iso_file'
- 'application/x-debian-package'
- 'debian_package_file'
priority: 5
options:
limit: 1000
'ScanLNK':
- positive:
flavors:
- 'lnk_file'
priority: 5
'ScanLsb':
- positive:
flavors:
- 'image/png'
- 'png_file'
- 'image/jpeg'
- 'jpeg_file'
- 'image/x-ms-bmp'
- 'bmp_file'
- 'image/webp'
negative:
source:
- 'ScanTranscode'
priority: 5
'ScanLzma':
- positive:
flavors:
- 'application/x-lzma'
- 'lzma_file'
- 'application/x-xz'
- 'xz_file'
priority: 5
'ScanMacho':
- positive:
flavors:
- 'application/x-mach-binary'
- 'macho_file'
priority: 5
options:
tmp_directory: '/dev/shm/'
'ScanManifest':
- positive:
flavors:
- 'browser_manifest'
priority: 5
'ScanMsi':
- positive:
flavors:
- "image/vnd.fpx"
- "application/vnd.ms-msi"
- "application/x-msi"
priority: 5
options:
tmp_directory: '/dev/shm/'
keys:
- 'Author'
- 'Characters'
- 'Company'
- 'CreateDate'
- 'LastModifiedBy'
- 'Lines'
- 'ModifyDate'
- 'Pages'
- 'Paragraphs'
- 'RevisionNumber'
- 'Software'
- 'Template'
- 'Title'
- 'TotalEditTime'
- 'Words'
'ScanOcr':
- positive:
flavors:
- 'image/jpeg'
- 'jpeg_file'
- 'image/png'
- 'png_file'
- 'image/tiff'
- 'type_is_tiff'
- 'image/x-ms-bmp'
- 'bmp_file'
priority: 5
options:
extract_text: False
tmp_directory: '/dev/shm/'
'ScanOle':
- positive:
flavors:
- 'application/CDFV2'
- 'application/msword'
- 'olecf_file'
priority: 5
'ScanOnenote':
- positive:
flavors:
- 'application/onenote'
- 'application/msonenote'
- 'onenote_file'
priority: 5
'ScanPdf':
- positive:
flavors:
- 'application/pdf'
- 'pdf_file'
priority: 5
options:
extract_text: False
limit: 2000
'ScanPe':
- positive:
flavors:
- 'application/x-dosexec'
- 'mz_file'
priority: 5
'ScanPgp':
- positive:
flavors:
- 'application/pgp-keys'
- 'pgp_file'
priority: 5
'ScanPhp':
- positive:
flavors:
- 'text/x-php'
- 'php_file'
priority: 5
'ScanPkcs7':
- positive:
flavors:
- 'pkcs7_file'
priority: 5
options:
tmp_directory: '/dev/shm/'
'ScanPlist':
- positive:
flavors:
- 'bplist_file'
- 'plist_file'
priority: 5
options:
keys:
- 'KeepAlive'
- 'Label'
- 'NetworkState'
- 'Program'
- 'ProgramArguments'
- 'RunAtLoad'
- 'StartInterval'
'ScanPngEof':
- positive:
flavors:
- 'image/png'
- 'png_file'
negative:
source:
- 'ScanTranscode'
priority: 5
'ScanQr':
- positive:
flavors:
- 'image/jpeg'
- 'jpeg_file'
- 'image/png'
- 'png_file'
- 'image/tiff'
- 'type_is_tiff'
- 'image/x-ms-bmp'
- 'bmp_file'
- 'image/webp'
priority: 5
options:
support_inverted: True
'ScanRar':
- positive:
flavors:
- 'application/x-rar'
- 'rar_file'
priority: 5
options:
limit: 1000
'ScanRpm':
- positive:
flavors:
- 'application/x-rpm'
- 'rpm_file'
priority: 5
options:
tmp_directory: '/dev/shm/'
'ScanRtf':
- positive:
flavors:
- 'text/rtf'
- 'rtf_file'
priority: 5
options:
limit: 1000
'ScanSevenZip':
- positive:
flavors:
- 'application/x-7z-compressed'
- '_7zip_file'
- "image/vnd.fpx"
- "application/vnd.ms-msi"
- "application/x-msi"
priority: 5
options:
scanner_timeout: 150
crack_pws: True
log_pws: True
'ScanSwf':
- positive:
flavors:
- 'application/x-shockwave-flash'
- 'fws_file'
- 'cws_file'
- 'zws_file'
priority: 5
'ScanTar':
- positive:
flavors:
- 'application/x-tar'
- 'tar_file'
priority: 5
options:
limit: 1000
'ScanTnef':
- positive:
flavors:
- 'application/vnd.ms-tnef'
- 'tnef_file'
priority: 5
'ScanUpx':
- positive:
flavors:
- 'upx_file'
priority: 5
options:
tmp_directory: '/dev/shm/'
'ScanUrl':
- negative:
flavors:
- 'javascript_file'
positive:
flavors:
- 'text/plain'
priority: 5
'ScanVb':
- positive:
flavors:
- 'vb_file'
- 'vbscript'
- 'hta_file'
priority: 5
'ScanVba':
- positive:
flavors:
- 'mhtml_file'
- 'application/msword'
- 'olecf_file'
- 'wordml_file'
priority: 5
options:
analyze_macros: True
'ScanVhd':
- positive:
flavors:
- 'application/x-vhd'
- 'vhd_file'
- 'vhdx_file'
priority: 5
options:
limit: 100
'ScanVsto':
- positive:
flavors:
- 'vsto_file'
priority: 5
'ScanX509':
- positive:
flavors:
- 'x509_der_file'
priority: 5
options:
type: 'der'
- positive:
flavors:
- 'x509_pem_file'
priority: 5
options:
type: 'pem'
'ScanXml':
- positive:
flavors:
- 'application/xml'
- 'text/xml'
- 'xml_file'
- 'mso_file'
- 'soap_file'
priority: 5
'ScanYara':
- positive:
flavors:
- '*'
priority: 5
options:
location: '/etc/yara/'
compiled:
enabled: True
filename: "rules.compiled"
store_offset: True
offset_meta_key: "StrelkaHexDump"
offset_padding: 32
'ScanZip':
- positive:
flavors:
- 'application/java-archive'
- 'application/zip'
- 'zip_file'
- 'application/vnd.openxmlformats-officedocument'
- 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
- 'ooxml_file'
priority: 5
options:
limit: 1000
password_file: '/etc/strelka/passwords.dat'
'ScanZlib':
- positive:
flavors:
- 'application/zlib'
- 'zlib_file'
priority: 5
logging:
version: 1
formatters:
simple:
format: '%(asctime)s - [%(levelname)s] %(name)s [%(module)s.%(funcName)s]: %(message)s'
datefmt: '%Y-%m-%d %H:%M:%S'
handlers:
console:
class: logging.StreamHandler
formatter: simple
stream: ext://sys.stdout
root:
level: DEBUG
handlers: [console]
loggers:
OpenSSL:
propagate: 0
bs4:
propagate: 0
bz2:
propagate: 0
chardet:
propagate: 0
docx:
propagate: 0
elftools:
propagate: 0
email:
propagate: 0
entropy:
propagate: 0
esprima:
propagate: 0
gzip:
propagate: 0
hashlib:
propagate: 0
json:
propagate: 0
libarchive:
propagate: 0
lxml:
propagate: 0
lzma:
propagate: 0
macholibre:
propagate: 0
olefile:
propagate: 0
oletools:
propagate: 0
pdfminer:
propagate: 0
pefile:
propagate: 0
pgpdump:
propagate: 0
pygments:
propagate: 0
pylzma:
propagate: 0
rarfile:
propagate: 0
requests:
propagate: 0
rpmfile:
propagate: 0
ssdeep:
propagate: 0
tarfile:
propagate: 0
tnefparse:
propagate: 0
yara:
propagate: 0
zipfile:
propagate: 0
zlib:
propagate: 0
passwords:
- infected
- password
filestream:
enabled: False
config:
conn:
server: 'HOST:57314'
cert: ''
timeout:
dial: 5s
file: 1m
throughput:
concurrency: 8
chunk: 32768
delay: 0s
files:
patterns:
- '/nsm/strelka/unprocessed/*'
delete: false
gatekeeper: true
processed: '/nsm/strelka/processed'
response:
report: 5s
delta: 5s
staging: '/nsm/strelka/staging'
frontend:
enabled: False
config:
server: ":57314"
coordinator:
addr: 'HOST:6380'
db: 0
gatekeeper:
addr: 'HOST:6381'
db: 0
ttl: 1h
response:
log: "/var/log/strelka/strelka.log"
broker:
bootstrap: "PLACEHOLDER"
protocol: "PLACEHOLDER"
certlocation: "PLACEHOLDER"
keylocation: "PLACEHOLDER"
calocation: "PLACEHOLDER"
topic: "PLACEHOLDER"
s3redundancy: "PLACEHOLDER - This should be a boolean value"
s3:
accesskey: "PLACEHOLDER"
secretkey: "PLACEHOLDER"
bucketName: "PLACEHOLDER"
region: "PLACEHOLDER"
endpoint: "PLACEHOLDER"
manager:
enabled: False
config:
coordinator:
addr: 'HOST:6380'
db: 0
coordinator:
enabled: False
gatekeeper:
enabled: False
rules:
enabled: True
filecheck:
historypath: '/nsm/strelka/history/'
strelkapath: '/nsm/strelka/unprocessed/'
logfile: '/opt/so/log/strelka/filecheck.log'

View File

@@ -1,98 +0,0 @@
#!/usr/bin/env python3
# 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.
import os
import shutil
import time
import hashlib
import logging
import yaml
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
with open("/opt/so/conf/strelka/filecheck.yaml", "r") as ymlfile:
cfg = yaml.load(ymlfile, Loader=yaml.Loader)
extract_path = cfg["filecheck"]["extract_path"]
historypath = cfg["filecheck"]["historypath"]
strelkapath = cfg["filecheck"]["strelkapath"]
logfile = cfg["filecheck"]["logfile"]
recycle_secs = cfg["filecheck"].get("recycle_secs", 300)
logging.basicConfig(filename=logfile, filemode='w', format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S', level=logging.INFO)
def checkexisting():
logging.info("Checking for existing files");
for root, dirs, files in os.walk(extract_path):
for file in files:
try:
path = os.path.join(root, file)
filename = os.path.join(extract_path, path)
checksum(filename)
except Exception as err:
logging.error("Failed to process file: " + file)
def checksum(filename):
if os.path.isfile(filename) and "/tmp/" not in filename:
with open(filename, 'rb') as afile:
logging.info("Processing file: " + filename)
shawnuff = hashlib.sha1()
buf = afile.read(8192)
while len(buf) > 0:
shawnuff.update(buf)
buf = afile.read(8192)
hizash=shawnuff.hexdigest()
process(filename, hizash)
def process(filename, hizash):
if os.path.exists(historypath + hizash):
logging.info(filename + " Already exists.. removing")
os.remove(filename)
else:
# Write the file
logging.info(filename + " is new. Creating a record and sending to Strelka")
with open(os.path.join(historypath + hizash), 'w') as fp:
pass
head, tail = os.path.split(filename)
# Move the file
shutil.move(filename, strelkapath + tail)
class CreatedEventHandler(FileSystemEventHandler):
def on_created(self, event):
logging.info("File create detected: " + event.src_path)
checksum(event.src_path)
def on_moved(self, event):
logging.info("File move detected: " + event.src_path + " -> " + event.dest_path)
checksum(event.dest_path)
if __name__ == "__main__":
logging.info("Starting filecheck")
event_handler =CreatedEventHandler()
shutdown = False
while not shutdown:
checkexisting()
logging.info("Scheduling observer")
observer = Observer()
observer.schedule(event_handler, extract_path, recursive=True)
observer.start()
try:
time.sleep(recycle_secs)
except KeyboardInterrupt:
logging.warn("User requested shutdown")
shutdown = True
observer.stop()
observer.join()
if not shutdown:
logging.info("Recycling observer to pick up new subdirectories")
logging.info("Exiting filecheck")

View File

@@ -1,2 +0,0 @@
filecheck:
{{ FILECHECKCONFIG | yaml(false) | indent(width=2) }}

View File

@@ -1,165 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'strelka/map.jinja' import STRELKAMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% from 'strelka/map.jinja' import filecheck_runas %}
include:
- strelka.config
- strelka.filestream.sostatus
strelkaprocessed:
file.directory:
- name: /nsm/strelka/processed
- user: 939
- group: 939
- makedirs: True
strelkastaging:
file.directory:
- name: /nsm/strelka/staging
- user: 939
- group: 939
- makedirs: True
strelkaunprocessed:
file.directory:
- name: /nsm/strelka/unprocessed
- user: 939
- group: 939
- mode: 775
- makedirs: True
filestream_config:
file.managed:
- name: /opt/so/conf/strelka/filestream/filestream.yaml
- source: salt://strelka/filestream/files/filestream.yaml.jinja
- template: jinja
- user: 939
- group: 939
- makedirs: True
- defaults:
FILESTREAMCONFIG: {{ STRELKAMERGED.filestream.config }}
# Filecheck Section
remove_old_watchdog:
pkg.removed:
- name: python3-watchdog
install_watchdog:
pkg.installed:
- name: securityonion-python39-watchdog
filecheck_logdir:
file.directory:
- name: /opt/so/log/strelka
- user: 939
- group: 939
- mode: 775
- makedirs: True
filecheck_history:
file.directory:
- name: /nsm/strelka/history
- user: 939
- group: 939
- mode: 775
- makedirs: True
filecheck_conf:
file.managed:
- name: /opt/so/conf/strelka/filecheck.yaml
- source: salt://strelka/filecheck/filecheck.yaml.jinja
- template: jinja
- defaults:
FILECHECKCONFIG: {{ STRELKAMERGED.filecheck }}
filecheck_script:
file.managed:
- name: /opt/so/conf/strelka/filecheck
- source: salt://strelka/filecheck/filecheck
- user: 939
- group: 939
- mode: 755
filecheck.log:
file.managed:
- name: /opt/so/log/strelka/filecheck.log
- user: {{ filecheck_runas }}
- group: {{ filecheck_runas }}
- replace: False
filecheck_stdout.log:
file.managed:
- name: /opt/so/log/strelka/filecheck_stdout.log
- user: {{ filecheck_runas }}
- group: {{ filecheck_runas }}
- replace: False
{% if GLOBALS.md_engine == 'ZEEK' %}
remove_filecheck_run:
cron.absent:
- identifier: filecheck_run
- user: socore
filecheck_run_socore:
cron.present:
- name: 'ps -ef | grep filecheck | grep -v grep > /dev/null 2>&1 || python3 /opt/so/conf/strelka/filecheck >> /opt/so/log/strelka/filecheck_stdout.log 2>&1 &'
- identifier: filecheck_run_socore
- user: socore
remove_filecheck_run_suricata:
cron.absent:
- identifier: filecheck_run_suricata
- user: suricata
{% elif GLOBALS.md_engine == 'SURICATA'%}
remove_filecheck_run:
cron.absent:
- identifier: filecheck_run
- user: suricata
filecheck_run_suricata:
cron.present:
- name: 'ps -ef | grep filecheck | grep -v grep > /dev/null 2>&1 || python3 /opt/so/conf/strelka/filecheck >> /opt/so/log/strelka/filecheck_stdout.log 2>&1 &'
- identifier: filecheck_run_suricata
- user: suricata
remove_filecheck_run_socore:
cron.absent:
- identifier: filecheck_run_socore
- user: socore
{% endif %}
filecheck_restart:
cmd.run:
- name: pkill -f "python3 /opt/so/conf/strelka/filecheck"
- hide_output: True
- success_retcodes: [0,1]
- onchanges:
- file: filecheck_script
- file: filecheck_conf
- pkg: install_watchdog
filcheck_history_clean:
cron.present:
- name: '/usr/bin/find /nsm/strelka/history/ -type f -mtime +2 -exec rm {} + > /dev/null 2>&1'
- identifier: filecheck_history_clean
- minute: '33'
# End Filecheck Section
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,27 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.filestream.sostatus
so-strelka-filestream:
docker_container.absent:
- force: True
so-strelka-filestream_so-status.disabled:
file.comment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-filestream$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,64 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
include:
- strelka.filestream.config
- strelka.filestream.sostatus
strelka_filestream:
docker_container.running:
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-manager:{{ GLOBALS.so_version }}
- binds:
- /opt/so/conf/strelka/filestream/:/etc/strelka/:ro
- /nsm/strelka:/nsm/strelka
{% if DOCKERMERGED.containers['so-strelka-filestream'].custom_bind_mounts %}
{% for BIND in DOCKERMERGED.containers['so-strelka-filestream'].custom_bind_mounts %}
- {{ BIND }}
{% endfor %}
{% endif %}
- name: so-strelka-filestream
- networks:
- sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-strelka-filestream'].ip }}
- command: strelka-filestream
- extra_hosts:
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
{% if DOCKERMERGED.containers['so-strelka-filestream'].extra_hosts %}
{% for XTRAHOST in DOCKERMERGED.containers['so-strelka-filestream'].extra_hosts %}
- {{ XTRAHOST }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-filestream'].extra_env %}
- environment:
{% for XTRAENV in DOCKERMERGED.containers['so-strelka-filestream'].extra_env %}
- {{ XTRAENV }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-filestream'].ulimits %}
- ulimits:
{% for ULIMIT in DOCKERMERGED.containers['so-strelka-filestream'].ulimits %}
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
{% endfor %}
{% endif %}
- watch:
- file: filestream_config
delete_so-strelka-filestream_so-status.disabled:
file.uncomment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-filestream$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1 +0,0 @@
{{ FILESTREAMCONFIG | yaml(false) }}

View File

@@ -1,13 +0,0 @@
# 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 'strelka/map.jinja' import STRELKAMERGED %}
include:
{% if STRELKAMERGED.filestream.enabled %}
- strelka.filestream.enabled
{% else %}
- strelka.filestream.disabled
{% endif %}

View File

@@ -1,21 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
append_so-strelka-filestream_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-strelka-filestream
- unless: grep -q so-strelka-filestream /opt/so/conf/so-status/so-status.conf
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,36 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'strelka/map.jinja' import STRELKAMERGED %}
include:
- strelka.config
- strelka.frontend.sostatus
# Check to see if Strelka frontend port is available
strelkaportavailable:
cmd.run:
- name: netstat -utanp | grep ":57314" | grep -qvE 'docker|TIME_WAIT' && PROCESS=$(netstat -utanp | grep ":57314" | uniq) && echo "Another process ($PROCESS) appears to be using port 57314. Please terminate this process, or reboot to ensure a clean state so that Strelka can start properly." && exit 1 || exit 0
frontend_config:
file.managed:
- name: /opt/so/conf/strelka/frontend/frontend.yaml
- source: salt://strelka/frontend/files/frontend.yaml.jinja
- template: jinja
- user: 939
- group: 939
- makedirs: True
- defaults:
FRONTENDCONFIG: {{ STRELKAMERGED.frontend.config }}
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,27 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.frontend.sostatus
so-strelka-frontend:
docker_container.absent:
- force: True
so-strelka-frontend_so-status.disabled:
file.comment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-frontend$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,69 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
include:
- strelka.frontend.config
- strelka.frontend.sostatus
strelka_frontend:
docker_container.running:
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-manager:{{ GLOBALS.so_version }}
- binds:
- /opt/so/conf/strelka/frontend/:/etc/strelka/:ro
- /nsm/strelka/log/:/var/log/strelka/:rw
{% if DOCKERMERGED.containers['so-strelka-frontend'].custom_bind_mounts %}
{% for BIND in DOCKERMERGED.containers['so-strelka-frontend'].custom_bind_mounts %}
- {{ BIND }}
{% endfor %}
{% endif %}
- privileged: True
- name: so-strelka-frontend
- networks:
- sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-strelka-frontend'].ip }}
- command: strelka-frontend
- extra_hosts:
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
{% if DOCKERMERGED.containers['so-strelka-frontend'].extra_hosts %}
{% for XTRAHOST in DOCKERMERGED.containers['so-strelka-frontend'].extra_hosts %}
- {{ XTRAHOST }}
{% endfor %}
{% endif %}
- port_bindings:
{% for BINDING in DOCKERMERGED.containers['so-strelka-frontend'].port_bindings %}
- {{ BINDING }}
{% endfor %}
{% if DOCKERMERGED.containers['so-strelka-frontend'].extra_env %}
- environment:
{% for XTRAENV in DOCKERMERGED.containers['so-strelka-frontend'].extra_env %}
- {{ XTRAENV }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-frontend'].ulimits %}
- ulimits:
{% for ULIMIT in DOCKERMERGED.containers['so-strelka-frontend'].ulimits %}
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
{% endfor %}
{% endif %}
- watch:
- file: frontend_config
delete_so-strelka-frontend_so-status.disabled:
file.uncomment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-frontend$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1 +0,0 @@
{{ FRONTENDCONFIG | yaml(false) }}

View File

@@ -1,13 +0,0 @@
# 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 'strelka/map.jinja' import STRELKAMERGED %}
include:
{% if STRELKAMERGED.frontend.enabled %}
- strelka.frontend.enabled
{% else %}
- strelka.frontend.disabled
{% endif %}

View File

@@ -1,21 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
append_so-strelka-frontend_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-strelka-frontend
- unless: grep -q so-strelka-frontend /opt/so/conf/so-status/so-status.conf
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,19 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.config
- strelka.gatekeeper.sostatus
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,27 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.gatekeeper.sostatus
so-strelka-gatekeeper:
docker_container.absent:
- force: True
so-strelka-gatekeeper_so-status.disabled:
file.comment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-gatekeeper$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,65 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
include:
- strelka.gatekeeper.config
- strelka.gatekeeper.sostatus
strelka_gatekeeper:
docker_container.running:
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }}
- name: so-strelka-gatekeeper
- networks:
- sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-strelka-gatekeeper'].ip }}
- entrypoint: redis-server --save "" --appendonly no --maxmemory-policy allkeys-lru
- extra_hosts:
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
{% if DOCKERMERGED.containers['so-strelka-gatekeeper'].extra_hosts %}
{% for XTRAHOST in DOCKERMERGED.containers['so-strelka-gatekeeper'].extra_hosts %}
- {{ XTRAHOST }}
{% endfor %}
{% endif %}
- port_bindings:
{% for BINDING in DOCKERMERGED.containers['so-strelka-gatekeeper'].port_bindings %}
- {{ BINDING }}
{% endfor %}
- binds:
- /nsm/strelka/gk-redis-data:/data:rw
{% if DOCKERMERGED.containers['so-strelka-gatekeeper'].custom_bind_mounts %}
{% for BIND in DOCKERMERGED.containers['so-strelka-gatekeeper'].custom_bind_mounts %}
- {{ BIND }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-gatekeeper'].extra_env %}
- environment:
{% for XTRAENV in DOCKERMERGED.containers['so-strelka-gatekeeper'].extra_env %}
- {{ XTRAENV }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-gatekeeper'].ulimits %}
- ulimits:
{% for ULIMIT in DOCKERMERGED.containers['so-strelka-gatekeeper'].ulimits %}
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
{% endfor %}
{% endif %}
delete_so-strelka-gatekeeper_so-status.disabled:
file.uncomment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-gatekeeper$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,13 +0,0 @@
# 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 'strelka/map.jinja' import STRELKAMERGED %}
include:
{% if STRELKAMERGED.gatekeeper.enabled %}
- strelka.gatekeeper.enabled
{% else %}
- strelka.gatekeeper.disabled
{% endif %}

View File

@@ -1,21 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
append_so-strelka-gatekeeper_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-strelka-gatekeeper
- unless: grep -q so-strelka-gatekeeper /opt/so/conf/so-status/so-status.conf
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,43 +0,0 @@
# 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 'strelka/map.jinja' import STRELKAMERGED %}
include:
{% if STRELKAMERGED.coordinator.enabled %}
- strelka.coordinator.enabled
{% else %}
- strelka.coordinator.disabled
{% endif %}
{% if STRELKAMERGED.gatekeeper.enabled %}
- strelka.gatekeeper.enabled
{% else %}
- strelka.gatekeeper.disabled
{% endif %}
{% if STRELKAMERGED.frontend.enabled %}
- strelka.frontend.enabled
{% else %}
- strelka.frontend.disabled
{% endif %}
{% if STRELKAMERGED.backend.enabled %}
- strelka.backend.enabled
{% else %}
- strelka.backend.disabled
{% endif %}
{% if STRELKAMERGED.manager.enabled %}
- strelka.manager.enabled
{% else %}
- strelka.manager.disabled
{% endif %}
{% if STRELKAMERGED.filestream.enabled %}
- strelka.filestream.enabled
{% else %}
- strelka.filestream.disabled
{% endif %}

View File

@@ -1,37 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{# if strelka.manager or strelka in allowed_states #}
{% if sls in allowed_states or sls.split('.')[0] in allowed_states %}
# Strelka config
strelkarulesdir:
file.directory:
- name: /opt/so/conf/strelka/rules
- user: 939
- group: 939
- makedirs: True
strelkacompileyara:
file.managed:
- name: /opt/so/conf/strelka/compile_yara.py
- source: salt://strelka/compile_yara/compile_yara.py
- user: 939
- group: 939
strelkareposdir:
file.directory:
- name: /opt/so/conf/strelka/repos
- user: 939
- group: 939
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,31 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'strelka/map.jinja' import STRELKAMERGED %}
include:
- strelka.config
- strelka.manager.sostatus
manager_config:
file.managed:
- name: /opt/so/conf/strelka/manager/manager.yaml
- source: salt://strelka/manager/files/manager.yaml.jinja
- template: jinja
- user: 939
- group: 939
- makedirs: True
- defaults:
MANAGERCONFIG: {{ STRELKAMERGED.manager.config }}
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,27 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
include:
- strelka.manager.sostatus
so-strelka-manager:
docker_container.absent:
- force: True
so-strelka-manager_so-status.disabled:
file.comment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-manager$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,63 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %}
include:
- strelka.manager.config
- strelka.manager.sostatus
strelka_manager:
docker_container.running:
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-manager:{{ GLOBALS.so_version }}
- binds:
- /opt/so/conf/strelka/manager/:/etc/strelka/:ro
{% if DOCKERMERGED.containers['so-strelka-manager'].custom_bind_mounts %}
{% for BIND in DOCKERMERGED.containers['so-strelka-manager'].custom_bind_mounts %}
- {{ BIND }}
{% endfor %}
{% endif %}
- name: so-strelka-manager
- networks:
- sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-strelka-manager'].ip }}
- command: strelka-manager
- extra_hosts:
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
{% if DOCKERMERGED.containers['so-strelka-manager'].extra_hosts %}
{% for XTRAHOST in DOCKERMERGED.containers['so-strelka-manager'].extra_hosts %}
- {{ XTRAHOST }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-manager'].extra_env %}
- environment:
{% for XTRAENV in DOCKERMERGED.containers['so-strelka-manager'].extra_env %}
- {{ XTRAENV }}
{% endfor %}
{% endif %}
{% if DOCKERMERGED.containers['so-strelka-manager'].ulimits %}
- ulimits:
{% for ULIMIT in DOCKERMERGED.containers['so-strelka-manager'].ulimits %}
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
{% endfor %}
{% endif %}
- watch:
- file: manager_config
delete_so-strelka-manager_so-status.disabled:
file.uncomment:
- name: /opt/so/conf/so-status/so-status.conf
- regex: ^so-strelka-manager$
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1 +0,0 @@
{{ MANAGERCONFIG | yaml(false) }}

View File

@@ -1,13 +0,0 @@
# 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 'strelka/map.jinja' import STRELKAMERGED %}
include:
{% if STRELKAMERGED.manager.enabled %}
- strelka.manager.enabled
{% else %}
- strelka.manager.disabled
{% endif %}

View File

@@ -1,21 +0,0 @@
# 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 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
append_so-strelka-manager_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-strelka-manager
- unless: grep -q so-strelka-manager /opt/so/conf/so-status/so-status.conf
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

View File

@@ -1,35 +0,0 @@
{# 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 %}
{% import_yaml 'strelka/defaults.yaml' as STRELKADEFAULTS %}
{% set HOST = GLOBALS.hostname %}
{% set backend_coordinator_port = STRELKADEFAULTS.strelka.backend.config.backend.coordinator.addr.split(':')[1] %}
{% do STRELKADEFAULTS.strelka.backend.config.backend.coordinator.update({'addr': HOST ~ ':' ~ backend_coordinator_port}) %}
{% set filestream_conn_port = STRELKADEFAULTS.strelka.filestream.config.conn.server.split(':')[1] %}
{% do STRELKADEFAULTS.strelka.filestream.config.conn.update({'server': HOST ~ ':' ~ filestream_conn_port}) %}
{% set frontend_coordinator_port = STRELKADEFAULTS.strelka.frontend.config.coordinator.addr.split(':')[1] %}
{% do STRELKADEFAULTS.strelka.frontend.config.coordinator.update({'addr': HOST ~ ':' ~ frontend_coordinator_port}) %}
{% set frontend_gatekeeper_port = STRELKADEFAULTS.strelka.frontend.config.gatekeeper.addr.split(':')[1] %}
{% do STRELKADEFAULTS.strelka.frontend.config.gatekeeper.update({'addr': HOST ~ ':' ~ frontend_gatekeeper_port}) %}
{% set manager_coordinator_port = STRELKADEFAULTS.strelka.manager.config.coordinator.addr.split(':')[1] %}
{% do STRELKADEFAULTS.strelka.manager.config.coordinator.update({'addr': HOST ~ ':' ~ manager_coordinator_port}) %}
{% if GLOBALS.md_engine == "SURICATA" %}
{% set extract_path = '/nsm/suricata/extracted' %}
{% set filecheck_runas = 'suricata' %}
{% else %}
{% set extract_path = '/nsm/zeek/extracted/complete' %}
{% set filecheck_runas = 'socore' %}
{% endif %}
{% do STRELKADEFAULTS.strelka.filecheck.update({'extract_path': extract_path}) %}
{% set STRELKAMERGED = salt['pillar.get']('strelka', STRELKADEFAULTS.strelka, merge=True) %}

View File

@@ -1,627 +0,0 @@
strelka:
backend:
enabled:
description: Enables or disables the Strelka file analysis process.
forcedType: bool
helpLink: strelka
config:
backend:
logging_cfg:
description: Path to the Python logging configuration.
readonly: True
global: False
helpLink: strelka
advanced: True
limits:
max_files:
description: Number of files the backend will process before shutting down.
readonly: False
global: False
helpLink: strelka
time_to_live:
description: Amount of time (in seconds) that the backend will run before shutting down (0 to disable).
readonly: False
global: False
helpLink: strelka
max_depth:
description: Maximum depth that extracted files will be processed by the backend.
readonly: False
global: False
helpLink: strelka
distribution:
description: Amount of time (in seconds) that a single file can be distributed to all scanners.
readonly: False
global: False
helpLink: strelka
scanner:
description: Amount of time (in seconds) that a scanner can spend scanning a file (can be overridden per scanner).
readonly: False
global: False
helpLink: strelka
coordinator:
addr:
description: Network address of the coordinator.
readonly: False
global: False
helpLink: strelka
advanced: True
db:
description: Redis database of the coordinator.
readonly: False
global: False
helpLink: strelka
advanced: True
tasting:
mime_db:
description: Location of the MIME database used to taste files.
readonly: True
global: False
helpLink: strelka
advanced: True
yara_rules:
description: Location of the directory of YARA files that contains rules used to taste files.
readonly: True
global: False
helpLink: strelka
advanced: True
scanners:
'ScanBase64PE': &scannerOptions
description: Configuration options for this scanner.
readonly: False
global: False
helpLink: strelka
advanced: True
forcedType: "[]{}"
syntax: json
'ScanBatch': *scannerOptions
'ScanBmpEof': *scannerOptions
'ScanBzip2': *scannerOptions
'ScanDmg': *scannerOptions
'ScanDocx': *scannerOptions
'ScanDonut': *scannerOptions
'ScanElf': *scannerOptions
'ScanEmail': *scannerOptions
'ScanEncryptedDoc': *scannerOptions
'ScanEncryptedZip': *scannerOptions
'ScanEntropy': *scannerOptions
'ScanExiftool': *scannerOptions
'ScanFooter': *scannerOptions
'ScanGif': *scannerOptions
'ScanGzip': *scannerOptions
'ScanHash': *scannerOptions
'ScanHeader': *scannerOptions
'ScanHtml': *scannerOptions
'ScanIni': *scannerOptions
'ScanIqy': *scannerOptions
'ScanIso': *scannerOptions
'ScanJarManifest': *scannerOptions
'ScanJavascript': *scannerOptions
'ScanJpeg': *scannerOptions
'ScanJson': *scannerOptions
'ScanLibarchive': *scannerOptions
'ScanLNK': *scannerOptions
'ScanLsb': *scannerOptions
'ScanLzma': *scannerOptions
'ScanMacho': *scannerOptions
'ScanManifest': *scannerOptions
'ScanMsi': *scannerOptions
'ScanOcr': *scannerOptions
'ScanOle': *scannerOptions
'ScanOnenote': *scannerOptions
'ScanPdf': *scannerOptions
'ScanPe': *scannerOptions
'ScanPgp': *scannerOptions
'ScanPhp': *scannerOptions
'ScanPkcs7': *scannerOptions
'ScanPlist': *scannerOptions
'ScanPngEof': *scannerOptions
'ScanQr': *scannerOptions
'ScanRar': *scannerOptions
'ScanRpm': *scannerOptions
'ScanRtf': *scannerOptions
'ScanRuby': *scannerOptions
'ScanSevenZip': *scannerOptions
'ScanSwf': *scannerOptions
'ScanTar': *scannerOptions
'ScanTnef': *scannerOptions
'ScanUpx': *scannerOptions
'ScanUrl': *scannerOptions
'ScanVb': *scannerOptions
'ScanVba': *scannerOptions
'ScanVhd': *scannerOptions
'ScanVsto': *scannerOptions
'ScanX509': *scannerOptions
'ScanXml': *scannerOptions
'ScanYara': *scannerOptions
'ScanZip': *scannerOptions
'ScanZlib': *scannerOptions
logging:
version:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
formatters:
simple:
format:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
datefmt:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
handlers:
console:
class:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
formatter:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
stream:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
root:
level:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
handlers:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
loggers:
OpenSSL:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
bs4:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
bz2:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
chardet:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
docx:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
elftools:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
email:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
entropy:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
esprima:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
gzip:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
hashlib:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
json:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
libarchive:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
lxml:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
lzma:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
macholibre:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
olefile:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
oletools:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
pdfminer:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
pefile:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
pgpdump:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
pygments:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
pylzma:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
rarfile:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
requests:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
rpmfile:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
ssdeep:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
tarfile:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
tnefparse:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
yara:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
zipfile:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
zlib:
propagate:
description: This is an advanced option for Strelka logging.
readonly: False
global: False
helpLink: strelka
advanced: True
passwords:
description: Passwords that will be stored in the password_file used in scanner options.
readonly: False
global: False
helpLink: strelka
multiline: True
filestream:
enabled:
description: You can enable or disable Strelka filestream.
forcedType: bool
helpLink: strelka
config:
conn:
server:
description: Network address of the frontend server.
readonly: False
global: False
helpLink: strelka
advanced: True
cert:
description: Local path to the frontend SSL server certificate.
readonly: False
global: False
helpLink: strelka
advanced: True
timeout:
dial:
description: Amount of time to wait for the client to dial the server.
readonly: False
global: False
helpLink: strelka
advanced: True
file:
description: Amount of time to wait for an individual file to complete a scan.
readonly: False
global: False
helpLink: strelka
advanced: True
throughput:
concurrency:
description: Number of concurrent requests to make.
readonly: False
global: False
helpLink: strelka
advanced: True
chunk:
description: Size of file chunks that will be sent to the frontend server.
readonly: False
global: False
helpLink: strelka
advanced: True
delay:
description: Artificial sleep between the submission of each chunk.
readonly: False
global: False
helpLink: strelka
advanced: True
files:
patterns:
description: List of glob patterns that determine which files will be sent for scanning.
readonly: False
global: False
helpLink: strelka
advanced: True
delete:
description: Boolean that determines if files should be deleted after being sent for scanning.
forcedType: bool
readonly: False
global: False
helpLink: strelka
advanced: True
gatekeeper:
description: Boolean that determines if events should be pulled from the temporary event cache.
forcedType: bool
readonly: False
global: False
helpLink: strelka
advanced: True
processed:
description: Directory where files will be moved after being submitted for scanning.
readonly: False
global: False
helpLink: strelka
advanced: True
response:
report:
description: Frequency at which the frontend reports the number of files processed.
readonly: False
global: False
helpLink: strelka
advanced: True
delta:
description: Time value that determines how much time must pass since a file was last modified before it is sent for scanning.
readonly: False
global: False
helpLink: strelka
advanced: True
staging:
description: Directory where files are staged before being sent to the cluster.
readonly: False
global: False
helpLink: strelka
advanced: True
frontend:
enabled:
description: You can enable or disable Strelka frontend.
forcedType: bool
helpLink: strelka
config:
server:
description: Network address of the frontend server.
readonly: False
global: False
helpLink: strelka
advanced: True
coordinator:
addr:
description: Network address of the coordinator.
readonly: False
global: False
helpLink: strelka
advanced: True
db:
description: Redis database of the coordinator.
readonly: False
global: False
helpLink: strelka
advanced: True
gatekeeper:
addr:
description: Network address of the gatekeeper.
readonly: False
global: False
helpLink: strelka
advanced: True
db:
description: Redis database of the gatekeeper.
readonly: False
global: False
helpLink: strelka
advanced: True
ttl:
description: Time-to-live for events added to the gatekeeper.
readonly: False
global: False
helpLink: strelka
advanced: True
response:
log:
description: Location where worker scan results are logged to.
readonly: False
global: False
helpLink: strelka
advanced: True
manager:
enabled:
description: You can enable or disable Strelka manager.
forcedType: bool
helpLink: strelka
config:
coordinator:
addr:
description: Network address of the coordinator.
readonly: False
global: False
helpLink: strelka
advanced: True
db:
description: Redis database of the coordinator.
readonly: False
global: False
helpLink: strelka
advanced: True
coordinator:
enabled:
description: You can enable or disable Strelka coordinator.
forcedType: bool
helpLink: strelka
gatekeeper:
enabled:
description: You can enable or disable Strelka gatekeeper.
forcedType: bool
helpLink: strelka
rules:
enabled:
description: Boolean that determines if yara rules sync from the Salt manager to the backend nodes.
forcedType: bool
readonly: False
global: False
helpLink: strelka
advanced: False
filecheck:
historypath:
description: The path for previously scanned files.
readonly: True
global: False
helpLink: strelka
advanced: True
strelkapath:
description: The path for unprocessed files.
readonly: True
global: False
helpLink: strelka
advanced: True
logfile:
description: The path for the filecheck log.
readonly: False
global: False
helpLink: strelka
advanced: True

View File

@@ -1,18 +0,0 @@
#!/bin/bash
# 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.
. /usr/sbin/so-common
/usr/sbin/so-stop strelka-filestream $1
/usr/sbin/so-stop strelka-manager $1
/usr/sbin/so-stop strelka-frontend $1
/usr/sbin/so-stop strelka-backend $1
/usr/sbin/so-stop strelka-gatekeeper $1
/usr/sbin/so-stop strelka-coordinator $1
/usr/sbin/so-start strelka $1

Some files were not shown because too many files have changed in this diff Show More