Compare commits

..

2 Commits

Author SHA1 Message Date
reyesj2 670d2b2757 casing 2026-06-30 12:57:56 -05:00
reyesj2 3b8459c6ec soup upgrade kafka cluster metadata v4 2026-06-30 12:43:42 -05:00
11 changed files with 78 additions and 252 deletions
-14
View File
@@ -291,20 +291,6 @@ download_and_verify() {
fi
}
# check if container with name is running and optionally stop it
docker_check_running() {
# show running containers, only names
if docker ps --format '{{.Names}}' | grep -q "^so-${1}$"; then
if [[ "$2" == "--stop" ]]; then
docker stop "so-${1}"
fi
return 0
else
return 1
fi
}
elastic_license() {
read -r -d '' message <<- EOM
+19 -33
View File
@@ -5,41 +5,27 @@
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
# Usage: so-restart kibana | playbook
. /usr/sbin/so-common
usage() {
echo "Usage: $0 <component> [args]"
echo ""
echo "Supported args:"
echo " --force | -f Force stop all Salt jobs before starting component."
echo ""
echo "Examples:"
echo " $0 kibana Restart Kibana"
echo " $0 kibana --force Force stop all Salt jobs before restarting Kibana"
exit 1
}
if [ $# -ge 1 ]; then
if [[ $# -lt 1 ]]; then
usage
fi
echo $banner
printf "Restarting $1...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n"
echo $banner
#shellcheck disable=SC2154
echo "$banner"
printf "Restarting %s...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n" "$1"
echo "$banner"
if [[ "$2" = "--force" ]] || [[ "$2" = "-f" ]]; then
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
salt-call saltutil.kill_all_jobs
if [ "$2" = "--force" ]; then
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
salt-call saltutil.kill_all_jobs
fi
case $1 in
"elastic-fleet") docker stop so-elastic-fleet && docker rm so-elastic-fleet && salt-call state.apply elasticfleet queue=True;;
*) docker stop so-$1 ; docker rm so-$1 ; salt-call state.apply $1 queue=True;;
esac
else
echo -e "\nPlease provide an argument by running like so-restart $component, or by using the component-specific script.\nEx. so-restart logstash, or so-logstash-restart\n"
fi
case $1 in
"elastic-fleet"|"elasticfleet")
docker_check_running "elastic-fleet" "--stop"
docker rm "so-elastic-fleet" 2> /dev/null
salt-call state.apply elasticfleet queue=True
;;
*)
docker_check_running "$1" "--stop"
docker rm "so-${1}" 2> /dev/null
salt-call state.apply "$1" queue=True
;;
esac
+20 -47
View File
@@ -5,54 +5,27 @@
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
# shellcheck disable=SC1091
# Usage: so-start all | kibana | playbook
. /usr/sbin/so-common
usage() {
echo "Usage: $0 <component> [args]"
echo ""
echo "Supported args:"
echo " --force | -f Force stop all Salt jobs before starting component."
echo ""
echo "Examples:"
echo " $0 kibana Start Kibana"
echo " $0 kibana --force Force stop all Salt jobs before starting Kibana"
exit 1
}
if [ $# -ge 1 ]; then
echo $banner
printf "Starting $1...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n"
echo $banner
if [[ $# -lt 1 ]]; then
usage
if [ "$2" = "--force" ]; then
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
salt-call saltutil.kill_all_jobs
fi
case $1 in
"all") salt-call state.highstate queue=True;;
"elastic-fleet") if docker ps | grep -q so-$1; then printf "\n$1 is already running!\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply elasticfleet queue=True; fi ;;
*) if docker ps | grep -E -q '^so-$1$'; then printf "\n$1 is already running\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply $1 queue=True; fi ;;
esac
else
echo -e "\nPlease provide an argument by running like so-start $component, or by using the component-specific script.\nEx. so-start logstash, or so-logstash-start\n"
fi
#shellcheck disable=SC2154
echo "$banner"
printf "Starting %s...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n" "$1"
echo "$banner"
if [[ "$2" = "--force" ]] || [[ "$2" == "-f" ]]; then
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
salt-call saltutil.kill_all_jobs
fi
case "$1" in
"all")
salt-call state.highstate queue=True
;;
"elastic-fleet"|"elasticfleet")
if docker_check_running "elastic-fleet"; then
printf "\nso-%s is already running!\n\n" "elastic-fleet"
/usr/sbin/so-status
else
docker rm "so-elastic-fleet" 2> /dev/null
salt-call state.apply elasticfleet queue=True
fi
;;
*)
if docker_check_running "$1"; then
printf "\nso-%s is already running\n\n" "$1"
/usr/sbin/so-status
else
docker rm "so-${1}" 2> /dev/null
salt-call state.apply "$1" queue=True
fi
;;
esac
+13 -25
View File
@@ -5,33 +5,21 @@
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
# shellcheck disable=SC1091
# Usage: so-stop kibana | playbook | thehive
. /usr/sbin/so-common
usage() {
echo "Usage: $0 <component>"
echo ""
echo "Examples:"
echo " $0 kibana Stop Kibana"
exit 1
}
if [ $# -ge 1 ]; then
echo $banner
printf "Stopping $1...\n"
echo $banner
if [[ $# -lt 1 ]]; then
usage
case $1 in
*) docker stop so-$1 ; docker rm so-$1 ;;
esac
else
echo -e "\nPlease provide an argument by running like so-stop $component, or by using the component-specific script.\nEx. so-stop logstash, or so-logstash-stop\n"
fi
#shellcheck disable=SC2154
echo "$banner"
printf "Stopping %s...\n" "$1"
echo "$banner"
case $1 in
"elasticfleet"|"elastic-fleet")
docker_check_running "elastic-fleet" "--stop"
docker rm "so-elastic-fleet" 2> /dev/null
;;
*)
docker_check_running "$1" "--stop"
docker rm "so-${1}" 2> /dev/null
;;
esac
+24
View File
@@ -850,6 +850,28 @@ kibana_backport_streams_index_template() {
}
# Runs kafka-features.sh upgrade --release-version $1
# Upgrades Kafka KRaft cluster metadata
update_kafka_metadata() {
metadata_version="$1"
global_pillar="/opt/so/saltstack/local/pillar/global/soc_global.sls"
if PIPELINE=$(so-yaml.py get -r "$global_pillar" global.pipeline 2> /dev/null) && [[ "$PIPELINE" == "KAFKA" ]]; then
kafka_nodes_raw=$(salt-call pillar.get kafka:nodes --out=json)
if kafka_nodes=$(jq -er '.local | select(type == "object" and length > 0)' <<< "$kafka_nodes_raw"); then
bootstrap_servers=$(jq -r '[to_entries[] | select(.value.role | contains("broker")) | "\(.value.ip):9092"] | join(",")' <<< "$kafka_nodes")
echo "Upgrading Kafka KRaft cluster version"
so-kafka-cli kafka-features.sh --bootstrap-server "$bootstrap_servers" --command-config /opt/kafka/config/kraft/client.properties upgrade --release-version "$metadata_version" 2>/dev/null || true
return 0
else
FINAL_MESSAGE_QUEUE+=("WARNING: Unable to automatically perform Kafka KRaft cluster metadata update. This step can be performed manually using the following command (replacing \$BROKER_IP with the ip of atleast 1 available Kafka broker):")
FINAL_MESSAGE_QUEUE+=(" - so-kafka-cli kafka-features.sh --bootstrap-server \$BROKER_IP:9092 --command-config /opt/kafka/config/kraft/client.properties upgrade --release-version $metadata_version")
fi
else
echo "Nothing to do!"
fi
}
up_to_3.2.0() {
fix_logstash_0013_lumberjack_pipeline_name
@@ -867,6 +889,8 @@ post_to_3.2.0() {
kibana_backport_streams_index_template
update_kafka_metadata "4.3"
POSTVERSION=3.2.0
}
-16
View File
@@ -134,22 +134,6 @@ socsigmasopipeline:
- group: 939
- mode: 600
socsigmaplaybookpipeline:
file.managed:
- name: /opt/so/conf/soc/sigma_playbook_pipeline.yaml
- source: salt://soc/files/soc/sigma_playbook_pipeline.yaml
- user: 939
- group: 939
- mode: 600
socplaybookplaceholdermap:
file.managed:
- name: /opt/so/conf/soc/playbook_placeholder_map.yaml
- source: salt://soc/files/soc/playbook_placeholder_map.yaml
- user: 939
- group: 939
- mode: 600
socbanner:
file.managed:
- name: /opt/so/conf/soc/banner.md
+2 -2
View File
@@ -1499,9 +1499,9 @@ soc:
playbookRepoPath: /opt/sensoroni/playbooks/
playbookRepos:
default:
- repo: https://github.com/defensivedepth/HCIP-Sigma
- repo: https://github.com/Security-Onion-Solutions/securityonion-resources-playbooks
branch: main
folder: playbooks
folder: securityonion-normalized
airgap:
- repo: file:///nsm/airgap-resources/playbooks/securityonion-resources-playbooks
branch: main
-3
View File
@@ -45,9 +45,7 @@ so-soc:
- /opt/so/conf/soc/motd.md:/opt/sensoroni/html/motd.md:ro
- /opt/so/conf/soc/banner.md:/opt/sensoroni/html/login/banner.md:ro
- /opt/so/conf/soc/sigma_so_pipeline.yaml:/opt/sensoroni/sigma_so_pipeline.yaml:ro
- /opt/so/conf/soc/sigma_playbook_pipeline.yaml:/opt/sensoroni/sigma_playbook_pipeline.yaml:ro
- /opt/so/conf/soc/sigma_final_pipeline.yaml:/opt/sensoroni/sigma_final_pipeline.yaml:rw
- /opt/so/conf/soc/playbook_placeholder_map.yaml:/opt/sensoroni/playbook_placeholder_map.yaml:ro
- /opt/so/conf/soc/custom.js:/opt/sensoroni/html/js/custom.js:ro
- /opt/so/conf/soc/custom_roles:/opt/sensoroni/rbac/custom_roles:ro
- /opt/so/conf/soc/soc_users_roles:/opt/sensoroni/rbac/users_roles:rw
@@ -101,7 +99,6 @@ so-soc:
- file: soccustomroles
- file: socusersroles
- file: socclientsroles
- file: socplaybookplaceholdermap
delete_so-soc_so-status.disabled:
file.uncomment:
@@ -1,49 +0,0 @@
# Global playbook placeholder map: %token% -> event field path.
#
# Loaded by the SOC Playbook module and used to resolve `field|expand:%placeholder%` values
# from an alert when converting playbook questions to OQL.
# Left: the %token% used in a question
# Right: the event field its value is read from (event_data.-nested or bare; the module
# tries both).
#
# Example: with `src_ip: source.ip` (below), a question that writes
# `source.ip|expand: '%src_ip%'` resolves %src_ip% to the alert's source.ip at convert time.
#
# This is the base layer - a playbook repo can extend it with a co-located *.placeholders.yaml
# config file that overlays these for that repo's playbooks.
CommandLine: process.command_line
CurrentDirectory: process.working_directory
Image: process.executable
ImageLoaded: dll.name
ParentImage: process.parent.executable
ParentName: process.parent.name
ParentProcessGuid: process.parent.entity_id
ProcessGuid: process.entity_id
TargetFilename: file.name
TargetObject: registry.path
TargetUserName: user.target.name
User: user.name
community_id: network.community_id
dns_resolved_ip: dns.resolved_ip
document_id: soc_id
dst_ip: destination.ip
dst_port: destination.port
event_data_source_ip: source.ip
file_path: file.path
file_dirs: process.file_dirs
file_name: process.name
file_paths: process.file_paths
hostname: host.name
private_ip: network.private_ip
public_ip: network.public_ip
related_hosts: related.hosts
related_ip: related.ip
src_ip: source.ip
dns_query_name: dns.query_name
flow_id: log.id.uid
payload: network.data.decoded
rule_category: rule.category
rule_name: rule.name
rule_uuid: rule.uuid
src_port: source.port
@@ -1,12 +0,0 @@
name: Security Onion - Playbook Pipeline
priority: 97
transformations:
# Route string fields to their lowercase-normalized .caseless subfield so wildcard
# matches are case-insensitive.
- id: case_insensitive_string_fields
type: field_name_mapping
mapping:
process.executable: process.executable.caseless
process.parent.executable: process.parent.executable.caseless
process.command_line: process.command_line.caseless
process.parent.command_line: process.parent.command_line.caseless
-51
View File
@@ -63,14 +63,6 @@ transformations:
rule_conditions:
- type: logsource
category: antivirus
# OS-agnostic process_creation scoping for product-less (NIDS/host-pivot) rules.
- id: process_creation_os_agnostic
type: add_condition
conditions:
event.category: process
rule_conditions:
- type: logsource
category: process_creation
# Transforms the `Hashes` field to ECS fields
# ECS fields are used by the hash fields emitted by Elastic Defend
# If shipped with Elastic Agent, sysmon logs will also have hashes mapped to ECS fields
@@ -116,40 +108,6 @@ transformations:
- type: logsource
product: windows
category: driver_load
- id: ecs_fix_process_creation
type: field_name_mapping
mapping:
# bare `Hashes` (the combined-string case is broken out above)
winlog.event_data.Hashes: process.hash.sha256
winlog.event_data.IntegrityLevel: process.Ext.token.integrity_level_name
winlog.event_data.ParentName: process.parent.name
rule_conditions:
- type: logsource
product: windows
category: process_creation
- id: ecs_fix_registry_set
type: field_name_mapping
mapping:
winlog.event_data.Details: registry.data.strings
# field rename only; EventType values (SetValue/CreateKey) still differ from
# event.action values (modification/creation)
winlog.event_data.EventType: event.action
rule_conditions:
- type: logsource
product: windows
category: registry_set
- id: ecs_fix_image_load
type: field_name_mapping
mapping:
file.path: dll.path
file.code_signature.signed: dll.code_signature.exists
winlog.event_data.Signature: dll.code_signature.subject_name
file.code_signature.status: dll.code_signature.status
winlog.event_data.Hashes: dll.hash.sha256
rule_conditions:
- type: logsource
product: windows
category: image_load
- id: linux_security_add-fields
type: add_condition
conditions:
@@ -323,15 +281,6 @@ transformations:
rule_conditions:
- type: logsource
category: file_event
# Scope image_load rules to Elastic Endpoint library events (event.category:library, dll.*
# populated).
- id: endpoint_image_load_add-fields
type: add_condition
conditions:
event.category: 'library'
rule_conditions:
- type: logsource
category: image_load
# Maps network rules to all network logs
# This targets all network logs, all services, generated from endpoints and network
- id: network_add-fields