Skip to content

Commit 945d04a

Browse files
authored
Merge pull request #13391 from Security-Onion-Solutions/2.4/dev
2.4.90
2 parents c2d43e5 + 658db27 commit 945d04a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+659
-416
lines changed

DOWNLOAD_AND_VERIFY_ISO.md

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
### 2.4.80-20240624 ISO image released on 2024/06/25
1+
### 2.4.90-20240729 ISO image released on 2024/07/29
22

33

44
### Download and Verify
55

6-
2.4.80-20240624 ISO image:
7-
https://download.securityonion.net/file/securityonion/securityonion-2.4.80-20240624.iso
6+
2.4.90-20240729 ISO image:
7+
https://download.securityonion.net/file/securityonion/securityonion-2.4.90-20240729.iso
88

9-
MD5: 139F9762E926F9CB3C4A9528A3752C31
10-
SHA1: BC6CA2C5F4ABC1A04E83A5CF8FFA6A53B1583CC9
11-
SHA256: 70E90845C84FFA30AD6CF21504634F57C273E7996CA72F7250428DDBAAC5B1BD
9+
MD5: 9A7714F5922EE555F08675D25E6237D5
10+
SHA1: D3B331452627DB716906BA9F3922574DFA3852DC
11+
SHA256: 5B0CE32543944DBC50C4E906857384211E1BE83EF409619778F18FC62017E0E0
1212

1313
Signature for ISO image:
14-
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.80-20240624.iso.sig
14+
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.90-20240729.iso.sig
1515

1616
Signing key:
1717
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS
@@ -25,22 +25,22 @@ wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.
2525

2626
Download the signature file for the ISO:
2727
```
28-
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.80-20240624.iso.sig
28+
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.90-20240729.iso.sig
2929
```
3030

3131
Download the ISO image:
3232
```
33-
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.80-20240624.iso
33+
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.90-20240729.iso
3434
```
3535

3636
Verify the downloaded ISO image using the signature file:
3737
```
38-
gpg --verify securityonion-2.4.80-20240624.iso.sig securityonion-2.4.80-20240624.iso
38+
gpg --verify securityonion-2.4.90-20240729.iso.sig securityonion-2.4.90-20240729.iso
3939
```
4040

4141
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
4242
```
43-
gpg: Signature made Mon 24 Jun 2024 02:42:03 PM EDT using RSA key ID FE507013
43+
gpg: Signature made Thu 25 Jul 2024 06:51:11 PM EDT using RSA key ID FE507013
4444
gpg: Good signature from "Security Onion Solutions, LLC <[email protected]>"
4545
gpg: WARNING: This key is not certified with a trusted signature!
4646
gpg: There is no indication that the signature belongs to the owner.

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.4.80
1+
2.4.90

pillar/elasticsearch/nodes.sls

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{% set node_types = {} %}
2+
{% for minionid, ip in salt.saltutil.runner(
3+
'mine.get',
4+
tgt='elasticsearch:enabled:true',
5+
fun='network.ip_addrs',
6+
tgt_type='pillar') | dictsort()
7+
%}
8+
9+
# only add a node to the pillar if it returned an ip from the mine
10+
{% if ip | length > 0%}
11+
{% set hostname = minionid.split('_') | first %}
12+
{% set node_type = minionid.split('_') | last %}
13+
{% if node_type not in node_types.keys() %}
14+
{% do node_types.update({node_type: {hostname: ip[0]}}) %}
15+
{% else %}
16+
{% if hostname not in node_types[node_type] %}
17+
{% do node_types[node_type].update({hostname: ip[0]}) %}
18+
{% else %}
19+
{% do node_types[node_type][hostname].update(ip[0]) %}
20+
{% endif %}
21+
{% endif %}
22+
{% endif %}
23+
{% endfor %}
24+
25+
26+
elasticsearch:
27+
nodes:
28+
{% for node_type, values in node_types.items() %}
29+
{{node_type}}:
30+
{% for hostname, ip in values.items() %}
31+
{{hostname}}:
32+
ip: {{ip}}
33+
{% endfor %}
34+
{% endfor %}

pillar/logstash/nodes.sls

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
{% set node_types = {} %}
2-
{% set cached_grains = salt.saltutil.runner('cache.grains', tgt='*') %}
32
{% for minionid, ip in salt.saltutil.runner(
43
'mine.get',
5-
tgt='G@role:so-manager or G@role:so-managersearch or G@role:so-standalone or G@role:so-searchnode or G@role:so-heavynode or G@role:so-receiver or G@role:so-fleet ',
4+
tgt='logstash:enabled:true',
65
fun='network.ip_addrs',
7-
tgt_type='compound') | dictsort()
6+
tgt_type='pillar') | dictsort()
87
%}
98

109
# only add a node to the pillar if it returned an ip from the mine
1110
{% if ip | length > 0%}
12-
{% set hostname = cached_grains[minionid]['host'] %}
13-
{% set node_type = minionid.split('_')[1] %}
11+
{% set hostname = minionid.split('_') | first %}
12+
{% set node_type = minionid.split('_') | last %}
1413
{% if node_type not in node_types.keys() %}
1514
{% do node_types.update({node_type: {hostname: ip[0]}}) %}
1615
{% else %}

pillar/redis/nodes.sls

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{% set node_types = {} %}
2+
{% for minionid, ip in salt.saltutil.runner(
3+
'mine.get',
4+
tgt='redis:enabled:true',
5+
fun='network.ip_addrs',
6+
tgt_type='pillar') | dictsort()
7+
%}
8+
9+
# only add a node to the pillar if it returned an ip from the mine
10+
{% if ip | length > 0%}
11+
{% set hostname = minionid.split('_') | first %}
12+
{% set node_type = minionid.split('_') | last %}
13+
{% if node_type not in node_types.keys() %}
14+
{% do node_types.update({node_type: {hostname: ip[0]}}) %}
15+
{% else %}
16+
{% if hostname not in node_types[node_type] %}
17+
{% do node_types[node_type].update({hostname: ip[0]}) %}
18+
{% else %}
19+
{% do node_types[node_type][hostname].update(ip[0]) %}
20+
{% endif %}
21+
{% endif %}
22+
{% endif %}
23+
{% endfor %}
24+
25+
26+
redis:
27+
nodes:
28+
{% for node_type, values in node_types.items() %}
29+
{{node_type}}:
30+
{% for hostname, ip in values.items() %}
31+
{{hostname}}:
32+
ip: {{ip}}
33+
{% endfor %}
34+
{% endfor %}

pillar/top.sls

+8
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@ base:
4747
- kibana.adv_kibana
4848
- kratos.soc_kratos
4949
- kratos.adv_kratos
50+
- redis.nodes
5051
- redis.soc_redis
5152
- redis.adv_redis
5253
- influxdb.soc_influxdb
5354
- influxdb.adv_influxdb
55+
- elasticsearch.nodes
5456
- elasticsearch.soc_elasticsearch
5557
- elasticsearch.adv_elasticsearch
5658
- elasticfleet.soc_elasticfleet
@@ -147,10 +149,12 @@ base:
147149
- idstools.adv_idstools
148150
- kratos.soc_kratos
149151
- kratos.adv_kratos
152+
- redis.nodes
150153
- redis.soc_redis
151154
- redis.adv_redis
152155
- influxdb.soc_influxdb
153156
- influxdb.adv_influxdb
157+
- elasticsearch.nodes
154158
- elasticsearch.soc_elasticsearch
155159
- elasticsearch.adv_elasticsearch
156160
- elasticfleet.soc_elasticfleet
@@ -215,18 +219,22 @@ base:
215219
- logstash.nodes
216220
- logstash.soc_logstash
217221
- logstash.adv_logstash
222+
- elasticsearch.nodes
218223
- elasticsearch.soc_elasticsearch
219224
- elasticsearch.adv_elasticsearch
220225
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
221226
- elasticsearch.auth
222227
{% endif %}
228+
- redis.nodes
223229
- redis.soc_redis
224230
- redis.adv_redis
225231
- minions.{{ grains.id }}
226232
- minions.adv_{{ grains.id }}
227233
- stig.soc_stig
228234
- soc.license
229235
- kafka.nodes
236+
- kafka.soc_kafka
237+
- kafka.adv_kafka
230238

231239
'*_receiver':
232240
- logstash.nodes

salt/allowed_states.map.jinja

+3-2
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@
136136
'firewall',
137137
'schedule',
138138
'docker_clean',
139-
'stig'
139+
'stig',
140+
'kafka.ca',
141+
'kafka.ssl'
140142
],
141143
'so-standalone': [
142144
'salt.master',
@@ -195,7 +197,6 @@
195197
'schedule',
196198
'docker_clean',
197199
'kafka',
198-
'elasticsearch.ca',
199200
'stig'
200201
],
201202
'so-desktop': [

salt/common/tools/sbin/so-log-check

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ exclude_log "mysqld.log" # MySQL is removed as of 2.4.70, logs may still be on
241241
exclude_log "soctopus.log" # Soctopus is removed as of 2.4.70, logs may still be on disk
242242
exclude_log "agentstatus.log" # ignore this log since it tracks agents in error state
243243
exclude_log "detections_runtime-status_yara.log" # temporarily ignore this log until Detections is more stable
244+
exclude_log "/nsm/kafka/data/" # ignore Kafka data directory from log check.
244245

245246
for log_file in $(cat /tmp/log_check_files); do
246247
status "Checking log file $log_file"

salt/elasticsearch/config.map.jinja

+21-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
1+
{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
2+
or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
3+
https://securityonion.net/license; you may not use this file except in compliance with the
4+
Elastic License 2.0. #}
5+
16
{% from 'vars/globals.map.jinja' import GLOBALS %}
27
{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS with context %}
38

49
{% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %}
510

6-
{# ES_LOGSTASH_NODES is the same as LOGSTASH_NODES from logstash/map.jinja but heavynodes and fleet nodes are removed #}
7-
{% set ES_LOGSTASH_NODES = [] %}
8-
{% set node_data = salt['pillar.get']('logstash:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %}
11+
{# this is a list of dicts containing hostname:ip for elasticsearch nodes that need to know about each other for cluster #}
12+
{% set ELASTICSEARCH_SEED_HOSTS = [] %}
13+
{% set node_data = salt['pillar.get']('elasticsearch:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %}
914
{% for node_type, node_details in node_data.items() | sort %}
10-
{% if node_type not in ['heavynode', 'fleet'] %}
15+
{% if node_type != 'heavynode' %}
1116
{% for hostname in node_data[node_type].keys() %}
12-
{% do ES_LOGSTASH_NODES.append({hostname:node_details[hostname].ip}) %}
17+
{% do ELASTICSEARCH_SEED_HOSTS.append({hostname:node_details[hostname].ip}) %}
1318
{% endfor %}
1419
{% endif %}
1520
{% endfor %}
1621

22+
{# this is a list of dicts containing hostname:ip of all nodes running elasticsearch #}
23+
{% set ELASTICSEARCH_NODES = [] %}
24+
{% set node_data = salt['pillar.get']('elasticsearch:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %}
25+
{% for node_type, node_details in node_data.items() %}
26+
{% for hostname in node_data[node_type].keys() %}
27+
{% do ELASTICSEARCH_NODES.append({hostname:node_details[hostname].ip}) %}
28+
{% endfor %}
29+
{% endfor %}
30+
1731
{% if grains.id.split('_') | last in ['manager','managersearch','standalone'] %}
18-
{% if ES_LOGSTASH_NODES | length > 1 %}
32+
{% if ELASTICSEARCH_SEED_HOSTS | length > 1 %}
1933
{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.update({'discovery': {'seed_hosts': []}}) %}
20-
{% for NODE in ES_LOGSTASH_NODES %}
34+
{% for NODE in ELASTICSEARCH_SEED_HOSTS %}
2135
{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.discovery.seed_hosts.append(NODE.keys()|first) %}
2236
{% endfor %}
2337
{% endif %}

salt/elasticsearch/defaults.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ elasticsearch:
296296
limit: 1500
297297
number_of_replicas: 0
298298
number_of_shards: 1
299-
refresh_interval: 30s
299+
refresh_interval: 1s
300300
sort:
301301
field: '@timestamp'
302302
order: desc

salt/elasticsearch/enabled.sls

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
{% if sls.split('.')[0] in allowed_states %}
88
{% from 'vars/globals.map.jinja' import GLOBALS %}
99
{% from 'docker/docker.map.jinja' import DOCKER %}
10-
{% from 'logstash/map.jinja' import LOGSTASH_NODES %}
11-
{% from 'elasticsearch/config.map.jinja' import ES_LOGSTASH_NODES %}
10+
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_NODES %}
11+
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCH_SEED_HOSTS %}
1212
{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %}
1313
{% set TEMPLATES = salt['pillar.get']('elasticsearch:templates', {}) %}
1414
{% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %}
@@ -27,7 +27,7 @@ so-elasticsearch:
2727
- sobridge:
2828
- ipv4_address: {{ DOCKER.containers['so-elasticsearch'].ip }}
2929
- extra_hosts:
30-
{% for node in LOGSTASH_NODES %}
30+
{% for node in ELASTICSEARCH_NODES %}
3131
{% for hostname, ip in node.items() %}
3232
- {{hostname}}:{{ip}}
3333
{% endfor %}
@@ -38,7 +38,7 @@ so-elasticsearch:
3838
{% endfor %}
3939
{% endif %}
4040
- environment:
41-
{% if ES_LOGSTASH_NODES | length == 1 or GLOBALS.role == 'so-heavynode' %}
41+
{% if ELASTICSEARCH_SEED_HOSTS | length == 1 or GLOBALS.role == 'so-heavynode' %}
4242
- discovery.type=single-node
4343
{% endif %}
4444
- ES_JAVA_OPTS=-Xms{{ GLOBALS.elasticsearch.es_heap }} -Xmx{{ GLOBALS.elasticsearch.es_heap }} -Des.transport.cname_in_publish_address=true -Dlog4j2.formatMsgNoLookups=true

salt/elasticsearch/template.map.jinja

+25-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
2+
or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
3+
https://securityonion.net/license; you may not use this file except in compliance with the
4+
Elastic License 2.0. #}
5+
16
{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %}
27
{% set DEFAULT_GLOBAL_OVERRIDES = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings.pop('global_overrides') %}
38

@@ -17,10 +22,26 @@
1722
{% set ES_INDEX_SETTINGS = {} %}
1823
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.update(salt['defaults.merge'](ES_INDEX_SETTINGS_GLOBAL_OVERRIDES, ES_INDEX_PILLAR, in_place=False)) %}
1924
{% for index, settings in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.items() %}
20-
{# if policy isn't defined in the original index settings, then dont merge policy from the global_overrides #}
21-
{# this will prevent so-elasticsearch-ilm-policy-load from trying to load policy on non ILM manged indices #}
22-
{% if not ES_INDEX_SETTINGS_ORIG[index].policy is defined and ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %}
23-
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].pop('policy') %}
25+
26+
{# prevent this action from being performed on custom defined indices. #}
27+
{# the custom defined index is not present in either of the dictionaries and fails to reder. #}
28+
{% if index in ES_INDEX_SETTINGS_ORIG and index in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES %}
29+
30+
{# dont merge policy from the global_overrides if policy isn't defined in the original index settingss #}
31+
{# this will prevent so-elasticsearch-ilm-policy-load from trying to load policy on non ILM manged indices #}
32+
{% if not ES_INDEX_SETTINGS_ORIG[index].policy is defined and ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %}
33+
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].pop('policy') %}
34+
{% endif %}
35+
36+
{# this prevents and index from inderiting a policy phase from global overrides if it wasnt defined in the defaults. #}
37+
{% if ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %}
38+
{% for phase in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy.phases.copy() %}
39+
{% if ES_INDEX_SETTINGS_ORIG[index].policy.phases[phase] is not defined %}
40+
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy.phases.pop(phase) %}
41+
{% endif %}
42+
{% endfor %}
43+
{% endif %}
44+
2445
{% endif %}
2546

2647
{% if settings.index_template is defined %}

salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-cluster-settings

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# https://securityonion.net/license; you may not use this file except in compliance with the
55
# Elastic License 2.0.
66
{%- from 'vars/globals.map.jinja' import GLOBALS %}
7-
{%- set node_data = salt['pillar.get']('logstash:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %}
7+
{%- set node_data = salt['pillar.get']('elasticsearch:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %}
88

99
. /usr/sbin/so-common
1010

salt/idstools/tools/sbin_jinja/so-rule-update

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
1111
{%- set proxy = salt['pillar.get']('manager:proxy') %}
1212
{%- set noproxy = salt['pillar.get']('manager:no_proxy', '') %}
1313

14-
# Download the rules from the internet
1514
{%- if proxy %}
15+
# Download the rules from the internet
1616
export http_proxy={{ proxy }}
1717
export https_proxy={{ proxy }}
1818
export no_proxy="{{ noproxy }}"
1919
{%- endif %}
2020

2121
mkdir -p /nsm/rules/suricata
2222
chown -R socore:socore /nsm/rules/suricata
23+
{%- if not GLOBALS.airgap %}
2324
# Download the rules from the internet
24-
{%- if GLOBALS.airgap != 'True' %}
2525
{%- if IDSTOOLSMERGED.config.ruleset == 'ETOPEN' %}
2626
docker exec so-idstools idstools-rulecat -v --suricata-version 6.0 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force
2727
{%- elif IDSTOOLSMERGED.config.ruleset == 'ETPRO' %}

salt/influxdb/templates/dashboard-security_onion_performance.json

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)