Merge remote-tracking branch 'origin/2.4/dev' into salt3006.6

This commit is contained in:
m0duspwnens
2024-02-01 11:07:06 -05:00
45 changed files with 246746 additions and 430 deletions

View File

@@ -536,11 +536,10 @@ secretGroup = 4
[allowlist]
description = "global allow lists"
regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''', '''RPM-GPG-KEY.*''']
regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''', '''RPM-GPG-KEY.*''', '''.*:.*StrelkaHexDump.*''', '''.*:.*PLACEHOLDER.*''']
paths = [
'''gitleaks.toml''',
'''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
'''(go.mod|go.sum)$''',
'''salt/nginx/files/enterprise-attack.json'''
]

View File

@@ -1,17 +1,17 @@
### 2.4.30-20231228 ISO image released on 2024/01/02
### 2.4.40-20240116 ISO image released on 2024/01/17
### Download and Verify
2.4.30-20231228 ISO image:
https://download.securityonion.net/file/securityonion/securityonion-2.4.30-20231228.iso
2.4.40-20240116 ISO image:
https://download.securityonion.net/file/securityonion/securityonion-2.4.40-20240116.iso
MD5: DBD47645CD6FA8358C51D8753046FB54
SHA1: 2494091065434ACB028F71444A5D16E8F8A11EDF
SHA256: 3345AE1DC58AC7F29D82E60D9A36CDF8DE19B7DFF999D8C4F89C7BD36AEE7F1D
MD5: AC55D027B663F3CE0878FEBDAD9DD78B
SHA1: C2B51723B17F3DC843CC493EB80E93B123E3A3E1
SHA256: C5F135FCF45A836BBFF58C231F95E1EA0CD894898322187AD5FBFCD24BC2F123
Signature for ISO image:
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.30-20231228.iso.sig
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.40-20240116.iso.sig
Signing key:
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.
Download the signature file for the ISO:
```
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.30-20231228.iso.sig
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.40-20240116.iso.sig
```
Download the ISO image:
```
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.30-20231228.iso
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.40-20240116.iso
```
Verify the downloaded ISO image using the signature file:
```
gpg --verify securityonion-2.4.30-20231228.iso.sig securityonion-2.4.30-20231228.iso
gpg --verify securityonion-2.4.40-20240116.iso.sig securityonion-2.4.40-20240116.iso
```
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
```
gpg: Signature made Thu 28 Dec 2023 10:08:31 AM EST using RSA key ID FE507013
gpg: Signature made Tue 16 Jan 2024 07:34:40 PM EST using RSA key ID FE507013
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.

View File

@@ -1 +1 @@
2.4.40
2.4.50

View File

@@ -65,6 +65,7 @@ base:
- soctopus.adv_soctopus
- minions.{{ grains.id }}
- minions.adv_{{ grains.id }}
- stig.soc_stig
'*_sensor':
- healthcheck.sensor
@@ -80,6 +81,8 @@ base:
- suricata.adv_suricata
- minions.{{ grains.id }}
- minions.adv_{{ grains.id }}
- stig.soc_stig
- soc.license
'*_eval':
- secrets
@@ -180,6 +183,7 @@ base:
- suricata.adv_suricata
- minions.{{ grains.id }}
- minions.adv_{{ grains.id }}
- stig.soc_stig
'*_heavynode':
- elasticsearch.auth
@@ -222,6 +226,8 @@ base:
- redis.adv_redis
- minions.{{ grains.id }}
- minions.adv_{{ grains.id }}
- stig.soc_stig
- soc.license
'*_receiver':
- logstash.nodes

View File

@@ -102,7 +102,8 @@
'utility',
'schedule',
'soctopus',
'docker_clean'
'docker_clean',
'stig'
],
'so-managersearch': [
'salt.master',
@@ -123,7 +124,8 @@
'utility',
'schedule',
'soctopus',
'docker_clean'
'docker_clean',
'stig'
],
'so-searchnode': [
'ssl',
@@ -131,7 +133,8 @@
'telegraf',
'firewall',
'schedule',
'docker_clean'
'docker_clean',
'stig'
],
'so-standalone': [
'salt.master',
@@ -156,7 +159,8 @@
'schedule',
'soctopus',
'tcpreplay',
'docker_clean'
'docker_clean',
'stig'
],
'so-sensor': [
'ssl',
@@ -168,7 +172,8 @@
'healthcheck',
'schedule',
'tcpreplay',
'docker_clean'
'docker_clean',
'stig'
],
'so-fleet': [
'ssl',

View File

@@ -366,6 +366,13 @@ is_feature_enabled() {
return 1
}
read_feat() {
if [ -f /opt/so/log/sostatus/lks_enabled ]; then
lic_id=$(cat /opt/so/saltstack/local/pillar/soc/license.sls | grep license_id: | awk '{print $2}')
echo "$lic_id/$(cat /opt/so/log/sostatus/lks_enabled)/$(cat /opt/so/log/sostatus/fps_enabled)"
fi
}
require_manager() {
if is_manager_node; then
echo "This is a manager, so we can proceed."
@@ -559,6 +566,14 @@ status () {
printf "\n=========================================================================\n$(date) | $1\n=========================================================================\n"
}
sync_options() {
set_version
set_os
salt_minion_count
echo "$VERSION/$OS/$(uname -r)/$MINIONCOUNT/$(read_feat)"
}
systemctl_func() {
local action=$1
local echo_action=$1

View File

@@ -8,6 +8,7 @@
import sys
import subprocess
import os
import json
sys.path.append('/opt/saltstack/salt/lib/python3.10/site-packages/')
import salt.config
@@ -36,17 +37,63 @@ def check_needs_restarted():
with open(outfile, 'w') as f:
f.write(val)
def check_for_fps():
feat = 'fps'
feat_full = feat.replace('ps', 'ips')
fps = 0
try:
result = subprocess.run([feat_full + '-mode-setup', '--is-enabled'], stdout=subprocess.PIPE)
if result.returncode == 0:
fps = 1
except FileNotFoundError:
fn = '/proc/sys/crypto/' + feat_full + '_enabled'
with open(fn, 'r') as f:
contents = f.read()
if '1' in contents:
fps = 1
with open('/opt/so/log/sostatus/lks_enabled', 'w') as f:
f.write(str(fps))
def check_for_lks():
feat = 'Lks'
feat_full = feat.replace('ks', 'uks')
lks = 0
result = subprocess.run(['lsblk', '-p', '-J'], check=True, stdout=subprocess.PIPE)
data = json.loads(result.stdout)
for device in data['blockdevices']:
if 'children' in device:
for gc in device['children']:
if 'children' in gc:
try:
arg = 'is' + feat_full
result = subprocess.run(['cryptsetup', arg, gc['name']], stdout=subprocess.PIPE)
if result.returncode == 0:
lks = 1
except FileNotFoundError:
for ggc in gc['children']:
if 'crypt' in ggc['type']:
lks = 1
if lks:
break
with open('/opt/so/log/sostatus/fps_enabled', 'w') as f:
f.write(str(lks))
def fail(msg):
print(msg, file=sys.stderr)
sys.exit(1)
def main():
proc = subprocess.run(['id', '-u'], stdout=subprocess.PIPE, encoding="utf-8")
if proc.stdout.strip() != "0":
fail("This program must be run as root")
# Ensure that umask is 0022 so that files created by this script have rw-r-r permissions
org_umask = os.umask(0o022)
check_needs_restarted()
check_for_fps()
check_for_lks()
# Restore umask to whatever value was set before this script was run. SXIG sets to 0077 rw---
os.umask(org_umask)
if __name__ == "__main__":
main()

View File

@@ -45,6 +45,8 @@ elasticfleet:
- cisco_ise
- cisco_meraki
- cisco_umbrella
- citrix_adc
- citrix_waf
- cloudflare
- crowdstrike
- darktrace
@@ -75,6 +77,7 @@ elasticfleet:
- mimecast
- mysql
- netflow
- nginx
- o365
- okta
- osquery_manager
@@ -103,6 +106,7 @@ elasticfleet:
- udp
- vsphere
- windows
- winlog
- zscaler_zia
- zscaler_zpa
- 1password

View File

@@ -0,0 +1,34 @@
{
"package": {
"name": "log",
"version": ""
},
"name": "rita-logs",
"namespace": "so",
"description": "RITA Logs",
"policy_id": "so-grid-nodes_general",
"vars": {},
"inputs": {
"logs-logfile": {
"enabled": true,
"streams": {
"log.logs": {
"enabled": true,
"vars": {
"paths": [
"/nsm/rita/beacons.csv",
"/nsm/rita/exploded-dns.csv",
"/nsm/rita/long-connections.csv"
],
"exclude_files": [],
"ignore_older": "72h",
"data_stream.dataset": "rita",
"tags": [],
"processors": "- dissect:\n tokenizer: \"/nsm/rita/%{pipeline}.csv\"\n field: \"log.file.path\"\n trim_chars: \".csv\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\").split(\"-\");\n if (pl.length > 1) {\n pl = pl[1];\n }\n else {\n pl = pl[0];\n }\n event.Put(\"@metadata.pipeline\", \"rita.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: rita",
"custom": "exclude_lines: ['^Score', '^Source', '^Domain', '^No results']"
}
}
}
}
}
}

View File

@@ -118,6 +118,19 @@ esingestconf:
- user: 930
- group: 939
# Auto-generate Elasticsearch ingest node pipelines from pillar
{% for pipeline, config in ELASTICSEARCHMERGED.pipelines.items() %}
es_ingest_conf_{{pipeline}}:
file.managed:
- name: /opt/so/conf/elasticsearch/ingest/{{ pipeline }}
- source: salt://elasticsearch/base-template.json.jinja
- defaults:
TEMPLATE_CONFIG: {{ config }}
- template: jinja
- onchanges_in:
- file: so-pipelines-reload
{% endfor %}
eslog4jfile:
file.managed:
- name: /opt/so/conf/elasticsearch/log4j2.properties

View File

@@ -55,6 +55,87 @@ elasticsearch:
key: /usr/share/elasticsearch/config/elasticsearch.key
verification_mode: none
enabled: false
pipelines:
custom001:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom001
- pipeline:
name: common
custom002:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom002
- pipeline:
name: common
custom003:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom003
- pipeline:
name: common
custom004:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom004
- pipeline:
name: common
custom005:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom005
- pipeline:
name: common
custom006:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom006
- pipeline:
name: common
custom007:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom007
- pipeline:
name: common
custom008:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom008
- pipeline:
name: common
custom009:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom009
- pipeline:
name: common
custom010:
description: Custom Pipeline
processors:
- set:
field: tags
value: custom010
- pipeline:
name: common
index_settings:
global_overrides:
index_template:
@@ -2537,6 +2618,270 @@ elasticsearch:
set_priority:
priority: 50
min_age: 30d
so-logs-citrix_adc_x_interface:
index_sorting: False
index_template:
index_patterns:
- "logs-citrix_adc.interface-*"
template:
settings:
index:
lifecycle:
name: so-logs-citrix_adc.interface-logs
number_of_replicas: 0
composed_of:
- "logs-citrix_adc.interface@package"
- "logs-citrix_adc.interface@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-citrix_adc_x_lbvserver:
index_sorting: False
index_template:
index_patterns:
- "logs-citrix_adc.lbvserver-*"
template:
settings:
index:
lifecycle:
name: so-logs-citrix_adc.lbvserver-logs
number_of_replicas: 0
composed_of:
- "logs-citrix_adc.lbvserver@package"
- "logs-citrix_adc.lbvserver@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-citrix_adc_x_service:
index_sorting: False
index_template:
index_patterns:
- "logs-citrix_adc.service-*"
template:
settings:
index:
lifecycle:
name: so-logs-citrix_adc.service-logs
number_of_replicas: 0
composed_of:
- "logs-citrix_adc.service@package"
- "logs-citrix_adc.service@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-citrix_adc_x_system:
index_sorting: False
index_template:
index_patterns:
- "logs-citrix_adc.system-*"
template:
settings:
index:
lifecycle:
name: so-logs-citrix_adc.system-logs
number_of_replicas: 0
composed_of:
- "logs-citrix_adc.system@package"
- "logs-citrix_adc.system@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-citrix_adc_x_vpn:
index_sorting: False
index_template:
index_patterns:
- "logs-citrix_adc.vpn-*"
template:
settings:
index:
lifecycle:
name: so-logs-citrix_adc.vpn-logs
number_of_replicas: 0
composed_of:
- "logs-citrix_adc.vpn@package"
- "logs-citrix_adc.vpn@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-citrix_waf_x_log:
index_sorting: False
index_template:
index_patterns:
- "logs-citrix_waf.log-*"
template:
settings:
index:
lifecycle:
name: so-logs-citrix_waf.log-logs
number_of_replicas: 0
composed_of:
- "logs-citrix_waf.log@package"
- "logs-citrix_waf.log@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-cloudflare_x_audit:
index_sorting: false
index_template:
@@ -3539,6 +3884,62 @@ elasticsearch:
set_priority:
priority: 50
min_age: 30d
so-logs-endpoint_x_diagnostic_x_collection:
index_sorting: false
index_template:
composed_of:
- event-mappings
- logs-endpoint.diagnostic.collection@custom
- logs-endpoint.diagnostic.collection@package
- so-fleet_globals-1
- so-fleet_agent_id_verification-1
data_stream:
allow_custom_routing: false
hidden: false
index_patterns:
- logs-endpoint.diagnostic.collection-*
priority: 501
template:
settings:
index:
lifecycle:
name: so-logs-endpoint.diagnostic.collection-logs
mapping:
total_fields:
limit: 5000
number_of_replicas: 0
sort:
field: '@timestamp'
order: desc
policy:
_meta:
managed: true
managed_by: security_onion
package:
name: elastic_agent
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-endpoint_x_events_x_api:
index_sorting: false
index_template:
@@ -6659,6 +7060,138 @@ elasticsearch:
set_priority:
priority: 50
min_age: 30d
so-logs-nginx_x_access:
index_sorting: False
index_template:
index_patterns:
- "logs-nginx.access-*"
template:
settings:
index:
lifecycle:
name: so-logs-nginx.access-logs
number_of_replicas: 0
composed_of:
- "logs-nginx.access@package"
- "logs-nginx.access@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-nginx_x_error:
index_sorting: False
index_template:
index_patterns:
- "logs-nginx.error-*"
template:
settings:
index:
lifecycle:
name: so-logs-nginx.error-logs
number_of_replicas: 0
composed_of:
- "logs-nginx.error@package"
- "logs-nginx.error@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-metrics-nginx_x_stubstatus:
index_sorting: False
index_template:
index_patterns:
- "metrics-nginx.stubstatus-*"
template:
settings:
index:
lifecycle:
name: so-metrics-nginx.stubstatus-logs
number_of_replicas: 0
composed_of:
- "metrics-nginx.stubstatus@package"
- "metrics-nginx.stubstatus@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-o365_x_audit:
index_sorting: false
index_template:
@@ -8854,6 +9387,50 @@ elasticsearch:
set_priority:
priority: 50
min_age: 30d
so-logs-winlog_x_winlog:
index_sorting: False
index_template:
index_patterns:
- "logs-winlog.winlog-*"
template:
settings:
index:
lifecycle:
name: so-logs-winlog.winlog-logs
number_of_replicas: 0
composed_of:
- "logs-winlog.winlog@package"
- "logs-winlog.winlog@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-zscaler_zia_x_alerts:
index_sorting: false
index_template:

View File

@@ -67,7 +67,8 @@
{ "set": { "if": "ctx.scan?.pe?.image_version == '0'", "field": "scan.pe.image_version", "value": "0.0", "override": true } },
{ "set": { "field": "observer.name", "value": "{{agent.name}}" }},
{ "convert" : { "field" : "scan.exiftool","type": "string", "ignore_missing":true }},
{ "remove": { "field": ["host", "path", "message", "exiftool", "scan.yara.meta"], "ignore_missing": true } },
{ "pipeline": { "name": "common" } }
{ "convert" : { "field" : "scan.pe.flags","type": "string", "ignore_missing":true }},
{ "remove": { "field": ["host", "path", "message", "exiftool", "scan.yara.meta"], "ignore_missing": true } },
{ "pipeline": { "name": "common" } }
]
}

View File

@@ -4,6 +4,7 @@
{ "json": { "field": "message", "target_field": "message2", "ignore_failure": true } },
{ "rename": { "field": "message2.pkt_src", "target_field": "network.packet_source","ignore_failure": true } },
{ "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_failure": true } },
{ "rename": { "field": "message2.in_iface", "target_field": "observer.ingress.interface.name", "ignore_failure": true } },
{ "rename": { "field": "message2.flow_id", "target_field": "log.id.uid", "ignore_failure": true } },
{ "rename": { "field": "message2.src_ip", "target_field": "source.ip", "ignore_failure": true } },
{ "rename": { "field": "message2.src_port", "target_field": "source.port", "ignore_failure": true } },
@@ -12,6 +13,7 @@
{ "rename": { "field": "message2.vlan", "target_field": "network.vlan.id", "ignore_failure": true } },
{ "rename": { "field": "message2.community_id", "target_field": "network.community_id", "ignore_missing": true } },
{ "rename": { "field": "message2.xff", "target_field": "xff.ip", "ignore_missing": true } },
{ "lowercase": { "field": "network.transport", "ignore_failure": true } },
{ "set": { "field": "event.dataset", "value": "{{ message2.event_type }}" } },
{ "set": { "field": "observer.name", "value": "{{agent.name}}" } },
{ "set": { "field": "event.ingested", "value": "{{@timestamp}}" } },

View File

@@ -0,0 +1,21 @@
{
"description" : "suricata.ike",
"processors" : [
{ "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } },
{ "rename": { "field": "message2.app_proto", "target_field": "network.protocol", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.alg_auth", "target_field": "ike.algorithm.authentication", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.alg_enc", "target_field": "ike.algorithm.encryption", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.alg_esn", "target_field": "ike.algorithm.esn", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.alg_dh", "target_field": "ike.algorithm.dh", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.alg_prf", "target_field": "ike.algorithm.prf", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.exchange_type", "target_field": "ike.exchange_type", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.payload", "target_field": "ike.payload", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.role", "target_field": "ike.role", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.init_spi", "target_field": "ike.spi.initiator", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.resp_spi", "target_field": "ike.spi.responder", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.version_major", "target_field": "ike.version.major", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.version_minor", "target_field": "ike.version.minor", "ignore_missing": true } },
{ "rename": { "field": "message2.ike.ikev2.errors", "target_field": "ike.ikev2.errors", "ignore_missing": true } },
{ "pipeline": { "name": "common" } }
]
}

View File

@@ -1,8 +0,0 @@
{
"description" : "suricata.ikev2",
"processors" : [
{ "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } },
{ "rename": { "field": "message2.app_proto", "target_field": "network.protocol", "ignore_missing": true } },
{ "pipeline": { "name": "common" } }
]
}

View File

@@ -45,6 +45,28 @@ elasticsearch:
description: Max number of boolean clauses per query.
global: True
helpLink: elasticsearch.html
pipelines:
custom001: &pipelines
description:
description: Description of the ingest node pipeline
global: True
advanced: True
helpLink: elasticsearch.html
processors:
description: Processors for the ingest node pipeline
global: True
advanced: True
multiline: True
helpLink: elasticsearch.html
custom002: *pipelines
custom003: *pipelines
custom004: *pipelines
custom005: *pipelines
custom006: *pipelines
custom007: *pipelines
custom008: *pipelines
custom009: *pipelines
custom010: *pipelines
index_settings:
global_overrides:
index_template:
@@ -318,6 +340,7 @@ elasticsearch:
so-logs-windows_x_powershell: *indexSettings
so-logs-windows_x_powershell_operational: *indexSettings
so-logs-windows_x_sysmon_operational: *indexSettings
so-logs-winlog_x_winlog: *indexSettings
so-logs-apache_x_access: *indexSettings
so-logs-apache_x_error: *indexSettings
so-logs-auditd_x_log: *indexSettings
@@ -346,6 +369,12 @@ elasticsearch:
so-logs-cisco_ftd_x_log: *indexSettings
so-logs-cisco_ios_x_log: *indexSettings
so-logs-cisco_ise_x_log: *indexSettings
so-logs-citrix_adc_x_interface: *indexSettings
so-logs-citrix_adc_x_lbvserver: *indexSettings
so-logs-citrix_adc_x_service: *indexSettings
so-logs-citrix_adc_x_system: *indexSettings
so-logs-citrix_adc_x_vpn: *indexSettings
so-logs-citrix_waf_x_log: *indexSettings
so-logs-cloudflare_x_audit: *indexSettings
so-logs-cloudflare_x_logpull: *indexSettings
so-logs-crowdstrike_x_falcon: *indexSettings
@@ -406,6 +435,8 @@ elasticsearch:
so-logs-mysql_x_error: *indexSettings
so-logs-mysql_x_slowlog: *indexSettings
so-logs-netflow_x_log: *indexSettings
so-logs-nginx_x_access: *indexSettings
so-logs-nginx_x_error: *indexSettings
so-logs-o365_x_audit: *indexSettings
so-logs-okta_x_system: *indexSettings
so-logs-panw_x_panos: *indexSettings
@@ -471,6 +502,7 @@ elasticsearch:
so-metrics-endpoint_x_metadata: *indexSettings
so-metrics-endpoint_x_metrics: *indexSettings
so-metrics-endpoint_x_policy: *indexSettings
so-metrics-nginx_x_stubstatus: *indexSettings
so-case: *indexSettings
so-common: *indexSettings
so-endgame: *indexSettings

View File

@@ -1,382 +1,383 @@
{"template": {
"settings": {
"index": {
"lifecycle": {
"name": "logs"
},
"codec": "best_compression",
"default_pipeline": "logs-elastic_agent-1.13.1",
"mapping": {
"total_fields": {
"limit": "10000"
{
"template": {
"settings": {
"index": {
"lifecycle": {
"name": "logs"
},
"codec": "best_compression",
"default_pipeline": "logs-elastic_agent-1.13.1",
"mapping": {
"total_fields": {
"limit": "10000"
}
},
"query": {
"default_field": [
"cloud.account.id",
"cloud.availability_zone",
"cloud.instance.id",
"cloud.instance.name",
"cloud.machine.type",
"cloud.provider",
"cloud.region",
"cloud.project.id",
"cloud.image.id",
"container.id",
"container.image.name",
"container.name",
"host.architecture",
"host.hostname",
"host.id",
"host.mac",
"host.name",
"host.os.family",
"host.os.kernel",
"host.os.name",
"host.os.platform",
"host.os.version",
"host.os.build",
"host.os.codename",
"host.type",
"ecs.version",
"agent.build.original",
"agent.ephemeral_id",
"agent.id",
"agent.name",
"agent.type",
"agent.version",
"log.level",
"message",
"elastic_agent.id",
"elastic_agent.process",
"elastic_agent.version",
"component.id",
"component.type",
"component.binary",
"component.state",
"component.old_state",
"unit.id",
"unit.type",
"unit.state",
"unit.old_state"
]
}
}
},
"mappings": {
"dynamic": false,
"dynamic_templates": [
{
"container.labels": {
"path_match": "container.labels.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
}
],
"properties": {
"container": {
"properties": {
"image": {
"properties": {
"name": {
"ignore_above": 1024,
"type": "keyword"
}
},
"query": {
"default_field": [
"cloud.account.id",
"cloud.availability_zone",
"cloud.instance.id",
"cloud.instance.name",
"cloud.machine.type",
"cloud.provider",
"cloud.region",
"cloud.project.id",
"cloud.image.id",
"container.id",
"container.image.name",
"container.name",
"host.architecture",
"host.hostname",
"host.id",
"host.mac",
"host.name",
"host.os.family",
"host.os.kernel",
"host.os.name",
"host.os.platform",
"host.os.version",
"host.os.build",
"host.os.codename",
"host.type",
"ecs.version",
"agent.build.original",
"agent.ephemeral_id",
"agent.id",
"agent.name",
"agent.type",
"agent.version",
"log.level",
"message",
"elastic_agent.id",
"elastic_agent.process",
"elastic_agent.version",
"component.id",
"component.type",
"component.binary",
"component.state",
"component.old_state",
"unit.id",
"unit.type",
"unit.state",
"unit.old_state"
]
}
},
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
}
},
"mappings": {
"dynamic": false,
"dynamic_templates": [
{
"container.labels": {
"path_match": "container.labels.*",
"mapping": {
"type": "keyword"
},
"match_mapping_type": "string"
}
},
"agent": {
"properties": {
"build": {
"properties": {
"original": {
"ignore_above": 1024,
"type": "keyword"
}
}
],
"properties": {
"container": {
"properties": {
"image": {
"properties": {
"name": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
}
},
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
},
"ephemeral_id": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"log": {
"properties": {
"level": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"elastic_agent": {
"properties": {
"process": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
},
"snapshot": {
"type": "boolean"
}
}
},
"message": {
"type": "text"
},
"cloud": {
"properties": {
"availability_zone": {
"ignore_above": 1024,
"type": "keyword"
},
"image": {
"properties": {
"id": {
"ignore_above": 1024,
"type": "keyword"
}
},
"agent": {
"properties": {
"build": {
"properties": {
"original": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
},
"ephemeral_id": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"instance": {
"properties": {
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
}
},
"log": {
"properties": {
"level": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"provider": {
"ignore_above": 1024,
"type": "keyword"
},
"machine": {
"properties": {
"type": {
"ignore_above": 1024,
"type": "keyword"
}
},
"elastic_agent": {
"properties": {
"process": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
},
"snapshot": {
"type": "boolean"
}
}
},
"project": {
"properties": {
"id": {
"ignore_above": 1024,
"type": "keyword"
}
},
"message": {
"type": "text"
},
"cloud": {
"properties": {
"availability_zone": {
"ignore_above": 1024,
"type": "keyword"
},
"image": {
"properties": {
"id": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"instance": {
"properties": {
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"provider": {
"ignore_above": 1024,
"type": "keyword"
},
"machine": {
"properties": {
"type": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"project": {
"properties": {
"id": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"region": {
"ignore_above": 1024,
"type": "keyword"
},
"account": {
"properties": {
"id": {
"ignore_above": 1024,
"type": "keyword"
}
}
}
}
},
"component": {
"properties": {
"binary": {
"ignore_above": 1024,
"type": "keyword"
},
"old_state": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "wildcard"
},
"state": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"unit": {
"properties": {
"old_state": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "wildcard"
},
"state": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"@timestamp": {
"type": "date"
},
"ecs": {
"properties": {
"version": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
},
"type": {
"type": "constant_keyword"
},
"dataset": {
"type": "constant_keyword"
}
}
},
"host": {
"properties": {
"hostname": {
"ignore_above": 1024,
"type": "keyword"
},
"os": {
"properties": {
"build": {
"ignore_above": 1024,
"type": "keyword"
},
"kernel": {
"ignore_above": 1024,
"type": "keyword"
},
"codename": {
"ignore_above": 1024,
"type": "keyword"
},
"name": {
"ignore_above": 1024,
"type": "keyword",
"fields": {
"text": {
"type": "text"
}
}
},
"family": {
"ignore_above": 1024,
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
},
"platform": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"domain": {
"ignore_above": 1024,
"type": "keyword"
},
"ip": {
"type": "ip"
},
"containerized": {
"type": "boolean"
},
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
},
"mac": {
"ignore_above": 1024,
"type": "keyword"
},
"architecture": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"event": {
"properties": {
"dataset": {
"type": "constant_keyword"
}
}
},
"region": {
"ignore_above": 1024,
"type": "keyword"
},
"account": {
"properties": {
"id": {
"ignore_above": 1024,
"type": "keyword"
}
}
}
}
},
"_meta": {
"package": {
"name": "elastic_agent"
},
"managed_by": "fleet",
"managed": true
"component": {
"properties": {
"binary": {
"ignore_above": 1024,
"type": "keyword"
},
"old_state": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "wildcard"
},
"state": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"unit": {
"properties": {
"old_state": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "wildcard"
},
"state": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"@timestamp": {
"type": "date"
},
"ecs": {
"properties": {
"version": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
},
"type": {
"type": "constant_keyword"
},
"dataset": {
"type": "constant_keyword"
}
}
},
"host": {
"properties": {
"hostname": {
"ignore_above": 1024,
"type": "keyword"
},
"os": {
"properties": {
"build": {
"ignore_above": 1024,
"type": "keyword"
},
"kernel": {
"ignore_above": 1024,
"type": "keyword"
},
"codename": {
"ignore_above": 1024,
"type": "keyword"
},
"name": {
"ignore_above": 1024,
"type": "keyword",
"fields": {
"text": {
"type": "text"
}
}
},
"family": {
"ignore_above": 1024,
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
},
"platform": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"domain": {
"ignore_above": 1024,
"type": "keyword"
},
"ip": {
"type": "ip"
},
"containerized": {
"type": "boolean"
},
"name": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
},
"mac": {
"ignore_above": 1024,
"type": "keyword"
},
"architecture": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"event": {
"properties": {
"dataset": {
"type": "constant_keyword"
}
}
}
}
}
},
"_meta": {
"package": {
"name": "elastic_agent"
},
"managed_by": "fleet",
"managed": true
}
}

View File

@@ -0,0 +1,12 @@
{
"template": {
"settings": {}
},
"_meta": {
"package": {
"name": "endpoint"
},
"managed_by": "fleet",
"managed": true
}
}

View File

@@ -0,0 +1,132 @@
{
"template": {
"settings": {
"index": {
"lifecycle": {
"name": "logs-endpoint.collection-diagnostic"
},
"codec": "best_compression",
"default_pipeline": "logs-endpoint.diagnostic.collection-8.10.2",
"mapping": {
"total_fields": {
"limit": "10000"
},
"ignore_malformed": "true"
},
"query": {
"default_field": [
"ecs.version",
"event.action",
"event.category",
"event.code",
"event.dataset",
"event.hash",
"event.id",
"event.kind",
"event.module",
"event.outcome",
"event.provider",
"event.type"
]
}
}
},
"mappings": {
"dynamic": false,
"properties": {
"@timestamp": {
"ignore_malformed": false,
"type": "date"
},
"ecs": {
"properties": {
"version": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"data_stream": {
"properties": {
"namespace": {
"type": "constant_keyword"
},
"type": {
"type": "constant_keyword"
},
"dataset": {
"type": "constant_keyword"
}
}
},
"event": {
"properties": {
"severity": {
"type": "long"
},
"code": {
"ignore_above": 1024,
"type": "keyword"
},
"created": {
"type": "date"
},
"kind": {
"ignore_above": 1024,
"type": "keyword"
},
"module": {
"ignore_above": 1024,
"type": "keyword"
},
"type": {
"ignore_above": 1024,
"type": "keyword"
},
"sequence": {
"type": "long"
},
"ingested": {
"type": "date"
},
"provider": {
"ignore_above": 1024,
"type": "keyword"
},
"action": {
"ignore_above": 1024,
"type": "keyword"
},
"id": {
"ignore_above": 1024,
"type": "keyword"
},
"category": {
"ignore_above": 1024,
"type": "keyword"
},
"dataset": {
"ignore_above": 1024,
"type": "keyword"
},
"hash": {
"ignore_above": 1024,
"type": "keyword"
},
"outcome": {
"ignore_above": 1024,
"type": "keyword"
}
}
}
}
}
},
"_meta": {
"package": {
"name": "endpoint"
},
"managed_by": "fleet",
"managed": true
}
}

View File

@@ -14,16 +14,19 @@
},
"pe": {
"properties": {
"sections": {
"flags": {
"type": "text"
},
"image_version": {
"type": "float"
},
"sections": {
"properties": {
"entropy": {
"type": "float"
}
}
},
"image_version": {
"type": "float"
}
}
}
},
"elf": {

View File

@@ -21,7 +21,7 @@
{% set KRATOSMERGED = salt['pillar.get']('kratos', default=KRATOSDEFAULTS.kratos, merge=true) %}
{% if KRATOSMERGED.oidc.enabled and 'oidc' in salt['pillar.get']('features') %}
{% if KRATOSMERGED.oidc.enabled and 'odc' in salt['pillar.get']('features') %}
{% do KRATOSMERGED.config.selfservice.methods.update({'oidc': {'enabled': true, 'config': {'providers': [KRATOSMERGED.oidc.config]}}}) %}
{% endif %}

View File

@@ -63,6 +63,20 @@ lspipelinedir:
- user: 931
- group: 939
# Auto-generate Logstash pipeline config
{% for pipeline, config in LOGSTASH_MERGED.pipeline_config.items() %}
{% for assigned_pipeline in ASSIGNED_PIPELINES %}
{% set custom_pipeline = 'custom/' + pipeline + '.conf' %}
{% if custom_pipeline in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %}
ls_custom_pipeline_conf_{{assigned_pipeline}}_{{pipeline}}:
file.managed:
- name: /opt/so/conf/logstash/pipelines/{{assigned_pipeline}}/{{ pipeline }}.conf
- contents: LOGSTASH_MERGED.pipeline_config.{{pipeline}}
{% endif %}
{% endfor %}
{% endfor %}
{% for assigned_pipeline in ASSIGNED_PIPELINES %}
{% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %}
ls_pipeline_{{assigned_pipeline}}_{{CONFIGFILE.split('.')[0] | replace("/","_") }}:

View File

@@ -42,6 +42,24 @@ logstash:
custom2: []
custom3: []
custom4: []
pipeline_config:
custom001: |-
filter {
if [event][module] =~ "zeek" {
mutate {
add_tag => ["network_stuff"]
}
}
}
custom002: PLACEHOLDER
custom003: PLACEHOLDER
custom004: PLACEHOLDER
custom005: PLACEHOLDER
custom006: PLACEHOLDER
custom007: PLACEHOLDER
custom008: PLACEHOLDER
custom009: PLACEHOLDER
custom010: PLACEHOLDER
settings:
lsheap: 500m
config:

View File

@@ -31,6 +31,22 @@ logstash:
custom2: *defined_pipelines
custom3: *defined_pipelines
custom4: *defined_pipelines
pipeline_config:
custom001: &pipeline_config
description: Pipeline configuration for Logstash
advanced: True
multiline: True
forcedType: string
helpLink: logstash.html
custom002: *pipeline_config
custom003: *pipeline_config
custom004: *pipeline_config
custom005: *pipeline_config
custom006: *pipeline_config
custom007: *pipeline_config
custom008: *pipeline_config
custom009: *pipeline_config
custom010: *pipeline_config
settings:
lsheap:
description: Heap size to use for logstash

View File

@@ -7,12 +7,8 @@
NOROOT=1
. /usr/sbin/so-common
set_version
set_os
salt_minion_count
set -e
curl --retry 5 --retry-delay 60 -A "reposync/$VERSION/$OS/$(uname -r)/$MINIONCOUNT" https://sigs.securityonion.net/checkup --output /tmp/checkup
curl --retry 5 --retry-delay 60 -A "reposync/$(sync_options)" https://sigs.securityonion.net/checkup --output /tmp/checkup
dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionsync --download-metadata -p /nsm/repo/
createrepo /nsm/repo

View File

@@ -347,7 +347,7 @@ function syncElastic() {
[[ $? != 0 ]] && fail "Unable to read credential hashes from database"
user_data_formatted=$(echo "${userData}" | jq -r '.user + ":" + .data.hashed_password')
if lookup_salt_value "licensed_features" "" "pillar" | grep -x oidc; then
if lookup_salt_value "features" "" "pillar" | grep -x odc; then
# generate random placeholder salt/hash for users without passwords
random_crypt=$(get_random_value 53)
user_data_formatted=$(echo "${user_data_formatted}" | sed -r "s/^(.+:)\$/\\1\$2a\$12${random_crypt}/")

View File

@@ -372,6 +372,17 @@ enable_highstate() {
echo ""
}
get_soup_script_hashes() {
CURRENTSOUP=$(md5sum /usr/sbin/soup | awk '{print $1}')
GITSOUP=$(md5sum $UPDATE_DIR/salt/manager/tools/sbin/soup | awk '{print $1}')
CURRENTCMN=$(md5sum /usr/sbin/so-common | awk '{print $1}')
GITCMN=$(md5sum $UPDATE_DIR/salt/common/tools/sbin/so-common | awk '{print $1}')
CURRENTIMGCMN=$(md5sum /usr/sbin/so-image-common | awk '{print $1}')
GITIMGCMN=$(md5sum $UPDATE_DIR/salt/common/tools/sbin/so-image-common | awk '{print $1}')
CURRENTSOFIREWALL=$(md5sum /usr/sbin/so-firewall | awk '{print $1}')
GITSOFIREWALL=$(md5sum $UPDATE_DIR/salt/manager/tools/sbin/so-firewall | awk '{print $1}')
}
highstate() {
# Run a highstate.
salt-call state.highstate -l info queue=True
@@ -405,6 +416,7 @@ preupgrade_changes() {
[[ "$INSTALLEDVERSION" == 2.4.10 ]] && up_to_2.4.20
[[ "$INSTALLEDVERSION" == 2.4.20 ]] && up_to_2.4.30
[[ "$INSTALLEDVERSION" == 2.4.30 ]] && up_to_2.4.40
[[ "$INSTALLEDVERSION" == 2.4.40 ]] && up_to_2.4.50
true
}
@@ -419,6 +431,7 @@ postupgrade_changes() {
[[ "$POSTVERSION" == 2.4.10 ]] && post_to_2.4.20
[[ "$POSTVERSION" == 2.4.20 ]] && post_to_2.4.30
[[ "$POSTVERSION" == 2.4.30 ]] && post_to_2.4.40
[[ "$POSTVERSION" == 2.4.40 ]] && post_to_2.4.50
true
}
@@ -470,6 +483,11 @@ post_to_2.4.40() {
POSTVERSION=2.4.40
}
post_to_2.4.50() {
echo "Nothing to apply"
POSTVERSION=2.4.50
}
repo_sync() {
echo "Sync the local repo."
su socore -c '/usr/sbin/so-repo-sync' || fail "Unable to complete so-repo-sync."
@@ -570,6 +588,15 @@ up_to_2.4.40() {
INSTALLEDVERSION=2.4.40
}
up_to_2.4.50() {
echo "Creating additional pillars.."
mkdir -p /opt/so/saltstack/local/pillar/stig/
touch /opt/so/saltstack/local/pillar/stig/adv_stig.sls
touch /opt/so/saltstack/local/pillar/stig/soc_stig.sls
INSTALLEDVERSION=2.4.50
}
determine_elastic_agent_upgrade() {
if [[ $is_airgap -eq 0 ]]; then
update_elastic_agent_airgap
@@ -742,31 +769,32 @@ upgrade_salt() {
}
verify_latest_update_script() {
# Check to see if the update scripts match. If not run the new one.
CURRENTSOUP=$(md5sum /usr/sbin/soup | awk '{print $1}')
GITSOUP=$(md5sum $UPDATE_DIR/salt/manager/tools/sbin/soup | awk '{print $1}')
CURRENTCMN=$(md5sum /usr/sbin/so-common | awk '{print $1}')
GITCMN=$(md5sum $UPDATE_DIR/salt/common/tools/sbin/so-common | awk '{print $1}')
CURRENTIMGCMN=$(md5sum /usr/sbin/so-image-common | awk '{print $1}')
GITIMGCMN=$(md5sum $UPDATE_DIR/salt/common/tools/sbin/so-image-common | awk '{print $1}')
CURRENTSOFIREWALL=$(md5sum /usr/sbin/so-firewall | awk '{print $1}')
GITSOFIREWALL=$(md5sum $UPDATE_DIR/salt/manager/tools/sbin/so-firewall | awk '{print $1}')
get_soup_script_hashes
if [[ "$CURRENTSOUP" == "$GITSOUP" && "$CURRENTCMN" == "$GITCMN" && "$CURRENTIMGCMN" == "$GITIMGCMN" && "$CURRENTSOFIREWALL" == "$GITSOFIREWALL" ]]; then
echo "This version of the soup script is up to date. Proceeding."
else
echo "You are not running the latest soup version. Updating soup and its components. This might take multiple runs to complete."
cp $UPDATE_DIR/salt/manager/tools/sbin/soup $DEFAULT_SALT_DIR/salt/common/tools/sbin/
cp $UPDATE_DIR/salt/manager/tools/sbin/soup $DEFAULT_SALT_DIR/salt/manager/tools/sbin/
cp $UPDATE_DIR/salt/common/tools/sbin/so-common $DEFAULT_SALT_DIR/salt/common/tools/sbin/
cp $UPDATE_DIR/salt/common/tools/sbin/so-image-common $DEFAULT_SALT_DIR/salt/common/tools/sbin/
cp $UPDATE_DIR/salt/manager/tools/sbin/so-firewall $DEFAULT_SALT_DIR/salt/common/tools/sbin/
cp $UPDATE_DIR/salt/manager/tools/sbin/so-firewall $DEFAULT_SALT_DIR/salt/manager/tools/sbin/
salt-call state.apply common.soup_scripts queue=True -linfo --file-root=$UPDATE_DIR/salt --local
# Verify that soup scripts updated as expected
get_soup_script_hashes
if [[ "$CURRENTSOUP" == "$GITSOUP" && "$CURRENTCMN" == "$GITCMN" && "$CURRENTIMGCMN" == "$GITIMGCMN" && "$CURRENTSOFIREWALL" == "$GITSOFIREWALL" ]]; then
echo "Succesfully updated soup scripts."
else
# When STIGs are enabled soup scripts will fail to update using --file-root --local.
# After checking that the expected hashes are not present, retry updating soup scripts using salt master.
echo "There was a problem updating soup scripts.. Trying to rerun script update"
salt-call state.apply common.soup_scripts queue=True -linfo
fi
echo ""
echo "The soup script has been modified. Please run soup again to continue the upgrade."
exit 0
fi
}
}
# Keeping this block in case we need to do a hotfix that requires salt update
apply_hotfix() {
if [[ "$INSTALLEDVERSION" == "2.4.20" ]] ; then

View File

@@ -7,6 +7,7 @@ logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
localpkg_gpgcheck=1
plugins=1
installonly_limit={{ salt['pillar.get']('yum:config:installonly_limit', 2) }}
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum

3
salt/stig/defaults.yaml Normal file
View File

@@ -0,0 +1,3 @@
stig:
enabled: False
run_interval: 12

15
salt/stig/disabled.sls Normal file
View File

@@ -0,0 +1,15 @@
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
{% from 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %}
stig_remediate_schedule:
schedule.absent
remove_stig_script:
file.absent:
- name: /usr/sbin/so-stig
{% endif %}

104
salt/stig/enabled.sls Normal file
View File

@@ -0,0 +1,104 @@
# 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.
#
# Note: Per the Elastic License 2.0, the second limitation states:
#
# "You may not move, change, disable, or circumvent the license key functionality
# in the software, and you may not remove or obscure any functionality in the
# software that is protected by the license key."
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% from 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states and GLOBALS.os == 'OEL' %}
{% if 'stg' in salt['pillar.get']('features', []) %}
{% set OSCAP_PROFILE_NAME = 'xccdf_org.ssgproject.content_profile_stig' %}
{% set OSCAP_PROFILE_LOCATION = '/opt/so/conf/stig/sos-oscap.xml' %}
{% set OSCAP_OUTPUT_DIR = '/opt/so/log/stig' %}
oscap_packages:
pkg.installed:
- skip_suggestions: True
- pkgs:
- openscap
- openscap-scanner
- scap-security-guide
make_some_dirs:
file.directory:
- name: /opt/so/log/stig
- user: socore
- group: socore
- makedirs: True
make_more_dir:
file.directory:
- name: /opt/so/conf/stig
- user: socore
- group: socore
- makedirs: True
update_stig_profile:
file.managed:
- name: /opt/so/conf/stig/sos-oscap.xml
- source: salt://stig/files/sos-oscap.xml
- user: socore
- group: socore
- mode: 0644
{% if not salt['file.file_exists'](OSCAP_OUTPUT_DIR ~ '/pre-oscap-report.html') %}
run_initial_scan:
module.run:
- name: openscap.xccdf
- params: 'eval --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/pre-oscap-results.xml --report {{ OSCAP_OUTPUT_DIR }}/pre-oscap-report.html {{ OSCAP_PROFILE_LOCATION }}'
{% endif %}
run_remediate:
module.run:
- name: openscap.xccdf
- params: 'eval --remediate --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/post-oscap-results.xml --report {{ OSCAP_PROFILE_LOCATION }}'
{# OSCAP rule id: xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_burstaction #}
disable_ctrl_alt_del_action:
file.replace:
- name: /etc/systemd/system.conf
- pattern: '^#CtrlAltDelBurstAction=none'
- repl: 'CtrlAltDelBurstAction=none'
- backup: '.bak'
{# OSCAP rule id: xccdf_org.ssgproject.content_rule_no_empty_passwords #}
remove_nullok_from_password_auth:
file.replace:
- name: /etc/pam.d/password-auth
- pattern: ' nullok'
- repl: ''
- backup: '.bak'
remove_nullok_from_system_auth_auth:
file.replace:
- name: /etc/pam.d/system-auth
- pattern: ' nullok'
- repl: ''
- backup: '.bak'
run_post_scan:
module.run:
- name: openscap.xccdf
- params: 'eval --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/post-oscap-results.xml --report {{ OSCAP_OUTPUT_DIR }}/post-oscap-report.html {{ OSCAP_PROFILE_LOCATION }}'
{% else %}
{{sls}}_no_license_detected:
test.fail_without_changes:
- name: {{sls}}_no_license_detected
- comment:
- "The application of STIGs is a feature supported only for customers with a valid license.
Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com
for more information about purchasing a license to enable this feature."
{% endif %}
{% else %}
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %}

244945
salt/stig/files/sos-oscap.xml Normal file

File diff suppressed because one or more lines are too long

16
salt/stig/init.sls Normal file
View File

@@ -0,0 +1,16 @@
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
{% from 'stig/map.jinja' import STIGMERGED %}
include:
{% if STIGMERGED.enabled %}
- stig.schedule
{% if not salt['schedule.is_enabled'](name="stig_remediate_schedule") %}
- stig.enabled
{% endif %}
{% else %}
- stig.disabled
{% endif %}

0
salt/stig/license.sls Normal file
View File

7
salt/stig/map.jinja Normal file
View File

@@ -0,0 +1,7 @@
{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
https://securityonion.net/license; you may not use this file except in compliance with the
Elastic License 2.0. #}
{% import_yaml 'stig/defaults.yaml' as STIGDEFAULTS with context %}
{% set STIGMERGED = salt['pillar.get']('stig', STIGDEFAULTS.stig, merge=True) %}

24
salt/stig/schedule.sls Normal file
View File

@@ -0,0 +1,24 @@
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
{% from 'stig/map.jinja' import STIGMERGED %}
{% if 'stg' in salt['pillar.get']('features', []) %}
stig_remediate_schedule:
schedule.present:
- function: state.apply
- job_args:
- stig.enabled
- hours: {{ STIGMERGED.run_interval }}
- maxrunning: 1
- enabled: true
{% else %}
{{sls}}_no_license_detected:
test.fail_without_changes:
- name: {{sls}}_no_license_detected
- comment:
- "The application of STIGs is a feature supported only for customers with a valid license.
Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com
for more information about purchasing a license to enable this feature."
{% endif %}

11
salt/stig/soc_stig.yaml Normal file
View File

@@ -0,0 +1,11 @@
stig:
enabled:
description: You can enable or disable the application of STIGS using oscap. Note that the actions performed by OSCAP are not automatically reversible.
forcedType: bool
advanced: True
run_interval:
description: The interval in hours between OSCAP remediate executions.
forcedType: int
regex: ^([1-9][0-9]{0,2})$
regexFailureMessage: The value must be an integer between 1 and 999.
advanced: True

View File

@@ -17,9 +17,10 @@ strelka:
mime_db: '/usr/lib/file/magic.mgc'
yara_rules: '/etc/strelka/taste/'
scanners:
'ScanBase64':
'ScanBase64PE':
- positive:
filename: '^base64_'
flavors:
- 'base64_pe'
priority: 5
'ScanBatch':
- positive:
@@ -27,12 +28,27 @@ strelka:
- 'text/x-msdos-batch'
- 'batch_file'
priority: 5
'ScanBmpEof':
- positive:
flavors:
- 'image/x-ms-bmp'
- 'bmp_file'
negative:
source:
- 'ScanTranscode'
priority: 5
'ScanBzip2':
- positive:
flavors:
- 'application/x-bzip2'
- 'bzip2_file'
priority: 5
'ScanDmg':
- positive:
flavors:
- 'dmg_disk_image'
- 'hfsplus_disk_image'
priority: 5
'ScanDocx':
- positive:
flavors:
@@ -40,6 +56,11 @@ strelka:
priority: 5
options:
extract_text: False
'ScanDonut':
- positive:
flavors:
- 'hacktool_win_shellcode_donut'
priority: 5
'ScanElf':
- positive:
flavors:
@@ -56,6 +77,26 @@ strelka:
- 'message/rfc822'
- 'email_file'
priority: 5
'ScanEncryptedDoc':
- positive:
flavors:
- 'encrypted_word_document'
priority: 5
options:
max_length: 5
scanner_timeout: 150
log_pws: True
password_file: "/etc/strelka/passwords.dat"
'ScanEncryptedZip':
- positive:
flavors:
- 'encrypted_zip'
priority: 5
options:
max_length: 5
scanner_timeout: 150
log_pws: True
password_file: '/etc/strelka/passwords.dat'
'ScanEntropy':
- positive:
flavors:
@@ -111,6 +152,16 @@ strelka:
priority: 5
options:
tmp_directory: '/dev/shm/'
'ScanFooter':
- positive:
flavors:
- '*'
priority: 5
options:
length: 50
encodings:
- classic
- backslash
'ScanGif':
- positive:
flavors:
@@ -144,13 +195,25 @@ strelka:
- 'html_file'
priority: 5
options:
parser: "html5lib"
max_hyperlinks: 50
'ScanIqy':
- positive:
flavors:
- 'iqy_file'
priority: 5
'ScanIni':
- positive:
filename: '(\.([Cc][Ff][Gg]|[Ii][Nn][Ii])|PROJECT)$'
flavors:
- 'ini_file'
priority: 5
'ScanIso':
- positive:
flavors:
- 'application/x-iso9660-image'
priority: 5
options:
limit: 50
'ScanJarManifest':
- positive:
flavors:
@@ -198,6 +261,25 @@ strelka:
priority: 5
options:
limit: 1000
'ScanLNK':
- positive:
flavors:
- 'lnk_file'
priority: 5
'ScanLsb':
- positive:
flavors:
- 'image/png'
- 'png_file'
- 'image/jpeg'
- 'jpeg_file'
- 'image/x-ms-bmp'
- 'bmp_file'
- 'image/webp'
negative:
source:
- 'ScanTranscode'
priority: 5
'ScanLzma':
- positive:
flavors:
@@ -214,6 +296,36 @@ strelka:
priority: 5
options:
tmp_directory: '/dev/shm/'
'ScanManifest':
- positive:
flavors:
- 'browser_manifest'
priority: 5
'ScanMsi':
- positive:
flavors:
- "image/vnd.fpx"
- "application/vnd.ms-msi"
- "application/x-msi"
priority: 5
options:
tmp_directory: '/dev/shm/'
keys:
- 'Author'
- 'Characters'
- 'Company'
- 'CreateDate'
- 'LastModifiedBy'
- 'Lines'
- 'ModifyDate'
- 'Pages'
- 'Paragraphs'
- 'RevisionNumber'
- 'Software'
- 'Template'
- 'Title'
- 'TotalEditTime'
- 'Words'
'ScanOcr':
- positive:
flavors:
@@ -236,6 +348,13 @@ strelka:
- 'application/msword'
- 'olecf_file'
priority: 5
'ScanOnenote':
- positive:
flavors:
- 'application/onenote'
- 'application/msonenote'
- 'onenote_file'
priority: 5
'ScanPdf':
- positive:
flavors:
@@ -285,6 +404,30 @@ strelka:
- 'ProgramArguments'
- 'RunAtLoad'
- 'StartInterval'
'ScanPngEof':
- positive:
flavors:
- 'image/png'
- 'png_file'
negative:
source:
- 'ScanTranscode'
priority: 5
'ScanQr':
- positive:
flavors:
- 'image/jpeg'
- 'jpeg_file'
- 'image/png'
- 'png_file'
- 'image/tiff'
- 'type_is_tiff'
- 'image/x-ms-bmp'
- 'bmp_file'
- 'image/webp'
priority: 5
options:
support_inverted: True
'ScanRar':
- positive:
flavors:
@@ -309,6 +452,19 @@ strelka:
priority: 5
options:
limit: 1000
'ScanSevenZip':
- positive:
flavors:
- 'application/x-7z-compressed'
- '_7zip_file'
- "image/vnd.fpx"
- "application/vnd.ms-msi"
- "application/x-msi"
priority: 5
options:
scanner_timeout: 150
crack_pws: True
log_pws: True
'ScanSwf':
- positive:
flavors:
@@ -351,6 +507,7 @@ strelka:
flavors:
- 'vb_file'
- 'vbscript'
- 'hta_file'
priority: 5
'ScanVba':
- positive:
@@ -362,6 +519,20 @@ strelka:
priority: 5
options:
analyze_macros: True
'ScanVhd':
- positive:
flavors:
- 'application/x-vhd'
- 'vhd_file'
- 'vhdx_file'
priority: 5
options:
limit: 100
'ScanVsto':
- positive:
flavors:
- 'vsto_file'
priority: 5
'ScanX509':
- positive:
flavors:
@@ -391,6 +562,12 @@ strelka:
priority: 5
options:
location: '/etc/yara/'
compiled:
enabled: False
filename: "rules.compiled"
store_offset: True
offset_meta_key: "StrelkaHexDump"
offset_padding: 32
'ScanZip':
- positive:
flavors:
@@ -530,6 +707,20 @@ strelka:
ttl: 1h
response:
log: "/var/log/strelka/strelka.log"
broker:
bootstrap: "PLACEHOLDER"
protocol: "PLACEHOLDER"
certlocation: "PLACEHOLDER"
keylocation: "PLACEHOLDER"
calocation: "PLACEHOLDER"
topic: "PLACEHOLDER"
s3redundancy: "PLACEHOLDER - This should be a boolean value"
s3:
accesskey: "PLACEHOLDER"
secretkey: "PLACEHOLDER"
bucketName: "PLACEHOLDER"
region: "PLACEHOLDER"
endpoint: "PLACEHOLDER"
manager:
enabled: False
config:

View File

@@ -36,6 +36,7 @@ telegraf:
- suriloss.sh
- zeekcaptureloss.sh
- zeekloss.sh
- features.sh
manager:
- influxdbsize.sh
- lasthighstate.sh
@@ -43,6 +44,7 @@ telegraf:
- raid.sh
- redis.sh
- sostatus.sh
- features.sh
managersearch:
- eps.sh
- influxdbsize.sh
@@ -51,6 +53,7 @@ telegraf:
- raid.sh
- redis.sh
- sostatus.sh
- features.sh
import:
- influxdbsize.sh
- lasthighstate.sh
@@ -67,6 +70,7 @@ telegraf:
- suriloss.sh
- zeekcaptureloss.sh
- zeekloss.sh
- features.sh
heavynode:
- checkfiles.sh
- eps.sh
@@ -90,6 +94,7 @@ telegraf:
- os.sh
- raid.sh
- sostatus.sh
- features.sh
receiver:
- eps.sh
- lasthighstate.sh

View File

@@ -0,0 +1,17 @@
#!/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.
if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
FPS_ENABLED=$(cat /var/log/sostatus/fps_enabled)
LKS_ENABLED=$(cat /var/log/sostatus/lks_enabled)
echo "features fps=$FPS_ENABLED"
echo "features lks=$LKS_ENABLED"
fi
exit 0

View File

@@ -1,5 +1,5 @@
# 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
# 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.
@@ -46,6 +46,7 @@ base:
- zeek
- strelka
- elasticfleet.install_agent_grid
- stig
'*_eval and G@saltversion:{{saltversion}}':
- match: compound
@@ -110,6 +111,7 @@ base:
- soctopus
- playbook
- elasticfleet
- stig
'*_standalone and G@saltversion:{{saltversion}}':
- match: compound
@@ -128,7 +130,7 @@ base:
- sensoroni
- telegraf
- idstools
- suricata.manager
- suricata.manager
- healthcheck
- mysql
- elasticsearch
@@ -146,6 +148,7 @@ base:
- soctopus
- playbook
- elasticfleet
- stig
'*_searchnode and G@saltversion:{{saltversion}}':
- match: compound
@@ -157,6 +160,7 @@ base:
- elasticsearch
- logstash
- elasticfleet.install_agent_grid
- stig
'*_managersearch and G@saltversion:{{saltversion}}':
- match: compound
@@ -187,6 +191,7 @@ base:
- soctopus
- playbook
- elasticfleet
- stig
'*_heavynode and G@saltversion:{{saltversion}}':
- match: compound
@@ -206,7 +211,7 @@ base:
- zeek
- elasticfleet.install_agent_grid
- elasticagent
'*_import and G@saltversion:{{saltversion}}':
- match: compound
- salt.master

View File

@@ -1413,7 +1413,7 @@ make_some_dirs() {
mkdir -p $local_salt_dir/salt/firewall/portgroups
mkdir -p $local_salt_dir/salt/firewall/ports
for THEDIR in bpf pcap elasticsearch ntp firewall redis backup influxdb strelka sensoroni soc soctopus docker zeek suricata nginx telegraf logstash soc manager kratos idstools idh elastalert global;do
for THEDIR in bpf pcap elasticsearch ntp firewall redis backup influxdb strelka sensoroni soc soctopus docker zeek suricata nginx telegraf logstash soc manager kratos idstools idh elastalert stig global;do
mkdir -p $local_salt_dir/pillar/$THEDIR
touch $local_salt_dir/pillar/$THEDIR/adv_$THEDIR.sls
touch $local_salt_dir/pillar/$THEDIR/soc_$THEDIR.sls
@@ -1933,7 +1933,11 @@ saltify() {
logCmd "dnf -y install salt-$SALTVERSION salt-master-$SALTVERSION salt-minion-$SALTVERSION"
else
# We just need the minion
logCmd "dnf -y install salt-$SALTVERSION salt-minion-$SALTVERSION"
if [[ $is_airgap ]]; then
logCmd "dnf -y install salt salt-minion"
else
logCmd "dnf -y install salt-$SALTVERSION salt-minion-$SALTVERSION"
fi
fi
fi

Binary file not shown.