Compare commits

..

13 Commits

Author SHA1 Message Date
Mike Reeves
e0e0e3e97b Exclude README from zkg sync 2026-03-17 13:36:56 -04:00
Mike Reeves
6b039b3f94 Consolidate zkg directory creation into file.recurse with makedirs 2026-03-17 13:36:03 -04:00
Mike Reeves
e6ee7dac7c Add salt states for custom Zeek package loading
Create /opt/so/conf/zeek/zkg directory and sync custom packages
from the manager via file.recurse. Bind mount the directory into
the so-zeek container so the entrypoint can install packages on
startup.
2026-03-17 13:22:59 -04:00
Jason Ertel
70597a77ab Merge pull request #15623 from Security-Onion-Solutions/jertel/wip
fix hydra health check
2026-03-17 07:53:00 -04:00
Jason Ertel
f5faf86cb3 fix hydra health check 2026-03-17 07:50:40 -04:00
Mike Reeves
be4e253620 Merge pull request #15621 from Security-Onion-Solutions/analyzer-cp314-wheels
Rebuild analyzer source-packages wheels for Python 3.14
2026-03-16 19:07:27 -04:00
Mike Reeves
ebc1152376 Rebuild all analyzer source-packages for Python 3.14
Full rebuild of all analyzer source-packages via pip download targeting
cp314/manylinux_2_17_x86_64 to match the so-soc Dockerfile base image
(python:3.14.3-slim).

Replaces cp313 wheels with cp314 for pyyaml and charset_normalizer,
and picks up certifi 2026.2.25 (from 2026.1.4).
2026-03-16 18:58:24 -04:00
Mike Reeves
625bfb3ba7 Rebuild analyzer source-packages wheels for Python 3.14
The so-soc Dockerfile base image moved to python:3.14.3-slim but
analyzer source-packages still contained cp313 wheels for pyyaml and
charset_normalizer, causing pip install failures at container startup.

Replace all cp313 wheels with cp314 builds (pyyaml 6.0.3,
charset_normalizer 3.4.6) across all 14 analyzers and update the
CI python-test workflow to match.
2026-03-16 18:58:23 -04:00
Jason Ertel
c11b83c712 Merge pull request #15622 from Security-Onion-Solutions/jertel/wip
fix health check for new hydra version
2026-03-16 18:45:34 -04:00
Jason Ertel
a3b471c1d1 fix health check for new hydra version 2026-03-16 18:43:36 -04:00
Mike Reeves
64bb0dfb5b Merge pull request #15610 from Security-Onion-Solutions/moresoup
Add -r flag to so-yaml get and migrate pcap pillar to suricata
2026-03-16 17:36:32 -04:00
Mike Reeves
ddb26a9f42 Add test for raw dict output in so-yaml get to reach 100% coverage
Covers the dict/list branch in raw mode (line 358) that was missing
test coverage.
2026-03-16 17:19:14 -04:00
Mike Reeves
4a89f7f26b Add -r flag to so-yaml get for raw output without YAML formatting
Preserve default get behavior with yaml.safe_dump output for backwards
compatibility. Add -r flag for clean scalar output used by soup pcap
migration.
2026-03-13 16:24:41 -04:00
118 changed files with 452 additions and 59 deletions

View File

@@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.13"]
python-version: ["3.14"]
python-code-path: ["salt/sensoroni/files/analyzers", "salt/manager/tools/sbin"]
steps:

View File

@@ -1,14 +1,24 @@
from os import path
import subprocess
def check():
osfam = __grains__['os_family']
retval = 'False'
cmd = 'needs-restarting -r > /dev/null 2>&1'
if osfam == 'Debian':
if path.exists('/var/run/reboot-required'):
retval = 'True'
try:
needs_restarting = subprocess.check_call(cmd, shell=True)
except subprocess.CalledProcessError:
retval = 'True'
elif osfam == 'RedHat':
cmd = 'needs-restarting -r > /dev/null 2>&1'
try:
needs_restarting = subprocess.check_call(cmd, shell=True)
except subprocess.CalledProcessError:
retval = 'True'
else:
retval = 'Unsupported OS: %s' % os
return retval

View File

@@ -3,6 +3,8 @@
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
{% from 'vars/globals.map.jinja' import GLOBALS %}
include:
- docker
@@ -16,3 +18,9 @@ trusttheca:
- show_changes: False
- makedirs: True
{% if GLOBALS.os_family == 'Debian' %}
symlinkca:
file.symlink:
- target: /etc/pki/tls/certs/intca.crt
- name: /etc/ssl/certs/intca.crt
{% endif %}

View File

@@ -20,6 +20,11 @@ kernel.printk:
sysctl.present:
- value: "3 4 1 3"
# Remove variables.txt from /tmp - This is temp
rmvariablesfile:
file.absent:
- name: /tmp/variables.txt
# Add socore Group
socoregroup:
group.present:
@@ -144,6 +149,28 @@ common_sbin_jinja:
- so-import-pcap
{% endif %}
{% if GLOBALS.role == 'so-heavynode' %}
remove_so-pcap-import_heavynode:
file.absent:
- name: /usr/sbin/so-pcap-import
remove_so-import-pcap_heavynode:
file.absent:
- name: /usr/sbin/so-import-pcap
{% endif %}
{% if not GLOBALS.is_manager%}
# prior to 2.4.50 these scripts were in common/tools/sbin on the manager because of soup and distributed to non managers
# these two states remove the scripts from non manager nodes
remove_soup:
file.absent:
- name: /usr/sbin/soup
remove_so-firewall:
file.absent:
- name: /usr/sbin/so-firewall
{% endif %}
so-status_script:
file.managed:
- name: /usr/sbin/so-status

View File

@@ -1,5 +1,52 @@
# we cannot import GLOBALS from vars/globals.map.jinja in this state since it is called in setup.virt.init
# since it is early in setup of a new VM, the pillars imported in GLOBALS are not yet defined
{% if grains.os_family == 'Debian' %}
commonpkgs:
pkg.installed:
- skip_suggestions: True
- pkgs:
- apache2-utils
- wget
- ntpdate
- jq
- curl
- ca-certificates
- software-properties-common
- apt-transport-https
- openssl
- netcat-openbsd
- sqlite3
- libssl-dev
- procps
- python3-dateutil
- python3-docker
- python3-packaging
- python3-lxml
- git
- rsync
- vim
- tar
- unzip
- bc
{% if grains.oscodename != 'focal' %}
- python3-rich
{% endif %}
{% if grains.oscodename == 'focal' %}
# since Ubuntu requires and internet connection we can use pip to install modules
python3-pip:
pkg.installed
python-rich:
pip.installed:
- name: rich
- target: /usr/local/lib/python3.8/dist-packages/
- require:
- pkg: python3-pip
{% endif %}
{% endif %}
{% if grains.os_family == 'RedHat' %}
remove_mariadb:
pkg.removed:
@@ -37,3 +84,5 @@ commonpkgs:
- unzip
- wget
- yum-utils
{% endif %}

View File

@@ -11,6 +11,14 @@
{% endif %}
{% set SOVERSION = salt['file.read']('/etc/soversion').strip() %}
remove_common_soup:
file.absent:
- name: /opt/so/saltstack/default/salt/common/tools/sbin/soup
remove_common_so-firewall:
file.absent:
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-firewall
# This section is used to put the scripts in place in the Salt file system
# in case a state run tries to overwrite what we do in the next section.
copy_so-common_common_tools_sbin:

34
salt/curator/disabled.sls Normal file
View File

@@ -0,0 +1,34 @@
# 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.
so-curator:
docker_container.absent:
- force: True
so-curator_so-status.disabled:
file.line:
- name: /opt/so/conf/so-status/so-status.conf
- match: ^so-curator$
- mode: delete
so-curator-cluster-close:
cron.absent:
- identifier: so-curator-cluster-close
so-curator-cluster-delete:
cron.absent:
- identifier: so-curator-cluster-delete
delete_curator_configuration:
file.absent:
- name: /opt/so/conf/curator
- recurse: True
{% set files = salt.file.find(path='/usr/sbin', name='so-curator*') %}
{% if files|length > 0 %}
delete_curator_scripts:
file.absent:
- names: {{files|yaml}}
{% endif %}

View File

@@ -15,6 +15,39 @@ dockergroup:
- name: docker
- gid: 920
{% if GLOBALS.os_family == 'Debian' %}
{% if grains.oscodename == 'bookworm' %}
dockerheldpackages:
pkg.installed:
- pkgs:
- containerd.io: 2.2.1-1~debian.12~bookworm
- docker-ce: 5:29.2.1-1~debian.12~bookworm
- docker-ce-cli: 5:29.2.1-1~debian.12~bookworm
- docker-ce-rootless-extras: 5:29.2.1-1~debian.12~bookworm
- hold: True
- update_holds: True
{% elif grains.oscodename == 'jammy' %}
dockerheldpackages:
pkg.installed:
- pkgs:
- containerd.io: 2.2.1-1~ubuntu.22.04~jammy
- docker-ce: 5:29.2.1-1~ubuntu.22.04~jammy
- docker-ce-cli: 5:29.2.1-1~ubuntu.22.04~jammy
- docker-ce-rootless-extras: 5:29.2.1-1~ubuntu.22.04~jammy
- hold: True
- update_holds: True
{% else %}
dockerheldpackages:
pkg.installed:
- pkgs:
- containerd.io: 1.7.21-1
- docker-ce: 5:27.2.0-1~ubuntu.20.04~focal
- docker-ce-cli: 5:27.2.0-1~ubuntu.20.04~focal
- docker-ce-rootless-extras: 5:27.2.0-1~ubuntu.20.04~focal
- hold: True
- update_holds: True
{% endif %}
{% else %}
dockerheldpackages:
pkg.installed:
- pkgs:
@@ -24,6 +57,7 @@ dockerheldpackages:
- docker-ce-rootless-extras: 29.2.1-1.el9
- hold: True
- update_holds: True
{% endif %}
#disable docker from managing iptables
iptables_disabled:

View File

@@ -6,6 +6,8 @@
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS with context %}
{% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %}
{# this is a list of dicts containing hostname:ip for elasticsearch nodes that need to know about each other for cluster #}
{% set ELASTICSEARCH_SEED_HOSTS = [] %}
{% set node_data = salt['pillar.get']('elasticsearch:nodes', {GLOBALS.role.split('-')[1]: {GLOBALS.hostname: {'ip': GLOBALS.node_ip}}}) %}
@@ -34,8 +36,14 @@
{% endfor %}
{% endif %}
{% elif grains.id.split('_') | last == 'searchnode' %}
{% if HIGHLANDER %}
{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.node.roles.extend(['ml', 'master', 'transform']) %}
{% endif %}
{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.update({'discovery': {'seed_hosts': [GLOBALS.manager]}}) %}
{% endif %}
{% if HIGHLANDER %}
{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.xpack.ml.update({'enabled': true}) %}
{% endif %}
{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.node.update({'name': GLOBALS.hostname}) %}
{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.cluster.update({'name': GLOBALS.hostname}) %}

View File

@@ -98,6 +98,10 @@ esrolesdir:
- group: 939
- makedirs: True
eslibdir:
file.absent:
- name: /opt/so/conf/elasticsearch/lib
esingestdynamicconf:
file.recurse:
- name: /opt/so/conf/elasticsearch/ingest
@@ -115,6 +119,11 @@ esingestconf:
- group: 939
- show_changes: False
# Remove .fleet_final_pipeline-1 because we are using global@custom now
so-fleet-final-pipeline-remove:
file.absent:
- name: /opt/so/conf/elasticsearch/ingest/.fleet_final_pipeline-1
# Auto-generate Elasticsearch ingest node pipelines from pillar
{% for pipeline, config in ELASTICSEARCHMERGED.pipelines.items() %}
es_ingest_conf_{{pipeline}}:

View File

@@ -1,3 +1,5 @@
{%- set HIGHLANDER = salt['pillar.get']('global:highlander', False) -%}
{%- raw -%}
{
"description" : "common",
"processors" : [
@@ -65,7 +67,19 @@
{ "append": { "if": "ctx.dataset_tag_temp != null", "field": "tags", "value": "{{dataset_tag_temp.1}}" } },
{ "grok": { "if": "ctx.http?.response?.status_code != null", "field": "http.response.status_code", "patterns": ["%{NUMBER:http.response.status_code:long} %{GREEDYDATA}"]} },
{ "set": { "if": "ctx?.metadata?.kafka != null" , "field": "kafka.id", "value": "{{metadata.kafka.partition}}{{metadata.kafka.offset}}{{metadata.kafka.timestamp}}", "ignore_failure": true } },
{ "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset", "dataset_tag_temp", "event.dataset_temp" ], "ignore_missing": true, "ignore_failure": true } },
{ "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset", "dataset_tag_temp", "event.dataset_temp" ], "ignore_missing": true, "ignore_failure": true } }
{%- endraw %}
{%- if HIGHLANDER %}
,
{
"pipeline": {
"name": "ecs"
}
}
{%- endif %}
{%- raw %}
,
{ "pipeline": { "name": "global@custom", "ignore_missing_pipeline": true, "description": "[Fleet] Global pipeline for all data streams" } }
]
}
{% endraw %}

View File

@@ -27,12 +27,14 @@ iptables_config:
- source: salt://firewall/iptables.jinja
- template: jinja
{% if grains.os_family == 'RedHat' %}
disable_firewalld:
service.dead:
- name: firewalld
- enable: False
- require:
- file: iptables_config
{% endif %}
iptables_restore:
cmd.run:
@@ -42,6 +44,7 @@ iptables_restore:
- onlyif:
- iptables-restore --test {{ iptmap.configfile }}
{% if grains.os_family == 'RedHat' %}
enable_firewalld:
service.running:
- name: firewalld
@@ -49,6 +52,7 @@ enable_firewalld:
- onfail:
- file: iptables_config
- cmd: iptables_restore
{% endif %}
{% else %}

View File

@@ -1,6 +1,14 @@
{% set iptmap = {
'service': 'iptables',
'iptpkg': 'iptables-nft',
'persistpkg': 'iptables-nft-services',
'configfile': '/etc/sysconfig/iptables'
} %}
{% set iptmap = salt['grains.filter_by']({
'Debian': {
'service': 'netfilter-persistent',
'iptpkg': 'iptables',
'persistpkg': 'iptables-persistent',
'configfile': '/etc/iptables/rules.v4'
},
'RedHat': {
'service': 'iptables',
'iptpkg': 'iptables-nft',
'persistpkg': 'iptables-nft-services',
'configfile': '/etc/sysconfig/iptables'
},
}) %}

View File

@@ -67,7 +67,7 @@ delete_so-hydra_so-status.disabled:
wait_for_hydra:
http.wait_for_successful_query:
- name: 'http://{{ GLOBALS.manager }}:4444/'
- name: 'http://{{ GLOBALS.manager }}:4444/health/alive'
- ssl: True
- verify_ssl: False
- status:

View File

@@ -3,6 +3,7 @@
include:
- idh.openssh
{% if grains.os_family == 'RedHat' %}
idh_sshd_selinux:
selinux.port_policy_present:
- port: {{ openssh_map.config.port }}
@@ -12,6 +13,7 @@ idh_sshd_selinux:
- file: openssh_config
- require:
- pkg: python_selinux_mgmt_tools
{% endif %}
openssh_config:
file.replace:

View File

@@ -16,6 +16,8 @@ openssh:
- name: {{ openssh_map.service }}
{% endif %}
{% if grains.os_family == 'RedHat' %}
python_selinux_mgmt_tools:
pkg.installed:
- name: policycoreutils-python-utils
{% endif %}

View File

@@ -5,6 +5,7 @@
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% import_yaml 'kibana/defaults.yaml' as KIBANADEFAULTS with context %}
{% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %}
{% do KIBANADEFAULTS.kibana.config.server.update({'publicBaseUrl': 'https://' ~ GLOBALS.url_base ~ '/kibana'}) %}
{% do KIBANADEFAULTS.kibana.config.elasticsearch.update({'hosts': ['https://' ~ GLOBALS.manager ~ ':9200']}) %}

View File

@@ -3,6 +3,7 @@
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
{% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %}
include:
- kibana.enabled
@@ -28,3 +29,27 @@ so-kibana-dashboard-load:
- require:
- sls: kibana.enabled
- file: dashboard_saved_objects_template
{%- if HIGHLANDER %}
dashboard_saved_objects_template_hl:
file.managed:
- name: /opt/so/conf/kibana/hl.ndjson.template
- source: salt://kibana/files/hl.ndjson
- user: 932
- group: 939
- show_changes: False
dashboard_saved_objects_hl_changes:
file.absent:
- names:
- /opt/so/state/kibana_hl.txt
- onchanges:
- file: dashboard_saved_objects_template_hl
so-kibana-dashboard-load_hl:
cmd.run:
- name: /usr/sbin/so-kibana-config-load -i /opt/so/conf/kibana/hl.ndjson.template
- cwd: /opt/so
- require:
- sls: kibana.enabled
- file: dashboard_saved_objects_template_hl
{%- endif %}

View File

@@ -1,5 +1,6 @@
#!/bin/bash
. /usr/sbin/so-common
{% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %}
wait_for_web_response "http://localhost:5601/api/spaces/space/default" "default" 300 "curl -K /opt/so/conf/elasticsearch/curl.config"
## This hackery will be removed if using Elastic Auth ##
@@ -8,6 +9,10 @@ SESSIONCOOKIE=$(curl -K /opt/so/conf/elasticsearch/curl.config -c - -X GET http:
# Disable certain Features from showing up in the Kibana UI
echo
echo "Setting up default Kibana Space:"
echo "Setting up default Space:"
{% if HIGHLANDER %}
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X PUT "localhost:5601/api/spaces/space/default" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d' {"id":"default","name":"Default","disabledFeatures":["enterpriseSearch"]} ' >> /opt/so/log/kibana/misc.log
{% else %}
curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -L -X PUT "localhost:5601/api/spaces/space/default" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d' {"id":"default","name":"Default","disabledFeatures":["ml","enterpriseSearch","logs","infrastructure","apm","uptime","monitoring","stackAlerts","actions","securitySolutionCasesV3","inventory","dataQuality","searchSynonyms","enterpriseSearchApplications","enterpriseSearchAnalytics","securitySolutionTimeline","securitySolutionNotes","entityManager"]} ' >> /opt/so/log/kibana/misc.log
{% endif %}
echo

View File

@@ -36,6 +36,10 @@ logstash:
- gid: 931
- home: /opt/so/conf/logstash
lslibdir:
file.absent:
- name: /opt/so/conf/logstash/lib
logstash_sbin:
file.recurse:
- name: /usr/sbin

View File

@@ -63,9 +63,11 @@ yara_log_dir:
- user
- group
{% if GLOBALS.os_family == 'RedHat' %}
install_createrepo:
pkg.installed:
- name: createrepo_c
{% endif %}
repo_conf_dir:
file.directory:

View File

@@ -134,8 +134,8 @@ function require() {
function verifyEnvironment() {
require "jq"
require "curl"
response=$(curl -Ss -L ${hydraUrl}/)
[[ "$response" != *"Error 404"* ]] && fail "Unable to communicate with Hydra; specify URL via HYDRA_URL environment variable"
response=$(curl -Ss -L ${hydraUrl}/health/alive)
[[ "$response" != '{"status":"ok"}' ]] && fail "Unable to communicate with Hydra; specify URL via HYDRA_URL environment variable"
}
function createFile() {

View File

@@ -22,7 +22,7 @@ def showUsage(args):
print(' removelistitem - Remove a list item from a yaml key, if it exists and is a list. Requires KEY and LISTITEM args.', file=sys.stderr)
print(' replacelistobject - Replace a list object based on a condition. Requires KEY, CONDITION_FIELD, CONDITION_VALUE, and JSON_OBJECT args.', file=sys.stderr)
print(' add - Add a new key and set its value. Fails if key already exists. Requires KEY and VALUE args.', file=sys.stderr)
print(' get - Displays (to stdout) the value stored in the given key. Requires KEY arg.', file=sys.stderr)
print(' get [-r] - Displays (to stdout) the value stored in the given key. Requires KEY arg. Use -r for raw output without YAML formatting.', file=sys.stderr)
print(' remove - Removes a yaml key, if it exists. Requires KEY arg.', file=sys.stderr)
print(' replace - Replaces (or adds) a new key and set its value. Requires KEY and VALUE args.', file=sys.stderr)
print(' help - Prints this usage information.', file=sys.stderr)
@@ -332,6 +332,11 @@ def getKeyValue(content, key):
def get(args):
raw = False
if len(args) > 0 and args[0] == '-r':
raw = True
args = args[1:]
if len(args) != 2:
print('Missing filename or key arg', file=sys.stderr)
showUsage(None)
@@ -346,12 +351,15 @@ def get(args):
print(f"Key '{key}' not found by so-yaml.py", file=sys.stderr)
return 2
if isinstance(output, bool):
print(str(output).lower())
elif isinstance(output, (dict, list)):
print(yaml.safe_dump(output).strip())
if raw:
if isinstance(output, bool):
print(str(output).lower())
elif isinstance(output, (dict, list)):
print(yaml.safe_dump(output).strip())
else:
print(output)
else:
print(output)
print(yaml.safe_dump(output))
return 0

View File

@@ -393,6 +393,17 @@ class TestRemove(unittest.TestCase):
result = soyaml.get([filename, "key1.child2.deep1"])
self.assertEqual(result, 0)
self.assertIn("45\n...", mock_stdout.getvalue())
def test_get_int_raw(self):
with patch('sys.stdout', new=StringIO()) as mock_stdout:
filename = "/tmp/so-yaml_test-get.yaml"
file = open(filename, "w")
file.write("{key1: { child1: 123, child2: { deep1: 45 } }, key2: false, key3: [e,f,g]}")
file.close()
result = soyaml.get(["-r", filename, "key1.child2.deep1"])
self.assertEqual(result, 0)
self.assertEqual("45\n", mock_stdout.getvalue())
def test_get_str(self):
@@ -404,6 +415,17 @@ class TestRemove(unittest.TestCase):
result = soyaml.get([filename, "key1.child2.deep1"])
self.assertEqual(result, 0)
self.assertIn("hello\n...", mock_stdout.getvalue())
def test_get_str_raw(self):
with patch('sys.stdout', new=StringIO()) as mock_stdout:
filename = "/tmp/so-yaml_test-get.yaml"
file = open(filename, "w")
file.write("{key1: { child1: 123, child2: { deep1: \"hello\" } }, key2: false, key3: [e,f,g]}")
file.close()
result = soyaml.get(["-r", filename, "key1.child2.deep1"])
self.assertEqual(result, 0)
self.assertEqual("hello\n", mock_stdout.getvalue())
def test_get_bool(self):
@@ -415,8 +437,31 @@ class TestRemove(unittest.TestCase):
result = soyaml.get([filename, "key2"])
self.assertEqual(result, 0)
self.assertIn("false\n...", mock_stdout.getvalue())
def test_get_bool_raw(self):
with patch('sys.stdout', new=StringIO()) as mock_stdout:
filename = "/tmp/so-yaml_test-get.yaml"
file = open(filename, "w")
file.write("{key1: { child1: 123, child2: { deep1: 45 } }, key2: false, key3: [e,f,g]}")
file.close()
result = soyaml.get(["-r", filename, "key2"])
self.assertEqual(result, 0)
self.assertEqual("false\n", mock_stdout.getvalue())
def test_get_dict_raw(self):
with patch('sys.stdout', new=StringIO()) as mock_stdout:
filename = "/tmp/so-yaml_test-get.yaml"
file = open(filename, "w")
file.write("{key1: { child1: 123, child2: { deep1: 45 } }, key2: false, key3: [e,f,g]}")
file.close()
result = soyaml.get(["-r", filename, "key1"])
self.assertEqual(result, 0)
self.assertIn("child1: 123", mock_stdout.getvalue())
self.assertNotIn("...", mock_stdout.getvalue())
def test_get_list(self):
with patch('sys.stdout', new=StringIO()) as mock_stdout:
filename = "/tmp/so-yaml_test-get.yaml"

View File

@@ -396,7 +396,7 @@ migrate_pcap_to_suricata() {
for pillar_file in "$PCAPFILE" "$MINIONDIR"/*.sls; do
[[ -f "$pillar_file" ]] || continue
pcap_enabled=$(so-yaml.py get "$pillar_file" pcap.enabled 2>/dev/null) || continue
pcap_enabled=$(so-yaml.py get -r "$pillar_file" pcap.enabled 2>/dev/null) || continue
so-yaml.py add "$pillar_file" suricata.pcap.enabled "$pcap_enabled"
so-yaml.py remove "$pillar_file" pcap
done

View File

@@ -2,6 +2,7 @@
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% from 'ntp/config.map.jinja' import NTPCONFIG %}
chrony_pkg:
@@ -16,7 +17,11 @@ chronyconf:
- defaults:
NTPCONFIG: {{ NTPCONFIG }}
{% if GLOBALS.os_family == 'RedHat' %}
chronyd:
{% else %}
chrony:
{% endif %}
service.running:
- enable: True
- watch:

View File

@@ -1,29 +1,43 @@
{% set REPOPATH = '/etc/yum.repos.d/' %}
{% set ABSENTFILES = [
'centos-addons.repo',
'centos-devel.repo',
'centos-extras.repo',
'centos.repo',
'docker-ce.repo',
'epel.repo',
'epel-testing.repo',
'saltstack.repo',
'salt-latest.repo',
'wazuh.repo'
'Rocky-Base.repo',
'Rocky-CR.repo',
'Rocky-Debuginfo.repo',
'Rocky-fasttrack.repo',
'Rocky-Media.repo',
'Rocky-Sources.repo',
'Rocky-Vault.repo',
'Rocky-x86_64-kernel.repo',
'rocky-addons.repo',
'rocky-devel.repo',
'rocky-extras.repo',
'rocky.repo',
'oracle-linux-ol9.repo',
'uek-ol9.repo',
'virt-ol9.repo'
]
%}
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% if GLOBALS.os_family == 'RedHat' %}
{% set REPOPATH = '/etc/yum.repos.d/' %}
{% if GLOBALS.os == 'OEL' %}
{% set ABSENTFILES = [
'centos-addons.repo',
'centos-devel.repo',
'centos-extras.repo',
'centos.repo',
'docker-ce.repo',
'epel.repo',
'epel-testing.repo',
'saltstack.repo',
'salt-latest.repo',
'wazuh.repo'
'Rocky-Base.repo',
'Rocky-CR.repo',
'Rocky-Debuginfo.repo',
'Rocky-fasttrack.repo',
'Rocky-Media.repo',
'Rocky-Sources.repo',
'Rocky-Vault.repo',
'Rocky-x86_64-kernel.repo',
'rocky-addons.repo',
'rocky-devel.repo',
'rocky-extras.repo',
'rocky.repo',
'oracle-linux-ol9.repo',
'uek-ol9.repo',
'virt-ol9.repo'
]
%}
{% else %}
{% set ABSENTFILES = [] %}
{% endif %}
{% else %}
{% set REPOPATH = '/etc/apt/sources.list.d/' %}
{% set ABSENTFILES = [] %}
{% endif %}

View File

@@ -1,3 +1,10 @@
{% if grains.oscodename == 'focal' %}
saltpymodules:
pkg.installed:
- pkgs:
- python3-docker
{% endif %}
# distribute to minions for salt upgrades
salt_bootstrap:
file.managed:

View File

@@ -17,12 +17,22 @@
{% set SALTVERSION = saltminion.salt.minion.version | string %}
{% set INSTALLEDSALTVERSION = grains.saltversion | string %}
{% set SPLITCHAR = '-' %}
{% set SALTPACKAGES = ['salt', 'salt-master', 'salt-minion', 'salt-cloud'] %}
{% set SYSTEMD_UNIT_FILE = '/usr/lib/systemd/system/salt-minion.service' %}
{% if grains.os_family == 'Debian' %}
{% set SPLITCHAR = '+' %}
{% set SALTPACKAGES = ['salt-common', 'salt-master', 'salt-minion', 'salt-cloud'] %}
{% set SYSTEMD_UNIT_FILE = '/lib/systemd/system/salt-minion.service' %}
{% else %}
{% set SPLITCHAR = '-' %}
{% set SALTPACKAGES = ['salt', 'salt-master', 'salt-minion', 'salt-cloud'] %}
{% set SYSTEMD_UNIT_FILE = '/usr/lib/systemd/system/salt-minion.service' %}
{% endif %}
{% if INSTALLEDSALTVERSION != SALTVERSION %}
{% set UPGRADECOMMAND = 'yum clean all ; /usr/sbin/bootstrap-salt.sh -X -r -F stable ' ~ SALTVERSION %}
{% if grains.os_family|lower == 'redhat' %}
{% set UPGRADECOMMAND = 'yum clean all ; /usr/sbin/bootstrap-salt.sh -X -r -F stable ' ~ SALTVERSION %}
{% elif grains.os_family|lower == 'debian' %}
{% set UPGRADECOMMAND = '/usr/sbin/bootstrap-salt.sh -X -F stable ' ~ SALTVERSION %}
{% endif %}
{% else %}
{% set UPGRADECOMMAND = 'echo Already running Salt Minion version ' ~ SALTVERSION %}
{% endif %}

View File

@@ -23,6 +23,15 @@ sync_runners:
- name: saltutil.sync_runners
{% endif %}
# prior to 2.4.30 this engine ran on the manager with salt-minion
# this has changed to running with the salt-master in 2.4.30
remove_engines_config:
file.absent:
- name: /etc/salt/minion.d/engines.conf
- source: salt://salt/files/engines.conf
- watch_in:
- service: salt_minion_service
checkmine_engine:
file.managed:
- name: /etc/salt/engines/checkmine.py

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