Compare commits

..

93 Commits

Author SHA1 Message Date
Jorge Reyes b81257bf45 Merge pull request #15973 from Security-Onion-Solutions/reyesj2/dlm-support
Data stream lifecycle management support
2026-06-15 14:47:51 -05:00
reyesj2 1a423a2434 update message 2026-06-15 14:17:34 -05:00
reyesj2 95cae4c734 remove so-elasticsearch-indices-delete cron when using DLM 2026-06-15 13:32:45 -05:00
reyesj2 596471e140 using new annotation config 2026-06-15 13:31:53 -05:00
reyesj2 d10f21399c remove comments 2026-06-15 13:31:23 -05:00
Josh Brower ea73216f4e Merge pull request #15971 from Security-Onion-Solutions/delta
userid vs names
2026-06-15 15:28:03 +02:00
Josh Brower 9031c1fd22 userid vs names 2026-06-12 11:18:59 -04:00
reyesj2 c505160480 set default DLM retention 90d 2026-06-11 15:13:28 -05:00
reyesj2 d9f6cde4e1 remove global setting from data_retention annotation 2026-06-11 15:11:29 -05:00
Jorge Reyes f03f0155f4 Merge pull request #15966 from Security-Onion-Solutions/reyesj2-patch-8
update so-elastic-fleet-package-upgrade script
2026-06-11 14:36:03 -05:00
Jason Ertel 0cc94980af Merge pull request #15967 from Security-Onion-Solutions/jertel/wip
Jertel/wip
2026-06-11 08:22:14 -04:00
Jason Ertel b8bf684077 ver 2026-06-11 08:18:38 -04:00
Jason Ertel f083db67e4 disable telemetry for automated tests 2026-06-11 08:17:39 -04:00
reyesj2 4741cc92bd fleet manager start kibana if it isn't already running and wait for healthly status 2026-06-10 17:52:08 -05:00
reyesj2 46655860e9 http 2026-06-10 17:27:23 -05:00
reyesj2 289ddda5e8 kibana health check for fleet scripts 2026-06-10 17:06:22 -05:00
reyesj2 f905afbc6f logging 2026-06-10 15:01:22 -05:00
reyesj2 bd5e77afc5 increase delay in so-elastic-fleet-package-upgrade attempts 2026-06-10 14:59:29 -05:00
reyesj2 944e773759 save exit until all packages have been attempted 2026-06-10 14:58:49 -05:00
reyesj2 cf456dc58c reuse existing index templates 2026-06-09 23:21:43 -05:00
reyesj2 9aa9ea3255 Iniitial DLM support 2026-06-09 23:19:26 -05:00
Josh Patterson 3ba96da3b7 Merge pull request #15965 from Security-Onion-Solutions/nostartupstates
remove startup states from salt config
2026-06-09 16:26:47 -04:00
Jorge Reyes f0712bd780 Merge pull request #15964 from Security-Onion-Solutions/reyesj2-patch-8
use pipe exit status for update_docker_containers
2026-06-09 13:49:24 -05:00
Josh Patterson 448668a72e Merge remote-tracking branch 'origin/3/dev' into nostartupstates 2026-06-09 14:02:00 -04:00
Josh Patterson f088a27159 so-boot-mine-update: warm master pillar cache before highstate
A complete mine is not enough: elasticsearch:nodes, redis:nodes,
logstash:nodes (tgt_type=pillar) and hypervisor:nodes (tgt_type=compound)
resolve their target against the master's per-minion data cache
(grains+pillar in data.p), which is populated only when a minion's pillar
is recompiled -- separately from the mine. After a reboot a node can be in
the mine (so node_data/glob sees it) yet absent from that cache, so it
fails the elasticsearch:enabled:true pillar match and is dropped from
elasticsearch:nodes -> so-elasticsearch ExtraHosts -> container recreate.

After the mine-completeness wait, run salt '*' saltutil.refresh_pillar
wait=True to synchronously cache every up node's pillar (the same lever
deploy_newnode.sls uses), then verify with salt-run cache.pillar and retry
stragglers, bounded by MINE_UPDATE_MAX_WAIT. Also log elasticsearch:nodes
alongside node_data for inspection.
2026-06-09 13:52:19 -04:00
reyesj2 9f5a9616a5 use pipe exit status for update_docker_containers 2026-06-09 12:51:58 -05:00
Josh Patterson 27c7702325 so-boot-mine-update: wait for a complete mine before highstate
Mine-backed pillars (node_data, elasticsearch:nodes, redis:nodes,
logstash:nodes, hypervisor:nodes) include a node only if it returned an
IP from the mine, and the configs they build are rebuilt fresh every
highstate. After a manager reboot with a flushed mine, the first boot
highstate could run before an up node re-reported network.ip_addrs,
dropping it from e.g. so-elasticsearch ExtraHosts and forcing a
container recreate.

After the initial broad mine.update, poll until every currently-up
minion actually has network.ip_addrs in the mine, re-pushing mine.update
to stragglers, before releasing the boot highstate. Shares the existing
MINE_UPDATE_MAX_WAIT backstop so a slow/down node never blocks boot, and
still logs the rendered node_data for inspection.
2026-06-09 10:10:32 -04:00
Josh Patterson 8c306eb37d so-boot-mine-update: log the rendered node_data content
Dump the actual rendered node_data pillar (pretty-printed JSON) to the
journal instead of just a rendered/empty verdict, so the boot-time render
attempt is fully inspectable. Empty renders print false/null and still
emit the WARNING.
2026-06-09 09:49:19 -04:00
Josh Patterson e536ffa363 so-boot-mine-update: render node_data after mine.update before highstate
After the boot-time mine.update, have the manager actually render the
node_data pillar and log whether it came back populated. node_data: False
makes salt/top.sls apply the bootstrap recovery branch instead of the
manager's real config, so surfacing this in the journal makes the
condition visible before so-boot-highstate runs. Best-effort and
non-blocking: always exits 0 so highstate proceeds regardless.
2026-06-09 09:35:24 -04:00
Jason Ertel eb82f9ea9d kilo version 2026-06-08 16:53:35 -04:00
Jorge Reyes d7aa7ab228 Merge pull request #15961 from Security-Onion-Solutions/reyesj2/fleet-autoconfigure
respect elasticfleet enable_auto_configuration setting for so-elastic…
2026-06-08 15:09:58 -05:00
Jorge Reyes fe0b68d24c Merge pull request #15958 from Security-Onion-Solutions/reyesj2-patch-template
fix elasticsearch template generation issue
2026-06-08 15:07:49 -05:00
reyesj2 6ad345730b respect elasticfleet enable_auto_configuration setting for so-elastic-fleet-urls-update 2026-06-08 15:02:57 -05:00
Josh Patterson 9580976ba2 Add manager boot-time grid mine.update oneshot before highstate
so-boot-mine-update.service is a manager-only Type=oneshot unit that runs
once per boot after salt-master/salt-minion start and before
so-boot-highstate.service. It pushes mine.update to all reachable minions
so mine-backed pillars (node IPs, ES/Redis/Logstash discovery) are fresh
before the boot highstate renders them.

The helper waits for the responsive minion set to settle (plateau) rather
than for every accepted key to report up, so an intentionally powered-off
minion doesn't block the update; MAX_WAIT remains as a backstop.
2026-06-08 11:05:13 -04:00
reyesj2 ac907ba45f fix elasticsearch template generation issue 2026-06-05 16:42:08 -05:00
Josh Patterson f957954abf Merge pull request #15956 from Security-Onion-Solutions/nostartupstates
higstate on host start, not salt-minion start
2026-06-04 16:51:10 -04:00
Josh Patterson cb3631da81 Move setup-complete marker from /opt/so/conf to /opt/so/state
The setup-complete marker is a runtime-state file, not config, so move it
to /opt/so/state/setup-complete. Updates both writers (mark_setup_complete
in setup/so-functions and the upgrade-path state in minion/init.sls) and the
three readers (so-boot-highstate.service ConditionPathExists, boot_highstate.sls
enable gate, and the so-user_sync cron gate).
2026-06-04 15:07:27 -04:00
Josh Patterson f5d63f585e Merge remote-tracking branch 'origin/3/dev' into nostartupstates 2026-06-04 09:19:01 -04:00
Josh Patterson 13f8be40b5 so-boot-highstate: wait for docker before running highstate
Add docker.service to After= and Wants= so the boot-time highstate
starts after docker is up. Uses Wants (soft) so highstate still runs
if docker fails to start.
2026-06-04 08:46:35 -04:00
Jason Ertel 9ee90a5bc0 Merge pull request #15955 from Security-Onion-Solutions/jertel/wip
config updates
2026-06-03 17:26:51 -04:00
Jason Ertel ca85c5d900 fix version 2026-06-03 17:26:08 -04:00
Josh Patterson 2d653b6f1b does not need to be jinja template 2026-06-03 15:46:58 -04:00
Josh Patterson 34fee25b0c Merge remote-tracking branch 'origin/3/dev' into nostartupstates 2026-06-03 15:44:41 -04:00
Jason Ertel 1d3d98f759 kilo 2026-06-03 12:24:41 -04:00
Jason Ertel a767c79641 restore soup db init 2026-06-03 10:39:37 -04:00
Jason Ertel 61e72c89e4 postgres updates 2026-06-03 09:49:53 -04:00
Jason Ertel d9fb7313f9 merge 2026-06-03 09:30:05 -04:00
Jason Ertel 7ca2313255 move to securityonion db 2026-06-03 09:05:23 -04:00
Jorge Reyes 534f0e639d Merge pull request #15954 from Security-Onion-Solutions/reyesj2-patch-4
run elastic agent regen installer script in post_to_3.2.0
2026-06-02 15:25:55 -05:00
reyesj2 559465b407 run elastic agent gen installers script in post_to_3.2.0 2026-06-02 15:18:00 -05:00
reyesj2 f9c2579261 remove logstash pipeline rename from hotfix moving to up_to_3.2.0 2026-06-02 15:18:00 -05:00
Jorge Reyes 33699a914b Merge pull request #15952 from Security-Onion-Solutions/reyesj2-patch-3
use so-config-backup script in soup
2026-06-02 15:02:27 -05:00
Jorge Reyes 0c2d8f8973 Merge pull request #15951 from Security-Onion-Solutions/reyesj2-patch-2
check if there is a version or hotfix to upgrade to before verifiying elasticsearch compatibility
2026-06-02 15:02:10 -05:00
reyesj2 f2996fb888 use so-config-backup script in soup 2026-06-01 11:52:35 -05:00
reyesj2 3c533cccbc and after free space check 2026-06-01 11:28:59 -05:00
reyesj2 79da9f9f2c check if there is a version or hotfix to upgrade to before verifiying elasticsearch compatibility 2026-06-01 11:26:52 -05:00
Mike Reeves 99a027589b Merge pull request #15949 from Security-Onion-Solutions/jertel/wip
fix version
2026-05-30 09:50:14 -04:00
Jason Ertel 68a82a425b fix version 2026-05-30 08:12:50 -04:00
Jason Ertel d86a3c5cc9 Merge pull request #15947 from Security-Onion-Solutions/jertel/wip
refactored soc config
2026-05-29 14:07:06 -04:00
Jason Ertel 86edc5aaba version 2026-05-28 22:57:59 -04:00
Josh Patterson 9a70a06b3b Merge remote-tracking branch 'origin/3/dev' into jertel/wip 2026-05-28 13:55:12 -04:00
Mike Reeves 526d739b3b Merge pull request #15940 from Security-Onion-Solutions/TOoSmOotH-patch-4
Remove outdated HOTFIX version number
2026-05-28 10:25:28 -04:00
Mike Reeves 68d783e760 Remove outdated HOTFIX version number 2026-05-28 10:24:47 -04:00
Mike Reeves 1e9b6b0975 Merge pull request #15939 from Security-Onion-Solutions/3/main
main to dev for hotfix
2026-05-28 10:24:21 -04:00
Mike Reeves 2131e7d450 Merge pull request #15937 from Security-Onion-Solutions/hotfix/3.1.0
Hotfix/3.1.0
2026-05-28 10:20:53 -04:00
Mike Reeves 2a2d853ac4 Merge pull request #15936 from Security-Onion-Solutions/hotfix310
3.1.0 hotfix
2026-05-28 09:53:00 -04:00
Mike Reeves 5abd6de4b5 3.1.0 hotfix 2026-05-28 09:34:17 -04:00
Josh Patterson bb8ae91d91 fix so-soc postgres bootstrap 2026-05-27 16:39:52 -04:00
Josh Patterson 93ffce98d7 add onionconfig and postgres modules to soc config 2026-05-27 15:07:25 -04:00
Jorge Reyes 5599cce22c Merge pull request #15934 from Security-Onion-Solutions/reyesj2-patch-1
keep logstash lumberjack pipeline name update unified
2026-05-27 13:37:41 -05:00
reyesj2 b2a82fec29 fix_logstash_0013_lumberjack_pipeline_name
Before removing from apply_hotfix function first verify that older installs < 3.1.0 are still upgradable when referencing 'so/0013_input_lumberjack_fleet.conf' via pillar. Failure to do so will prevent logstash from starting
2026-05-27 13:24:23 -05:00
reyesj2 613eca52fc update hotfix date 2026-05-27 13:24:10 -05:00
Josh Patterson 79987f3659 bootstrap so-soc db in postgres during soup 2026-05-27 13:55:30 -04:00
reyesj2 bf609a112e LF 2026-05-27 12:21:44 -05:00
reyesj2 0b4a4de609 always run logstash pipeline rename 2026-05-27 12:21:22 -05:00
Jorge Reyes ad376d2a43 Merge pull request #15930 from Security-Onion-Solutions/reyesj2-patch-1
check for stale logstash pipeline name in local pillar
2026-05-27 10:16:39 -05:00
reyesj2 0834998cca usuable for next soup 2026-05-27 09:52:29 -05:00
reyesj2 473f93f0ee check for stale logstash pipeline name in pillars 2026-05-27 09:33:15 -05:00
Josh Patterson 16055c4d88 Merge remote-tracking branch 'origin/3/dev' into jertel/wip 2026-05-27 09:18:33 -04:00
Jorge Reyes 7cc2e045fb Merge pull request #15925 from Security-Onion-Solutions/reyesj2/soup-heavynode
use multiple or combined input
2026-05-26 08:34:33 -05:00
Mike Reeves 6955ee73bf Merge pull request #15924 from Security-Onion-Solutions/TOoSmOotH-patch-3
Add version number to HOTFIX file
2026-05-26 09:28:41 -04:00
Mike Reeves c0272ddb81 Add version number to HOTFIX file 2026-05-26 09:24:10 -04:00
reyesj2 d72219c586 use multiple or combined input 2026-05-22 20:04:21 -05:00
Mike Reeves ffd34d4e0e Merge pull request #15919 from Security-Onion-Solutions/TOoSmOotH-patch-2
Add 3.2.0 option to discussion template
2026-05-21 15:58:28 -04:00
Mike Reeves aa78978740 Add 3.2.0 option to discussion template 2026-05-21 15:57:57 -04:00
Mike Reeves 75d4f5e496 Merge pull request #15918 from Security-Onion-Solutions/TOoSmOotH-patch-1
Bump version from 3.1.0 to 3.2.0
2026-05-21 15:49:08 -04:00
Mike Reeves 89a28d2cfe Bump version from 3.1.0 to 3.2.0 2026-05-21 15:45:58 -04:00
Jason Ertel e45ad45d73 Merge branch '3/dev' into jertel/wip 2026-05-14 18:33:40 -04:00
Josh Patterson fabecb8288 remove highstate from startup_states. highstate on system start 2026-05-14 13:57:40 -04:00
Jason Ertel 907f699721 state rename 2026-05-14 11:03:08 -04:00
Jason Ertel e7a7047f71 Merge branch '3/dev' into jertel/wip 2026-05-14 11:01:36 -04:00
Jason Ertel 936295f1c4 Merge branch '3/dev' into jertel/wip 2026-05-13 17:28:25 -04:00
Jason Ertel 61ca60a94c prep for soc db config 2026-05-13 17:28:07 -04:00
42 changed files with 1373 additions and 197 deletions
+1
View File
@@ -11,6 +11,7 @@ body:
- -
- 3.0.0 - 3.0.0
- 3.1.0 - 3.1.0
- 3.2.0
- Other (please provide detail below) - Other (please provide detail below)
validations: validations:
required: true required: true
+11 -11
View File
@@ -1,17 +1,17 @@
### 3.1.0-20260521 ISO image released on 2026/05/21 ### 3.1.0-20260528 ISO image released on 2026/05/28
### Download and Verify ### Download and Verify
3.1.0-20260521 ISO image: 3.1.0-20260528 ISO image:
https://download.securityonion.net/file/securityonion/securityonion-3.1.0-20260521.iso https://download.securityonion.net/file/securityonion/securityonion-3.1.0-20260528.iso
MD5: A853BC118639ABCE1795D6E313BFFBDE MD5: 9D6FF58DEEE24089D722C73169765B3E
SHA1: FCA615AD6E31710B33AE5870FEF447861FDB3B8F SHA1: 2B8B816B6CEC3B7F96B3C5E040EBF502DD2C412F
SHA256: CE2A5947274D9ED2C5068A1FD46B64C4FEF70445EA9B61A98DD3621781329F2C SHA256: 62FAB57E247C843D6A04F0796D8162C732B65D82FC3E4A59D087135B9FD32912
Signature for ISO image: Signature for ISO image:
https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.1.0-20260521.iso.sig https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.1.0-20260528.iso.sig
Signing key: Signing key:
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/main/KEYS https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/main/KEYS
@@ -25,22 +25,22 @@ wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/
Download the signature file for the ISO: Download the signature file for the ISO:
``` ```
wget https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.1.0-20260521.iso.sig wget https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.1.0-20260528.iso.sig
``` ```
Download the ISO image: Download the ISO image:
``` ```
wget https://download.securityonion.net/file/securityonion/securityonion-3.1.0-20260521.iso wget https://download.securityonion.net/file/securityonion/securityonion-3.1.0-20260528.iso
``` ```
Verify the downloaded ISO image using the signature file: Verify the downloaded ISO image using the signature file:
``` ```
gpg --verify securityonion-3.1.0-20260521.iso.sig securityonion-3.1.0-20260521.iso gpg --verify securityonion-3.1.0-20260528.iso.sig securityonion-3.1.0-20260528.iso
``` ```
The output should show "Good signature" and the Primary key fingerprint should match what's shown below: The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
``` ```
gpg: Signature made Thu 21 May 2026 11:10:01 AM EDT using RSA key ID FE507013 gpg: Signature made Wed 27 May 2026 03:03:59 PM EDT using RSA key ID FE507013
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>" gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
gpg: WARNING: This key is not certified with a trusted signature! gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner. gpg: There is no indication that the signature belongs to the owner.
+1
View File
@@ -0,0 +1 @@
+1 -1
View File
@@ -1 +1 @@
3.1.0 3.2.0
@@ -25,9 +25,11 @@ if [ ! -f $BACKUPFILE ]; then
# Create empty backup file # Create empty backup file
tar -cf $BACKUPFILE -T /dev/null tar -cf $BACKUPFILE -T /dev/null
# Loop through all paths defined in global.sls, and append them to backup file # Loop through all paths defined in global.sls, and append them to backup file if they exist
{%- for LOCATION in BACKUPLOCATIONS %} {%- for LOCATION in BACKUPLOCATIONS %}
if [[ -d {{ LOCATION }} || -f {{ LOCATION }} ]]; then
tar -rf $BACKUPFILE "${EXCLUSIONS[@]}" {{ LOCATION }} tar -rf $BACKUPFILE "${EXCLUSIONS[@]}" {{ LOCATION }}
fi
{%- endfor %} {%- endfor %}
fi fi
+5
View File
@@ -142,6 +142,11 @@ check_elastic_license() {
fi fi
} }
check_elasticsearch_responsive() {
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."
}
check_salt_master_status() { check_salt_master_status() {
local count=0 local count=0
local attempts="${1:- 10}" local attempts="${1:- 10}"
@@ -9,7 +9,6 @@
{% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %} {% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %}
{% set ADDON_CONTENT_INTEGRATION_DEFAULTS = {} %} {% set ADDON_CONTENT_INTEGRATION_DEFAULTS = {} %}
{% set DEBUG_STUFF = {} %}
{% for pkg in ADDON_CONTENT_PACKAGE_COMPONENTS %} {% for pkg in ADDON_CONTENT_PACKAGE_COMPONENTS %}
{% if pkg.name in CORE_ESFLEET_PACKAGES %} {% if pkg.name in CORE_ESFLEET_PACKAGES %}
+11
View File
@@ -101,6 +101,17 @@ so-elastic-fleet:
- file: trusttheca - file: trusttheca
- x509: etc_elasticfleet_key - x509: etc_elasticfleet_key
- x509: etc_elasticfleet_crt - x509: etc_elasticfleet_crt
wait_for_so-elastic-fleet:
http.wait_for_successful_query:
- name: "https://localhost:8220/api/status"
- ssl: True
- verify_ssl: False
- status: 200
- wait_for: 300
- request_interval: 15
- require:
- docker_container: so-elastic-fleet
{% endif %} {% endif %}
delete_so-elastic-fleet_so-status.disabled: delete_so-elastic-fleet_so-status.disabled:
@@ -9,7 +9,6 @@
{% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %} {% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %}
{% set ADDON_INPUT_INTEGRATION_DEFAULTS = {} %} {% set ADDON_INPUT_INTEGRATION_DEFAULTS = {} %}
{% set DEBUG_STUFF = {} %}
{% for pkg in ADDON_INPUT_PACKAGE_COMPONENTS %} {% for pkg in ADDON_INPUT_PACKAGE_COMPONENTS %}
{% if pkg.name in CORE_ESFLEET_PACKAGES %} {% if pkg.name in CORE_ESFLEET_PACKAGES %}
@@ -116,7 +115,6 @@
{% do ADDON_INPUT_INTEGRATION_DEFAULTS.update({integration_key: integration_defaults}) %} {% do ADDON_INPUT_INTEGRATION_DEFAULTS.update({integration_key: integration_defaults}) %}
{% do DEBUG_STUFF.update({integration_key: "Generating defaults for "+ pkg.name })%}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endif %} {% endif %}
+25 -2
View File
@@ -9,15 +9,19 @@
include: include:
- elasticfleet.config - elasticfleet.config
- kibana.enabled
# If enabled, automatically update Fleet Logstash Outputs # If enabled, automatically update Fleet Logstash Outputs
{% if ELASTICFLEETMERGED.config.server.enable_auto_configuration and grains.role not in ['so-import', 'so-eval'] %} {% if ELASTICFLEETMERGED.config.server.enable_auto_configuration %}
{% if grains.role not in ['so-import', 'so-eval']%}
so-elastic-fleet-auto-configure-logstash-outputs: so-elastic-fleet-auto-configure-logstash-outputs:
cmd.run: cmd.run:
- name: /usr/sbin/so-elastic-fleet-outputs-update - name: /usr/sbin/so-elastic-fleet-outputs-update
- retry: - retry:
attempts: 4 attempts: 4
interval: 30 interval: 30
- require:
- http: wait_for_so-kibana
{% endif %} {% endif %}
# If enabled, automatically update Fleet Server URLs & ES Connection # If enabled, automatically update Fleet Server URLs & ES Connection
@@ -27,6 +31,9 @@ so-elastic-fleet-auto-configure-server-urls:
- retry: - retry:
attempts: 4 attempts: 4
interval: 30 interval: 30
- require:
- http: wait_for_so-kibana
{% endif %}
# Automatically update Fleet Server Elasticsearch URLs & Agent Artifact URLs # Automatically update Fleet Server Elasticsearch URLs & Agent Artifact URLs
so-elastic-fleet-auto-configure-elasticsearch-urls: so-elastic-fleet-auto-configure-elasticsearch-urls:
@@ -35,6 +42,8 @@ so-elastic-fleet-auto-configure-elasticsearch-urls:
- retry: - retry:
attempts: 4 attempts: 4
interval: 30 interval: 30
- require:
- http: wait_for_so-kibana
so-elastic-fleet-auto-configure-artifact-urls: so-elastic-fleet-auto-configure-artifact-urls:
cmd.run: cmd.run:
@@ -42,6 +51,8 @@ so-elastic-fleet-auto-configure-artifact-urls:
- retry: - retry:
attempts: 4 attempts: 4
interval: 30 interval: 30
- require:
- http: wait_for_so-kibana
so-elastic-fleet-package-statefile: so-elastic-fleet-package-statefile:
file.managed: file.managed:
@@ -53,7 +64,9 @@ so-elastic-fleet-package-upgrade:
- name: /usr/sbin/so-elastic-fleet-package-upgrade - name: /usr/sbin/so-elastic-fleet-package-upgrade
- retry: - retry:
attempts: 3 attempts: 3
interval: 10 interval: 30
- require:
- http: wait_for_so-kibana
- onchanges: - onchanges:
- file: /opt/so/state/elastic_fleet_packages.txt - file: /opt/so/state/elastic_fleet_packages.txt
@@ -63,6 +76,8 @@ so-elastic-fleet-integrations:
- retry: - retry:
attempts: 3 attempts: 3
interval: 10 interval: 10
- require:
- http: wait_for_so-kibana
so-elastic-agent-grid-upgrade: so-elastic-agent-grid-upgrade:
cmd.run: cmd.run:
@@ -70,6 +85,8 @@ so-elastic-agent-grid-upgrade:
- retry: - retry:
attempts: 12 attempts: 12
interval: 5 interval: 5
- require:
- http: wait_for_so-kibana
so-elastic-fleet-integration-upgrade: so-elastic-fleet-integration-upgrade:
cmd.run: cmd.run:
@@ -77,16 +94,22 @@ so-elastic-fleet-integration-upgrade:
- retry: - retry:
attempts: 3 attempts: 3
interval: 10 interval: 10
- require:
- http: wait_for_so-kibana
{# Optional integrations script doesn't need the retries like so-elastic-fleet-integration-upgrade which loads the default integrations #} {# Optional integrations script doesn't need the retries like so-elastic-fleet-integration-upgrade which loads the default integrations #}
so-elastic-fleet-addon-integrations: so-elastic-fleet-addon-integrations:
cmd.run: cmd.run:
- name: /usr/sbin/so-elastic-fleet-optional-integrations-load - name: /usr/sbin/so-elastic-fleet-optional-integrations-load
- require:
- http: wait_for_so-kibana
{% if ELASTICFLEETMERGED.config.defend_filters.enable_auto_configuration %} {% if ELASTICFLEETMERGED.config.defend_filters.enable_auto_configuration %}
so-elastic-defend-manage-filters-file-watch: so-elastic-defend-manage-filters-file-watch:
cmd.run: cmd.run:
- name: python3 /sbin/so-elastic-defend-manage-filters.py -c /opt/so/conf/elasticsearch/curl.config -d /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml -i /nsm/securityonion-resources/event_filters/ -i /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters/ &>> /opt/so/log/elasticfleet/elastic-defend-manage-filters.log - name: python3 /sbin/so-elastic-defend-manage-filters.py -c /opt/so/conf/elasticsearch/curl.config -d /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml -i /nsm/securityonion-resources/event_filters/ -i /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters/ &>> /opt/so/log/elasticfleet/elastic-defend-manage-filters.log
- require:
- http: wait_for_so-kibana
- onchanges: - onchanges:
- file: elasticdefendcustom - file: elasticdefendcustom
- file: elasticdefenddisabled - file: elasticdefenddisabled
@@ -108,9 +108,12 @@ if [ ! -f /opt/so/state/eaintegrations.txt ]; then
done done
# Only create the state file if all policies were created/updated successfully # Only create the state file if all policies were created/updated successfully
if [[ "$RETURN_CODE" != "1" ]]; then if [[ $RETURN_CODE -eq 0 ]]; then
touch /opt/so/state/eaintegrations.txt touch /opt/so/state/eaintegrations.txt
else
exit 1
fi fi
else else
exit $RETURN_CODE echo "Fleet integration policies already loaded."
exit 0
fi fi
@@ -8,18 +8,33 @@
. /usr/sbin/so-elastic-fleet-common . /usr/sbin/so-elastic-fleet-common
PKG_LOAD_FAILURES=0
PKG_LOAD_FAILURES_NAMES=()
{%- for PACKAGE in SUPPORTED_PACKAGES %} {%- for PACKAGE in SUPPORTED_PACKAGES %}
echo "Upgrading {{ PACKAGE }} package..." echo "Upgrading {{ PACKAGE }} package..."
if VERSION=$(elastic_fleet_package_latest_version_check "{{ PACKAGE }}"); then if VERSION=$(elastic_fleet_package_latest_version_check "{{ PACKAGE }}"); then
if ! elastic_fleet_package_install "{{ PACKAGE }}" "$VERSION"; then if ! elastic_fleet_package_install "{{ PACKAGE }}" "$VERSION"; then
# exit 1 on failure to upgrade a default package, allow salt to handle retries PKG_LOAD_FAILURES=$((PKG_LOAD_FAILURES + 1))
echo -e "\nERROR: Failed to upgrade $PACKAGE to version: $VERSION" PKG_LOAD_FAILURES_NAMES+=("{{ PACKAGE }}")
exit 1
fi fi
else else
echo -e "\nERROR: Failed to get version information for integration $PACKAGE" PKG_LOAD_FAILURES=$((PKG_LOAD_FAILURES + 1))
PKG_LOAD_FAILURES_NAMES+=("{{ PACKAGE }}")
fi fi
echo echo
{%- endfor %} {%- endfor %}
if [ $PKG_LOAD_FAILURES -gt 0 ]; then
echo "ERROR: Failed to upgrade $PKG_LOAD_FAILURES package(s):"
for PKG in "${PKG_LOAD_FAILURES_NAMES[@]}"; do
echo " - $PKG"
done
# exit 1 on failure to upgrade a default package, allow salt to handle retries
exit 1
else
echo "Successfully upgraded all packages."
fi
echo echo
/usr/sbin/so-elasticsearch-templates-load /usr/sbin/so-elasticsearch-templates-load
+32 -2
View File
@@ -9,9 +9,12 @@
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %} {% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %}
{% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS, SO_MANAGED_INDICES %} {% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS, SO_MANAGED_INDICES %}
{% if GLOBALS.role != 'so-heavynode' %} {% if GLOBALS.role != 'so-heavynode' %}
{% from 'elasticsearch/template.map.jinja' import ALL_ADDON_SETTINGS %} {% from 'elasticsearch/template.map.jinja' import ALL_ADDON_SETTINGS, ADDON_INDICES %}
{% endif %} {% endif %}
include:
- elasticsearch.enabled
escomponenttemplates: escomponenttemplates:
file.recurse: file.recurse:
- name: /opt/so/conf/elasticsearch/templates/component - name: /opt/so/conf/elasticsearch/templates/component
@@ -35,6 +38,20 @@ so_index_template_dir:
{%- endfor %} {%- endfor %}
{%- endif %} {%- endif %}
{% if GLOBALS.role != "so-heavynode" %}
# Clean up legacy and non-SO managed templates from the elasticsearch/templates/addon-index/ directory
addon_index_template_dir:
file.directory:
- name: /opt/so/conf/elasticsearch/templates/addon-index
- clean: True
{%- if ADDON_INDICES %}
- require:
{%- for index in ADDON_INDICES %}
- file: addon_index_template_{{index}}
{%- endfor %}
{%- endif %}
{% endif %}
# Auto-generate index templates for SO managed indices (directly defined in elasticsearch/defaults.yaml) # 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 # These index templates are for the core SO datasets and are always required
{% for index, settings in ES_INDEX_SETTINGS.items() %} {% for index, settings in ES_INDEX_SETTINGS.items() %}
@@ -116,6 +133,18 @@ so-elasticsearch-templates:
- docker_container: so-elasticsearch - docker_container: so-elasticsearch
- file: elasticsearch_sbin_jinja - file: elasticsearch_sbin_jinja
so-elasticsearch-dlm-apply:
cmd.run:
- name: /usr/sbin/so-elasticsearch-dlm-apply
- cwd: /opt/so
- require:
- docker_container: so-elasticsearch
- file: elasticsearch_sbin_jinja
- cmd: so-elasticsearch-templates
- retry:
attempts: 3
interval: 10
so-elasticsearch-pipelines: so-elasticsearch-pipelines:
cmd.run: cmd.run:
- name: /usr/sbin/so-elasticsearch-pipelines {{ GLOBALS.hostname }} - name: /usr/sbin/so-elasticsearch-pipelines {{ GLOBALS.hostname }}
@@ -136,7 +165,8 @@ so-elasticsearch-roles-load:
{% set ap = "absent" %} {% set ap = "absent" %}
{% endif %} {% endif %}
{% if grains.role in ['so-eval', 'so-standalone', 'so-heavynode'] %} {% if grains.role in ['so-eval', 'so-standalone', 'so-heavynode'] %}
{% if ELASTICSEARCHMERGED.index_clean %} {# Remove so-elasticsearch-indices-delete script when using DLM #}
{% if ELASTICSEARCHMERGED.index_clean and ELASTICSEARCHMERGED.data_retention_method == "ILM" %}
{% set ap = "present" %} {% set ap = "present" %}
{% else %} {% else %}
{% set ap = "absent" %} {% set ap = "absent" %}
+135 -7
View File
@@ -2,6 +2,7 @@ elasticsearch:
enabled: false enabled: false
version: 9.3.3 version: 9.3.3
index_clean: true index_clean: true
data_retention_method: DLM
vm: vm:
max_map_count: 1048576 max_map_count: 1048576
config: config:
@@ -63,6 +64,8 @@ elasticsearch:
verification_mode: none verification_mode: none
index_settings: index_settings:
global_overrides: global_overrides:
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
template: template:
settings: settings:
@@ -143,6 +146,8 @@ elasticsearch:
order: desc order: desc
so-common: so-common:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -304,6 +309,8 @@ elasticsearch:
number_of_shards: 1 number_of_shards: 1
so-assistant-chat: so-assistant-chat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: ""
index_template: index_template:
composed_of: composed_of:
- assistant-chat-mappings - assistant-chat-mappings
@@ -344,6 +351,8 @@ elasticsearch:
min_age: 0ms min_age: 0ms
so-assistant-session: so-assistant-session:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: ""
index_template: index_template:
composed_of: composed_of:
- assistant-session-mappings - assistant-session-mappings
@@ -497,6 +506,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-idh: so-idh:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -605,6 +616,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-import: so-import:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -787,6 +800,8 @@ elasticsearch:
min_age: 0ms min_age: 0ms
so-kismet: so-kismet:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- kismet-mappings - kismet-mappings
@@ -836,6 +851,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-kratos: so-kratos:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -904,6 +921,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-hydra: so-hydra:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -1049,6 +1068,8 @@ elasticsearch:
min_age: 0ms min_age: 0ms
so-logs: so-logs:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- so-data-streams-mappings - so-data-streams-mappings
@@ -1129,6 +1150,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-detections_x_alerts: so-logs-detections_x_alerts:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- so-data-streams-mappings - so-data-streams-mappings
@@ -1192,6 +1215,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent: so-logs-elastic_agent:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -1307,6 +1332,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-elastic-agent-monitor: so-elastic-agent-monitor:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -1369,6 +1396,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_apm_server: so-logs-elastic_agent_x_apm_server:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-elastic_agent.apm_server@package - logs-elastic_agent.apm_server@package
@@ -1433,6 +1462,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_auditbeat: so-logs-elastic_agent_x_auditbeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-elastic_agent.auditbeat@package - logs-elastic_agent.auditbeat@package
@@ -1497,6 +1528,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_cloudbeat: so-logs-elastic_agent_x_cloudbeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-elastic_agent.cloudbeat@package - logs-elastic_agent.cloudbeat@package
@@ -1561,6 +1594,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_endpoint_security: so-logs-elastic_agent_x_endpoint_security:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -1620,6 +1655,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_filebeat: so-logs-elastic_agent_x_filebeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -1679,6 +1716,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_fleet_server: so-logs-elastic_agent_x_fleet_server:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -1735,6 +1774,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_heartbeat: so-logs-elastic_agent_x_heartbeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-elastic_agent.heartbeat@package - logs-elastic_agent.heartbeat@package
@@ -1799,6 +1840,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_metricbeat: so-logs-elastic_agent_x_metricbeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -1858,6 +1901,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_osquerybeat: so-logs-elastic_agent_x_osquerybeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -1917,6 +1962,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elastic_agent_x_packetbeat: so-logs-elastic_agent_x_packetbeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-elastic_agent.packetbeat@package - logs-elastic_agent.packetbeat@package
@@ -1981,6 +2028,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-elasticsearch_x_server: so-logs-elasticsearch_x_server:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-elasticsearch.server@package - logs-elasticsearch.server@package
@@ -2045,10 +2094,13 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_actions: so-logs-endpoint_x_actions:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- .logs-endpoint.actions@package - .logs-endpoint.actions@package
- .logs-endpoint.actions@custom - .logs-endpoint.actions@custom
- endpoint@custom
- event-mappings - event-mappings
- so-fleet_integrations.ip_mappings-1 - so-fleet_integrations.ip_mappings-1
- so-fleet_globals-1 - so-fleet_globals-1
@@ -2058,8 +2110,9 @@ elasticsearch:
hidden: false hidden: false
ignore_missing_component_templates: ignore_missing_component_templates:
- .logs-endpoint.actions@custom - .logs-endpoint.actions@custom
- endpoint@custom
index_patterns: index_patterns:
- logs-endpoint.actions-* - .logs-endpoint.actions-*
priority: 501 priority: 501
template: template:
settings: settings:
@@ -2104,10 +2157,13 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_action_x_responses: so-logs-endpoint_x_action_x_responses:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- .logs-endpoint.action.responses@package - .logs-endpoint.action.responses@package
- .logs-endpoint.action.responses@custom - .logs-endpoint.action.responses@custom
- endpoint@custom
- event-mappings - event-mappings
- so-fleet_integrations.ip_mappings-1 - so-fleet_integrations.ip_mappings-1
- so-fleet_globals-1 - so-fleet_globals-1
@@ -2117,14 +2173,15 @@ elasticsearch:
hidden: false hidden: false
ignore_missing_component_templates: ignore_missing_component_templates:
- .logs-endpoint.action.responses@custom - .logs-endpoint.action.responses@custom
- endpoint@custom
index_patterns: index_patterns:
- logs-endpoint.action.responses-* - .logs-endpoint.action.responses-*
priority: 501 priority: 501
template: template:
settings: settings:
index: index:
lifecycle: lifecycle:
name: so-logs-endpoint.actions-logs name: so-logs-endpoint.action.responses-logs
mapping: mapping:
total_fields: total_fields:
limit: 5000 limit: 5000
@@ -2163,6 +2220,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_alerts: so-logs-endpoint_x_alerts:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.alerts@package - logs-endpoint.alerts@package
@@ -2222,6 +2281,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_diagnostic_x_collection: so-logs-endpoint_x_diagnostic_x_collection:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- .logs-endpoint.diagnostic.collection@package - .logs-endpoint.diagnostic.collection@package
@@ -2297,6 +2358,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_events_x_api: so-logs-endpoint_x_events_x_api:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.events.api@package - logs-endpoint.events.api@package
@@ -2356,6 +2419,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_events_x_file: so-logs-endpoint_x_events_x_file:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.events.file@package - logs-endpoint.events.file@package
@@ -2415,6 +2480,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_events_x_library: so-logs-endpoint_x_events_x_library:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.events.library@package - logs-endpoint.events.library@package
@@ -2474,6 +2541,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_events_x_network: so-logs-endpoint_x_events_x_network:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.events.network@package - logs-endpoint.events.network@package
@@ -2533,6 +2602,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_events_x_process: so-logs-endpoint_x_events_x_process:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.events.process@package - logs-endpoint.events.process@package
@@ -2592,6 +2663,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_events_x_registry: so-logs-endpoint_x_events_x_registry:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.events.registry@package - logs-endpoint.events.registry@package
@@ -2651,6 +2724,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_events_x_security: so-logs-endpoint_x_events_x_security:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-endpoint.events.security@package - logs-endpoint.events.security@package
@@ -2710,6 +2785,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-endpoint_x_heartbeat: so-logs-endpoint_x_heartbeat:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- .logs-endpoint.heartbeat@package - .logs-endpoint.heartbeat@package
@@ -2769,6 +2846,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-http_endpoint_x_generic: so-logs-http_endpoint_x_generic:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-http_endpoint.generic@package - logs-http_endpoint.generic@package
@@ -2817,6 +2896,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-httpjson_x_generic: so-logs-httpjson_x_generic:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-httpjson.generic@package - logs-httpjson.generic@package
@@ -2882,6 +2963,8 @@ elasticsearch:
number_of_replicas: 0 number_of_replicas: 0
so-logs-osquery-manager_x_action_x_responses: so-logs-osquery-manager_x_action_x_responses:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
_meta: _meta:
managed: true managed: true
@@ -2953,6 +3036,8 @@ elasticsearch:
number_of_replicas: 0 number_of_replicas: 0
so-logs-osquery-manager_x_result: so-logs-osquery-manager_x_result:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
_meta: _meta:
managed: true managed: true
@@ -3005,6 +3090,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-soc: so-logs-soc:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -3113,6 +3200,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-system_x_application: so-logs-system_x_application:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -3162,6 +3251,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-system_x_auth: so-logs-system_x_auth:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -3211,6 +3302,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-system_x_security: so-logs-system_x_security:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -3260,6 +3353,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-system_x_syslog: so-logs-system_x_syslog:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -3309,6 +3404,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-system_x_system: so-logs-system_x_system:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- event-mappings - event-mappings
@@ -3358,6 +3455,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-windows_x_forwarded: so-logs-windows_x_forwarded:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-windows.forwarded@package - logs-windows.forwarded@package
@@ -3405,6 +3504,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-windows_x_powershell: so-logs-windows_x_powershell:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-windows.powershell@package - logs-windows.powershell@package
@@ -3452,6 +3553,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-windows_x_powershell_operational: so-logs-windows_x_powershell_operational:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-windows.powershell_operational@package - logs-windows.powershell_operational@package
@@ -3499,6 +3602,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-windows_x_sysmon_operational: so-logs-windows_x_sysmon_operational:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-windows.sysmon_operational@package - logs-windows.sysmon_operational@package
@@ -3546,6 +3651,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logs-winlog_x_winlog: so-logs-winlog_x_winlog:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- logs-winlog.winlog@package - logs-winlog.winlog@package
@@ -3594,6 +3701,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-logstash: so-logstash:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -3709,6 +3818,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-metrics-endpoint_x_metadata: so-metrics-endpoint_x_metadata:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- metrics-endpoint.metadata@package - metrics-endpoint.metadata@package
@@ -3756,6 +3867,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-metrics-endpoint_x_metrics: so-metrics-endpoint_x_metrics:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- metrics-endpoint.metrics@package - metrics-endpoint.metrics@package
@@ -3803,6 +3916,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-metrics-endpoint_x_policy: so-metrics-endpoint_x_policy:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- metrics-endpoint.policy@package - metrics-endpoint.policy@package
@@ -3850,6 +3965,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-metrics-fleet_server_x_agent_status: so-metrics-fleet_server_x_agent_status:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- metrics@tsdb-settings - metrics@tsdb-settings
@@ -3874,6 +3991,8 @@ elasticsearch:
number_of_replicas: 0 number_of_replicas: 0
so-metrics-fleet_server_x_agent_versions: so-metrics-fleet_server_x_agent_versions:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- metrics@tsdb-settings - metrics@tsdb-settings
@@ -3898,6 +4017,8 @@ elasticsearch:
number_of_replicas: 0 number_of_replicas: 0
so-redis: so-redis:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -3958,13 +4079,10 @@ elasticsearch:
- vulnerability-mappings - vulnerability-mappings
- common-settings - common-settings
- common-dynamic-mappings - common-dynamic-mappings
- logs-redis.log@package
- logs-redis.log@custom
data_stream: data_stream:
allow_custom_routing: false allow_custom_routing: false
hidden: false hidden: false
ignore_missing_component_templates: ignore_missing_component_templates: []
- logs-redis.log@custom
index_patterns: index_patterns:
- logs-redis.log* - logs-redis.log*
priority: 501 priority: 501
@@ -4016,6 +4134,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-strelka: so-strelka:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -4133,6 +4253,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-suricata: so-suricata:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -4249,6 +4371,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-suricata_x_alerts: so-suricata_x_alerts:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -4365,6 +4489,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-syslog: so-syslog:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
@@ -4481,6 +4607,8 @@ elasticsearch:
min_age: 30d min_age: 30d
so-zeek: so-zeek:
index_sorting: false index_sorting: false
data_stream_lifecycle:
data_retention: 90d
index_template: index_template:
composed_of: composed_of:
- agent-mappings - agent-mappings
+394 -61
View File
@@ -4,6 +4,13 @@ elasticsearch:
forcedType: bool forcedType: bool
advanced: True advanced: True
helpLink: elasticsearch helpLink: elasticsearch
data_retention_method:
description: Method for data retention. Options are ILM or DLM. For single node deployments and most distributed grid users, DLM will be the recommended option for simplified management. Those with more complex use cases may prefer ILM. The latter allows for more granular control, but requires more management overhead.
options:
- ILM
- DLM
forcedType: string
global: True
version: version:
description: "This specifies the version of the following containers: so-elastic-fleet-package-registry, so-elastic-agent, so-elastic-fleet, so-kibana, so-logstash and so-elasticsearch. Modifying this value in the Elasticsearch defaults.yaml will result in catastrophic grid failure." description: "This specifies the version of the following containers: so-elastic-fleet-package-registry, so-elastic-agent, so-elastic-fleet, so-kibana, so-logstash and so-elasticsearch. Modifying this value in the Elasticsearch defaults.yaml will result in catastrophic grid failure."
readonly: True readonly: True
@@ -13,7 +20,7 @@ elasticsearch:
description: Specify the memory heap size in (m)egabytes for Elasticsearch. description: Specify the memory heap size in (m)egabytes for Elasticsearch.
helpLink: elasticsearch helpLink: elasticsearch
index_clean: index_clean:
description: Determines if indices should be considered for deletion by available disk space in the cluster. Otherwise, indices will only be deleted by the age defined in the ILM settings. This setting only applies to EVAL, STANDALONE, and HEAVY NODE installations. Other installations can only use ILM settings. description: Determines if indices should be considered for deletion by available disk space in the cluster. Otherwise, data is retained by the configured lifecycle settings. This setting only applies to EVAL, STANDALONE, and HEAVY NODE installations. Other installations use lifecycle settings only.
forcedType: bool forcedType: bool
helpLink: elasticsearch helpLink: elasticsearch
vm: vm:
@@ -139,6 +146,23 @@ elasticsearch:
custom010: *pipelines custom010: *pipelines
index_settings: index_settings:
global_overrides: global_overrides:
data_stream_lifecycle:
data_retention:
description: |
The retention period for all data streams. Retention does not define the period that the data will be removed, but the minimum time period they will be kept.
Use a number followed by a time unit, such as 7d. Leave blank for indefinite retention where supported.
Configured retention period also affects the frequency of rolling over data streams.
- If retention is less than or equal to 1 day, max_age will be 1 hour
- If retention is less than or equal to 14 days, max_age will be 1 day
- If retention is less than or equal to 90 days, max_age will be 7 days
- If retention is greater than 90 days, max_age will be 30 days
forcedType: string
allowedNodeTypes:
- heavynode
regex: ^$|^[0-9]{1,5}(?:d|h|m|s)$
regexFailureMessage: Must be blank or a number followed by d, h, m, or s, such as 7d.
index_template: index_template:
template: template:
settings: settings:
@@ -311,13 +335,30 @@ elasticsearch:
forcedType: string forcedType: string
global: True global: True
helpLink: elasticsearch helpLink: elasticsearch
so-logs: &indexSettings so-logs: &dataStreamSettings
index_sorting: index_sorting:
description: Sorts the index by event time, at the cost of additional processing resource consumption. description: Sorts the index by event time, at the cost of additional processing resource consumption.
forcedType: bool forcedType: bool
global: True global: True
advanced: True advanced: True
helpLink: elasticsearch helpLink: elasticsearch
data_stream_lifecycle:
data_retention:
description: |
The retention period for this data stream. Retention does not define the period that the data will be removed, but the minimum time period it will be kept.
Use a number followed by a time unit, such as 7d. Leave blank for indefinite retention where supported.
Configured retention period also affects the frequency of rolling over this data stream.
- If retention is less than or equal to 1 day, max_age will be 1 hour
- If retention is less than or equal to 14 days, max_age will be 1 day
- If retention is less than or equal to 90 days, max_age will be 7 days
- If retention is greater than 90 days, max_age will be 30 days
forcedType: string
allowedNodeTypes:
- heavynode
regex: ^$|^[0-9]{1,5}(?:d|h|m|s)$
regexFailureMessage: Must be blank or a number followed by d, h, m, or s, such as 7d.
index_template: index_template:
index_patterns: index_patterns:
description: Patterns for matching multiple indices or tables. description: Patterns for matching multiple indices or tables.
@@ -335,6 +376,14 @@ elasticsearch:
global: True global: True
advanced: True advanced: True
helpLink: elasticsearch helpLink: elasticsearch
auto_expand_replicas:
description: Automatically expand the number of replicas based on the number of data nodes in the cluster. This can help ensure high availability as the cluster scales up or down.
forcedType: string
regex: "^(0-[1-9]|1-[2-9]|2-[3-9]|3-[4-9]|4-[5-9]|5-[6-9]|6-[7-9]|7-[89]|8-9|[0-9]-all|false)$"
regexFailureMessage: Must be in the format of "x-y" where x is minimum number of replicas and y is maximum number of replicas, or "0-all" to specify a minimum of 0 and no maximum, or "false" to disable automatic replica expansion.
global: True
advanced: True
helpLink: elasticsearch
mapping: mapping:
total_fields: total_fields:
limit: limit:
@@ -596,65 +645,349 @@ elasticsearch:
global: True global: True
advanced: True advanced: True
helpLink: elasticsearch helpLink: elasticsearch
so-logs-system_x_auth: *indexSettings so-logs-system_x_auth: *dataStreamSettings
so-logs-system_x_syslog: *indexSettings so-logs-system_x_syslog: *dataStreamSettings
so-logs-system_x_system: *indexSettings so-logs-system_x_system: *dataStreamSettings
so-logs-system_x_application: *indexSettings so-logs-system_x_application: *dataStreamSettings
so-logs-system_x_security: *indexSettings so-logs-system_x_security: *dataStreamSettings
so-logs-windows_x_forwarded: *indexSettings so-logs-windows_x_forwarded: *dataStreamSettings
so-logs-windows_x_powershell: *indexSettings so-logs-windows_x_powershell: *dataStreamSettings
so-logs-windows_x_powershell_operational: *indexSettings so-logs-windows_x_powershell_operational: *dataStreamSettings
so-logs-windows_x_sysmon_operational: *indexSettings so-logs-windows_x_sysmon_operational: *dataStreamSettings
so-logs-winlog_x_winlog: *indexSettings so-logs-winlog_x_winlog: *dataStreamSettings
so-logs-detections_x_alerts: *indexSettings so-logs-detections_x_alerts: *dataStreamSettings
so-logs-http_endpoint_x_generic: *indexSettings so-logs-http_endpoint_x_generic: *dataStreamSettings
so-logs-httpjson_x_generic: *indexSettings so-logs-httpjson_x_generic: *dataStreamSettings
so-logs-osquery-manager-actions: *indexSettings so-logs-osquery-manager-actions: *dataStreamSettings
so-logs-osquery-manager-action_x_responses: *indexSettings so-logs-osquery-manager-action_x_responses: *dataStreamSettings
so-logs-osquery-manager_x_action_x_responses: *indexSettings so-logs-osquery-manager_x_action_x_responses: *dataStreamSettings
so-logs-osquery-manager_x_result: *indexSettings so-logs-osquery-manager_x_result: *dataStreamSettings
so-logs-elastic_agent_x_apm_server: *indexSettings so-logs-elastic_agent_x_apm_server: *dataStreamSettings
so-logs-elastic_agent_x_auditbeat: *indexSettings so-logs-elastic_agent_x_auditbeat: *dataStreamSettings
so-logs-elastic_agent_x_cloudbeat: *indexSettings so-logs-elastic_agent_x_cloudbeat: *dataStreamSettings
so-logs-elastic_agent_x_endpoint_security: *indexSettings so-logs-elastic_agent_x_endpoint_security: *dataStreamSettings
so-logs-endpoint_x_alerts: *indexSettings so-logs-endpoint_x_alerts: *dataStreamSettings
so-logs-endpoint_x_events_x_api: *indexSettings so-logs-endpoint_x_events_x_api: *dataStreamSettings
so-logs-endpoint_x_events_x_file: *indexSettings so-logs-endpoint_x_events_x_file: *dataStreamSettings
so-logs-endpoint_x_events_x_library: *indexSettings so-logs-endpoint_x_events_x_library: *dataStreamSettings
so-logs-endpoint_x_events_x_network: *indexSettings so-logs-endpoint_x_events_x_network: *dataStreamSettings
so-logs-endpoint_x_events_x_process: *indexSettings so-logs-endpoint_x_events_x_process: *dataStreamSettings
so-logs-endpoint_x_events_x_registry: *indexSettings so-logs-endpoint_x_events_x_registry: *dataStreamSettings
so-logs-endpoint_x_events_x_security: *indexSettings so-logs-endpoint_x_events_x_security: *dataStreamSettings
so-logs-elastic_agent_x_filebeat: *indexSettings so-logs-elastic_agent_x_filebeat: *dataStreamSettings
so-logs-elastic_agent_x_fleet_server: *indexSettings so-logs-elastic_agent_x_fleet_server: *dataStreamSettings
so-logs-elastic_agent_x_heartbeat: *indexSettings so-logs-elastic_agent_x_heartbeat: *dataStreamSettings
so-logs-elastic_agent: *indexSettings so-logs-elastic_agent: *dataStreamSettings
so-logs-elastic_agent_x_metricbeat: *indexSettings so-logs-elastic_agent_x_metricbeat: *dataStreamSettings
so-logs-elastic_agent_x_osquerybeat: *indexSettings so-logs-elastic_agent_x_osquerybeat: *dataStreamSettings
so-logs-elastic_agent_x_packetbeat: *indexSettings so-logs-elastic_agent_x_packetbeat: *dataStreamSettings
so-logs-elasticsearch_x_server: *indexSettings so-logs-elasticsearch_x_server: *dataStreamSettings
so-metrics-endpoint_x_metadata: *indexSettings so-metrics-endpoint_x_metadata: *dataStreamSettings
so-metrics-endpoint_x_metrics: *indexSettings so-metrics-endpoint_x_metrics: *dataStreamSettings
so-metrics-endpoint_x_policy: *indexSettings so-metrics-endpoint_x_policy: *dataStreamSettings
so-metrics-nginx_x_stubstatus: *indexSettings so-metrics-nginx_x_stubstatus: *dataStreamSettings
so-metrics-vsphere_x_datastore: *indexSettings so-metrics-vsphere_x_datastore: *dataStreamSettings
so-metrics-vsphere_x_host: *indexSettings so-metrics-vsphere_x_host: *dataStreamSettings
so-metrics-vsphere_x_virtualmachine: *indexSettings so-metrics-vsphere_x_virtualmachine: *dataStreamSettings
so-case: *indexSettings so-common: *dataStreamSettings
so-common: *indexSettings so-endgame: *dataStreamSettings
so-endgame: *indexSettings so-idh: *dataStreamSettings
so-idh: *indexSettings so-suricata: *dataStreamSettings
so-suricata: *indexSettings so-suricata_x_alerts: *dataStreamSettings
so-suricata_x_alerts: *indexSettings so-import: *dataStreamSettings
so-import: *indexSettings so-kratos: *dataStreamSettings
so-kratos: *indexSettings so-hydra: *dataStreamSettings
so-hydra: *indexSettings so-kismet: *dataStreamSettings
so-kismet: *indexSettings so-logstash: *dataStreamSettings
so-logstash: *indexSettings so-redis: *dataStreamSettings
so-redis: *indexSettings so-strelka: *dataStreamSettings
so-strelka: *indexSettings so-syslog: *dataStreamSettings
so-syslog: *indexSettings so-zeek: *dataStreamSettings
so-zeek: *indexSettings # Managed SOC integration annotations are inserted below this line. Referencing '*dataStreamSettings'
so-case: &indexSettings
index_sorting:
description: Sorts the index by event time, at the cost of additional processing resource consumption.
forcedType: bool
global: True
advanced: True
helpLink: elasticsearch
index_template:
index_patterns:
description: Patterns for matching multiple indices or tables.
forcedType: "[]string"
multiline: True
global: True
advanced: True
helpLink: elasticsearch
template:
settings:
index:
number_of_replicas:
description: Number of replicas required for this index. Multiple replicas protects against data loss, but also increases storage costs.
forcedType: int
global: True
advanced: True
helpLink: elasticsearch
auto_expand_replicas:
description: Automatically expand the number of replicas based on the number of data nodes in the cluster. This can help ensure high availability as the cluster scales up or down.
forcedType: string
regex: "^(0-[1-9]|1-[2-9]|2-[3-9]|3-[4-9]|4-[5-9]|5-[6-9]|6-[7-9]|7-[89]|8-9|[0-9]-all|false)$"
regexFailureMessage: Must be in the format of "x-y" where x is minimum number of replicas and y is maximum number of replicas, or "0-all" to specify a minimum of 0 and no maximum, or "false" to disable automatic replica expansion.
global: True
advanced: True
helpLink: elasticsearch
mapping:
total_fields:
limit:
description: Max number of fields that can exist on a single index. Larger values will consume more resources.
global: True
advanced: True
helpLink: elasticsearch
refresh_interval:
description: Seconds between index refreshes. Shorter intervals can cause query performance to suffer since this is a synchronous and resource-intensive operation.
global: True
advanced: True
helpLink: elasticsearch
number_of_shards:
description: Number of shards required for this index. Using multiple shards increases fault tolerance, but also increases storage and network costs.
global: True
advanced: True
helpLink: elasticsearch
sort:
field:
description: The field to sort by. Must set index_sorting to True.
global: True
advanced: True
helpLink: elasticsearch
order:
description: The order to sort by. Must set index_sorting to True.
global: True
advanced: True
helpLink: elasticsearch
mappings:
_meta:
package:
name:
description: Meta settings for the mapping.
global: True
advanced: True
helpLink: elasticsearch
managed_by:
description: Meta settings for the mapping.
global: True
advanced: True
helpLink: elasticsearch
managed:
description: Meta settings for the mapping.
forcedType: bool
global: True
advanced: True
helpLink: elasticsearch
composed_of:
description: The index template is composed of these component templates.
forcedType: "[]string"
global: True
advanced: True
helpLink: elasticsearch
priority:
description: The priority of the index template.
forcedType: int
global: True
advanced: True
helpLink: elasticsearch
policy:
phases:
hot:
min_age:
description: Minimum age of index. This determines when the index should be moved to the hot tier.
global: True
advanced: True
helpLink: elasticsearch
actions:
set_priority:
priority:
description: Priority of index. This is used for recovery after a node restart. Indices with higher priorities are recovered before indices with lower priorities.
forcedType: int
global: True
advanced: True
helpLink: elasticsearch
rollover:
max_age:
description: Maximum age of index. Once an index reaches this limit, it will be rolled over into a new index.
global: True
advanced: True
helpLink: elasticsearch
max_primary_shard_size:
description: Maximum primary shard size. Once an index reaches this limit, it will be rolled over into a new index.
global: True
advanced: True
helpLink: elasticsearch
shrink:
method:
description: Shrink the index to a new index with fewer primary shards. Shrink operation is by count or size.
options:
- COUNT
- SIZE
global: True
advanced: True
forcedType: string
number_of_shards:
title: shard count
description: Desired shard count. Note that this value is only used when the shrink method selected is 'COUNT'.
global: True
forcedType: int
advanced: True
max_primary_shard_size:
title: max shard size
description: Desired shard size in gb/tb/pb eg. 100gb. Note that this value is only used when the shrink method selected is 'SIZE'.
regex: ^[0-9]+(?:gb|tb|pb)$
global: True
forcedType: string
advanced: True
allow_write_after_shrink:
description: Allow writes after shrink.
global: True
forcedType: bool
default: False
advanced: True
forcemerge:
max_num_segments:
description: Reduce the number of segments in each index shard and clean up deleted documents.
global: True
forcedType: int
advanced: True
index_codec:
title: compression
description: Use higher compression for stored fields at the cost of slower performance.
forcedType: bool
global: True
default: False
advanced: True
warm:
min_age:
description: Minimum age of index. ex. 30d - This determines when the index should be moved to the warm tier. Nodes in the warm tier generally dont need to be as fast as those in the hot tier. Its important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and warm min_age set to 30 then there will be 30 days from index creation to rollover and then an additional 30 days before moving to warm tier.
regex: ^[0-9]{1,5}d$
forcedType: string
global: True
advanced: True
helpLink: elasticsearch
actions:
set_priority:
priority:
description: Priority of index. This is used for recovery after a node restart. Indices with higher priorities are recovered before indices with lower priorities.
forcedType: int
global: True
advanced: True
helpLink: elasticsearch
rollover:
max_age:
description: Maximum age of index. Once an index reaches this limit, it will be rolled over into a new index.
global: True
advanced: True
helpLink: elasticsearch
max_primary_shard_size:
description: Maximum primary shard size. Once an index reaches this limit, it will be rolled over into a new index.
global: True
advanced: True
helpLink: elasticsearch
shrink:
method:
description: Shrink the index to a new index with fewer primary shards. Shrink operation is by count or size.
options:
- COUNT
- SIZE
global: True
advanced: True
number_of_shards:
title: shard count
description: Desired shard count. Note that this value is only used when the shrink method selected is 'COUNT'.
global: True
forcedType: int
advanced: True
max_primary_shard_size:
title: max shard size
description: Desired shard size in gb/tb/pb eg. 100gb. Note that this value is only used when the shrink method selected is 'SIZE'.
regex: ^[0-9]+(?:gb|tb|pb)$
global: True
forcedType: string
advanced: True
allow_write_after_shrink:
description: Allow writes after shrink.
global: True
forcedType: bool
default: False
advanced: True
forcemerge:
max_num_segments:
description: Reduce the number of segments in each index shard and clean up deleted documents.
global: True
forcedType: int
advanced: True
index_codec:
title: compression
description: Use higher compression for stored fields at the cost of slower performance.
forcedType: bool
global: True
default: False
advanced: True
allocate:
number_of_replicas:
description: Set the number of replicas. Remains the same as the previous phase by default.
forcedType: int
global: True
advanced: True
cold:
min_age:
description: Minimum age of index. ex. 60d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed. Its important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and cold min_age set to 60 then there will be 30 days from index creation to rollover and then an additional 60 days before moving to cold tier.
regex: ^[0-9]{1,5}d$
forcedType: string
global: True
advanced: True
helpLink: elasticsearch
actions:
set_priority:
priority:
description: Used for index recovery after a node restart. Indices with higher priorities are recovered before indices with lower priorities.
forcedType: int
global: True
advanced: True
helpLink: elasticsearch
allocate:
number_of_replicas:
description: Set the number of replicas. Remains the same as the previous phase by default.
forcedType: int
global: True
advanced: True
delete:
min_age:
description: Minimum age of index. ex. 90d - This determines when the index should be deleted. Its important to note that this is calculated relative to the rollover date (NOT the original creation date of the index). For example, if you have an index that is set to rollover after 30 days and delete min_age set to 90 then there will be 30 days from index creation to rollover and then an additional 90 days before deletion.
regex: ^[0-9]{1,5}d$
forcedType: string
global: True
advanced: True
helpLink: elasticsearch
_meta:
package:
name:
description: Meta settings for the mapping.
global: True
advanced: True
helpLink: elasticsearch
managed_by:
description: Meta settings for the mapping.
global: True
advanced: True
helpLink: elasticsearch
managed:
description: Meta settings for the mapping.
forcedType: bool
global: True
advanced: True
helpLink: elasticsearch
sos-backup: *indexSettings
so-detection: *indexSettings
so-assistant-chat: *indexSettings
so-assistant-session: *indexSettings
so-metrics-fleet_server_x_agent_status: &fleetMetricsSettings so-metrics-fleet_server_x_agent_status: &fleetMetricsSettings
index_sorting: index_sorting:
description: Sorts the index by event time, at the cost of additional processing resource consumption. description: Sorts the index by event time, at the cost of additional processing resource consumption.
+34 -3
View File
@@ -5,6 +5,7 @@
{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %} {% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %}
{% set DEFAULT_GLOBAL_OVERRIDES = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings.pop('global_overrides') %} {% set DEFAULT_GLOBAL_OVERRIDES = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings.pop('global_overrides') %}
{% set DATA_RETENTION_METHOD = salt['pillar.get']('elasticsearch:data_retention_method', ELASTICSEARCHDEFAULTS.elasticsearch.get('data_retention_method', 'ILM')) %}
{% set PILLAR_GLOBAL_OVERRIDES = {} %} {% set PILLAR_GLOBAL_OVERRIDES = {} %}
{% set ES_INDEX_PILLAR = salt['pillar.get']('elasticsearch:index_settings', {}) %} {% set ES_INDEX_PILLAR = salt['pillar.get']('elasticsearch:index_settings', {}) %}
@@ -61,15 +62,25 @@
{% if ALL_ADDON_SETTINGS_ORIG.keys() | length > 0 %} {% if ALL_ADDON_SETTINGS_ORIG.keys() | length > 0 %}
{% for index in ALL_ADDON_SETTINGS_ORIG.keys() %} {% 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)}) %} {% do ALL_ADDON_SETTINGS_GLOBAL_OVERRIDES.update({index: salt['defaults.merge'](ALL_ADDON_SETTINGS_ORIG[index], PILLAR_GLOBAL_OVERRIDES, in_place=False)}) %}
{# Explicitly excluding addon indices from ES_INDEX_SETTINGS_ORIG
When manager.soc_managed_annotations runs, new entries are added to the salt/elasticsearch/defaults.yaml file to support 'revert to default' functionality.
Subsequent map renders will then incorrectly include 'integration X' in 'ES_INDEX_SETTINGS_ORIG' due to being in the defaults.yaml file. #}
{% if index in ES_INDEX_SETTINGS_ORIG.keys() %}
{% do ES_INDEX_SETTINGS_ORIG.pop(index) %}
{% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% set ES_INDEX_SETTINGS = {} %} {% set ES_INDEX_SETTINGS = {} %}
{% macro create_final_index_template(DEFINED_SETTINGS, GLOBAL_OVERRIDES, FINAL_INDEX_SETTINGS) %} {% macro create_final_index_template(DEFINED_SETTINGS, GLOBAL_OVERRIDES, FINAL_INDEX_SETTINGS, EXCLUDE_INDICES=[]) %}
{% do GLOBAL_OVERRIDES.update(salt['defaults.merge'](GLOBAL_OVERRIDES, ES_INDEX_PILLAR, in_place=False)) %} {% do GLOBAL_OVERRIDES.update(salt['defaults.merge'](GLOBAL_OVERRIDES, ES_INDEX_PILLAR, in_place=False)) %}
{% for index, settings in GLOBAL_OVERRIDES.items() %} {% for index, settings in GLOBAL_OVERRIDES.items() %}
{% if index in EXCLUDE_INDICES %}
{% continue %}
{% endif %}
{# prevent this action from being performed on custom defined indices. #} {# 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. #} {# 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 DEFINED_SETTINGS and index in GLOBAL_OVERRIDES %}
@@ -95,6 +106,17 @@
{% if not settings.get('index_sorting', False) | to_bool and settings.index_template.template.settings.index.sort is defined %} {% if not settings.get('index_sorting', False) | to_bool and settings.index_template.template.settings.index.sort is defined %}
{% do settings.index_template.template.settings.index.pop('sort') %} {% do settings.index_template.template.settings.index.pop('sort') %}
{% endif %} {% endif %}
{% if DATA_RETENTION_METHOD == 'DLM' and settings.index_template.data_stream is defined and settings.data_stream_lifecycle is defined %}
{% if settings.data_stream_lifecycle.data_retention is defined and settings.data_stream_lifecycle.data_retention %}
{% do settings.index_template.template.update({'lifecycle': {'data_retention': settings.data_stream_lifecycle.data_retention}}) %}
{% else %}
{% do settings.index_template.template.update({'lifecycle': {}}) %}
{% endif %}
{% if settings.index_template.template.settings.index.lifecycle is not defined %}
{% do settings.index_template.template.settings.index.update({'lifecycle': {}}) %}
{% endif %}
{% do settings.index_template.template.settings.index.lifecycle.update({'prefer_ilm': false}) %}
{% endif %}
{% endif %} {% endif %}
{# advanced ilm actions #} {# advanced ilm actions #}
@@ -150,10 +172,19 @@
{% endfor %} {% endfor %}
{% endmacro %} {% endmacro %}
{{ create_final_index_template(ES_INDEX_SETTINGS_ORIG, ES_INDEX_SETTINGS_GLOBAL_OVERRIDES, ES_INDEX_SETTINGS) }} {# Exclude addon integrations from final ES_INDEX_SETTINGS #}
{{ create_final_index_template(ALL_ADDON_SETTINGS_ORIG, ALL_ADDON_SETTINGS_GLOBAL_OVERRIDES, ALL_ADDON_SETTINGS) }} {{ create_final_index_template(ES_INDEX_SETTINGS_ORIG, ES_INDEX_SETTINGS_GLOBAL_OVERRIDES, ES_INDEX_SETTINGS, ALL_ADDON_SETTINGS_ORIG.keys() | list ) }}
{# Exclude SO managed indices, otherwise ALL_ADDON_SETTINGS will include pillar values
of core integrations without merging defaults, resulting in an overlapping, but bad index template being generated. #}
{{ create_final_index_template(ALL_ADDON_SETTINGS_ORIG, ALL_ADDON_SETTINGS_GLOBAL_OVERRIDES, ALL_ADDON_SETTINGS, ES_INDEX_SETTINGS_ORIG.keys() | list ) }}
{% set SO_MANAGED_INDICES = [] %} {% set SO_MANAGED_INDICES = [] %}
{% for index, settings in ES_INDEX_SETTINGS.items() %} {% for index, settings in ES_INDEX_SETTINGS.items() %}
{% do SO_MANAGED_INDICES.append(index) %} {% do SO_MANAGED_INDICES.append(index) %}
{% endfor %} {% endfor %}
{% set ADDON_INDICES = [] %}
{% for index, settings in ALL_ADDON_SETTINGS.items() %}
{% do ADDON_INDICES.append(index) %}
{% endfor %}
@@ -125,14 +125,6 @@ load_component_templates() {
done done
} }
check_elasticsearch_responsive() {
# 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."
}
index_templates_exist() { index_templates_exist() {
local templates_dir="$1" local templates_dir="$1"
@@ -0,0 +1,176 @@
#!/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
{%- import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %}
{%- set DATA_RETENTION_METHOD = salt['pillar.get']('elasticsearch:data_retention_method', ELASTICSEARCHDEFAULTS.elasticsearch.get('data_retention_method', 'ILM')) %}
ELASTICSEARCH_TEMPLATES_DIR="${ELASTICSEARCH_TEMPLATES_DIR:-/opt/so/conf/elasticsearch/templates}"
TEMPLATE_DIRS=(
"${ELASTICSEARCH_TEMPLATES_DIR}/index"
"${ELASTICSEARCH_TEMPLATES_DIR}/addon-index"
)
DATA_RETENTION_METHOD=$(cat <<'EOF'
{{ DATA_RETENTION_METHOD }}
EOF
)
DLM_FAILURES=0
DLM_FAILURE_NAMES=()
if [[ "$DATA_RETENTION_METHOD" != "DLM" && "$DATA_RETENTION_METHOD" != "ILM" ]]; then
echo "Unsupported data retention method $DATA_RETENTION_METHOD. Expected DLM or ILM."
exit 1
fi
validate_template_file() {
local template_file="$1"
if ! jq -e 'type == "object" and (.data_stream == null or (.data_stream | type == "object")) and (.template.lifecycle == null or (.template.lifecycle | type == "object")) and (.template.lifecycle.data_retention == null or (.template.lifecycle.data_retention | type == "string"))' >/dev/null 2>&1 "$template_file"; then
echo "Invalid index template JSON: $template_file"
return 1
fi
}
is_data_stream_template() {
jq -e '.data_stream | type == "object"' >/dev/null 2>&1 "$1"
}
has_data_stream_lifecycle() {
jq -e '.template.lifecycle | type == "object"' >/dev/null 2>&1 "$1"
}
get_data_retention() {
jq -r '.template.lifecycle.data_retention // ""' "$1"
}
find_template_file() {
local template="$1"
local template_dir
local template_file
for template_dir in "${TEMPLATE_DIRS[@]}"; do
template_file="${template_dir}/${template}-template.json"
if [[ -f "$template_file" ]]; then
echo "$template_file"
return 0
fi
done
return 1
}
set_data_stream_lifecycle() {
local data_stream="$1"
local data_retention="$2"
local body
local output
if [[ -n "$data_retention" ]]; then
if jq -e --arg data_stream "$data_stream" --arg data_retention "$data_retention" '.data_streams[]? | select(.name == $data_stream and .lifecycle.enabled == true and .lifecycle.data_retention == $data_retention)' >/dev/null 2>&1 <<< "$data_streams"; then
echo "DLM lifecycle already set for $data_stream with data_retention $data_retention, skipping."
return 0
fi
elif jq -e --arg data_stream "$data_stream" '.data_streams[]? | select(.name == $data_stream and .lifecycle.enabled == true and (.lifecycle.data_retention == null))' >/dev/null 2>&1 <<< "$data_streams"; then
echo "DLM lifecycle already set for $data_stream with indefinite retention, skipping."
return 0
fi
if [[ -n "$data_retention" ]]; then
body=$(jq -cn --arg data_retention "$data_retention" '{data_retention: $data_retention}')
else
# Setting indefinite retention
body='{}'
fi
if ! output=$(so-elasticsearch-query "_data_stream/${data_stream}/_lifecycle" -XPUT -d "$body" --retry 3 --retry-delay 5 --fail); then
echo "Failed to set data stream lifecycle for $data_stream."
return 1
fi
if [[ -n "$data_retention" ]]; then
echo "Set DLM lifecycle for $data_stream with data_retention $data_retention."
else
echo "Set DLM lifecycle for $data_stream with indefinite retention."
fi
}
disable_data_stream_lifecycle() {
local data_stream="$1"
local body='{"enabled":false}'
local output
if ! jq -e --arg data_stream "$data_stream" '.data_streams[]? | select(.name == $data_stream and .lifecycle != null and .lifecycle.enabled != false)' >/dev/null 2>&1 <<< "$data_streams"; then
# No action needed
return 0
fi
if ! output=$(so-elasticsearch-query "_data_stream/${data_stream}/_lifecycle" -XPUT -d "$body" --retry 3 --retry-delay 5 --fail); then
echo "Failed to disable data stream lifecycle for $data_stream."
return 1
fi
echo "Disabled DLM lifecycle for $data_stream."
}
process_data_stream() {
local data_stream="$1"
local data_retention="$2"
if [[ "$DATA_RETENTION_METHOD" == "DLM" ]]; then
set_data_stream_lifecycle "$data_stream" "$data_retention"
else
disable_data_stream_lifecycle "$data_stream"
fi
}
check_elasticsearch_responsive
if ! data_streams=$(so-elasticsearch-query "_data_stream?format=json" --retry 3 --retry-delay 5 --fail); then
echo "Failed to retrieve data streams."
exit 1
fi
while read -r data_stream_config; do
data_stream=$(jq -r '.name' <<< "$data_stream_config")
template=$(jq -r '.template' <<< "$data_stream_config")
if ! template_file=$(find_template_file "$template"); then
echo "Skipping $data_stream: index template file not found for $template."
continue
fi
validate_template_file "$template_file" || exit 1
if ! is_data_stream_template "$template_file"; then
echo "Skipping $data_stream: $template_file is not a data stream template."
continue
fi
if [[ "$DATA_RETENTION_METHOD" == "DLM" ]] && ! has_data_stream_lifecycle "$template_file"; then
echo "Skipping $data_stream: $template_file does not define data stream lifecycle."
continue
fi
data_retention=$(get_data_retention "$template_file")
if ! process_data_stream "$data_stream" "$data_retention"; then
DLM_FAILURES=$((DLM_FAILURES + 1))
DLM_FAILURE_NAMES+=("$data_stream")
fi
done < <(jq -c '.data_streams[]' <<< "$data_streams")
if [[ $DLM_FAILURES -eq 0 ]]; then
echo "Data stream lifecycle updates completed successfully."
else
echo "Encountered $DLM_FAILURES failure(s) updating data stream lifecycle:"
for failed_data_stream in "${DLM_FAILURE_NAMES[@]}"; do
echo " - $failed_data_stream"
done
exit 1
fi
+1 -1
View File
@@ -32,7 +32,7 @@ so-kafka:
- networks: - networks:
- sobridge: - sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-kafka'].ip }} - ipv4_address: {{ DOCKERMERGED.containers['so-kafka'].ip }}
- user: kafka - user: "960"
- environment: - environment:
KAFKA_HEAP_OPTS: -Xmx2G -Xms1G KAFKA_HEAP_OPTS: -Xmx2G -Xms1G
KAFKA_OPTS: "-javaagent:/opt/jolokia/agents/jolokia-agent-jvm-javaagent.jar=port=8778,host={{ DOCKERMERGED.containers['so-kafka'].ip }},policyLocation=file:/opt/jolokia/jolokia.xml {%- if KAFKA_EXTERNAL_ACCESS %} -Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf {% endif -%}" KAFKA_OPTS: "-javaagent:/opt/jolokia/agents/jolokia-agent-jvm-javaagent.jar=port=8778,host={{ DOCKERMERGED.containers['so-kafka'].ip }},policyLocation=file:/opt/jolokia/jolokia.xml {%- if KAFKA_EXTERNAL_ACCESS %} -Djava.security.auth.login.config=/opt/kafka/config/kafka_server_jaas.conf {% endif -%}"
+15 -1
View File
@@ -6,6 +6,7 @@
{% from 'allowed_states.map.jinja' import allowed_states %} {% from 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %} {% if sls.split('.')[0] in allowed_states %}
{% from 'docker/docker.map.jinja' import DOCKERMERGED %} {% from 'docker/docker.map.jinja' import DOCKERMERGED %}
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %}
{% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'vars/globals.map.jinja' import GLOBALS %}
include: include:
@@ -17,7 +18,7 @@ so-kibana:
docker_container.running: docker_container.running:
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kibana:{{ GLOBALS.so_version }} - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kibana:{{ GLOBALS.so_version }}
- hostname: kibana - hostname: kibana
- user: kibana - user: "932:0"
- networks: - networks:
- sobridge: - sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-kibana'].ip }} - ipv4_address: {{ DOCKERMERGED.containers['so-kibana'].ip }}
@@ -60,6 +61,19 @@ so-kibana:
- watch: - watch:
- file: kibanaconfig - file: kibanaconfig
wait_for_so-kibana:
http.wait_for_successful_query:
- name: "http://localhost:5601/api/status"
- username: 'so_elastic'
- password: '{{ ELASTICSEARCHMERGED.auth.users.so_elastic_user.pass }}'
- ssl: True
- verify_ssl: False
- status: 200
- wait_for: 300
- request_interval: 15
- require:
- docker_container: so-kibana
delete_so-kibana_so-status.disabled: delete_so-kibana_so-status.disabled:
file.uncomment: file.uncomment:
- name: /opt/so/conf/so-status/so-status.conf - name: /opt/so/conf/so-status/so-status.conf
+1 -1
View File
@@ -103,7 +103,7 @@ kratos:
config: config:
session: session:
lifespan: lifespan:
description: Defines the length of a login session. description: Defines the length of a login session before it will timeout, and require a new login.
global: True global: True
helpLink: kratos helpLink: kratos
whoami: whoami:
+1 -1
View File
@@ -33,7 +33,7 @@ so-logstash:
- networks: - networks:
- sobridge: - sobridge:
- ipv4_address: {{ DOCKERMERGED.containers['so-logstash'].ip }} - ipv4_address: {{ DOCKERMERGED.containers['so-logstash'].ip }}
- user: logstash - user: "931:0"
- extra_hosts: - extra_hosts:
{% for node in LOGSTASH_NODES %} {% for node in LOGSTASH_NODES %}
{% for hostname, ip in node.items() %} {% for hostname, ip in node.items() %}
+26 -31
View File
@@ -16,40 +16,35 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% set soc_annotation_lines = [] %}
{% set defaults_lines = [] %}
{% for k in matched_integration_names %}
{% do soc_annotation_lines.append(' ' ~ k ~ ': *dataStreamSettings') %}
{% do defaults_lines.append(' ' ~ k ~ ':') %}
{% set defaults_yaml = salt['slsutil.serialize']('yaml', ADDON_INTEGRATION_DEFAULTS[k], default_flow_style=False).strip() %}
{% for line in defaults_yaml.splitlines() %}
{% do defaults_lines.append(' ' ~ line) %}
{% endfor %}
{% endfor %}
{% set es_soc_annotations = '/opt/so/saltstack/default/salt/elasticsearch/soc_elasticsearch.yaml' %} {% set es_soc_annotations = '/opt/so/saltstack/default/salt/elasticsearch/soc_elasticsearch.yaml' %}
{{ es_soc_annotations }}: manage_soc_annotations:
file.serialize: file.blockreplace:
- dataset: - name: {{ es_soc_annotations }}
{% set data = salt['file.read'](es_soc_annotations) | load_yaml %} - marker_start: ' # START managed SOC integration annotations'
{% set es = data.get('elasticsearch', {}) %} - marker_end: ' # END managed SOC integration annotations'
{% set index_settings = es.get('index_settings', {}) %} - content: {{ soc_annotation_lines | join('\n') | tojson }}
{% set input = index_settings.get('so-logs', {}) %} - insert_after_match: '^ # Managed SOC integration annotations are inserted below this line\.'
{% for k in matched_integration_names %} - append_if_not_found: False
{% do index_settings.update({k: input}) %} - show_changes: True
{% endfor %}
{% for k in addon_integration_keys %}
{% if k not in matched_integration_names and k in index_settings %}
{% do index_settings.pop(k) %}
{% endif %}
{% endfor %}
{{ data }}
{# Managed elasticsearch/defaults.yaml file for enabling 'Revert to default' via SOC UI for newly added config items #} {# Managed elasticsearch/defaults.yaml file for enabling 'Revert to default' via SOC UI for newly added config items #}
{% set es_defaults = '/opt/so/saltstack/default/salt/elasticsearch/defaults.yaml' %} {% set es_defaults = '/opt/so/saltstack/default/salt/elasticsearch/defaults.yaml' %}
{{ es_defaults }}: {{ es_defaults }}:
file.serialize: file.blockreplace:
- dataset: - marker_start: ' # START managed SOC integration defaults'
{% set data = salt['file.read'](es_defaults) | load_yaml %} - marker_end: ' # END managed SOC integration defaults'
{% set es = data.get('elasticsearch', {}) %} - content: {{ defaults_lines | join('\n') | tojson }}
{% set index_settings = es.get('index_settings', {}) %} - insert_after_match: '^ index_settings:$'
{% for k in matched_integration_names %} - append_if_not_found: False
{% set input = ADDON_INTEGRATION_DEFAULTS[k] %} - show_changes: True
{% do index_settings.update({k: input})%}
{% endfor %}
{% for k in addon_integration_keys %}
{% if k not in matched_integration_names and k in index_settings %}
{% do index_settings.pop(k) %}
{% endif %}
{% endfor %}
{{ data }}
{% endif %} {% endif %}
+5 -3
View File
@@ -31,11 +31,13 @@ sync_es_users:
- http: wait_for_kratos - http: wait_for_kratos
- file: so-user.lock # require so-user.lock file to be missing - file: so-user.lock # require so-user.lock file to be missing
# we dont want this added too early in setup, so we add the onlyif to verify 'startup_states: highstate' # we dont want this added too early in setup, so the onlyif gates on the
# is in the minion config. That line is added before the final highstate during setup # /opt/so/state/setup-complete marker. The marker is written by
# mark_setup_complete in setup/so-functions just before the final setup
# highstate (and by an upgrade-path state for systems set up under the old gate).
so-user_sync: so-user_sync:
cron.present: cron.present:
- user: root - user: root
- name: 'PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin /usr/sbin/so-user sync &>> /opt/so/log/soc/sync.log' - name: 'PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin /usr/sbin/so-user sync &>> /opt/so/log/soc/sync.log'
- identifier: so-user_sync - identifier: so-user_sync
- onlyif: "grep -x 'startup_states: highstate' /etc/salt/minion" - onlyif: "test -e /opt/so/state/setup-complete"
+117
View File
@@ -0,0 +1,117 @@
#!/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.
# Runs once per boot on managers (via so-boot-mine-update.service), before
# so-boot-highstate.service. Waits for the responsive minion set to settle, pushes
# mine.update, waits until every up minion has actually reported to the mine, then
# warms the master's per-minion pillar cache so the mine-backed node pillars (node
# IPs, ES/Redis/Logstash/hypervisor discovery -- some glob- and some pillar/grain-
# targeted) are complete before the boot highstate renders them. Otherwise a node
# that is up but not yet fully reported gets dropped from those pillars and torn
# out of the configs they build (e.g. so-elasticsearch ExtraHosts -> container recreate).
MAX_WAIT=${MINE_UPDATE_MAX_WAIT:-180} # hard backstop only
INTERVAL=10
STABLE_CHECKS=3 # up-count must hold steady this many polls
elapsed=0
prev=-1
stable=0
up=0
# Wait for the *reachable* minion set to settle rather than for every accepted
# key to report up: an operator may accept a minion's key and then intentionally
# power off that host, so requiring up >= accepted would never be satisfied and
# we'd always burn the full MAX_WAIT. Once the responsive count stops growing we
# stop waiting and run mine.update against whoever is up.
while [ "$elapsed" -lt "$MAX_WAIT" ]; do
up=$(/usr/bin/salt-run manage.up --out=json 2>/dev/null \
| python3 -c 'import sys,json; print(len(json.load(sys.stdin)))' 2>/dev/null)
up=${up:-0}
if [ "$up" -gt 0 ] && [ "$up" -eq "$prev" ]; then
stable=$((stable + 1))
[ "$stable" -ge "$STABLE_CHECKS" ] && break
else
stable=0
fi
prev=$up
sleep "$INTERVAL"
elapsed=$((elapsed + INTERVAL))
done
echo "so-boot-mine-update: ${up} minions up (settled after ${elapsed}s); running mine.update"
/usr/bin/salt '*' mine.update --out=txt
# A node that is up but has not yet re-reported network.ip_addrs to the mine is
# silently dropped from mine-backed pillars (elasticsearch:nodes, node_data, ...)
# when highstate recompiles them -- which e.g. removes it from so-elasticsearch
# ExtraHosts and forces a container recreate. After the broad mine.update above,
# wait until every up minion actually has network.ip_addrs in the mine, re-pushing
# mine.update to stragglers, before releasing the boot highstate. Bounded by the
# same MAX_WAIT backstop so a slow/down node never blocks boot indefinitely.
missing=""
while [ "$elapsed" -lt "$MAX_WAIT" ]; do
up_json=$(/usr/bin/salt-run manage.up --out=json 2>/dev/null)
mine_json=$(/usr/bin/salt-run mine.get '*' network.ip_addrs tgt_type=glob --out=json 2>/dev/null)
missing=$(printf '%s' "$up_json" | python3 -c '
import sys, json
up = set(json.load(sys.stdin) or [])
mine = {k for k, v in (json.loads(sys.argv[1]) or {}).items() if v}
print("\n".join(sorted(up - mine)))
' "$mine_json" 2>/dev/null)
if [ -z "$missing" ]; then
echo "so-boot-mine-update: mine complete for all up minions after ${elapsed}s"
break
fi
echo "so-boot-mine-update: mine missing up minion(s): $(echo $missing); re-running mine.update"
for m in $missing; do /usr/bin/salt "$m" mine.update --out=txt; done
sleep "$INTERVAL"
elapsed=$((elapsed + INTERVAL))
done
[ -n "$missing" ] && echo "so-boot-mine-update: WARNING ${MAX_WAIT}s backstop hit; up minion(s) still absent from mine: $(echo $missing); highstate may drop them from configs"
# The pillar/compound-targeted node pillars (elasticsearch:nodes, redis:nodes,
# logstash:nodes, hypervisor:nodes) resolve their target against the master's
# per-minion data cache (grains+pillar in .../minions/<id>/data.p), populated only
# when a minion's pillar is (re)compiled -- separately from the mine. A freshly
# booted node can be in the mine (glob/node_data sees it) yet absent from that
# cache, so it is dropped from those pillars and from the configs they build (e.g.
# so-elasticsearch ExtraHosts). Force a synchronous pillar refresh so the master
# caches every up node's pillar; refresh_pillar wait=True returns only once the
# pillar is recompiled (and thus cached for matching). Retry stragglers <= MAX_WAIT.
echo "so-boot-mine-update: warming master pillar cache for pillar/grain-targeted node pillars"
/usr/bin/salt '*' saltutil.refresh_pillar wait=True --out=txt
missing=""
while [ "$elapsed" -lt "$MAX_WAIT" ]; do
up_json=$(/usr/bin/salt-run manage.up --out=json 2>/dev/null)
cached_json=$(/usr/bin/salt-run cache.pillar tgt='*' --out=json 2>/dev/null)
missing=$(printf '%s' "$up_json" | python3 -c '
import sys, json
up = set(json.load(sys.stdin) or [])
cached = {k for k, v in (json.loads(sys.argv[1]) or {}).items() if v}
print("\n".join(sorted(up - cached)))
' "$cached_json" 2>/dev/null)
if [ -z "$missing" ]; then
echo "so-boot-mine-update: pillar cache warm for all up minions after ${elapsed}s"
break
fi
echo "so-boot-mine-update: pillar not yet cached for: $(echo $missing); refreshing"
for m in $missing; do /usr/bin/salt "$m" saltutil.refresh_pillar wait=True --out=txt; done
sleep "$INTERVAL"
elapsed=$((elapsed + INTERVAL))
done
[ -n "$missing" ] && echo "so-boot-mine-update: WARNING ${MAX_WAIT}s backstop hit; pillar not cached for: $(echo $missing); pillar-targeted pillars may drop them"
# Log what the mine-backed pillars render so the boot-time state is inspectable.
/usr/bin/salt-call saltutil.refresh_pillar >/dev/null 2>&1
sleep 2
for key in node_data elasticsearch:nodes; do
rendered=$(/usr/bin/salt-call --out=json pillar.get "$key" 2>/dev/null \
| python3 -c 'import sys,json; print(json.dumps(json.load(sys.stdin).get("local"), indent=2, sort_keys=True))' 2>/dev/null)
echo "so-boot-mine-update: ${key} rendered as:"
echo "${rendered:-null}"
done
exit 0
+122 -14
View File
@@ -188,13 +188,6 @@ airgap_update_dockers() {
fi fi
} }
backup_old_states_pillars() {
tar czf /nsm/backup/$(echo $INSTALLEDVERSION)_$(date +%Y%m%d-%H%M%S)_soup_default_states_pillars.tar.gz /opt/so/saltstack/default/
tar czf /nsm/backup/$(echo $INSTALLEDVERSION)_$(date +%Y%m%d-%H%M%S)_soup_local_states_pillars.tar.gz /opt/so/saltstack/local/
}
update_registry() { update_registry() {
docker stop so-dockerregistry docker stop so-dockerregistry
docker rm so-dockerregistry docker rm so-dockerregistry
@@ -372,6 +365,7 @@ preupgrade_changes() {
[[ "$INSTALLEDVERSION" =~ ^2\.4\.21[0-9]+$ ]] && up_to_3.0.0 [[ "$INSTALLEDVERSION" =~ ^2\.4\.21[0-9]+$ ]] && up_to_3.0.0
[[ "$INSTALLEDVERSION" == "3.0.0" ]] && up_to_3.1.0 [[ "$INSTALLEDVERSION" == "3.0.0" ]] && up_to_3.1.0
[[ "$INSTALLEDVERSION" == "3.1.0" ]] && up_to_3.2.0
true true
} }
@@ -381,6 +375,7 @@ postupgrade_changes() {
[[ "$POSTVERSION" =~ ^2\.4\.21[0-9]+$ ]] && post_to_3.0.0 [[ "$POSTVERSION" =~ ^2\.4\.21[0-9]+$ ]] && post_to_3.0.0
[[ "$POSTVERSION" == "3.0.0" ]] && post_to_3.1.0 [[ "$POSTVERSION" == "3.0.0" ]] && post_to_3.1.0
[[ "$POSTVERSION" == "3.1.0" ]] && post_to_3.2.0
true true
} }
@@ -533,6 +528,23 @@ elasticfleet_set_agent_logging_level_warn() {
done <<< "$policies_to_update" done <<< "$policies_to_update"
} }
update_logstash_pipeline_name() {
local original_pipeline_name="$1"
local new_pipeline_name="$2"
echo "Checking for conflicting logstash defined_pipelines pillar value."
local LOGSTASH_FILE=/opt/so/saltstack/local/pillar/logstash/soc_logstash.sls
local MINIONDIR=/opt/so/saltstack/local/pillar/minions
for pillar_file in "$LOGSTASH_FILE" "$MINIONDIR"/*.sls; do
[[ -f "$pillar_file" ]] || continue
if grep -q "$original_pipeline_name$" "$pillar_file"; then
echo "Found conflicting defined_pipeline pillar value in $pillar_file. Updating to use the new logstash pipeline name."
sed -i "s#$original_pipeline_name\$#$new_pipeline_name#g" "$pillar_file"
chown socore:socore "$pillar_file"
fi
done
}
check_transform_health_and_reauthorize() { check_transform_health_and_reauthorize() {
. /usr/sbin/so-elastic-fleet-common . /usr/sbin/so-elastic-fleet-common
@@ -676,6 +688,10 @@ rename_strelka_scan_lnk() {
rm -f "$TMP_VALUE_FILE" rm -f "$TMP_VALUE_FILE"
} }
fix_logstash_0013_lumberjack_pipeline_name() {
update_logstash_pipeline_name "so/0013_input_lumberjack_fleet.conf" "so/0013_input_lumberjack_fleet.conf.jinja"
}
up_to_3.1.0() { up_to_3.1.0() {
ensure_postgres_local_pillar ensure_postgres_local_pillar
ensure_postgres_secret ensure_postgres_secret
@@ -684,6 +700,7 @@ up_to_3.1.0() {
# Clear existing component template state file. # Clear existing component template state file.
rm -f /opt/so/state/esfleet_component_templates.json rm -f /opt/so/state/esfleet_component_templates.json
rename_strelka_scan_lnk rename_strelka_scan_lnk
fix_logstash_0013_lumberjack_pipeline_name
INSTALLEDVERSION=3.1.0 INSTALLEDVERSION=3.1.0
} }
@@ -720,6 +737,96 @@ post_to_3.1.0() {
### 3.1.0 End ### ### 3.1.0 End ###
### 3.2.0 Scripts ###
bootstrap_so_soc_database() {
# init-db.sh is mounted into so-postgres at /docker-entrypoint-initdb.d/init-db.sh
# and runs automatically only on a fresh data directory. Hosts upgrading from
# 3.1.0 already have /nsm/postgres populated, so the so_soc bootstrap block
# added in 3.2 never fires. Re-run the script explicitly; it's idempotent.
echo "Bootstrapping so_soc database via init-db.sh."
# The postgres image has no USER directive, so `docker exec` defaults to
# root, and the container env intentionally omits POSTGRES_USER (the upstream
# entrypoint defaults it transiently during first-init only). Recreate both
# so psql inside init-db.sh resolves the connect user correctly.
local exec_cmd="docker exec -u postgres -e POSTGRES_USER=postgres so-postgres bash /docker-entrypoint-initdb.d/init-db.sh"
if ! /usr/sbin/so-postgres-wait; then
FINAL_MESSAGE_QUEUE+=("WARNING: so-postgres was not ready during the 3.2.0 upgrade; the so_soc database may not have been bootstrapped. Re-run manually: $exec_cmd")
return 0
fi
if ! $exec_cmd; then
FINAL_MESSAGE_QUEUE+=("WARNING: init-db.sh failed inside so-postgres during the 3.2.0 upgrade; the so_soc database may not have been bootstrapped. Re-run manually: $exec_cmd")
return 0
fi
echo "so_soc bootstrap complete."
}
# Existing grids should keep ILM unless an admin explicitly opts in to DLM.
pin_elasticsearch_data_retention_method() {
local elasticsearch_file=/opt/so/saltstack/local/pillar/elasticsearch/soc_elasticsearch.sls
mkdir -p "$(dirname "$elasticsearch_file")"
[[ -f "$elasticsearch_file" ]] || touch "$elasticsearch_file"
if so-yaml.py get -r "$elasticsearch_file" elasticsearch.data_retention_method >/dev/null 2>&1; then
echo "elasticsearch.data_retention_method already set; leaving as-is."
return 0
fi
echo "Pinning existing grid to ILM data retention."
so-yaml.py add "$elasticsearch_file" elasticsearch.data_retention_method ILM
chown socore:socore "$elasticsearch_file"
}
# Addes auto_expand_replicas setting to .kibana_streams index template
#
# In Kibana 9.3.3 the auto_expand_replicas setting was not added to the .kibana_streams index template. Causing single node deployments to be stuck in yellow state (unable to assign replica). Here we update the template in place using the so_kibana system user (system managed index template) to include the auto_expand_replicas setting
#
# Reference: https://github.com/elastic/kibana/issues/263048
kibana_backport_streams_index_template() {
local current_template updated_template
current_template=$(so-elasticsearch-query "_index_template/.kibana_streams" --retry 3 --retry-delay 5 --fail)
if [[ -z "$current_template" ]]; then
echo "Index template .kibana_streams does not exist, skipping backport."
return 0
fi
updated_template=$(jq '.index_templates[0].index_template | .template.settings += {"index.auto_expand_replicas": "0-1"} | del(.created_date_millis, .modified_date_millis)' <<< "$current_template")
if ! kibana_user_pass=$(/usr/sbin/so-yaml.py get -r /opt/so/saltstack/local/pillar/elasticsearch/auth.sls elasticsearch.auth.users.so_kibana_user.pass); then
echo "Unable to retrieve so_kibana_user password, skipping .kibana_streams index template backport."
return 0
fi
if ! so-elasticsearch-query "_index_template/.kibana_streams" -XPUT -d "$updated_template" -u "so_kibana:$kibana_user_pass" --retry 3 --retry-delay 5 --fail; then
echo "Unable to automatically update .kibana_streams index template"
return 0
fi
}
up_to_3.2.0() {
fix_logstash_0013_lumberjack_pipeline_name
pin_elasticsearch_data_retention_method
INSTALLEDVERSION=3.2.0
}
post_to_3.2.0() {
bootstrap_so_soc_database
# Including agent regen script here since it was missed in post_to_3.1.0
echo "Regenerating Elastic Agent Installers"
/sbin/so-elastic-agent-gen-installers
kibana_backport_streams_index_template
POSTVERSION=3.2.0
}
### 3.2.0 End ###
repo_sync() { repo_sync() {
echo "Sync the local repo." echo "Sync the local repo."
@@ -1139,7 +1246,7 @@ verify_es_version_compatibility() {
while IFS= read -r heavynode_minion; do while IFS= read -r heavynode_minion; do
[[ -z "$heavynode_minion" ]] && continue [[ -z "$heavynode_minion" ]] && continue
if ! echo "$HEAVYNODE_ES_VERSIONS" | jq -e --arg minion "$heavynode_minion" 'has($minion)' > /dev/null; then if ! echo "$HEAVYNODE_ES_VERSIONS" | jq -se --arg minion "$heavynode_minion" 'add | has($minion)' > /dev/null; then
echo "Heavynode $heavynode_minion did not report an Elasticsearch version. It may be offline or still upgrading." echo "Heavynode $heavynode_minion did not report an Elasticsearch version. It may be offline or still upgrading."
all_heavynodes_compatible=false all_heavynodes_compatible=false
fi fi
@@ -1578,13 +1685,13 @@ main() {
echo "Verifying we have the latest soup script." echo "Verifying we have the latest soup script."
verify_latest_update_script verify_latest_update_script
echo "Verifying Elasticsearch version compatibility across the grid before upgrading."
verify_es_version_compatibility
echo "Let's see if we need to update Security Onion." echo "Let's see if we need to update Security Onion."
upgrade_check upgrade_check
upgrade_space upgrade_space
echo "Verifying Elasticsearch version compatibility across the grid before upgrading."
verify_es_version_compatibility
echo "Checking for Salt Master and Minion updates." echo "Checking for Salt Master and Minion updates."
upgrade_check_salt upgrade_check_salt
set -e set -e
@@ -1604,7 +1711,8 @@ main() {
echo "Applying $HOTFIXVERSION hotfix" echo "Applying $HOTFIXVERSION hotfix"
# since we don't run the backup.config_backup state on import we wont snapshot previous version states and pillars # since we don't run the backup.config_backup state on import we wont snapshot previous version states and pillars
if [[ ! "$MINION_ROLE" == "import" ]]; then if [[ ! "$MINION_ROLE" == "import" ]]; then
backup_old_states_pillars echo "Running so-config-backup script."
/sbin/so-config-backup
fi fi
copy_new_files copy_new_files
create_local_directories "/opt/so/saltstack/default" create_local_directories "/opt/so/saltstack/default"
@@ -1660,8 +1768,8 @@ main() {
# since we don't run the backup.config_backup state on import we wont snapshot previous version states and pillars # since we don't run the backup.config_backup state on import we wont snapshot previous version states and pillars
if [[ ! "$MINION_ROLE" == "import" ]]; then if [[ ! "$MINION_ROLE" == "import" ]]; then
echo "" echo ""
echo "Creating snapshots of default and local Salt states and pillars and saving to /nsm/backup/" echo "Running so-config-backup script."
backup_old_states_pillars /sbin/so-config-backup
fi fi
echo "" echo ""
+1
View File
@@ -17,6 +17,7 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E
END IF; END IF;
END END
\$\$; \$\$;
GRANT ALL ON SCHEMA public TO "$SO_POSTGRES_USER";
GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB" TO "$SO_POSTGRES_USER"; GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB" TO "$SO_POSTGRES_USER";
-- Lock the SOC database down at the connect layer; PUBLIC gets CONNECT -- Lock the SOC database down at the connect layer; PUBLIC gets CONNECT
-- by default, which would let per-minion telegraf roles open sessions -- by default, which would let per-minion telegraf roles open sessions
+2 -16
View File
@@ -18,26 +18,12 @@ include:
{% set TG_OUT = TELEGRAFMERGED.output | upper %} {% set TG_OUT = TELEGRAFMERGED.output | upper %}
{% if TG_OUT in ['POSTGRES', 'BOTH'] %} {% if TG_OUT in ['POSTGRES', 'BOTH'] %}
# docker_container.running returns as soon as the container starts, but on
# first-init docker-entrypoint.sh starts a temporary postgres with
# `listen_addresses=''` to run /docker-entrypoint-initdb.d scripts, then
# shuts it down before exec'ing the real CMD. A default pg_isready check
# (Unix socket) passes during that ephemeral phase and races the shutdown
# with "the database system is shutting down". Checking TCP readiness on
# 127.0.0.1 only succeeds after the final postgres binds the port.
postgres_wait_ready: postgres_wait_ready:
cmd.run: cmd.run:
- name: | - name: /usr/sbin/so-postgres-wait
for i in $(seq 1 60); do
if docker exec so-postgres pg_isready -h 127.0.0.1 -U postgres -q 2>/dev/null; then
exit 0
fi
sleep 2
done
echo "so-postgres did not accept TCP connections within 120s" >&2
exit 1
- require: - require:
- docker_container: so-postgres - docker_container: so-postgres
- file: postgres_sbin
# Ensure the shared Telegraf database exists. init-db.sh only runs on a # Ensure the shared Telegraf database exists. init-db.sh only runs on a
# fresh data dir, so hosts upgraded onto an existing /nsm/postgres volume # fresh data dir, so hosts upgraded onto an existing /nsm/postgres volume
+32
View File
@@ -0,0 +1,32 @@
#!/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.
# Wait for the so-postgres container to accept TCP connections.
#
# docker_container.running returns as soon as the container starts, but on
# first-init docker-entrypoint.sh starts a temporary postgres with
# `listen_addresses=''` to run /docker-entrypoint-initdb.d scripts, then
# shuts it down before exec'ing the real CMD. A default pg_isready check
# (Unix socket) passes during that ephemeral phase and races the shutdown
# with "the database system is shutting down". Checking TCP readiness on
# 127.0.0.1 only succeeds after the final postgres binds the port.
#
# Usage: so-postgres-wait [iterations] [sleep_seconds]
# Default: 60 iterations, 2s sleep (~120s total).
ITERATIONS=${1:-60}
SLEEP_SECONDS=${2:-2}
for i in $(seq 1 "$ITERATIONS"); do
if docker exec so-postgres pg_isready -h 127.0.0.1 -U postgres -q 2>/dev/null; then
exit 0
fi
sleep "$SLEEP_SECONDS"
done
echo "so-postgres did not accept TCP connections within $((ITERATIONS * SLEEP_SECONDS))s" >&2
exit 1
+1
View File
@@ -14,6 +14,7 @@
include: include:
- salt.minion - salt.minion
- salt.master.boot_mine_update
{% if 'vrt' in salt['pillar.get']('features', []) %} {% if 'vrt' in salt['pillar.get']('features', []) %}
- salt.cloud - salt.cloud
- salt.cloud.reactor_config_hypervisor - salt.cloud.reactor_config_hypervisor
+29
View File
@@ -0,0 +1,29 @@
# 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.
# Manages /etc/systemd/system/so-boot-mine-update.service, a manager-only
# Type=oneshot unit that pushes `salt '*' mine.update` once per boot, ordered
# before so-boot-highstate.service so mine-backed pillars (node IPs, ES/Redis/
# Logstash discovery) are fresh before the boot highstate renders them.
include:
- systemd.reload
so_boot_mine_update_unit_file:
file.managed:
- name: /etc/systemd/system/so-boot-mine-update.service
- source: salt://salt/service/so-boot-mine-update.service
- onchanges_in:
- module: systemd_reload
# Only enable once setup is complete. Until then the gate file is missing and
# the unit's own ConditionPathExists would no-op it anyway.
so_boot_mine_update_service:
service.enabled:
- name: so-boot-mine-update.service
- onlyif: test -e /opt/so/state/setup-complete
- require:
- file: so_boot_mine_update_unit_file
- module: systemd_reload
+31
View File
@@ -0,0 +1,31 @@
# 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.
# Manages /etc/systemd/system/so-boot-highstate.service, a Type=oneshot
# RemainAfterExit=yes unit that runs `salt-call state.highstate` exactly once
# per system boot. Replaces the legacy `startup_states: highstate` minion
# config, which fired on every salt-minion service restart (causing a redundant
# highstate whenever a highstate itself restarted salt-minion).
include:
- systemd.reload
so_boot_highstate_unit_file:
file.managed:
- name: /etc/systemd/system/so-boot-highstate.service
- source: salt://salt/service/so-boot-highstate.service
- onchanges_in:
- module: systemd_reload
# Only enable once setup is complete. Until then the gate file is missing and
# the unit's own ConditionPathExists would no-op it anyway -- this just keeps
# `systemctl is-enabled` honest for the sync_es_users gate.
so_boot_highstate_service:
service.enabled:
- name: so-boot-highstate.service
- onlyif: test -e /opt/so/state/setup-complete
- require:
- file: so_boot_highstate_unit_file
- module: systemd_reload
+27 -4
View File
@@ -17,6 +17,7 @@ include:
- repo.client - repo.client
- salt.mine_functions - salt.mine_functions
- salt.minion.service_file - salt.minion.service_file
- salt.minion.boot_highstate
{% if GLOBALS.is_manager %} {% if GLOBALS.is_manager %}
- ca.signing_policy - ca.signing_policy
{% endif %} {% endif %}
@@ -80,11 +81,33 @@ set_log_levels:
- "log_level: info" - "log_level: info"
- "log_level_logfile: info" - "log_level_logfile: info"
enable_startup_states: # startup_states: highstate caused a full highstate to run on every
file.uncomment: # salt-minion service start, including the restart triggered when a highstate
# itself modified the minion config (beacons, mine, unit file). Replaced by
# so-boot-highstate.service (managed in salt.minion.boot_highstate), which
# runs once per system boot only. Strip the line from /etc/salt/minion on
# upgrade; both the commented and uncommented forms historically existed.
remove_startup_states:
file.line:
- name: /etc/salt/minion - name: /etc/salt/minion
- regex: '^startup_states: highstate$' - match: 'startup_states: highstate'
- unless: pgrep so-setup - mode: delete
# Upgrade-path bridge: systems that already passed setup under the old gate
# (`grep -x 'startup_states: highstate' /etc/salt/minion`) get a /opt/so/state/setup-complete
# marker so so-boot-highstate.service can be enabled and the so-user_sync cron
# in sync_es_users.sls keeps installing. Setup-in-progress systems instead get
# the marker from `mark_setup_complete` in setup/so-functions at the right
# moment. `replace: false` means we never overwrite a marker once written.
mark_setup_complete_for_upgrades:
file.managed:
- name: /opt/so/state/setup-complete
- replace: false
- makedirs: True
- onlyif: "grep -qx 'startup_states: highstate' /etc/salt/minion"
- require_in:
- file: remove_startup_states
- service: so_boot_highstate_service
{% endif %} {% endif %}
@@ -0,0 +1,14 @@
[Unit]
Description=Security Onion boot-time highstate (runs once per boot)
After=salt-minion.service network-online.target docker.service
Wants=network-online.target docker.service
Requires=salt-minion.service
ConditionPathExists=/opt/so/state/setup-complete
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/salt-call state.highstate -l info queue=True
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,15 @@
[Unit]
Description=Security Onion boot-time grid mine.update (managers, runs once per boot before highstate)
After=salt-master.service salt-minion.service network-online.target
Wants=network-online.target
Requires=salt-master.service salt-minion.service
Before=so-boot-highstate.service
ConditionPathExists=/opt/so/state/setup-complete
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/so-boot-mine-update
[Install]
WantedBy=multi-user.target
-5
View File
@@ -8,11 +8,6 @@ set_role_grain:
- name: role - name: role
- value: so-{{ grains.id.split("_") | last }} - value: so-{{ grains.id.split("_") | last }}
set_highstate:
file.append:
- name: /etc/salt/minion
- text: 'startup_states: highstate'
enable_salt_minion: enable_salt_minion:
service.enabled: service.enabled:
- name: salt-minion - name: salt-minion
+10
View File
@@ -1519,6 +1519,16 @@ soc:
serviceAccountJSON: "" serviceAccountJSON: ""
serviceAccountLocation: "" serviceAccountLocation: ""
healthTimeoutSeconds: 5 healthTimeoutSeconds: 5
onionconfig:
saltstackDir: /opt/so/saltstack
bypassEnabled: false
postgres:
host: ""
port: 5432
sslMode: "allow"
database: securityonion
user: ""
password: ""
salt: salt:
queueDir: /opt/sensoroni/queue queueDir: /opt/sensoroni/queue
timeoutMs: 45000 timeoutMs: 45000
+8
View File
@@ -16,6 +16,14 @@
{% do SOCMERGED.config.server.update({'additionalCA': MANAGERMERGED.additionalCA}) %} {% do SOCMERGED.config.server.update({'additionalCA': MANAGERMERGED.additionalCA}) %}
{% do SOCMERGED.config.server.update({'insecureSkipVerify': MANAGERMERGED.insecureSkipVerify}) %} {% do SOCMERGED.config.server.update({'insecureSkipVerify': MANAGERMERGED.insecureSkipVerify}) %}
{% if not SOCMERGED.config.server.modules.postgres.host %}
{% do SOCMERGED.config.server.modules.postgres.update({'host': GLOBALS.manager}) %}
{% endif %}
{% if not SOCMERGED.config.server.modules.postgres.password %}
{% do SOCMERGED.config.server.modules.postgres.update({'password': salt['pillar.get']('postgres:auth:users:so_postgres_user:pass', '')}) %}
{% do SOCMERGED.config.server.modules.postgres.update({'user': salt['pillar.get']('postgres:auth:users:so_postgres_user:user', 'so_postgres')}) %}
{% endif %}
{# if SOCMERGED.config.server.modules.cases == httpcase details come from the soc pillar #} {# if SOCMERGED.config.server.modules.cases == httpcase details come from the soc pillar #}
{% if SOCMERGED.config.server.modules.cases != 'soc' %} {% if SOCMERGED.config.server.modules.cases != 'soc' %}
{% do SOCMERGED.config.server.modules.elastic.update({'casesEnabled': false}) %} {% do SOCMERGED.config.server.modules.elastic.update({'casesEnabled': false}) %}
+37
View File
@@ -453,6 +453,42 @@ soc:
description: Duration (in milliseconds) that must elapse after a grid node fails to check-in before the node will be marked offline (fault). description: Duration (in milliseconds) that must elapse after a grid node fails to check-in before the node will be marked offline (fault).
global: True global: True
advanced: True advanced: True
onionconfig:
saltstackDir:
description: Root directory containing the SaltStack tree that SOC reads and writes configuration from. Should not be changed under normal circumstances.
global: True
advanced: True
bypassEnabled:
description: When enabled, errors encountered while reading the SaltStack pillar tree (missing files, unreadable directories, etc.) are logged but do not prevent SOC from starting or serving settings. Intended for advanced troubleshooting and recovery scenarios when the pillar tree is partially unreadable.
global: True
advanced: True
forcedType: bool
postgres:
host:
description: Hostname or IP address of the PostgreSQL server used by SOC. Defaults to the manager hostname.
global: True
advanced: True
port:
description: Port of the PostgreSQL server used by SOC.
global: True
advanced: True
sslMode:
description: "Use encrypted connections to the PostgreSQL server. Must be one of the following values: disable, allow, prefer, require, verify-ca, verify-full. Defaults to allow."
global: True
advanced: True
database:
description: Database used by SOC to authenticate to the PostgreSQL server.
global: True
advanced: True
user:
description: Username used by SOC to authenticate to the PostgreSQL server.
global: True
advanced: True
password:
description: Password used by SOC to authenticate to the PostgreSQL server.
global: True
sensitive: True
advanced: True
salt: salt:
longRelayTimeoutMs: longRelayTimeoutMs:
description: Duration (in milliseconds) to wait for a response from the Salt API when executing tasks known for being long running before giving up and showing an error on the SOC UI. description: Duration (in milliseconds) to wait for a response from the Salt API when executing tasks known for being long running before giving up and showing an error on the SOC UI.
@@ -818,6 +854,7 @@ soc:
description: List of available external tools visible in the SOC UI. Each tool is defined in JSON object notation, and must include the "name" key and "link" key, where the link is the tool's URL. description: List of available external tools visible in the SOC UI. Each tool is defined in JSON object notation, and must include the "name" key and "link" key, where the link is the tool's URL.
global: True global: True
advanced: True advanced: True
multiline: True
forcedType: "[]{}" forcedType: "[]{}"
exportNodeId: exportNodeId:
description: The node ID on which export jobs will be executed. description: The node ID on which export jobs will be executed.
+11 -6
View File
@@ -539,16 +539,19 @@ configure_minion() {
" x509_v2: true"\ " x509_v2: true"\
"log_level: info"\ "log_level: info"\
"log_level_logfile: info"\ "log_level_logfile: info"\
"log_file: /opt/so/log/salt/minion"\ "log_file: /opt/so/log/salt/minion" >> "$minion_config"
"#startup_states: highstate" >> "$minion_config"
} }
checkin_at_boot() { mark_setup_complete() {
local minion_config=/etc/salt/minion # Writes the setup-complete marker. Salt's so-boot-highstate.service
# (boot-time oneshot) and the so-user_sync cron gate in
# salt/manager/sync_es_users.sls both key off this file.
local marker=/opt/so/state/setup-complete
info "Enabling checkin at boot" info "Marking setup as complete"
sed -i 's/#startup_states: highstate/startup_states: highstate/' "$minion_config" mkdir -p "$(dirname "$marker")"
touch "$marker"
} }
check_requirements() { check_requirements() {
@@ -977,6 +980,8 @@ docker_seed_registry() {
docker_seed_update_percent=25 docker_seed_update_percent=25
update_docker_containers 'netinstall' '' 'docker_seed_update' '/dev/stdout' 2>&1 | tee -a "$setup_log" update_docker_containers 'netinstall' '' 'docker_seed_update' '/dev/stdout' 2>&1 | tee -a "$setup_log"
# Use pipe exit status of 'update_docker_containers' for return code
return ${PIPESTATUS[0]}
fi fi
} }
+7 -2
View File
@@ -223,6 +223,8 @@ if [ -n "$test_profile" ]; then
WEBPASSWD1=0n10nus3r WEBPASSWD1=0n10nus3r
WEBPASSWD2=0n10nus3r WEBPASSWD2=0n10nus3r
NODE_DESCRIPTION="${HOSTNAME} - ${install_type} - ${MSRVIP_OFFSET}" NODE_DESCRIPTION="${HOSTNAME} - ${install_type} - ${MSRVIP_OFFSET}"
# opt out of telemetry for automated testing
telemetry=1
update_sudoers_for_testing update_sudoers_for_testing
fi fi
@@ -767,7 +769,10 @@ if ! [[ -f $install_opt_file ]]; then
title "Applying the registry state" title "Applying the registry state"
logCmd "salt-call state.apply -l info registry" logCmd "salt-call state.apply -l info registry"
title "Seeding the docker registry" title "Seeding the docker registry"
docker_seed_registry if ! docker_seed_registry; then
error "Failed to seed the docker registry"
fail_setup
fi
title "Applying the manager state" title "Applying the manager state"
logCmd "salt-call state.apply -l info manager" logCmd "salt-call state.apply -l info manager"
logCmd "salt-call state.apply influxdb -l info" logCmd "salt-call state.apply influxdb -l info"
@@ -792,7 +797,7 @@ if ! [[ -f $install_opt_file ]]; then
error "Failed to run so-elastic-fleet-setup" error "Failed to run so-elastic-fleet-setup"
fail_setup fail_setup
fi fi
checkin_at_boot mark_setup_complete
set_initial_firewall_access set_initial_firewall_access
initialize_elasticsearch_indices "so-case so-casehistory so-assistant-session so-assistant-chat" initialize_elasticsearch_indices "so-case so-casehistory so-assistant-session so-assistant-chat"
# run a final highstate before enabling scheduled highstates. # run a final highstate before enabling scheduled highstates.
Binary file not shown.