From 47a580d11068c32ce744167deb5ffbbdf519b548 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 5 May 2023 13:59:52 -0400 Subject: [PATCH 01/68] fix enabled and disable steno in ui --- salt/common/tools/sbin/so-minion | 4 +- salt/pcap/config.map.jinja | 5 +- salt/pcap/defaults.yaml | 20 ++-- salt/pcap/disabled.sls | 19 ++++ salt/pcap/enabled.sls | 131 ++++++++++++++++++++++++++ salt/pcap/files/config.jinja | 4 +- salt/pcap/init.sls | 152 ++----------------------------- salt/pcap/map.jinja | 11 --- salt/pcap/sostatus.sls | 5 + 9 files changed, 177 insertions(+), 174 deletions(-) create mode 100644 salt/pcap/disabled.sls create mode 100644 salt/pcap/enabled.sls delete mode 100644 salt/pcap/map.jinja create mode 100644 salt/pcap/sostatus.sls diff --git a/salt/common/tools/sbin/so-minion b/salt/common/tools/sbin/so-minion index 2f506863d..541104c4d 100755 --- a/salt/common/tools/sbin/so-minion +++ b/salt/common/tools/sbin/so-minion @@ -214,8 +214,8 @@ function add_sensor_to_minion() { echo " config:" >> $PILLARFILE echo " af-packet:" >> $PILLARFILE echo " threads: '$CORECOUNT'" >> $PILLARFILE - echo "pcap:" >> $PILLARFILE - echo " enabled: True" >> $PILLARFILE +# echo "pcap:" >> $PILLARFILE +# echo " enabled: True" >> $PILLARFILE } function create_fleet_policy() { diff --git a/salt/pcap/config.map.jinja b/salt/pcap/config.map.jinja index f335c9380..88e3a83dd 100644 --- a/salt/pcap/config.map.jinja +++ b/salt/pcap/config.map.jinja @@ -1,3 +1,2 @@ -{% import_yaml 'pcap/defaults.yaml' as pcap_defaults with context %} -{% set pcap_pillar = pillar.pcap %} -{% set PCAPMERGED = salt['defaults.merge'](pcap_defaults, pcap_pillar, in_place=False) %} +{% import_yaml 'pcap/defaults.yaml' as PCAPDEFAULTS %} +{% set PCAPMERGED = salt['pillar.get']('pcap', PCAPDEFAULTS.pcap, merge=True) %} diff --git a/salt/pcap/defaults.yaml b/salt/pcap/defaults.yaml index 701cde04d..5c9b141b4 100644 --- a/salt/pcap/defaults.yaml +++ b/salt/pcap/defaults.yaml @@ -1,11 +1,11 @@ pcap: - enabled: True - config: - maxdirectoryfiles: 30000 - diskfreepercentage: 10 - blocks: 2048 - preallocate_file_mb: 4096 - aiops: 128 - pin_to_cpu: False - cpus_to_pin_to: [] - disks: [] \ No newline at end of file + enabled: True + config: + maxdirectoryfiles: 30000 + diskfreepercentage: 10 + blocks: 2048 + preallocate_file_mb: 4096 + aiops: 128 + pin_to_cpu: False + cpus_to_pin_to: [] + disks: [] diff --git a/salt/pcap/disabled.sls b/salt/pcap/disabled.sls new file mode 100644 index 000000000..b9afd6e15 --- /dev/null +++ b/salt/pcap/disabled.sls @@ -0,0 +1,19 @@ +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} + +so-steno: + docker_container.absent: + - force: True + +so-steno_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-steno$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/pcap/enabled.sls b/salt/pcap/enabled.sls new file mode 100644 index 000000000..803c31e3a --- /dev/null +++ b/salt/pcap/enabled.sls @@ -0,0 +1,131 @@ +# 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 %} + +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from "pcap/config.map.jinja" import PCAPMERGED with context %} +{% from 'bpf/pcap.map.jinja' import PCAPBPF %} + +{% set BPF_COMPILED = "" %} + +# PCAP Section + +stenographergroup: + group.present: + - name: stenographer + - gid: 941 + +stenographer: + user.present: + - uid: 941 + - gid: 941 + - home: /opt/so/conf/steno + +stenoconfdir: + file.directory: + - name: /opt/so/conf/steno + - user: 941 + - group: 939 + - makedirs: True + +{% if PCAPBPF %} + {% set BPF_CALC = salt['cmd.script']('/usr/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + PCAPBPF|join(" "),cwd='/root') %} + {% if BPF_CALC['stderr'] == "" %} + {% set BPF_COMPILED = ",\\\"--filter=" + BPF_CALC['stdout'] + "\\\"" %} + {% else %} + +bpfcompilationfailure: + test.configurable_test_state: + - changes: False + - result: False + - comment: "BPF Compilation Failed - Discarding Specified BPF" + {% endif %} +{% endif %} + +stenoconf: + file.managed: + - name: /opt/so/conf/steno/config + - source: salt://pcap/files/config.jinja + - user: stenographer + - group: stenographer + - mode: 644 + - template: jinja + - defaults: + PCAPMERGED: {{ PCAPMERGED }} + BPF_COMPILED: "{{ BPF_COMPILED }}" + +stenoca: + file.directory: + - name: /opt/so/conf/steno/certs + - user: 941 + - group: 939 + +pcapdir: + file.directory: + - name: /nsm/pcap + - user: 941 + - group: 941 + - makedirs: True + +pcaptmpdir: + file.directory: + - name: /nsm/pcaptmp + - user: 941 + - group: 941 + - makedirs: True + +pcapoutdir: + file.directory: + - name: /nsm/pcapout + - user: 939 + - group: 939 + - makedirs: True + +pcapindexdir: + file.directory: + - name: /nsm/pcapindex + - user: 941 + - group: 941 + - makedirs: True + +stenolog: + file.directory: + - name: /opt/so/log/stenographer + - user: 941 + - group: 941 + - makedirs: True + +so-steno: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-steno:{{ GLOBALS.so_version }} + - start: True + - network_mode: host + - privileged: True + - binds: + - /opt/so/conf/steno/certs:/etc/stenographer/certs:rw + - /opt/so/conf/steno/config:/etc/stenographer/config:rw + - /nsm/pcap:/nsm/pcap:rw + - /nsm/pcapindex:/nsm/pcapindex:rw + - /nsm/pcaptmp:/tmp:rw + - /opt/so/log/stenographer:/var/log/stenographer:rw + - watch: + - file: stenoconf + - require: + - file: stenoconf + +delete_so-steno_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-steno$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/pcap/files/config.jinja b/salt/pcap/files/config.jinja index 420d12639..f0a4fc51d 100644 --- a/salt/pcap/files/config.jinja +++ b/salt/pcap/files/config.jinja @@ -1,11 +1,11 @@ { "Threads": [ - { "PacketsDirectory": "/nsm/pcap", "IndexDirectory": "/nsm/pcapindex", "MaxDirectoryFiles": {{ PCAPMERGED.pcap.config.maxdirectoryfiles }}, "DiskFreePercentage": {{ PCAPMERGED.pcap.config.diskfreepercentage }} } + { "PacketsDirectory": "/nsm/pcap", "IndexDirectory": "/nsm/pcapindex", "MaxDirectoryFiles": {{ PCAPMERGED.config.maxdirectoryfiles }}, "DiskFreePercentage": {{ PCAPMERGED.config.diskfreepercentage }} } ] , "StenotypePath": "/usr/bin/stenotype" , "Interface": "{{ pillar.sensor.interface }}" , "Port": 1234 , "Host": "127.0.0.1" - , "Flags": ["-v", "--blocks={{ PCAPMERGED.pcap.config.blocks }}", "--preallocate_file_mb={{ PCAPMERGED.pcap.config.preallocate_file_mb }}", "--aiops={{ PCAPMERGED.pcap.config.aiops }}", "--uid=stenographer", "--gid=stenographer"{{ BPF_COMPILED }}] + , "Flags": ["-v", "--blocks={{ PCAPMERGED.config.blocks }}", "--preallocate_file_mb={{ PCAPMERGED.config.preallocate_file_mb }}", "--aiops={{ PCAPMERGED.config.aiops }}", "--uid=stenographer", "--gid=stenographer"{{ BPF_COMPILED }}] , "CertPath": "/etc/stenographer/certs" } diff --git a/salt/pcap/init.sls b/salt/pcap/init.sls index 73b384a53..31ac4dd31 100644 --- a/salt/pcap/init.sls +++ b/salt/pcap/init.sls @@ -1,149 +1,9 @@ -# 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 in allowed_states %} - -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from "pcap/map.jinja" import STENOOPTIONS with context %} -{% from "pcap/config.map.jinja" import PCAPMERGED with context %} -{% from 'bpf/pcap.map.jinja' import PCAPBPF %} - -{% set BPF_COMPILED = "" %} - -# PCAP Section - -stenographergroup: - group.present: - - name: stenographer - - gid: 941 - -stenographer: - user.present: - - uid: 941 - - gid: 941 - - home: /opt/so/conf/steno - -stenoconfdir: - file.directory: - - name: /opt/so/conf/steno - - user: 941 - - group: 939 - - makedirs: True - -{% if PCAPBPF %} - {% set BPF_CALC = salt['cmd.script']('/usr/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + PCAPBPF|join(" "),cwd='/root') %} - {% if BPF_CALC['stderr'] == "" %} - {% set BPF_COMPILED = ",\\\"--filter=" + BPF_CALC['stdout'] + "\\\"" %} - {% else %} - -bpfcompilationfailure: - test.configurable_test_state: - - changes: False - - result: False - - comment: "BPF Compilation Failed - Discarding Specified BPF" - {% endif %} -{% endif %} - -stenoconf: - file.managed: - - name: /opt/so/conf/steno/config - - source: salt://pcap/files/config.jinja - - user: stenographer - - group: stenographer - - mode: 644 - - template: jinja - - defaults: - PCAPMERGED: {{ PCAPMERGED }} - BPF_COMPILED: "{{ BPF_COMPILED }}" - -stenoca: - file.directory: - - name: /opt/so/conf/steno/certs - - user: 941 - - group: 939 - -pcapdir: - file.directory: - - name: /nsm/pcap - - user: 941 - - group: 941 - - makedirs: True - -pcaptmpdir: - file.directory: - - name: /nsm/pcaptmp - - user: 941 - - group: 941 - - makedirs: True - -pcapoutdir: - file.directory: - - name: /nsm/pcapout - - user: 939 - - group: 939 - - makedirs: True - -pcapindexdir: - file.directory: - - name: /nsm/pcapindex - - user: 941 - - group: 941 - - makedirs: True - -stenolog: - file.directory: - - name: /opt/so/log/stenographer - - user: 941 - - group: 941 - - makedirs: True - -so-steno: - docker_container.{{ STENOOPTIONS.status }}: - {% if STENOOPTIONS.status == 'running' %} - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-steno:{{ GLOBALS.so_version }} - - start: {{ STENOOPTIONS.start }} - - network_mode: host - - privileged: True - - binds: - - /opt/so/conf/steno/certs:/etc/stenographer/certs:rw - - /opt/so/conf/steno/config:/etc/stenographer/config:rw - - /nsm/pcap:/nsm/pcap:rw - - /nsm/pcapindex:/nsm/pcapindex:rw - - /nsm/pcaptmp:/tmp:rw - - /opt/so/log/stenographer:/var/log/stenographer:rw - - watch: - - file: stenoconf - - require: - - file: stenoconf - {% else %} {# if stenographer isn't enabled, then stop and remove the container #} - - force: True - {% endif %} - -append_so-steno_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-steno - - unless: grep -q so-steno /opt/so/conf/so-status/so-status.conf - - {% if not STENOOPTIONS.start %} -so-steno_so-status.disabled: - file.comment: - - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-steno$ - {% else %} -delete_so-steno_so-status.disabled: - file.uncomment: - - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-steno$ - {% endif %} +{% from 'pcap/config.map.jinja' import PCAPMERGED %} +include: + - pcap.sostatus +{% if PCAPMERGED.enabled %} + - pcap.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - pcap.disabled {% endif %} diff --git a/salt/pcap/map.jinja b/salt/pcap/map.jinja deleted file mode 100644 index ee939a0b4..000000000 --- a/salt/pcap/map.jinja +++ /dev/null @@ -1,11 +0,0 @@ -{% set STENOOPTIONS = {} %} -{% set ENABLED = salt['pillar.get']('steno:enabled', 'True') %} - -# don't start the docker container if it is an import node or disabled via pillar -{% if grains.id.split('_')|last == 'import' or ENABLED is sameas false %} - {% do STENOOPTIONS.update({'start': False}) %} - {% do STENOOPTIONS.update({'status': 'absent'}) %} -{% else %} - {% do STENOOPTIONS.update({'start': True}) %} - {% do STENOOPTIONS.update({'status': 'running'}) %} -{% endif %} diff --git a/salt/pcap/sostatus.sls b/salt/pcap/sostatus.sls new file mode 100644 index 000000000..9e23892c9 --- /dev/null +++ b/salt/pcap/sostatus.sls @@ -0,0 +1,5 @@ +append_so-steno_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-steno + - unless: grep -q so-steno /opt/so/conf/so-status/so-status.conf From 2a8ed240454ea479ae14001b07ee88f007f7fba2 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 5 May 2023 15:35:04 -0400 Subject: [PATCH 02/68] import GLOBALS --- salt/pcap/config.sls | 2 +- salt/pcap/enabled.sls | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/salt/pcap/config.sls b/salt/pcap/config.sls index c83abfe0f..26236e2ff 100644 --- a/salt/pcap/config.sls +++ b/salt/pcap/config.sls @@ -7,7 +7,7 @@ {% if sls.split('.')[0] in allowed_states %} {% from 'vars/globals.map.jinja' import GLOBALS %} -{% from "pcap/config.map.jinja" import PCAPMERGED with context %} +{% from "pcap/config.map.jinja" import PCAPMERGED %} {% from 'bpf/pcap.map.jinja' import PCAPBPF %} {% set BPF_COMPILED = "" %} diff --git a/salt/pcap/enabled.sls b/salt/pcap/enabled.sls index 6d2e79b61..b4027065f 100644 --- a/salt/pcap/enabled.sls +++ b/salt/pcap/enabled.sls @@ -5,6 +5,7 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} include: - pcap.config From a97fa9675b51fb8643d308e12f7f8c841d4e35d9 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 5 May 2023 16:33:59 -0400 Subject: [PATCH 03/68] enable/disable zeek in ui --- salt/zeek/config.map.jinja | 20 +-- salt/zeek/config.sls | 197 +++++++++++++++++++++++++ salt/zeek/defaults.yaml | 1 + salt/zeek/disabled.sls | 28 ++++ salt/zeek/enabled.sls | 65 +++++++++ salt/zeek/init.sls | 289 ++----------------------------------- salt/zeek/sostatus.sls | 16 ++ 7 files changed, 319 insertions(+), 297 deletions(-) create mode 100644 salt/zeek/config.sls create mode 100644 salt/zeek/disabled.sls create mode 100644 salt/zeek/enabled.sls create mode 100644 salt/zeek/sostatus.sls diff --git a/salt/zeek/config.map.jinja b/salt/zeek/config.map.jinja index 181666227..a2e68d825 100644 --- a/salt/zeek/config.map.jinja +++ b/salt/zeek/config.map.jinja @@ -1,28 +1,14 @@ {% from 'vars/sensor.map.jinja' import ROLE_GLOBALS %} -{% import_yaml 'zeek/defaults.yaml' as zeek_defaults with context %} -{% set ZEEKMERGED = salt['pillar.get']('zeek', zeek_defaults.zeek, merge=True) %} +{% import_yaml 'zeek/defaults.yaml' as ZEEKDEFAULTS with context %} +{% set ZEEKMERGED = salt['pillar.get']('zeek', ZEEKDEFAULTS.zeek, merge=True) %} {% do ZEEKMERGED.config.node.update({'interface': ROLE_GLOBALS.sensor.interface}) %} +{# we have to add the @ sign for the config since we remove it from defaults for the UI #} {% if ZEEKMERGED.config.local.load is defined %} {% set LOCALLOAD = ZEEKMERGED.config.local.pop('load') %} {% do ZEEKMERGED.config.local.update({'@load': LOCALLOAD}) %} {% endif %} - {% if ZEEKMERGED.config.local['load-sigs'] is defined %} {% set LOCALLOADSIGS = ZEEKMERGED.config.local.pop('load-sigs') %} {% do ZEEKMERGED.config.local.update({'@load-sigs': LOCALLOADSIGS}) %} {% endif %} - -{% set ZEEKOPTIONS = {} %} -{% set ENABLED = salt['pillar.get']('zeek:enabled', True) %} - -# don't start the docker container if it is an import node or disabled via pillar -{% if grains.id.split('_')|last == 'import' or not ENABLED %} - {% do ZEEKOPTIONS.update({'start': False}) %} - {% do ZEEKOPTIONS.update({'pl_cron_state': 'absent'}) %} - {% do ZEEKOPTIONS.update({'status': 'absent'}) %} -{% else %} - {% do ZEEKOPTIONS.update({'start': True}) %} - {% do ZEEKOPTIONS.update({'pl_cron_state': 'present'}) %} - {% do ZEEKOPTIONS.update({'status': 'running'}) %} -{% endif %} diff --git a/salt/zeek/config.sls b/salt/zeek/config.sls new file mode 100644 index 000000000..ab82bbc57 --- /dev/null +++ b/salt/zeek/config.sls @@ -0,0 +1,197 @@ +# 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 %} + +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from "zeek/config.map.jinja" import ZEEKMERGED %} + +{% from 'bpf/zeek.map.jinja' import ZEEKBPF %} + +{% set BPF_STATUS = 0 %} + +# Add Zeek group +zeekgroup: + group.present: + - name: zeek + - gid: 937 + +# Add Zeek User +zeek: + user.present: + - uid: 937 + - gid: 937 + - home: /home/zeek + +# Create some directories +zeekpolicydir: + file.directory: + - name: /opt/so/conf/zeek/policy + - user: 937 + - group: 939 + - makedirs: True + +# Zeek Log Directory +zeeklogdir: + file.directory: + - name: /nsm/zeek/logs + - user: 937 + - group: 939 + - makedirs: True + +# Zeek Spool Directory +zeekspooldir: + file.directory: + - name: /nsm/zeek/spool/manager + - user: 937 + - makedirs: True + +# Zeek extracted +zeekextractdir: + file.directory: + - name: /nsm/zeek/extracted + - user: 937 + - group: 939 + - mode: 770 + - makedirs: True + +zeekextractcompletedir: + file.directory: + - name: /nsm/zeek/extracted/complete + - user: 937 + - group: 939 + - mode: 770 + - makedirs: True + +# Sync the policies +zeekpolicysync: + file.recurse: + - name: /opt/so/conf/zeek/policy + - source: salt://zeek/policy + - user: 937 + - group: 939 + - template: jinja + - defaults: + FILE_EXTRACTION: {{ ZEEKMERGED.file_extraction }} + +# Ensure the zeek spool tree (and state.db) ownership is correct +zeekspoolownership: + file.directory: + - name: /nsm/zeek/spool + - user: 937 +zeekstatedbownership: + file.managed: + - name: /nsm/zeek/spool/state.db + - user: 937 + - replace: False + - create: False + +zeek_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://zeek/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#zeek_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://zeek/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +# Sync Intel +zeekintelloadsync: + file.managed: + - name: /opt/so/conf/policy/intel/__load__.zeek + - source: salt://zeek/policy/intel/__load__.zeek + - user: 937 + - group: 939 + - makedirs: True + +zeekctlcfg: + file.managed: + - name: /opt/so/conf/zeek/zeekctl.cfg + - source: salt://zeek/files/zeekctl.cfg.jinja + - user: 937 + - group: 939 + - template: jinja + - defaults: + ZEEKCTL: {{ ZEEKMERGED.config.zeekctl | tojson }} + +# Sync node.cfg +nodecfg: + file.managed: + - name: /opt/so/conf/zeek/node.cfg + - source: salt://zeek/files/node.cfg.jinja + - user: 937 + - group: 939 + - template: jinja + - defaults: + NODE: {{ ZEEKMERGED.config.node }} + +networkscfg: + file.managed: + - name: /opt/so/conf/zeek/networks.cfg + - source: salt://zeek/files/networks.cfg.jinja + - user: 937 + - group: 939 + - template: jinja + - defaults: + NETWORKS: {{ ZEEKMERGED.config.networks }} + +plcronscript: + file.managed: + - name: /usr/local/bin/packetloss.sh + - source: salt://zeek/cron/packetloss.sh + - mode: 755 + +# BPF compilation and configuration +{% if ZEEKBPF %} + {% set BPF_CALC = salt['cmd.script']('/usr/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + ZEEKBPF|join(" "),cwd='/root') %} + {% if BPF_CALC['stderr'] == "" %} + {% set BPF_STATUS = 1 %} + {% else %} +zeekbpfcompilationfailure: + test.configurable_test_state: + - changes: False + - result: False + - comment: "BPF Syntax Error - Discarding Specified BPF" + {% endif %} +{% endif %} + +zeekbpf: + file.managed: + - name: /opt/so/conf/zeek/bpf + - user: 940 + - group: 940 +{% if BPF_STATUS %} + - contents: {{ ZEEKBPF }} +{% else %} + - contents: + - "ip or not ip" +{% endif %} + +localzeek: + file.managed: + - name: /opt/so/conf/zeek/local.zeek + - source: salt://zeek/files/local.zeek.jinja + - user: 937 + - group: 939 + - template: jinja + - defaults: + LOCAL: {{ ZEEKMERGED.config.local | tojson }} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/zeek/defaults.yaml b/salt/zeek/defaults.yaml index b2629ab66..34ee40a8d 100644 --- a/salt/zeek/defaults.yaml +++ b/salt/zeek/defaults.yaml @@ -1,4 +1,5 @@ zeek: + enabled: True config: node: lb_procs: 0 diff --git a/salt/zeek/disabled.sls b/salt/zeek/disabled.sls new file mode 100644 index 000000000..62768b265 --- /dev/null +++ b/salt/zeek/disabled.sls @@ -0,0 +1,28 @@ +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} + +include: + - zeek.sostatus + +so-zeek: + docker_container.absent: + - force: True + +so-zeek_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-zeek$ + +zeekpacketlosscron: + cron.absent: + - name: /usr/local/bin/packetloss.sh + - identifier: zeekpacketlosscron + - user: root + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/zeek/enabled.sls b/salt/zeek/enabled.sls new file mode 100644 index 000000000..8b8af8a09 --- /dev/null +++ b/salt/zeek/enabled.sls @@ -0,0 +1,65 @@ +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} + +include: + - zeek.config + - zeek.sostatus + +so-zeek: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-zeek:{{ GLOBALS.so_version }} + - start: True + - privileged: True + - ulimits: + - core=0 + - nofile=1048576:1048576 + - binds: + - /nsm/zeek/logs:/nsm/zeek/logs:rw + - /nsm/zeek/spool:/nsm/zeek/spool:rw + - /nsm/zeek/extracted:/nsm/zeek/extracted:rw + - /opt/so/conf/zeek/local.zeek:/opt/zeek/share/zeek/site/local.zeek:ro + - /opt/so/conf/zeek/node.cfg:/opt/zeek/etc/node.cfg:ro + - /opt/so/conf/zeek/networks.cfg:/opt/zeek/etc/networks.cfg:ro + - /opt/so/conf/zeek/zeekctl.cfg:/opt/zeek/etc/zeekctl.cfg:ro + - /opt/so/conf/zeek/policy/securityonion:/opt/zeek/share/zeek/policy/securityonion:ro + - /opt/so/conf/zeek/policy/custom:/opt/zeek/share/zeek/policy/custom:ro + - /opt/so/conf/zeek/policy/cve-2020-0601:/opt/zeek/share/zeek/policy/cve-2020-0601:ro + - /opt/so/conf/zeek/policy/intel:/opt/zeek/share/zeek/policy/intel:rw + - /opt/so/conf/zeek/bpf:/opt/zeek/etc/bpf:ro + - network_mode: host + - watch: + - file: /opt/so/conf/zeek/local.zeek + - file: /opt/so/conf/zeek/node.cfg + - file: /opt/so/conf/zeek/networks.cfg + - file: /opt/so/conf/zeek/zeekctl.cfg + - file: /opt/so/conf/zeek/policy + - file: /opt/so/conf/zeek/bpf + - require: + - file: localzeek + - file: nodecfg + - file: zeekctlcfg + - file: zeekbpf + +delete_so-zeek_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-zeek$ + +zeekpacketlosscron: + cron.present: + - name: /usr/local/bin/packetloss.sh + - identifier: zeekpacketlosscron + - user: root + - minute: '*/10' + - hour: '*' + - daymonth: '*' + - month: '*' + - dayweek: '*' + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/zeek/init.sls b/salt/zeek/init.sls index ce5996888..f19fcef7e 100644 --- a/salt/zeek/init.sls +++ b/salt/zeek/init.sls @@ -1,283 +1,12 @@ -# 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 'vars/globals.map.jinja' import GLOBALS %} +{% from 'zeek/config.map.jinja' import ZEEKMERGED %} -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} - -{% from 'vars/globals.map.jinja' import GLOBALS with context %} -{% from "zeek/config.map.jinja" import ZEEKOPTIONS with context %} -{% from "zeek/config.map.jinja" import ZEEKMERGED with context %} - -{% from 'bpf/zeek.map.jinja' import ZEEKBPF %} - -{% set BPF_STATUS = 0 %} - -# Zeek Salt State - -# Add Zeek group -zeekgroup: - group.present: - - name: zeek - - gid: 937 - -# Add Zeek User -zeek: - user.present: - - uid: 937 - - gid: 937 - - home: /home/zeek - -# Create some directories -zeekpolicydir: - file.directory: - - name: /opt/so/conf/zeek/policy - - user: 937 - - group: 939 - - makedirs: True - -# Zeek Log Directory -zeeklogdir: - file.directory: - - name: /nsm/zeek/logs - - user: 937 - - group: 939 - - makedirs: True - -# Zeek Spool Directory -zeekspooldir: - file.directory: - - name: /nsm/zeek/spool/manager - - user: 937 - - makedirs: True - -# Zeek extracted -zeekextractdir: - file.directory: - - name: /nsm/zeek/extracted - - user: 937 - - group: 939 - - mode: 770 - - makedirs: True - -zeekextractcompletedir: - file.directory: - - name: /nsm/zeek/extracted/complete - - user: 937 - - group: 939 - - mode: 770 - - makedirs: True - -# Sync the policies -zeekpolicysync: - file.recurse: - - name: /opt/so/conf/zeek/policy - - source: salt://zeek/policy - - user: 937 - - group: 939 - - template: jinja - - defaults: - FILE_EXTRACTION: {{ ZEEKMERGED.file_extraction }} - -# Ensure the zeek spool tree (and state.db) ownership is correct -zeekspoolownership: - file.directory: - - name: /nsm/zeek/spool - - user: 937 -zeekstatedbownership: - file.managed: - - name: /nsm/zeek/spool/state.db - - user: 937 - - replace: False - - create: False - -zeek_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://zeek/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#zeek_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://zeek/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -# Sync Intel -zeekintelloadsync: - file.managed: - - name: /opt/so/conf/policy/intel/__load__.zeek - - source: salt://zeek/policy/intel/__load__.zeek - - user: 937 - - group: 939 - - makedirs: True - -zeekctlcfg: - file.managed: - - name: /opt/so/conf/zeek/zeekctl.cfg - - source: salt://zeek/files/zeekctl.cfg.jinja - - user: 937 - - group: 939 - - template: jinja - - defaults: - ZEEKCTL: {{ ZEEKMERGED.config.zeekctl | tojson }} - -# Sync node.cfg -nodecfg: - file.managed: - - name: /opt/so/conf/zeek/node.cfg - - source: salt://zeek/files/node.cfg.jinja - - user: 937 - - group: 939 - - template: jinja - - defaults: - NODE: {{ ZEEKMERGED.config.node }} - -networkscfg: - file.managed: - - name: /opt/so/conf/zeek/networks.cfg - - source: salt://zeek/files/networks.cfg.jinja - - user: 937 - - group: 939 - - template: jinja - - defaults: - NETWORKS: {{ ZEEKMERGED.config.networks }} - -#zeekcleanscript: -# file.managed: -# - name: /usr/local/bin/zeek_clean -# - source: salt://zeek/cron/zeek_clean -# - mode: 755 - -#/usr/local/bin/zeek_clean: -# cron.present: -# - user: root -# - minute: '*' -# - hour: '*' -# - daymonth: '*' -# - month: '*' -# - dayweek: '*' - -plcronscript: - file.managed: - - name: /usr/local/bin/packetloss.sh - - source: salt://zeek/cron/packetloss.sh - - mode: 755 - -zeekpacketlosscron: - cron.{{ZEEKOPTIONS.pl_cron_state}}: - - name: /usr/local/bin/packetloss.sh - - user: root - - minute: '*/10' - - hour: '*' - - daymonth: '*' - - month: '*' - - dayweek: '*' - -# BPF compilation and configuration -{% if ZEEKBPF %} - {% set BPF_CALC = salt['cmd.script']('/usr/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + ZEEKBPF|join(" "),cwd='/root') %} - {% if BPF_CALC['stderr'] == "" %} - {% set BPF_STATUS = 1 %} - {% else %} -zeekbpfcompilationfailure: - test.configurable_test_state: - - changes: False - - result: False - - comment: "BPF Syntax Error - Discarding Specified BPF" - {% endif %} -{% endif %} - -zeekbpf: - file.managed: - - name: /opt/so/conf/zeek/bpf - - user: 940 - - group: 940 -{% if BPF_STATUS %} - - contents: {{ ZEEKBPF }} +include: +{% if ZEEKMERGED.enabled and GLOBALS.role != 'so-import'%} + - zeek.enabled +{% elif GLOBALS.role == 'so-import' %} + - zeek.config + - zeek.disabled {% else %} - - contents: - - "ip or not ip" -{% endif %} - - -localzeek: - file.managed: - - name: /opt/so/conf/zeek/local.zeek - - source: salt://zeek/files/local.zeek.jinja - - user: 937 - - group: 939 - - template: jinja - - defaults: - LOCAL: {{ ZEEKMERGED.config.local | tojson }} - -so-zeek: - docker_container.{{ ZEEKOPTIONS.status }}: - {% if ZEEKOPTIONS.status == 'running' %} - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-zeek:{{ GLOBALS.so_version }} - - start: {{ ZEEKOPTIONS.start }} - - privileged: True - - ulimits: - - core=0 - - nofile=1048576:1048576 - - binds: - - /nsm/zeek/logs:/nsm/zeek/logs:rw - - /nsm/zeek/spool:/nsm/zeek/spool:rw - - /nsm/zeek/extracted:/nsm/zeek/extracted:rw - - /opt/so/conf/zeek/local.zeek:/opt/zeek/share/zeek/site/local.zeek:ro - - /opt/so/conf/zeek/node.cfg:/opt/zeek/etc/node.cfg:ro - - /opt/so/conf/zeek/networks.cfg:/opt/zeek/etc/networks.cfg:ro - - /opt/so/conf/zeek/zeekctl.cfg:/opt/zeek/etc/zeekctl.cfg:ro - - /opt/so/conf/zeek/policy/securityonion:/opt/zeek/share/zeek/policy/securityonion:ro - - /opt/so/conf/zeek/policy/custom:/opt/zeek/share/zeek/policy/custom:ro - - /opt/so/conf/zeek/policy/cve-2020-0601:/opt/zeek/share/zeek/policy/cve-2020-0601:ro - - /opt/so/conf/zeek/policy/intel:/opt/zeek/share/zeek/policy/intel:rw - - /opt/so/conf/zeek/bpf:/opt/zeek/etc/bpf:ro - - network_mode: host - - watch: - - file: /opt/so/conf/zeek/local.zeek - - file: /opt/so/conf/zeek/node.cfg - - file: /opt/so/conf/zeek/networks.cfg - - file: /opt/so/conf/zeek/zeekctl.cfg - - file: /opt/so/conf/zeek/policy - - file: /opt/so/conf/zeek/bpf - - require: - - file: localzeek - - file: nodecfg - - file: zeekctlcfg - - file: zeekbpf - {% else %} {# if Zeek isn't enabled, then stop and remove the container #} - - force: True - {% endif %} - -append_so-zeek_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-zeek - - unless: grep -q so-zeek /opt/so/conf/so-status/so-status.conf - - {% if not ZEEKOPTIONS.start %} -so-zeek_so-status.disabled: - file.comment: - - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-zeek$ - {% else %} -delete_so-zeek_so-status.disabled: - file.uncomment: - - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-zeek$ - {% endif %} - -{% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - zeek.disabled {% endif %} diff --git a/salt/zeek/sostatus.sls b/salt/zeek/sostatus.sls new file mode 100644 index 000000000..15dafa8c0 --- /dev/null +++ b/salt/zeek/sostatus.sls @@ -0,0 +1,16 @@ +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} + +append_so-zeek_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-zeek + - unless: grep -q so-zeek /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From e8a5a5bffb284ca7b677f2c5a294d40f2ba8d4f7 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 5 May 2023 16:44:46 -0400 Subject: [PATCH 04/68] import GLOBALS --- salt/zeek/enabled.sls | 2 ++ 1 file changed, 2 insertions(+) diff --git a/salt/zeek/enabled.sls b/salt/zeek/enabled.sls index 8b8af8a09..81a77fcd3 100644 --- a/salt/zeek/enabled.sls +++ b/salt/zeek/enabled.sls @@ -1,6 +1,8 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + include: - zeek.config - zeek.sostatus From 743bbfea35a5cd86b6362aa107dc2bd3542ff28f Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 5 May 2023 17:09:01 -0400 Subject: [PATCH 05/68] add zeek.enabled to zeek annotation file --- salt/zeek/soc_zeek.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/salt/zeek/soc_zeek.yaml b/salt/zeek/soc_zeek.yaml index a3ad624b6..8410d4e75 100644 --- a/salt/zeek/soc_zeek.yaml +++ b/salt/zeek/soc_zeek.yaml @@ -1,4 +1,7 @@ zeek: + enabled: + description: You can enable or disable ZEEK on all sensors or a single sensor. + helpLink: zeek.html logging: enabled: description: This is a list of Zeek logs that will be shipped through the pipeline. If you remove a log from this list, it will still persist on the sensor. From 5d50dbb69ea1a3663c37e98d7fec5c062faa58aa Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 10:12:32 -0400 Subject: [PATCH 06/68] enabled/disable zeek --- salt/allowed_states.map.jinja | 4 +--- salt/top.sls | 10 ---------- salt/zeek/config.map.jinja | 5 +++++ salt/zeek/config.sls | 2 -- salt/zeek/disabled.sls | 5 +++++ salt/zeek/enabled.sls | 5 +++++ salt/zeek/init.sls | 7 ++++++- salt/zeek/sostatus.sls | 5 +++++ 8 files changed, 27 insertions(+), 16 deletions(-) diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 0d88fe034..5e80dfd65 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -3,8 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. - -{% set ZEEKVER = salt['pillar.get']('global:mdengine', '') %} {% set PLAYBOOK = salt['pillar.get']('manager:playbook', '0') %} {% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} @@ -221,7 +219,7 @@ {% do allowed_states.append('mysql') %} {% endif %} - {%- if ZEEKVER != 'SURICATA' and grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %} + {%- if grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %} {% do allowed_states.append('zeek') %} {%- endif %} diff --git a/salt/top.sls b/salt/top.sls index 0c644d6bd..b3e4fba6c 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,8 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. - -{% set ZEEKVER = salt['pillar.get']('global:mdengine', '') %} {% set PLAYBOOK = salt['pillar.get']('manager:playbook', '0') %} {% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} @@ -52,9 +50,7 @@ base: - pcap - suricata - healthcheck - {%- if ZEEKVER != 'SURICATA' %} - zeek - {%- endif %} {%- if STRELKA %} - strelka {%- endif %} @@ -89,9 +85,7 @@ base: {%- endif %} - pcap - suricata - {%- if ZEEKVER != 'SURICATA' %} - zeek - {%- endif %} {%- if STRELKA %} - strelka {%- endif %} @@ -183,9 +177,7 @@ base: {%- endif %} - pcap - suricata - {%- if ZEEKVER != 'SURICATA' %} - zeek - {%- endif %} {%- if STRELKA %} - strelka {%- endif %} @@ -278,9 +270,7 @@ base: {%- endif %} - pcap - suricata - {%- if ZEEKVER != 'SURICATA' %} - zeek - {%- endif %} - elasticfleet.install_agent_grid - docker_clean diff --git a/salt/zeek/config.map.jinja b/salt/zeek/config.map.jinja index a2e68d825..58f927c11 100644 --- a/salt/zeek/config.map.jinja +++ b/salt/zeek/config.map.jinja @@ -1,3 +1,8 @@ +{# 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 'vars/sensor.map.jinja' import ROLE_GLOBALS %} {% import_yaml 'zeek/defaults.yaml' as ZEEKDEFAULTS with context %} {% set ZEEKMERGED = salt['pillar.get']('zeek', ZEEKDEFAULTS.zeek, merge=True) %} diff --git a/salt/zeek/config.sls b/salt/zeek/config.sls index ab82bbc57..703da8d85 100644 --- a/salt/zeek/config.sls +++ b/salt/zeek/config.sls @@ -8,9 +8,7 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} {% from "zeek/config.map.jinja" import ZEEKMERGED %} - {% from 'bpf/zeek.map.jinja' import ZEEKBPF %} - {% set BPF_STATUS = 0 %} # Add Zeek group diff --git a/salt/zeek/disabled.sls b/salt/zeek/disabled.sls index 62768b265..3cc3d88b7 100644 --- a/salt/zeek/disabled.sls +++ b/salt/zeek/disabled.sls @@ -1,3 +1,8 @@ +# 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 %} diff --git a/salt/zeek/enabled.sls b/salt/zeek/enabled.sls index 81a77fcd3..2a179a009 100644 --- a/salt/zeek/enabled.sls +++ b/salt/zeek/enabled.sls @@ -1,3 +1,8 @@ +# 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 %} diff --git a/salt/zeek/init.sls b/salt/zeek/init.sls index f19fcef7e..b2ba36ab1 100644 --- a/salt/zeek/init.sls +++ b/salt/zeek/init.sls @@ -1,8 +1,13 @@ +# 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 'vars/globals.map.jinja' import GLOBALS %} {% from 'zeek/config.map.jinja' import ZEEKMERGED %} include: -{% if ZEEKMERGED.enabled and GLOBALS.role != 'so-import'%} +{% if ZEEKMERGED.enabled and GLOBALS.role != 'so-import' and GLOBALS.md_engine != 'SURICATA' %} - zeek.enabled {% elif GLOBALS.role == 'so-import' %} - zeek.config diff --git a/salt/zeek/sostatus.sls b/salt/zeek/sostatus.sls index 15dafa8c0..3a75d217e 100644 --- a/salt/zeek/sostatus.sls +++ b/salt/zeek/sostatus.sls @@ -1,3 +1,8 @@ +# 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 %} From a2c444e03b9f12bfe9aba22186a49afe7bb62bb1 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 13:43:08 -0400 Subject: [PATCH 07/68] enabled/disable playbook in ui --- salt/playbook/config.sls | 112 ++++++++++++++++++++++ salt/playbook/defaults.yaml | 2 + salt/playbook/disabled.sls | 38 ++++++++ salt/playbook/enabled.sls | 72 ++++++++++++++ salt/playbook/init.sls | 160 +------------------------------- salt/playbook/map.jinja | 2 + salt/playbook/soc_playbook.yaml | 4 + salt/playbook/sostatus.sls | 20 ++++ 8 files changed, 254 insertions(+), 156 deletions(-) create mode 100644 salt/playbook/config.sls create mode 100644 salt/playbook/defaults.yaml create mode 100644 salt/playbook/disabled.sls create mode 100644 salt/playbook/enabled.sls create mode 100644 salt/playbook/map.jinja create mode 100644 salt/playbook/soc_playbook.yaml create mode 100644 salt/playbook/sostatus.sls diff --git a/salt/playbook/config.sls b/salt/playbook/config.sls new file mode 100644 index 000000000..4b86d90c0 --- /dev/null +++ b/salt/playbook/config.sls @@ -0,0 +1,112 @@ +# 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 in allowed_states %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set MYSQLPASS = salt['pillar.get']('secrets:mysql') %} +{% set PLAYBOOKPASS = salt['pillar.get']('secrets:playbook_db') %} + + +include: + - mysql + +create_playbookdbuser: + mysql_user.present: + - name: playbookdbuser + - password: {{ PLAYBOOKPASS }} + - host: "{{ DOCKER.sorange.split('/')[0] }}/255.255.255.0" + - connection_host: {{ GLOBALS.manager }} + - connection_port: 3306 + - connection_user: root + - connection_pass: {{ MYSQLPASS }} + +query_playbookdbuser_grants: + mysql_query.run: + - database: playbook + - query: "GRANT ALL ON playbook.* TO 'playbookdbuser'@'{{ DOCKER.sorange.split('/')[0] }}/255.255.255.0';" + - connection_host: {{ GLOBALS.manager }} + - connection_port: 3306 + - connection_user: root + - connection_pass: {{ MYSQLPASS }} + +query_updatwebhooks: + mysql_query.run: + - database: playbook + - query: "update webhooks set url = 'http://{{ GLOBALS.manager_ip}}:7000/playbook/webhook' where project_id = 1" + - connection_host: {{ GLOBALS.manager }} + - connection_port: 3306 + - connection_user: root + - connection_pass: {{ MYSQLPASS }} + +query_updatename: + mysql_query.run: + - database: playbook + - query: "update custom_fields set name = 'Custom Filter' where id = 21;" + - connection_host: {{ GLOBALS.manager }} + - connection_port: 3306 + - connection_user: root + - connection_pass: {{ MYSQLPASS }} + +query_updatepluginurls: + mysql_query.run: + - database: playbook + - query: |- + update settings set value = + "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess + project: '1' + convert_url: http://{{ GLOBALS.manager }}:7000/playbook/sigmac + create_url: http://{{ GLOBALS.manager }}:7000/playbook/play" + where id = 43 + - connection_host: {{ GLOBALS.manager }} + - connection_port: 3306 + - connection_user: root + - connection_pass: {{ MYSQLPASS }} + +playbook_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://playbook/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#playbook_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://playbook/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +playbooklogdir: + file.directory: + - name: /opt/so/log/playbook + - dir_mode: 775 + - user: 939 + - group: 939 + - makedirs: True + +{% if 'idh' in salt['cmd.shell']("ls /opt/so/saltstack/local/pillar/minions/|awk -F'_' {'print $2'}|awk -F'.' {'print $1'}").split() %} +idh-plays: + file.recurse: + - name: /opt/so/conf/soctopus/sigma-import + - source: salt://idh/plays + - makedirs: True + cmd.run: + - name: so-playbook-import True + - onchanges: + - file: /opt/so/conf/soctopus/sigma-import +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/playbook/defaults.yaml b/salt/playbook/defaults.yaml new file mode 100644 index 000000000..20859fef2 --- /dev/null +++ b/salt/playbook/defaults.yaml @@ -0,0 +1,2 @@ +playbook: + enabled: True diff --git a/salt/playbook/disabled.sls b/salt/playbook/disabled.sls new file mode 100644 index 000000000..0af127692 --- /dev/null +++ b/salt/playbook/disabled.sls @@ -0,0 +1,38 @@ +# 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 %} + +include: + - playbook.sostatus + +so-playbook: + docker_container.absent: + - force: True + +so-playbook_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-playbook$ + +so-playbook-sync_cron: + cron.absent: + - identifier: so-playbook-sync_cron + - user: root + + +so-playbook-ruleupdate_cron: + cron.absent: + - identifier: so-playbook-ruleupdate_cron + - user: root + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/playbook/enabled.sls b/salt/playbook/enabled.sls new file mode 100644 index 000000000..b83184628 --- /dev/null +++ b/salt/playbook/enabled.sls @@ -0,0 +1,72 @@ +# 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 %} + +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set PLAYBOOKPASS = salt['pillar.get']('secrets:playbook_db') %} + +include: + - playbook.config + - playbook.sostatus + +{% if PLAYBOOKPASS == None %} + +playbook_password_none: + test.configurable_test_state: + - changes: False + - result: False + - comment: "Playbook MySQL Password Error - Not Starting Playbook" + +{% else %} + +so-playbook: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-playbook:{{ GLOBALS.so_version }} + - hostname: playbook + - name: so-playbook + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-playbook'].ip }} + - binds: + - /opt/so/log/playbook:/playbook/log:rw + - extra_hosts: + - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} + - environment: + - REDMINE_DB_MYSQL={{ GLOBALS.manager }} + - REDMINE_DB_DATABASE=playbook + - REDMINE_DB_USERNAME=playbookdbuser + - REDMINE_DB_PASSWORD={{ PLAYBOOKPASS }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-playbook'].port_bindings %} + - {{ BINDING }} + {% endfor %} + +so-playbook-sync_cron: + cron.present: + - name: /usr/sbin/so-playbook-sync > /opt/so/log/playbook/sync.log 2>&1 + - identifier: so-playbook-sync_cron + - user: root + - minute: '*/5' + +so-playbook-ruleupdate_cron: + cron.present: + - name: /usr/sbin/so-playbook-ruleupdate > /opt/so/log/playbook/update.log 2>&1 + - identifier: so-playbook-ruleupdate_cron + - user: root + - minute: '1' + - hour: '6' + +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/playbook/init.sls b/salt/playbook/init.sls index 930c3b9ec..f8395f7b2 100644 --- a/salt/playbook/init.sls +++ b/salt/playbook/init.sls @@ -3,164 +3,12 @@ # 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 in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} {% from 'vars/globals.map.jinja' import GLOBALS %} -{%- set MYSQLPASS = salt['pillar.get']('secrets:mysql') -%} -{%- set PLAYBOOKPASS = salt['pillar.get']('secrets:playbook_db') -%} - +{% from 'playbook/map.jinja' import PLAYBOOKMERGED %} include: - - mysql - -create_playbookdbuser: - mysql_user.present: - - name: playbookdbuser - - password: {{ PLAYBOOKPASS }} - - host: "{{ DOCKER.sorange.split('/')[0] }}/255.255.255.0" - - connection_host: {{ GLOBALS.manager }} - - connection_port: 3306 - - connection_user: root - - connection_pass: {{ MYSQLPASS }} - -query_playbookdbuser_grants: - mysql_query.run: - - database: playbook - - query: "GRANT ALL ON playbook.* TO 'playbookdbuser'@'{{ DOCKER.sorange.split('/')[0] }}/255.255.255.0';" - - connection_host: {{ GLOBALS.manager }} - - connection_port: 3306 - - connection_user: root - - connection_pass: {{ MYSQLPASS }} - -query_updatwebhooks: - mysql_query.run: - - database: playbook - - query: "update webhooks set url = 'http://{{ GLOBALS.manager_ip}}:7000/playbook/webhook' where project_id = 1" - - connection_host: {{ GLOBALS.manager }} - - connection_port: 3306 - - connection_user: root - - connection_pass: {{ MYSQLPASS }} - -query_updatename: - mysql_query.run: - - database: playbook - - query: "update custom_fields set name = 'Custom Filter' where id = 21;" - - connection_host: {{ GLOBALS.manager }} - - connection_port: 3306 - - connection_user: root - - connection_pass: {{ MYSQLPASS }} - -query_updatepluginurls: - mysql_query.run: - - database: playbook - - query: |- - update settings set value = - "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess - project: '1' - convert_url: http://{{ GLOBALS.manager }}:7000/playbook/sigmac - create_url: http://{{ GLOBALS.manager }}:7000/playbook/play" - where id = 43 - - connection_host: {{ GLOBALS.manager }} - - connection_port: 3306 - - connection_user: root - - connection_pass: {{ MYSQLPASS }} - -playbook_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://playbook/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#playbook_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://playbook/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -playbooklogdir: - file.directory: - - name: /opt/so/log/playbook - - dir_mode: 775 - - user: 939 - - group: 939 - - makedirs: True - -{% if PLAYBOOKPASS == None %} - -playbook_password_none: - test.configurable_test_state: - - changes: False - - result: False - - comment: "Playbook MySQL Password Error - Not Starting Playbook" - +{% if PLAYBOOKMERGED.enabled %} + - playbook.enabled {% else %} - -so-playbook: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-playbook:{{ GLOBALS.so_version }} - - hostname: playbook - - name: so-playbook - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-playbook'].ip }} - - binds: - - /opt/so/log/playbook:/playbook/log:rw - - extra_hosts: - - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - - environment: - - REDMINE_DB_MYSQL={{ GLOBALS.manager }} - - REDMINE_DB_DATABASE=playbook - - REDMINE_DB_USERNAME=playbookdbuser - - REDMINE_DB_PASSWORD={{ PLAYBOOKPASS }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-playbook'].port_bindings %} - - {{ BINDING }} - {% endfor %} - -append_so-playbook_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-playbook - -{% endif %} - -so-playbook-sync_cron: - cron.present: - - name: /usr/sbin/so-playbook-sync > /opt/so/log/playbook/sync.log 2>&1 - - identifier: so-playbook-sync_cron - - user: root - - minute: '*/5' - -so-playbook-ruleupdate_cron: - cron.present: - - name: /usr/sbin/so-playbook-ruleupdate > /opt/so/log/playbook/update.log 2>&1 - - identifier: so-playbook-ruleupdate_cron - - user: root - - minute: '1' - - hour: '6' - -{% if 'idh' in salt['cmd.shell']("ls /opt/so/saltstack/local/pillar/minions/|awk -F'_' {'print $2'}|awk -F'.' {'print $1'}").split() %} -idh-plays: - file.recurse: - - name: /opt/so/conf/soctopus/sigma-import - - source: salt://idh/plays - - makedirs: True - cmd.run: - - name: so-playbook-import True - - onchanges: - - file: /opt/so/conf/soctopus/sigma-import -{% endif %} - -{% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - playbook.disabled {% endif %} diff --git a/salt/playbook/map.jinja b/salt/playbook/map.jinja new file mode 100644 index 000000000..0ee058c68 --- /dev/null +++ b/salt/playbook/map.jinja @@ -0,0 +1,2 @@ +{% import_yaml 'playbook/defaults.yaml' as PLAYBOOKDEFAULTS %} +{% set PLAYBOOKMERGED = salt['pillar.get']('playbook', PLAYBOOKDEFAULTS.playbook, merge=True) %} diff --git a/salt/playbook/soc_playbook.yaml b/salt/playbook/soc_playbook.yaml new file mode 100644 index 000000000..e07ae8653 --- /dev/null +++ b/salt/playbook/soc_playbook.yaml @@ -0,0 +1,4 @@ +playbook: + enabled: + description: You can enable or disable Playbook. + helpLink: playbook.html diff --git a/salt/playbook/sostatus.sls b/salt/playbook/sostatus.sls new file mode 100644 index 000000000..efa009685 --- /dev/null +++ b/salt/playbook/sostatus.sls @@ -0,0 +1,20 @@ +# 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 %} + +append_so-playbook_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-playbook + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From d5c7eec4ef2eaa6910a9291a184e60a6b84932c9 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 13:43:53 -0400 Subject: [PATCH 08/68] enabled false by default, enabled via pillar in so-minion --- salt/manager/tools/sbin/so-minion | 33 +++++++++++++++++++++---------- salt/pcap/defaults.yaml | 2 +- salt/zeek/defaults.yaml | 2 +- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index d5d7bb770..5cddb3e68 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -196,8 +196,8 @@ function add_sensoroni_to_minion() { printf '%s\n'\ "sensoroni:"\ - " node_description: '${NODE_DESCRIPTION//\'/''}'"\ - " " >> $PILLARFILE + " node_description: '${NODE_DESCRIPTION//\'/''}'"\ + " " >> $PILLARFILE } # Sensor settings for the minion pillar @@ -206,15 +206,25 @@ function add_sensor_to_minion() { echo " interface: '$INTERFACE'" >> $PILLARFILE echo " mtu: 9000" >> $PILLARFILE echo "zeek:" >> $PILLARFILE - echo " config:" >> $PILLARFILE - echo " node:" >> $PILLARFILE - echo " lb_procs: '$CORECOUNT'" >> $PILLARFILE + echo " enabled: True" >> $PILLARFILE + echo " config:" >> $PILLARFILE + echo " node:" >> $PILLARFILE + echo " lb_procs: '$CORECOUNT'" >> $PILLARFILE echo "suricata:" >> $PILLARFILE - echo " config:" >> $PILLARFILE - echo " af-packet:" >> $PILLARFILE - echo " threads: '$CORECOUNT'" >> $PILLARFILE -# echo "pcap:" >> $PILLARFILE -# echo " enabled: True" >> $PILLARFILE + echo " config:" >> $PILLARFILE + echo " af-packet:" >> $PILLARFILE + echo " threads: '$CORECOUNT'" >> $PILLARFILE + echo "pcap:" >> $PILLARFILE + echo " enabled: True" >> $PILLARFILE + echo " " >> $PILLARFILE +} + +# Add basic host info to the minion file +function add_playbook_to_minion() { + printf '%s\n'\ + "playbook:"\ + " enabled: True"\ + " " >> $PILLARFILE } function create_fleet_policy() { @@ -293,11 +303,13 @@ function createHEAVYNODE() { function createMANAGER() { add_elastic_to_minion add_logstash_to_minion + add_playbook_to_minion } function createMANAGERSEARCH() { add_elastic_to_minion add_logstash_to_minion + add_playbook_to_minion } function createSENSOR() { @@ -315,6 +327,7 @@ function createSTANDALONE() { add_elastic_to_minion add_logstash_to_minion add_sensor_to_minion + add_playbook_to_minion } function testConnection() { diff --git a/salt/pcap/defaults.yaml b/salt/pcap/defaults.yaml index 5c9b141b4..62c60e118 100644 --- a/salt/pcap/defaults.yaml +++ b/salt/pcap/defaults.yaml @@ -1,5 +1,5 @@ pcap: - enabled: True + enabled: False config: maxdirectoryfiles: 30000 diskfreepercentage: 10 diff --git a/salt/zeek/defaults.yaml b/salt/zeek/defaults.yaml index 34ee40a8d..ca3168b8b 100644 --- a/salt/zeek/defaults.yaml +++ b/salt/zeek/defaults.yaml @@ -1,5 +1,5 @@ zeek: - enabled: True + enabled: False config: node: lb_procs: 0 From ef18cb3704f779420496488368e7e2743483e22c Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 14:12:46 -0400 Subject: [PATCH 09/68] top and allow_states changes for playbook --- salt/allowed_states.map.jinja | 7 +++---- salt/playbook/defaults.yaml | 2 +- salt/playbook/disabled.sls | 1 - salt/top.sls | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 5e80dfd65..0476bc8ed 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set PLAYBOOK = salt['pillar.get']('manager:playbook', '0') %} {% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} @@ -215,7 +214,7 @@ ], }, grain='role') %} - {% if (PLAYBOOK != 0) and grains.role in ['so-eval', 'so-manager', 'so-managersearch', 'so-standalone'] %} + {% if grains.role in ['so-eval', 'so-manager', 'so-managersearch', 'so-standalone'] %} {% do allowed_states.append('mysql') %} {% endif %} @@ -248,11 +247,11 @@ {% do allowed_states.append('elastalert') %} {% endif %} - {% if (PLAYBOOK !=0) and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %} + {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %} {% do allowed_states.append('playbook') %} {% endif %} - {% if (PLAYBOOK !=0) and grains.role in ['so-eval'] %} + {% if (REDIS !=0) and grains.role in ['so-eval'] %} {% do allowed_states.append('redis') %} {% endif %} diff --git a/salt/playbook/defaults.yaml b/salt/playbook/defaults.yaml index 20859fef2..e75ec6a3c 100644 --- a/salt/playbook/defaults.yaml +++ b/salt/playbook/defaults.yaml @@ -1,2 +1,2 @@ playbook: - enabled: True + enabled: False diff --git a/salt/playbook/disabled.sls b/salt/playbook/disabled.sls index 0af127692..c8c876cfb 100644 --- a/salt/playbook/disabled.sls +++ b/salt/playbook/disabled.sls @@ -23,7 +23,6 @@ so-playbook-sync_cron: - identifier: so-playbook-sync_cron - user: root - so-playbook-ruleupdate_cron: cron.absent: - identifier: so-playbook-ruleupdate_cron diff --git a/salt/top.sls b/salt/top.sls index b3e4fba6c..49af8d21a 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set PLAYBOOK = salt['pillar.get']('manager:playbook', '0') %} {% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} @@ -95,8 +94,8 @@ base: {%- endif %} - utility - soctopus - {%- if PLAYBOOK != 0 %} - playbook + {%- if REDIS != 0 %} - redis {%- endif %} - elasticfleet From 9aaa33c22404426b6bb2e1920eab704e8bb818cf Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 14:51:10 -0400 Subject: [PATCH 10/68] fix allowed_states logic in playbook config --- salt/playbook/config.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/playbook/config.sls b/salt/playbook/config.sls index 4b86d90c0..9c8444a56 100644 --- a/salt/playbook/config.sls +++ b/salt/playbook/config.sls @@ -4,7 +4,7 @@ # Elastic License 2.0. {% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} +{% if sls.split('.')[0] in allowed_states %} {% from 'docker/docker.map.jinja' import DOCKER %} {% from 'vars/globals.map.jinja' import GLOBALS %} {% set MYSQLPASS = salt['pillar.get']('secrets:mysql') %} From 9049f9cf032bc4142f6a2bfa6db3808ea5df7966 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 15:56:26 -0400 Subject: [PATCH 11/68] enabled/disable elastalert via web ui --- salt/allowed_states.map.jinja | 3 +- salt/elastalert/config.sls | 103 ++++++++++++++ salt/elastalert/defaults.yaml | 1 + salt/elastalert/disabled.sls | 27 ++++ salt/elastalert/elastalert_config.map.jinja | 11 -- salt/elastalert/enabled.sls | 58 ++++++++ salt/elastalert/init.sls | 144 ++------------------ salt/elastalert/map.jinja | 15 ++ salt/elastalert/soc_elastalert.yaml | 3 + salt/elastalert/sostatus.sls | 21 +++ salt/manager/tools/sbin/so-minion | 49 ++++--- salt/pcap/config.map.jinja | 5 + salt/pcap/disabled.sls | 5 + salt/pcap/init.sls | 5 + salt/top.sls | 9 -- salt/zeek/enabled.sls | 2 +- 16 files changed, 284 insertions(+), 177 deletions(-) create mode 100644 salt/elastalert/config.sls create mode 100644 salt/elastalert/disabled.sls delete mode 100644 salt/elastalert/elastalert_config.map.jinja create mode 100644 salt/elastalert/enabled.sls create mode 100644 salt/elastalert/map.jinja create mode 100644 salt/elastalert/sostatus.sls diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 0476bc8ed..d5eaa5599 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} @@ -243,7 +242,7 @@ {% do allowed_states.append('curator') %} {% endif %} - {% if ELASTALERT and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %} + {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %} {% do allowed_states.append('elastalert') %} {% endif %} diff --git a/salt/elastalert/config.sls b/salt/elastalert/config.sls new file mode 100644 index 000000000..252aa83c0 --- /dev/null +++ b/salt/elastalert/config.sls @@ -0,0 +1,103 @@ +# 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 %} + +{% from 'elastalert/map.jinja' import ELASTALERTMERGED %} + +# Create the group +elastagroup: + group.present: + - name: elastalert + - gid: 933 + +# Add user +elastalert: + user.present: + - uid: 933 + - gid: 933 + - home: /opt/so/conf/elastalert + - createhome: False + +elastalogdir: + file.directory: + - name: /opt/so/log/elastalert + - user: 933 + - group: 933 + - makedirs: True + +elastalert_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://elastalert/tools/sbin + - user: 933 + - group: 939 + - file_mode: 755 + +#elastalert_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://elastalert/tools/sbin_jinja +# - user: 933 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +elastarules: + file.directory: + - name: /opt/so/rules/elastalert + - user: 933 + - group: 933 + - makedirs: True + +elastaconfdir: + file.directory: + - name: /opt/so/conf/elastalert + - user: 933 + - group: 933 + - makedirs: True + +elastasomodulesdir: + file.directory: + - name: /opt/so/conf/elastalert/modules/so + - user: 933 + - group: 933 + - makedirs: True + +elastacustmodulesdir: + file.directory: + - name: /opt/so/conf/elastalert/modules/custom + - user: 933 + - group: 933 + - makedirs: True + +elastasomodulesync: + file.recurse: + - name: /opt/so/conf/elastalert/modules/so + - source: salt://elastalert/files/modules/so + - user: 933 + - group: 933 + - makedirs: True + +elastaconf: + file.managed: + - name: /opt/so/conf/elastalert/elastalert_config.yaml + - source: salt://elastalert/files/elastalert_config.yaml.jinja + - context: + elastalert_config: {{ ELASTALERTMERGED.config }} + - user: 933 + - group: 933 + - mode: 660 + - template: jinja + - show_changes: False + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elastalert/defaults.yaml b/salt/elastalert/defaults.yaml index 6a051354e..1083fa8fd 100644 --- a/salt/elastalert/defaults.yaml +++ b/salt/elastalert/defaults.yaml @@ -1,4 +1,5 @@ elastalert: + enabled: False config: rules_folder: /opt/elastalert/rules/ scan_subdirectories: true diff --git a/salt/elastalert/disabled.sls b/salt/elastalert/disabled.sls new file mode 100644 index 000000000..5830bbd8f --- /dev/null +++ b/salt/elastalert/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - elastalert.sostatus + +so-elastalert: + docker_container.absent: + - force: True + +so-elastalert_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elastalert$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elastalert/elastalert_config.map.jinja b/salt/elastalert/elastalert_config.map.jinja deleted file mode 100644 index 26ddc08c9..000000000 --- a/salt/elastalert/elastalert_config.map.jinja +++ /dev/null @@ -1,11 +0,0 @@ -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% import_yaml 'elastalert/defaults.yaml' as ELASTALERT %} -{% set elastalert_pillar = salt['pillar.get']('elastalert:config', {}) %} - - -{% do ELASTALERT.elastalert.config.update({'es_host': GLOBALS.manager}) %} -{% do ELASTALERT.elastalert.config.update({'es_username': pillar.elasticsearch.auth.users.so_elastic_user.user}) %} -{% do ELASTALERT.elastalert.config.update({'es_password': pillar.elasticsearch.auth.users.so_elastic_user.pass}) %} - -{% do salt['defaults.merge'](ELASTALERT.elastalert.config, elastalert_pillar, in_place=True) %} - diff --git a/salt/elastalert/enabled.sls b/salt/elastalert/enabled.sls new file mode 100644 index 000000000..3e043b46c --- /dev/null +++ b/salt/elastalert/enabled.sls @@ -0,0 +1,58 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} + +include: + - elastalert.config + - elastalert.sostatus + +wait_for_elasticsearch: + cmd.run: + - name: so-elasticsearch-wait + +so-elastalert: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastalert:{{ GLOBALS.so_version }} + - hostname: elastalert + - name: so-elastalert + - user: so-elastalert + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-elastalert'].ip }} + - detach: True + - binds: + - /opt/so/rules/elastalert:/opt/elastalert/rules/:ro + - /opt/so/log/elastalert:/var/log/elastalert:rw + - /opt/so/conf/elastalert/modules/:/opt/elastalert/modules/:ro + - /opt/so/conf/elastalert/elastalert_config.yaml:/opt/elastalert/config.yaml:ro + - extra_hosts: + - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} + - require: + - cmd: wait_for_elasticsearch + - file: elastarules + - file: elastalogdir + - file: elastacustmodulesdir + - file: elastaconf + - watch: + - file: elastaconf + - onlyif: + - "so-elasticsearch-query / | jq -r '.version.number[0:1]' | grep -q 8" {# only run this state if elasticsearch is version 8 #} + +delete_so-elastalert_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elastalert$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elastalert/init.sls b/salt/elastalert/init.sls index 148fe7e1b..d0e86d07f 100644 --- a/salt/elastalert/init.sls +++ b/salt/elastalert/init.sls @@ -1,141 +1,13 @@ # 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; 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 in allowed_states %} +# 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 'docker/docker.map.jinja' import DOCKER %} -{% from 'elastalert/elastalert_config.map.jinja' import ELASTALERT as elastalert_config with context %} - -# Create the group -elastagroup: - group.present: - - name: elastalert - - gid: 933 - -# Add user -elastalert: - user.present: - - uid: 933 - - gid: 933 - - home: /opt/so/conf/elastalert - - createhome: False - -elastalogdir: - file.directory: - - name: /opt/so/log/elastalert - - user: 933 - - group: 933 - - makedirs: True - -elastalert_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://elastalert/tools/sbin - - user: 933 - - group: 939 - - file_mode: 755 - -#elastalert_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://elastalert/tools/sbin_jinja -# - user: 933 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -elastarules: - file.directory: - - name: /opt/so/rules/elastalert - - user: 933 - - group: 933 - - makedirs: True - -elastaconfdir: - file.directory: - - name: /opt/so/conf/elastalert - - user: 933 - - group: 933 - - makedirs: True - -elastasomodulesdir: - file.directory: - - name: /opt/so/conf/elastalert/modules/so - - user: 933 - - group: 933 - - makedirs: True - -elastacustmodulesdir: - file.directory: - - name: /opt/so/conf/elastalert/modules/custom - - user: 933 - - group: 933 - - makedirs: True - -elastasomodulesync: - file.recurse: - - name: /opt/so/conf/elastalert/modules/so - - source: salt://elastalert/files/modules/so - - user: 933 - - group: 933 - - makedirs: True - -elastaconf: - file.managed: - - name: /opt/so/conf/elastalert/elastalert_config.yaml - - source: salt://elastalert/files/elastalert_config.yaml.jinja - - context: - elastalert_config: {{ elastalert_config.elastalert.config }} - - user: 933 - - group: 933 - - mode: 660 - - template: jinja - - show_changes: False - -wait_for_elasticsearch: - cmd.run: - - name: so-elasticsearch-wait - -so-elastalert: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastalert:{{ GLOBALS.so_version }} - - hostname: elastalert - - name: so-elastalert - - user: so-elastalert - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-elastalert'].ip }} - - detach: True - - binds: - - /opt/so/rules/elastalert:/opt/elastalert/rules/:ro - - /opt/so/log/elastalert:/var/log/elastalert:rw - - /opt/so/conf/elastalert/modules/:/opt/elastalert/modules/:ro - - /opt/so/conf/elastalert/elastalert_config.yaml:/opt/elastalert/config.yaml:ro - - extra_hosts: - - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - - require: - - cmd: wait_for_elasticsearch - - file: elastarules - - file: elastalogdir - - file: elastacustmodulesdir - - file: elastaconf - - watch: - - file: elastaconf - - onlyif: - - "so-elasticsearch-query / | jq -r '.version.number[0:1]' | grep -q 8" {# only run this state if elasticsearch is version 8 #} - - -append_so-elastalert_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-elastalert +{% from 'elastalert/map.jinja' import ELASTALERTMERGED %} +include: +{% if ELASTALERTMERGED.enabled %} + - elastalert.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - elastalert.disabled {% endif %} diff --git a/salt/elastalert/map.jinja b/salt/elastalert/map.jinja new file mode 100644 index 000000000..cc395d8ee --- /dev/null +++ b/salt/elastalert/map.jinja @@ -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 'vars/globals.map.jinja' import GLOBALS %} +{% import_yaml 'elastalert/defaults.yaml' as ELASTALERTDEFAULTS %} +{% set elastalert_pillar = salt['pillar.get']('elastalert:config', {}) %} + + +{% do ELASTALERTDEFAULTS.elastalert.config.update({'es_host': GLOBALS.manager}) %} +{% do ELASTALERTDEFAULTS.elastalert.config.update({'es_username': pillar.elasticsearch.auth.users.so_elastic_user.user}) %} +{% do ELASTALERTDEFAULTS.elastalert.config.update({'es_password': pillar.elasticsearch.auth.users.so_elastic_user.pass}) %} + +{% set ELASTALERTMERGED = salt['pillar.get']('elastalert', ELASTALERTDEFAULTS.elastalert, merge=True) %} diff --git a/salt/elastalert/soc_elastalert.yaml b/salt/elastalert/soc_elastalert.yaml index fe01f2458..cde09b83e 100644 --- a/salt/elastalert/soc_elastalert.yaml +++ b/salt/elastalert/soc_elastalert.yaml @@ -1,4 +1,7 @@ elastalert: + enabled: + description: You can enable or disable Elastalert. + helpLink: elastalert.html config: disable_rules_on_error: description: Disable rules on failure. diff --git a/salt/elastalert/sostatus.sls b/salt/elastalert/sostatus.sls new file mode 100644 index 000000000..609a4482f --- /dev/null +++ b/salt/elastalert/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-elastalert_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-elastalert + - unless: grep -q so-elastalert /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 5cddb3e68..b94bfac59 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -227,6 +227,14 @@ function add_playbook_to_minion() { " " >> $PILLARFILE } +# Add basic host info to the minion file +function add_elastalert_to_minion() { + printf '%s\n'\ + "elastalert:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -274,6 +282,29 @@ function createEVAL() { add_elastic_to_minion add_logstash_to_minion add_sensor_to_minion + add_elastalert_to_minion +} + +function createSTANDALONE() { + add_elastic_to_minion + add_logstash_to_minion + add_sensor_to_minion + add_playbook_to_minion + add_elastalert_to_minion +} + +function createMANAGER() { + add_elastic_to_minion + add_logstash_to_minion + add_playbook_to_minion + add_elastalert_to_minion +} + +function createMANAGERSEARCH() { + add_elastic_to_minion + add_logstash_to_minion + add_playbook_to_minion + add_elastalert_to_minion } function createFLEET() { @@ -300,18 +331,6 @@ function createHEAVYNODE() { add_sensor_to_minion } -function createMANAGER() { - add_elastic_to_minion - add_logstash_to_minion - add_playbook_to_minion -} - -function createMANAGERSEARCH() { - add_elastic_to_minion - add_logstash_to_minion - add_playbook_to_minion -} - function createSENSOR() { add_sensor_to_minion } @@ -323,12 +342,6 @@ function createSEARCHNODE() { apply_ES_state } -function createSTANDALONE() { - add_elastic_to_minion - add_logstash_to_minion - add_sensor_to_minion - add_playbook_to_minion -} function testConnection() { retry 15 3 "salt '$MINION_ID' test.ping" True diff --git a/salt/pcap/config.map.jinja b/salt/pcap/config.map.jinja index 88e3a83dd..7ed500f25 100644 --- a/salt/pcap/config.map.jinja +++ b/salt/pcap/config.map.jinja @@ -1,2 +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 'pcap/defaults.yaml' as PCAPDEFAULTS %} {% set PCAPMERGED = salt['pillar.get']('pcap', PCAPDEFAULTS.pcap, merge=True) %} diff --git a/salt/pcap/disabled.sls b/salt/pcap/disabled.sls index eaa227303..5643fc870 100644 --- a/salt/pcap/disabled.sls +++ b/salt/pcap/disabled.sls @@ -1,3 +1,8 @@ +# 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 %} diff --git a/salt/pcap/init.sls b/salt/pcap/init.sls index 46ad04e95..9de272ad7 100644 --- a/salt/pcap/init.sls +++ b/salt/pcap/init.sls @@ -1,3 +1,8 @@ +# 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 'vars/globals.map.jinja' import GLOBALS %} {% from 'pcap/config.map.jinja' import PCAPMERGED %} diff --git a/salt/top.sls b/salt/top.sls index 49af8d21a..c108236b9 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} @@ -89,9 +88,7 @@ base: - strelka {%- endif %} - curator - {%- if ELASTALERT %} - elastalert - {%- endif %} - utility - soctopus - playbook @@ -133,9 +130,7 @@ base: - kibana.so_savedobjects_defaults {%- endif %} - curator - {%- if ELASTALERT %} - elastalert - {%- endif %} - utility - soctopus - playbook @@ -181,9 +176,7 @@ base: - strelka {%- endif %} - curator - {%- if ELASTALERT %} - elastalert - {%- endif %} - utility - soctopus - playbook @@ -238,9 +231,7 @@ base: - elastic-fleet-package-registry - kibana.so_savedobjects_defaults {%- endif %} - {%- if ELASTALERT %} - elastalert - {%- endif %} - utility - soctopus - playbook diff --git a/salt/zeek/enabled.sls b/salt/zeek/enabled.sls index 2a179a009..d2fc9fbc3 100644 --- a/salt/zeek/enabled.sls +++ b/salt/zeek/enabled.sls @@ -6,7 +6,7 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'vars/globals.map.jinja' import GLOBALS %} include: - zeek.config From f9804c218d887feb0eba11daf04cacd7ba64b3fe Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 16:20:17 -0400 Subject: [PATCH 12/68] only append to so-status.conf if needed --- salt/playbook/sostatus.sls | 1 + 1 file changed, 1 insertion(+) diff --git a/salt/playbook/sostatus.sls b/salt/playbook/sostatus.sls index efa009685..f635746d3 100644 --- a/salt/playbook/sostatus.sls +++ b/salt/playbook/sostatus.sls @@ -10,6 +10,7 @@ append_so-playbook_so-status.conf: file.append: - name: /opt/so/conf/so-status/so-status.conf - text: so-playbook + - unless: grep -q so-playbook /opt/so/conf/so-status/so-status.conf {% else %} From 2a979197a0f5a40293f62aa367342543030661da Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 09:33:37 -0400 Subject: [PATCH 13/68] enabled/disable elasticsearch in ui --- salt/elasticsearch/config.map.jinja | 29 +- salt/elasticsearch/config.sls | 262 +++++++++++ salt/elasticsearch/defaults.yaml | 1 + salt/elasticsearch/disabled.sls | 27 ++ salt/elasticsearch/enabled.sls | 182 ++++++++ salt/elasticsearch/init.sls | 424 +----------------- salt/elasticsearch/soc_elasticsearch.yaml | 3 + salt/elasticsearch/sostatus.sls | 21 + salt/elasticsearch/template.map.jinja | 4 +- .../so-elasticsearch-ilm-policy-load | 8 +- salt/manager/tools/sbin/so-minion | 17 +- salt/pcap/sostatus.sls | 5 + 12 files changed, 535 insertions(+), 448 deletions(-) create mode 100644 salt/elasticsearch/config.sls create mode 100644 salt/elasticsearch/disabled.sls create mode 100644 salt/elasticsearch/enabled.sls create mode 100644 salt/elasticsearch/sostatus.sls diff --git a/salt/elasticsearch/config.map.jinja b/salt/elasticsearch/config.map.jinja index 278bbde62..d367de287 100644 --- a/salt/elasticsearch/config.map.jinja +++ b/salt/elasticsearch/config.map.jinja @@ -1,44 +1,43 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} -{% import_yaml 'elasticsearch/defaults.yaml' as ESCONFIG with context %} +{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS with context %} {% from 'logstash/map.jinja' import LOGSTASH_NODES with context %} {% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %} {% if grains.id.split('_') | last in ['manager','managersearch','standalone'] %} {% if LOGSTASH_NODES | length > 1 %} - {% do ESCONFIG.elasticsearch.config.update({'discovery': {'seed_hosts': []}}) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.update({'discovery': {'seed_hosts': []}}) %} {% for NODE in LOGSTASH_NODES %} - {% do ESCONFIG.elasticsearch.config.discovery.seed_hosts.append(NODE.keys()|first) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.discovery.seed_hosts.append(NODE.keys()|first) %} {% endfor %} {% if grains.id.split('_') | last == 'manager' %} - {% do ESCONFIG.elasticsearch.config.node.update({'roles': ['master','data','remote_cluster_client']}) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.node.update({'roles': ['master','data','remote_cluster_client']}) %} {% else %} - {% do ESCONFIG.elasticsearch.config.node.update({'roles': ['master', 'data_hot', 'remote_cluster_client']}) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.node.update({'roles': ['master', 'data_hot', 'remote_cluster_client']}) %} {% endif %} {% endif %} {% elif grains.id.split('_') | last == 'searchnode' %} - {% do ESCONFIG.elasticsearch.config.node.update({'roles': ['data_hot', 'ingest']}) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.node.update({'roles': ['data_hot', 'ingest']}) %} {% if HIGHLANDER %} - {% do ESCONFIG.elasticsearch.config.node.roles.extend(['ml', 'master', 'transform']) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.node.roles.extend(['ml', 'master', 'transform']) %} {% endif %} - {% do ESCONFIG.elasticsearch.config.update({'discovery': {'seed_hosts': [GLOBALS.manager]}}) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.update({'discovery': {'seed_hosts': [GLOBALS.manager]}}) %} {% endif %} {% if HIGHLANDER %} - {% do ESCONFIG.elasticsearch.config.xpack.ml.update({'enabled': true}) %} + {% do ELASTICSEARCHDEFAULTS.elasticsearch.config.xpack.ml.update({'enabled': true}) %} {% endif %} -{% do ESCONFIG.elasticsearch.config.node.update({'name': GLOBALS.hostname}) %} -{% do ESCONFIG.elasticsearch.config.cluster.update({'name': GLOBALS.hostname}) %} -{% do ESCONFIG.elasticsearch.config.transport.update({'publish_host': GLOBALS.hostname}) %} +{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.node.update({'name': GLOBALS.hostname}) %} +{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.cluster.update({'name': GLOBALS.hostname}) %} +{% do ELASTICSEARCHDEFAULTS.elasticsearch.config.transport.update({'publish_host': GLOBALS.hostname}) %} -{# merge with the elasticsearch pillar #} -{% set ESCONFIG = salt['pillar.get']('elasticsearch:config', default=ESCONFIG.elasticsearch.config, merge=True) %} +{% set ELASTICSEARCHMERGED = salt['pillar.get']('elasticsearch', default=ELASTICSEARCHDEFAULTS.elasticsearch, merge=True) %} {% if salt['pillar.get']('elasticsearch:config:path:repo', False) %} {% for repo in pillar.elasticsearch.config.path.repo %} {# remove elasticsearch.config.path.repo value if the directory doesn't exist on the node #} {% if not salt['file.directory_exists'](repo) %} - {% do ESCONFIG.path.repo.remove(repo) %} + {% do ELASTICSEARCHMERGED.config.path.repo.remove(repo) %} {% endif %} {% endfor %} {% endif %} diff --git a/salt/elasticsearch/config.sls b/salt/elasticsearch/config.sls new file mode 100644 index 000000000..255d09376 --- /dev/null +++ b/salt/elasticsearch/config.sls @@ -0,0 +1,262 @@ +# 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 %} + +include: + - ssl + +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %} + +vm.max_map_count: + sysctl.present: + - value: 262144 + +# Add ES Group +elasticsearchgroup: + group.present: + - name: elasticsearch + - gid: 930 + +esconfdir: + file.directory: + - name: /opt/so/conf/elasticsearch + - user: 930 + - group: 939 + - makedirs: True + +# Add ES user +elasticsearch: + user.present: + - uid: 930 + - gid: 930 + - home: /opt/so/conf/elasticsearch + - createhome: False + +{% if GLOBALS.is_manager %} +# We have to add the Manager CA to the CA list +cascriptsync: + file.managed: + - name: /usr/sbin/so-catrust + - source: salt://elasticsearch/tools/sbin_jinja/so-catrust + - user: 939 + - group: 939 + - mode: 750 + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} + +# Run the CA magic +cascriptfun: + cmd.run: + - name: /usr/sbin/so-catrust + - require: + - file: cascriptsync +{% endif %} + +elasticsearch_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://elasticsearch/tools/sbin + - user: 930 + - group: 939 + - file_mode: 755 + - exclude_pat: + - so-catrust + - so-elasticsearch-pipelines # exclude this because we need to watch it for changes, we sync it in another state + +elasticsearch_sbin_jinja: + file.recurse: + - name: /usr/sbin + - source: salt://elasticsearch/tools/sbin_jinja + - user: 939 + - group: 939 + - file_mode: 755 + - template: jinja + - exclude_pat: + - so-elasticsearch-ilm-policy-load # exclude this because we need to watch it for changes, we sync it in another state + - defaults: + GLOBALS: {{ GLOBALS }} + +so-elasticsearch-ilm-policy-load-script: + file.managed: + - name: /usr/sbin/so-elasticsearch-ilm-policy-load + - source: salt://elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load + - user: 930 + - group: 939 + - mode: 754 + - template: jinja + +so-elasticsearch-pipelines-script: + file.managed: + - name: /usr/sbin/so-elasticsearch-pipelines + - source: salt://elasticsearch/tools/sbin/so-elasticsearch-pipelines + - user: 930 + - group: 939 + - mode: 754 + +# Move our new CA over so Elastic and Logstash can use SSL with the internal CA +catrustdir: + file.directory: + - name: /opt/so/conf/ca + - user: 939 + - group: 939 + - makedirs: True + +cacertz: + file.managed: + - name: /opt/so/conf/ca/cacerts + - source: salt://common/cacerts + - user: 939 + - group: 939 + +capemz: + file.managed: + - name: /opt/so/conf/ca/tls-ca-bundle.pem + - source: salt://common/tls-ca-bundle.pem + - user: 939 + - group: 939 + +esingestdir: + file.directory: + - name: /opt/so/conf/elasticsearch/ingest + - user: 930 + - group: 939 + - makedirs: True + +estemplatedir: + file.directory: + - name: /opt/so/conf/elasticsearch/templates/index + - user: 930 + - group: 939 + - makedirs: True + +esrolesdir: + file.directory: + - name: /opt/so/conf/elasticsearch/roles + - user: 930 + - group: 939 + - makedirs: True + +eslibdir: + file.absent: + - name: /opt/so/conf/elasticsearch/lib + +esingestdynamicconf: + file.recurse: + - name: /opt/so/conf/elasticsearch/ingest + - source: salt://elasticsearch/files/ingest-dynamic + - user: 930 + - group: 939 + - template: jinja + +esingestconf: + file.recurse: + - name: /opt/so/conf/elasticsearch/ingest + - source: salt://elasticsearch/files/ingest + - user: 930 + - group: 939 + +eslog4jfile: + file.managed: + - name: /opt/so/conf/elasticsearch/log4j2.properties + - source: salt://elasticsearch/files/log4j2.properties + - user: 930 + - group: 939 + - template: jinja + +esyml: + file.managed: + - name: /opt/so/conf/elasticsearch/elasticsearch.yml + - source: salt://elasticsearch/files/elasticsearch.yaml.jinja + - user: 930 + - group: 939 + - defaults: + ESCONFIG: {{ ELASTICSEARCHMERGED.config }} + - template: jinja + +esroles: + file.recurse: + - source: salt://elasticsearch/roles/ + - name: /opt/so/conf/elasticsearch/roles/ + - clean: True + - template: jinja + - user: 930 + - group: 939 + +nsmesdir: + file.directory: + - name: /nsm/elasticsearch + - user: 930 + - group: 939 + - makedirs: True + +eslogdir: + file.directory: + - name: /opt/so/log/elasticsearch + - user: 930 + - group: 939 + - makedirs: True + +es_repo_dir: + file.directory: + - name: /nsm/elasticsearch/repo/ + - user: 930 + - group: 930 + - require: + - file: nsmesdir + +so-pipelines-reload: + file.absent: + - name: /opt/so/state/espipelines.txt + - onchanges: + - file: esingestconf + - file: esingestdynamicconf + - file: esyml + - file: so-elasticsearch-pipelines-script + +auth_users: + file.managed: + - name: /opt/so/conf/elasticsearch/users.tmp + - source: salt://elasticsearch/files/users + - user: 930 + - group: 930 + - mode: 600 + - show_changes: False + +auth_users_roles: + file.managed: + - name: /opt/so/conf/elasticsearch/users_roles.tmp + - source: salt://elasticsearch/files/users_roles + - user: 930 + - group: 930 + - mode: 600 + - show_changes: False + +auth_users_inode: + require: + - file: auth_users + cmd.run: + - name: cat /opt/so/conf/elasticsearch/users.tmp > /opt/so/conf/elasticsearch/users && chown 930:939 /opt/so/conf/elasticsearch/users && chmod 660 /opt/so/conf/elasticsearch/users + - onchanges: + - file: /opt/so/conf/elasticsearch/users.tmp + +auth_users_roles_inode: + require: + - file: auth_users_roles + cmd.run: + - name: cat /opt/so/conf/elasticsearch/users_roles.tmp > /opt/so/conf/elasticsearch/users_roles && chown 930:939 /opt/so/conf/elasticsearch/users_roles && chmod 660 /opt/so/conf/elasticsearch/users_roles + - onchanges: + - file: /opt/so/conf/elasticsearch/users_roles.tmp + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticsearch/defaults.yaml b/salt/elasticsearch/defaults.yaml index 37f55ddc7..10cc347d1 100644 --- a/salt/elasticsearch/defaults.yaml +++ b/salt/elasticsearch/defaults.yaml @@ -1,4 +1,5 @@ elasticsearch: + enabled: False retention: retention_pct: 50 config: diff --git a/salt/elasticsearch/disabled.sls b/salt/elasticsearch/disabled.sls new file mode 100644 index 000000000..210ad59a4 --- /dev/null +++ b/salt/elasticsearch/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - elasticsearch.sostatus + +so-elasticsearch: + docker_container.absent: + - force: True + +so-elasticsearch_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elasticsearch$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticsearch/enabled.sls b/salt/elasticsearch/enabled.sls new file mode 100644 index 000000000..0fc77f0ee --- /dev/null +++ b/salt/elasticsearch/enabled.sls @@ -0,0 +1,182 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'logstash/map.jinja' import LOGSTASH_NODES %} +{% set TEMPLATES = salt['pillar.get']('elasticsearch:templates', {}) %} +{% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %} + +include: + - elasticsearch.config + - elasticsearch.sostatus + +so-elasticsearch: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ GLOBALS.so_version }} + - hostname: elasticsearch + - name: so-elasticsearch + - user: elasticsearch + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-elasticsearch'].ip }} + - extra_hosts: {{ LOGSTASH_NODES }} + - environment: + {% if LOGSTASH_NODES | length == 1 %} + - discovery.type=single-node + {% endif %} + - ES_JAVA_OPTS=-Xms{{ GLOBALS.elasticsearch.es_heap }} -Xmx{{ GLOBALS.elasticsearch.es_heap }} -Des.transport.cname_in_publish_address=true -Dlog4j2.formatMsgNoLookups=true + ulimits: + - memlock=-1:-1 + - nofile=65536:65536 + - nproc=4096 + - port_bindings: + {% for BINDING in DOCKER.containers['so-elasticsearch'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - binds: + - /opt/so/conf/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro + - /opt/so/conf/elasticsearch/log4j2.properties:/usr/share/elasticsearch/config/log4j2.properties:ro + - /nsm/elasticsearch:/usr/share/elasticsearch/data:rw + - /opt/so/log/elasticsearch:/var/log/elasticsearch:rw + - /opt/so/conf/ca/cacerts:/usr/share/elasticsearch/jdk/lib/security/cacerts:ro + {% if GLOBALS.is_manager %} + - /etc/pki/ca.crt:/usr/share/elasticsearch/config/ca.crt:ro + {% else %} + - /etc/ssl/certs/intca.crt:/usr/share/elasticsearch/config/ca.crt:ro + {% endif %} + - /etc/pki/elasticsearch.crt:/usr/share/elasticsearch/config/elasticsearch.crt:ro + - /etc/pki/elasticsearch.key:/usr/share/elasticsearch/config/elasticsearch.key:ro + - /etc/pki/elasticsearch.p12:/usr/share/elasticsearch/config/elasticsearch.p12:ro + - /opt/so/conf/elasticsearch/users_roles:/usr/share/elasticsearch/config/users_roles:ro + - /opt/so/conf/elasticsearch/users:/usr/share/elasticsearch/config/users:ro + {% if ELASTICSEARCHMERGED.config.path.get('repo', False) %} + {% for repo in ELASTICSEARCHMERGED.config.path.repo %} + - {{ repo }}:{{ repo }}:rw + {% endfor %} + {% endif %} + - watch: + - file: cacertz + - file: esyml + - require: + - file: esyml + - file: eslog4jfile + - file: nsmesdir + - file: eslogdir + - file: cacertz + - x509: /etc/pki/elasticsearch.crt + - x509: /etc/pki/elasticsearch.key + - file: elasticp12perms + {% if GLOBALS.is_manager %} + - x509: pki_public_ca_crt + {% else %} + - x509: trusttheca + {% endif %} + - cmd: auth_users_roles_inode + - cmd: auth_users_inode + +delete_so-elasticsearch_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elasticsearch$ + +{% if GLOBALS.role != "so-searchnode" %} +escomponenttemplates: + file.recurse: + - name: /opt/so/conf/elasticsearch/templates/component + - source: salt://elasticsearch/templates/component + - user: 930 + - group: 939 + - onchanges_in: + - cmd: so-elasticsearch-templates + +# Auto-generate templates from defaults file +{% for index, settings in ES_INDEX_SETTINGS.items() %} + {% if settings.index_template is defined %} +es_index_template_{{index}}: + file.managed: + - name: /opt/so/conf/elasticsearch/templates/index/{{ index }}-template.json + - source: salt://elasticsearch/base-template.json.jinja + - defaults: + TEMPLATE_CONFIG: {{ settings.index_template }} + - template: jinja + - onchanges_in: + - cmd: so-elasticsearch-templates +{% endif %} +{% endfor %} + +{% if TEMPLATES %} +# Sync custom templates to /opt/so/conf/elasticsearch/templates +{% for TEMPLATE in TEMPLATES %} +es_template_{{TEMPLATE.split('.')[0] | replace("/","_") }}: + file.managed: + - source: salt://elasticsearch/templates/index/{{TEMPLATE}} +{% if 'jinja' in TEMPLATE.split('.')[-1] %} + - name: /opt/so/conf/elasticsearch/templates/index/{{TEMPLATE.split('/')[1] | replace(".jinja", "")}} + - template: jinja +{% else %} + - name: /opt/so/conf/elasticsearch/templates/index/{{TEMPLATE.split('/')[1]}} +{% endif %} + - user: 930 + - group: 939 + - onchanges_in: + - cmd: so-elasticsearch-templates +{% endfor %} +{% endif %} + +so-es-cluster-settings: + cmd.run: + - name: /usr/sbin/so-elasticsearch-cluster-settings + - cwd: /opt/so + - template: jinja + - require: + - docker_container: so-elasticsearch + - file: elasticsearch_sbin_jinja + +so-elasticsearch-ilm-policy-load: + cmd.run: + - name: /usr/sbin/so-elasticsearch-ilm-policy-load + - cwd: /opt/so + - require: + - docker_container: so-elasticsearch + - file: so-elasticsearch-ilm-policy-load-script + - onchanges: + - file: so-elasticsearch-ilm-policy-load-script + +so-elasticsearch-templates: + cmd.run: + - name: /usr/sbin/so-elasticsearch-templates-load + - cwd: /opt/so + - template: jinja + - require: + - docker_container: so-elasticsearch + - file: elasticsearch_sbin_jinja + +so-elasticsearch-pipelines: + cmd.run: + - name: /usr/sbin/so-elasticsearch-pipelines {{ GLOBALS.hostname }} + - require: + - docker_container: so-elasticsearch + - file: so-elasticsearch-pipelines-script + +so-elasticsearch-roles-load: + cmd.run: + - name: /usr/sbin/so-elasticsearch-roles-load + - cwd: /opt/so + - template: jinja + - require: + - docker_container: so-elasticsearch + - file: elasticsearch_sbin_jinja +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticsearch/init.sls b/salt/elasticsearch/init.sls index 5e2ffae9d..301c836c2 100644 --- a/salt/elasticsearch/init.sls +++ b/salt/elasticsearch/init.sls @@ -3,425 +3,11 @@ # 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 in allowed_states %} +{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %} include: - - ssl - -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% set TEMPLATES = salt['pillar.get']('elasticsearch:templates', {}) %} -{% set ROLES = salt['pillar.get']('elasticsearch:roles', {}) %} -{% from 'elasticsearch/config.map.jinja' import ESCONFIG with context %} -{% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS without context %} -{% from 'logstash/map.jinja' import LOGSTASH_NODES %} - -vm.max_map_count: - sysctl.present: - - value: 262144 - -# Add ES Group -elasticsearchgroup: - group.present: - - name: elasticsearch - - gid: 930 - -esconfdir: - file.directory: - - name: /opt/so/conf/elasticsearch - - user: 930 - - group: 939 - - makedirs: True - -# Add ES user -elasticsearch: - user.present: - - uid: 930 - - gid: 930 - - home: /opt/so/conf/elasticsearch - - createhome: False - -{% if GLOBALS.is_manager %} -# We have to add the Manager CA to the CA list -cascriptsync: - file.managed: - - name: /usr/sbin/so-catrust - - source: salt://elasticsearch/tools/sbin_jinja/so-catrust - - user: 939 - - group: 939 - - mode: 750 - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} - -# Run the CA magic -cascriptfun: - cmd.run: - - name: /usr/sbin/so-catrust - - require: - - file: cascriptsync -{% endif %} - -elasticsearch_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://elasticsearch/tools/sbin - - user: 930 - - group: 939 - - file_mode: 755 - - exclude_pat: - - so-catrust - - so-elasticsearch-pipelines # exclude this because we need to watch it for changes, we sync it in another state - -elasticsearch_sbin_jinja: - file.recurse: - - name: /usr/sbin - - source: salt://elasticsearch/tools/sbin_jinja - - user: 939 - - group: 939 - - file_mode: 755 - - template: jinja - - exclude_pat: - - so-elasticsearch-ilm-policy-load # exclude this because we need to watch it for changes, we sync it in another state - - defaults: - GLOBALS: {{ GLOBALS }} - -so-elasticsearch-ilm-policy-load-script: - file.managed: - - name: /usr/sbin/so-elasticsearch-ilm-policy-load - - source: salt://elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load - - user: 930 - - group: 939 - - mode: 754 - - template: jinja - -so-elasticsearch-pipelines-script: - file.managed: - - name: /usr/sbin/so-elasticsearch-pipelines - - source: salt://elasticsearch/tools/sbin/so-elasticsearch-pipelines - - user: 930 - - group: 939 - - mode: 754 - -# Move our new CA over so Elastic and Logstash can use SSL with the internal CA -catrustdir: - file.directory: - - name: /opt/so/conf/ca - - user: 939 - - group: 939 - - makedirs: True - -cacertz: - file.managed: - - name: /opt/so/conf/ca/cacerts - - source: salt://common/cacerts - - user: 939 - - group: 939 - -capemz: - file.managed: - - name: /opt/so/conf/ca/tls-ca-bundle.pem - - source: salt://common/tls-ca-bundle.pem - - user: 939 - - group: 939 - -esingestdir: - file.directory: - - name: /opt/so/conf/elasticsearch/ingest - - user: 930 - - group: 939 - - makedirs: True - -estemplatedir: - file.directory: - - name: /opt/so/conf/elasticsearch/templates/index - - user: 930 - - group: 939 - - makedirs: True - -esrolesdir: - file.directory: - - name: /opt/so/conf/elasticsearch/roles - - user: 930 - - group: 939 - - makedirs: True - -eslibdir: - file.absent: - - name: /opt/so/conf/elasticsearch/lib - -esingestdynamicconf: - file.recurse: - - name: /opt/so/conf/elasticsearch/ingest - - source: salt://elasticsearch/files/ingest-dynamic - - user: 930 - - group: 939 - - template: jinja - -esingestconf: - file.recurse: - - name: /opt/so/conf/elasticsearch/ingest - - source: salt://elasticsearch/files/ingest - - user: 930 - - group: 939 - -eslog4jfile: - file.managed: - - name: /opt/so/conf/elasticsearch/log4j2.properties - - source: salt://elasticsearch/files/log4j2.properties - - user: 930 - - group: 939 - - template: jinja - -esyml: - file.managed: - - name: /opt/so/conf/elasticsearch/elasticsearch.yml - - source: salt://elasticsearch/files/elasticsearch.yaml.jinja - - user: 930 - - group: 939 - - defaults: - ESCONFIG: {{ ESCONFIG }} - - template: jinja - -{% if GLOBALS.role != "so-searchnode" %} -escomponenttemplates: - file.recurse: - - name: /opt/so/conf/elasticsearch/templates/component - - source: salt://elasticsearch/templates/component - - user: 930 - - group: 939 - - onchanges_in: - - cmd: so-elasticsearch-templates - -# Auto-generate templates from defaults file -{% for index, settings in ES_INDEX_SETTINGS.items() %} - {% if settings.index_template is defined %} -es_index_template_{{index}}: - file.managed: - - name: /opt/so/conf/elasticsearch/templates/index/{{ index }}-template.json - - source: salt://elasticsearch/base-template.json.jinja - - defaults: - TEMPLATE_CONFIG: {{ settings.index_template }} - - template: jinja - - onchanges_in: - - cmd: so-elasticsearch-templates - {% endif %} -{% endfor %} - -{% if TEMPLATES %} -# Sync custom templates to /opt/so/conf/elasticsearch/templates -{% for TEMPLATE in TEMPLATES %} -es_template_{{TEMPLATE.split('.')[0] | replace("/","_") }}: - file.managed: - - source: salt://elasticsearch/templates/index/{{TEMPLATE}} - {% if 'jinja' in TEMPLATE.split('.')[-1] %} - - name: /opt/so/conf/elasticsearch/templates/index/{{TEMPLATE.split('/')[1] | replace(".jinja", "")}} - - template: jinja - {% else %} - - name: /opt/so/conf/elasticsearch/templates/index/{{TEMPLATE.split('/')[1]}} - {% endif %} - - user: 930 - - group: 939 - - onchanges_in: - - cmd: so-elasticsearch-templates -{% endfor %} -{% endif %} -{% endif %} - -esroles: - file.recurse: - - source: salt://elasticsearch/roles/ - - name: /opt/so/conf/elasticsearch/roles/ - - clean: True - - template: jinja - - user: 930 - - group: 939 - -nsmesdir: - file.directory: - - name: /nsm/elasticsearch - - user: 930 - - group: 939 - - makedirs: True - -eslogdir: - file.directory: - - name: /opt/so/log/elasticsearch - - user: 930 - - group: 939 - - makedirs: True - -es_repo_dir: - file.directory: - - name: /nsm/elasticsearch/repo/ - - user: 930 - - group: 930 - - require: - - file: nsmesdir - -so-pipelines-reload: - file.absent: - - name: /opt/so/state/espipelines.txt - - onchanges: - - file: esingestconf - - file: esingestdynamicconf - - file: esyml - - file: so-elasticsearch-pipelines-script - -auth_users: - file.managed: - - name: /opt/so/conf/elasticsearch/users.tmp - - source: salt://elasticsearch/files/users - - user: 930 - - group: 930 - - mode: 600 - - show_changes: False - -auth_users_roles: - file.managed: - - name: /opt/so/conf/elasticsearch/users_roles.tmp - - source: salt://elasticsearch/files/users_roles - - user: 930 - - group: 930 - - mode: 600 - - show_changes: False - -auth_users_inode: - require: - - file: auth_users - cmd.run: - - name: cat /opt/so/conf/elasticsearch/users.tmp > /opt/so/conf/elasticsearch/users && chown 930:939 /opt/so/conf/elasticsearch/users && chmod 660 /opt/so/conf/elasticsearch/users - - onchanges: - - file: /opt/so/conf/elasticsearch/users.tmp - -auth_users_roles_inode: - require: - - file: auth_users_roles - cmd.run: - - name: cat /opt/so/conf/elasticsearch/users_roles.tmp > /opt/so/conf/elasticsearch/users_roles && chown 930:939 /opt/so/conf/elasticsearch/users_roles && chmod 660 /opt/so/conf/elasticsearch/users_roles - - onchanges: - - file: /opt/so/conf/elasticsearch/users_roles.tmp - -so-elasticsearch: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ GLOBALS.so_version }} - - hostname: elasticsearch - - name: so-elasticsearch - - user: elasticsearch - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-elasticsearch'].ip }} - - extra_hosts: {{ LOGSTASH_NODES }} - - environment: - {% if LOGSTASH_NODES | length == 1 %} - - discovery.type=single-node - {% endif %} - - ES_JAVA_OPTS=-Xms{{ GLOBALS.elasticsearch.es_heap }} -Xmx{{ GLOBALS.elasticsearch.es_heap }} -Des.transport.cname_in_publish_address=true -Dlog4j2.formatMsgNoLookups=true - ulimits: - - memlock=-1:-1 - - nofile=65536:65536 - - nproc=4096 - - port_bindings: - {% for BINDING in DOCKER.containers['so-elasticsearch'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - binds: - - /opt/so/conf/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro - - /opt/so/conf/elasticsearch/log4j2.properties:/usr/share/elasticsearch/config/log4j2.properties:ro - - /nsm/elasticsearch:/usr/share/elasticsearch/data:rw - - /opt/so/log/elasticsearch:/var/log/elasticsearch:rw - - /opt/so/conf/ca/cacerts:/usr/share/elasticsearch/jdk/lib/security/cacerts:ro - {% if GLOBALS.is_manager %} - - /etc/pki/ca.crt:/usr/share/elasticsearch/config/ca.crt:ro - {% else %} - - /etc/ssl/certs/intca.crt:/usr/share/elasticsearch/config/ca.crt:ro - {% endif %} - - /etc/pki/elasticsearch.crt:/usr/share/elasticsearch/config/elasticsearch.crt:ro - - /etc/pki/elasticsearch.key:/usr/share/elasticsearch/config/elasticsearch.key:ro - - /etc/pki/elasticsearch.p12:/usr/share/elasticsearch/config/elasticsearch.p12:ro - - /opt/so/conf/elasticsearch/users_roles:/usr/share/elasticsearch/config/users_roles:ro - - /opt/so/conf/elasticsearch/users:/usr/share/elasticsearch/config/users:ro - {% if ESCONFIG.path.get('repo', False) %} - {% for repo in ESCONFIG.path.repo %} - - {{ repo }}:{{ repo }}:rw - {% endfor %} - {% endif %} - - watch: - - file: cacertz - - file: esyml - - require: - - file: esyml - - file: eslog4jfile - - file: nsmesdir - - file: eslogdir - - file: cacertz - - x509: /etc/pki/elasticsearch.crt - - x509: /etc/pki/elasticsearch.key - - file: elasticp12perms - {% if GLOBALS.is_manager %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} - - cmd: auth_users_roles_inode - - cmd: auth_users_inode - -append_so-elasticsearch_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-elasticsearch - -{% if GLOBALS.role != "so-searchnode" %} - -so-es-cluster-settings: - cmd.run: - - name: /usr/sbin/so-elasticsearch-cluster-settings - - cwd: /opt/so - - template: jinja - - require: - - docker_container: so-elasticsearch - - file: elasticsearch_sbin_jinja - -so-elasticsearch-ilm-policy-load: - cmd.run: - - name: /usr/sbin/so-elasticsearch-ilm-policy-load - - cwd: /opt/so - - require: - - docker_container: so-elasticsearch - - file: so-elasticsearch-ilm-policy-load-script - - onchanges: - - file: so-elasticsearch-ilm-policy-load-script - -so-elasticsearch-templates: - cmd.run: - - name: /usr/sbin/so-elasticsearch-templates-load - - cwd: /opt/so - - template: jinja - - require: - - docker_container: so-elasticsearch - - file: elasticsearch_sbin_jinja - -so-elasticsearch-pipelines: - cmd.run: - - name: /usr/sbin/so-elasticsearch-pipelines {{ GLOBALS.hostname }} - - require: - - docker_container: so-elasticsearch - - file: so-elasticsearch-pipelines-script - -so-elasticsearch-roles-load: - cmd.run: - - name: /usr/sbin/so-elasticsearch-roles-load - - cwd: /opt/so - - template: jinja - - require: - - docker_container: so-elasticsearch - - file: elasticsearch_sbin_jinja -{% endif %} +{% if ELASTICSEARCHMERGED.enabled %} + - elasticsearch.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - -{% endif %} {# if 'elasticsearch' in top_states #} + - elasticsearch.disabled +{% endif %} diff --git a/salt/elasticsearch/soc_elasticsearch.yaml b/salt/elasticsearch/soc_elasticsearch.yaml index ded8e5be6..da22268f6 100644 --- a/salt/elasticsearch/soc_elasticsearch.yaml +++ b/salt/elasticsearch/soc_elasticsearch.yaml @@ -1,4 +1,7 @@ elasticsearch: + enabled: + description: You can enable or disable Elasticsearch. + helpLink: elasticsearch.html esheap: description: Specify the memory heap size in (m)egabytes for Elasticsearch. helpLink: elasticsearch.html diff --git a/salt/elasticsearch/sostatus.sls b/salt/elasticsearch/sostatus.sls new file mode 100644 index 000000000..2967a39db --- /dev/null +++ b/salt/elasticsearch/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-elasticsearch_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-elasticsearch + - unless: grep -q so-elasticsearch /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticsearch/template.map.jinja b/salt/elasticsearch/template.map.jinja index 9c90cc28f..49d86d187 100644 --- a/salt/elasticsearch/template.map.jinja +++ b/salt/elasticsearch/template.map.jinja @@ -1,5 +1,5 @@ -{% import_yaml 'elasticsearch/defaults.yaml' as ESCONFIG with context %} -{%- set ES_INDEX_SETTINGS = salt['pillar.get']('elasticsearch:index_settings', default=ESCONFIG.elasticsearch.index_settings, merge=True) %} +{% import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS with context %} +{%- set ES_INDEX_SETTINGS = salt['pillar.get']('elasticsearch:index_settings', default=ELASTICSEARCHDEFAULTS.elasticsearch.index_settings, merge=True) %} {% for index, settings in ES_INDEX_SETTINGS.items() %} {% if settings.index_template is defined %} {% if not settings.get('index_sorting', False) | to_bool and settings.index_template.template.settings.index.sort is defined %} diff --git a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load index afeddfa01..afb8bdc67 100755 --- a/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load +++ b/salt/elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load @@ -6,15 +6,15 @@ . /usr/sbin/so-common -{% import_yaml 'elasticsearch/defaults.yaml' as ESCONFIG with context %} -{%- set ES_INDEX_SETTINGS = salt['pillar.get']('elasticsearch:index_settings', default=ESCONFIG.elasticsearch.index_settings, merge=True) %} +{%- import_yaml 'elasticsearch/defaults.yaml' as ELASTICSEARCHDEFAULTS %} +{%- set ES_INDEX_SETTINGS = salt['pillar.get']('elasticsearch:index_settings', default=ELASTICSEARCHDEFAULTS.elasticsearch.index_settings, merge=True) %} {%- for index, settings in ES_INDEX_SETTINGS.items() %} - {%- if settings.policy is defined %} +{%- if settings.policy is defined %} echo echo "Setting up {{ index }}-logs policy..." curl -K /opt/so/conf/elasticsearch/curl.config -b "sid=$SESSIONCOOKIE" -s -k -L -X PUT "https://localhost:9200/_ilm/policy/{{ index }}-logs" -H 'Content-Type: application/json' -d'{ "policy": {{ settings.policy | tojson(true) }} }' echo - {%- endif %} +{%- endif %} {%- endfor %} echo diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index b94bfac59..0195cdb5c 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -125,9 +125,10 @@ function create_minion_files() { } # Add Elastic settings to the minion file -function add_elastic_to_minion() { +function add_elasticsearch_to_minion() { printf '%s\n'\ "elasticsearch:"\ + " enabled: True"\ " esheap: '$ES_HEAP_SIZE'"\ " " >> $PILLARFILE } @@ -279,14 +280,14 @@ function apply_ES_state() { salt-call state.apply elasticsearch concurrent=True } function createEVAL() { - add_elastic_to_minion + add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion add_elastalert_to_minion } function createSTANDALONE() { - add_elastic_to_minion + add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion add_playbook_to_minion @@ -294,14 +295,14 @@ function createSTANDALONE() { } function createMANAGER() { - add_elastic_to_minion + add_elasticsearch_to_minion add_logstash_to_minion add_playbook_to_minion add_elastalert_to_minion } function createMANAGERSEARCH() { - add_elastic_to_minion + add_elasticsearch_to_minion add_logstash_to_minion add_playbook_to_minion add_elastalert_to_minion @@ -320,13 +321,13 @@ function createIDH() { } function createIMPORT() { - add_elastic_to_minion + add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion } function createHEAVYNODE() { - add_elastic_to_minion + add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion } @@ -336,7 +337,7 @@ function createSENSOR() { } function createSEARCHNODE() { - add_elastic_to_minion + add_elasticsearch_to_minion add_logstash_to_minion updateMine apply_ES_state diff --git a/salt/pcap/sostatus.sls b/salt/pcap/sostatus.sls index d7380e804..41ff1a183 100644 --- a/salt/pcap/sostatus.sls +++ b/salt/pcap/sostatus.sls @@ -1,3 +1,8 @@ +{# 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 %} From 328b714306244543ef0e8a291af117f4843ad397 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 09:51:53 -0400 Subject: [PATCH 14/68] import ELASTICSEARCHMERGED --- salt/elasticsearch/enabled.sls | 1 + 1 file changed, 1 insertion(+) diff --git a/salt/elasticsearch/enabled.sls b/salt/elasticsearch/enabled.sls index 0fc77f0ee..fa51a4124 100644 --- a/salt/elasticsearch/enabled.sls +++ b/salt/elasticsearch/enabled.sls @@ -8,6 +8,7 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'docker/docker.map.jinja' import DOCKER %} {% from 'logstash/map.jinja' import LOGSTASH_NODES %} +{% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %} {% set TEMPLATES = salt['pillar.get']('elasticsearch:templates', {}) %} {% from 'elasticsearch/template.map.jinja' import ES_INDEX_SETTINGS %} From 7bd9a84aa1b1c80de40bb7712db07839d94a12bb Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 10:01:30 -0400 Subject: [PATCH 15/68] changes to top and allow_states for enable/disable elasticsearch in ui --- salt/allowed_states.map.jinja | 5 ++--- salt/top.sls | 15 --------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index d5eaa5599..8470a379c 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set CURATOR = salt['pillar.get']('curator:enabled', True) %} @@ -225,11 +224,11 @@ {% do allowed_states.append('strelka') %} {% endif %} - {% if ELASTICSEARCH and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-import'] %} + {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-import'] %} {% do allowed_states.append('elasticsearch') %} {% endif %} - {% if ELASTICSEARCH and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %} + {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %} {% do allowed_states.append('elasticsearch.auth') %} {% endif %} diff --git a/salt/top.sls b/salt/top.sls index c108236b9..f30de8763 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set REDIS = salt['pillar.get']('redis:enabled', True) %} @@ -74,9 +73,7 @@ base: - suricata.manager - healthcheck - mysql - {%- if ELASTICSEARCH %} - elasticsearch - {%- endif %} {%- if KIBANA %} - elastic-fleet-package-registry - kibana.so_savedobjects_defaults @@ -116,9 +113,7 @@ base: - idstools - suricata.manager - mysql - {%- if ELASTICSEARCH %} - elasticsearch - {%- endif %} {%- if LOGSTASH %} - logstash {%- endif %} @@ -156,9 +151,7 @@ base: - suricata.manager - healthcheck - mysql - {%- if ELASTICSEARCH %} - elasticsearch - {%- endif %} {%- if LOGSTASH %} - logstash {%- endif %} @@ -190,9 +183,7 @@ base: - nginx - telegraf - firewall - {%- if ELASTICSEARCH %} - elasticsearch - {%- endif %} {%- if LOGSTASH %} - logstash {%- endif %} @@ -217,9 +208,7 @@ base: - idstools - suricata.manager - mysql - {%- if ELASTICSEARCH %} - elasticsearch - {%- endif %} {%- if LOGSTASH %} - logstash {%- endif %} @@ -245,9 +234,7 @@ base: - nginx - telegraf - firewall - {%- if ELASTICSEARCH %} - elasticsearch - {%- endif %} {%- if LOGSTASH %} - logstash {%- endif %} @@ -281,9 +268,7 @@ base: - idstools - suricata.manager - pcap - {%- if ELASTICSEARCH %} - elasticsearch - {%- endif %} {%- if KIBANA %} - elastic-fleet-package-registry - kibana.so_savedobjects_defaults From 9d6fb98e3b1f42f676c9b82dcbd9e5aac4da0c8b Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 11:13:57 -0400 Subject: [PATCH 16/68] move cacertz and capemz to ca state --- salt/ca/init.sls | 16 ++++++++++++++++ salt/elasticsearch/config.sls | 14 -------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/salt/ca/init.sls b/salt/ca/init.sls index 4c7973cd0..88c32e12a 100644 --- a/salt/ca/init.sls +++ b/salt/ca/init.sls @@ -58,6 +58,22 @@ cakeyperms: - mode: 640 - group: 939 +{% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} +cacertz: + file.managed: + - name: /opt/so/conf/ca/cacerts + - source: salt://common/cacerts + - user: 939 + - group: 939 + +capemz: + file.managed: + - name: /opt/so/conf/ca/tls-ca-bundle.pem + - source: salt://common/tls-ca-bundle.pem + - user: 939 + - group: 939 +{% endif %} + {% else %} {{sls}}_state_not_allowed: diff --git a/salt/elasticsearch/config.sls b/salt/elasticsearch/config.sls index 255d09376..dcd0283c0 100644 --- a/salt/elasticsearch/config.sls +++ b/salt/elasticsearch/config.sls @@ -107,20 +107,6 @@ catrustdir: - group: 939 - makedirs: True -cacertz: - file.managed: - - name: /opt/so/conf/ca/cacerts - - source: salt://common/cacerts - - user: 939 - - group: 939 - -capemz: - file.managed: - - name: /opt/so/conf/ca/tls-ca-bundle.pem - - source: salt://common/tls-ca-bundle.pem - - user: 939 - - group: 939 - esingestdir: file.directory: - name: /opt/so/conf/elasticsearch/ingest From 6909d3ed14a8fa4855ec485fc0268a121630d8be Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 12:16:18 -0400 Subject: [PATCH 17/68] move cacertz and capemz to ssl state --- salt/ca/init.sls | 16 ---------------- salt/ssl/init.sls | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/salt/ca/init.sls b/salt/ca/init.sls index 88c32e12a..4c7973cd0 100644 --- a/salt/ca/init.sls +++ b/salt/ca/init.sls @@ -58,22 +58,6 @@ cakeyperms: - mode: 640 - group: 939 -{% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} -cacertz: - file.managed: - - name: /opt/so/conf/ca/cacerts - - source: salt://common/cacerts - - user: 939 - - group: 939 - -capemz: - file.managed: - - name: /opt/so/conf/ca/tls-ca-bundle.pem - - source: salt://common/tls-ca-bundle.pem - - user: 939 - - group: 939 -{% endif %} - {% else %} {{sls}}_state_not_allowed: diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index ec807e6aa..ca23179b7 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -35,6 +35,22 @@ include: {% set ca_server = global_ca_server[0] %} {% endif %} +{% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-searchnode'] %} +cacertz: + file.managed: + - name: /opt/so/conf/ca/cacerts + - source: salt://common/cacerts + - user: 939 + - group: 939 + +capemz: + file.managed: + - name: /opt/so/conf/ca/tls-ca-bundle.pem + - source: salt://common/tls-ca-bundle.pem + - user: 939 + - group: 939 +{% endif %} + # Trust the CA trusttheca: x509.pem_managed: From ec7bcd9b0c8786ecd937ababf161d44c5f8447ea Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 16:46:48 -0400 Subject: [PATCH 18/68] enabled/disable kibana in ui --- salt/allowed_states.map.jinja | 3 +- salt/kibana/config.map.jinja | 18 ---- salt/kibana/config.sls | 93 +++++++++++++++++ salt/kibana/defaults.yaml | 4 +- salt/kibana/disabled.sls | 27 +++++ salt/kibana/enabled.sls | 48 +++++++++ salt/kibana/init.sls | 127 ++--------------------- salt/kibana/map.jinja | 23 ++++ salt/kibana/so_config_load.sls | 2 +- salt/kibana/so_dashboard_load.sls | 2 +- salt/kibana/so_savedobjects_defaults.sls | 2 +- salt/kibana/so_securitySolution_load.sls | 2 +- salt/kibana/soc_kibana.yaml | 3 + salt/kibana/sostatus.sls | 21 ++++ salt/manager/tools/sbin/so-minion | 2 +- salt/pcap/sostatus.sls | 8 +- salt/top.sls | 21 +--- 17 files changed, 240 insertions(+), 166 deletions(-) delete mode 100644 salt/kibana/config.map.jinja create mode 100644 salt/kibana/config.sls create mode 100644 salt/kibana/disabled.sls create mode 100644 salt/kibana/enabled.sls create mode 100644 salt/kibana/map.jinja create mode 100644 salt/kibana/sostatus.sls diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 8470a379c..a932692cf 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set CURATOR = salt['pillar.get']('curator:enabled', True) %} {% set REDIS = salt['pillar.get']('redis:enabled', True) %} @@ -232,7 +231,7 @@ {% do allowed_states.append('elasticsearch.auth') %} {% endif %} - {% if KIBANA and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %} + {% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %} {% do allowed_states.append('kibana') %} {% do allowed_states.append('kibana.secrets') %} {% endif %} diff --git a/salt/kibana/config.map.jinja b/salt/kibana/config.map.jinja deleted file mode 100644 index 9ad1012f7..000000000 --- a/salt/kibana/config.map.jinja +++ /dev/null @@ -1,18 +0,0 @@ -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% import_yaml 'kibana/defaults.yaml' as KIBANACONFIG with context %} -{% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %} - -{% do KIBANACONFIG.kibana.config.server.update({'publicBaseUrl': 'https://' ~ GLOBALS.url_base ~ '/kibana'}) %} -{% do KIBANACONFIG.kibana.config.elasticsearch.update({'hosts': ['https://' ~ GLOBALS.manager ~ ':9200']}) %} - -{% do KIBANACONFIG.kibana.config.elasticsearch.update({'username': salt['pillar.get']('elasticsearch:auth:users:so_kibana_user:user'), 'password': salt['pillar.get']('elasticsearch:auth:users:so_kibana_user:pass')}) %} - -{% do KIBANACONFIG.kibana.config.xpack.fleet.update({'registryUrl': 'http://' ~ GLOBALS.manager_ip ~ ':8080'}) %} - -{% if salt['pillar.get']('kibana:secrets') %} - {% do KIBANACONFIG.kibana.config.xpack.update({'encryptedSavedObjects': {'encryptionKey': pillar['kibana']['secrets']['encryptedSavedObjects']['encryptionKey']}}) %} - {% do KIBANACONFIG.kibana.config.xpack.security.update({'encryptionKey': pillar['kibana']['secrets']['security']['encryptionKey']}) %} - {% do KIBANACONFIG.kibana.config.xpack.update({'reporting': {'encryptionKey': pillar['kibana']['secrets']['reporting']['encryptionKey']}}) %} -{% endif %} - -{% set KIBANACONFIG = salt['pillar.get']('kibana:config', default=KIBANACONFIG.kibana.config, merge=True) %} diff --git a/salt/kibana/config.sls b/salt/kibana/config.sls new file mode 100644 index 000000000..433fc9601 --- /dev/null +++ b/salt/kibana/config.sls @@ -0,0 +1,93 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% import_yaml 'kibana/defaults.yaml' as default_settings %} +{% from 'kibana/map.jinja' import KIBANAMERGED %} + +# Add ES Group +kibanasearchgroup: + group.present: + - name: kibana + - gid: 932 + +# Add ES user +kibana: + user.present: + - uid: 932 + - gid: 932 + - home: /opt/so/conf/kibana + - createhome: False + +# Drop the correct nginx config based on role + +kibanaconfdir: + file.directory: + - name: /opt/so/conf/kibana/etc + - user: 932 + - group: 939 + - makedirs: True + +kibana_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://kibana/tools/sbin + - user: 932 + - group: 939 + - file_mode: 755 + +kibana_sbin_jinja: + file.recurse: + - name: /usr/sbin + - source: salt://kibana/tools/sbin_jinja + - user: 932 + - group: 939 + - file_mode: 755 + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} + +kibanaconfig: + file.managed: + - name: /opt/so/conf/kibana/etc/kibana.yml + - source: salt://kibana/etc/kibana.yml.jinja + - user: 932 + - group: 939 + - mode: 660 + - template: jinja + - defaults: + KIBANACONFIG: {{ KIBANAMERGED.config }} + - show_changes: False + +kibanalogdir: + file.directory: + - name: /opt/so/log/kibana + - user: 932 + - group: 939 + - makedirs: True + +kibanacustdashdir: + file.directory: + - name: /opt/so/conf/kibana/customdashboards + - user: 932 + - group: 939 + - makedirs: True + +synckibanacustom: + file.recurse: + - name: /opt/so/conf/kibana/customdashboards + - source: salt://kibana/custom + - user: 932 + - group: 939 + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kibana/defaults.yaml b/salt/kibana/defaults.yaml index c0e279ca9..282521d12 100644 --- a/salt/kibana/defaults.yaml +++ b/salt/kibana/defaults.yaml @@ -1,5 +1,5 @@ kibana: - enabled: True + enabled: False config: server: name: kibana @@ -32,4 +32,4 @@ kibana: kibanaServer: hostname: localhost fleet: - registryUrl: "" \ No newline at end of file + registryUrl: "" diff --git a/salt/kibana/disabled.sls b/salt/kibana/disabled.sls new file mode 100644 index 000000000..eed2a623e --- /dev/null +++ b/salt/kibana/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - kibana.sostatus + +so-kibana: + docker_container.absent: + - force: True + +so-kibana_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-kibana$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kibana/enabled.sls b/salt/kibana/enabled.sls new file mode 100644 index 000000000..8d81beb56 --- /dev/null +++ b/salt/kibana/enabled.sls @@ -0,0 +1,48 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - kibana.config + - kibana.sostatus + +# Start the kibana docker +so-kibana: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kibana:{{ GLOBALS.so_version }} + - hostname: kibana + - user: kibana + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-kibana'].ip }} + - environment: + - ELASTICSEARCH_HOST={{ GLOBALS.manager }} + - ELASTICSEARCH_PORT=9200 + - MANAGER={{ GLOBALS.manager }} + - extra_hosts: + - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} + - binds: + - /opt/so/conf/kibana/etc:/usr/share/kibana/config:rw + - /opt/so/log/kibana:/var/log/kibana:rw + - /opt/so/conf/kibana/customdashboards:/usr/share/kibana/custdashboards:ro + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - port_bindings: + {% for BINDING in DOCKER.containers['so-kibana'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - watch: + - file: kibanaconfig + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kibana/init.sls b/salt/kibana/init.sls index a9d3c6da9..675106d8f 100644 --- a/salt/kibana/init.sls +++ b/salt/kibana/init.sls @@ -3,125 +3,14 @@ # 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 in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% import_yaml 'kibana/defaults.yaml' as default_settings %} -{% set KIBANA_SETTINGS = salt['grains.filter_by'](default_settings, default='kibana', merge=salt['pillar.get']('kibana', {})) %} -{% from 'kibana/config.map.jinja' import KIBANACONFIG with context %} - -# Add ES Group -kibanasearchgroup: - group.present: - - name: kibana - - gid: 932 - -# Add ES user -kibana: - user.present: - - uid: 932 - - gid: 932 - - home: /opt/so/conf/kibana - - createhome: False - -# Drop the correct nginx config based on role - -kibanaconfdir: - file.directory: - - name: /opt/so/conf/kibana/etc - - user: 932 - - group: 939 - - makedirs: True - -kibana_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://kibana/tools/sbin - - user: 932 - - group: 939 - - file_mode: 755 - -kibana_sbin_jinja: - file.recurse: - - name: /usr/sbin - - source: salt://kibana/tools/sbin_jinja - - user: 932 - - group: 939 - - file_mode: 755 - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} - -kibanaconfig: - file.managed: - - name: /opt/so/conf/kibana/etc/kibana.yml - - source: salt://kibana/etc/kibana.yml.jinja - - user: 932 - - group: 939 - - mode: 660 - - template: jinja - - defaults: - KIBANACONFIG: {{ KIBANACONFIG }} - - show_changes: False - -kibanalogdir: - file.directory: - - name: /opt/so/log/kibana - - user: 932 - - group: 939 - - makedirs: True - -kibanacustdashdir: - file.directory: - - name: /opt/so/conf/kibana/customdashboards - - user: 932 - - group: 939 - - makedirs: True - -synckibanacustom: - file.recurse: - - name: /opt/so/conf/kibana/customdashboards - - source: salt://kibana/custom - - user: 932 - - group: 939 - -# Start the kibana docker -so-kibana: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kibana:{{ GLOBALS.so_version }} - - hostname: kibana - - user: kibana - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-kibana'].ip }} - - environment: - - ELASTICSEARCH_HOST={{ GLOBALS.manager }} - - ELASTICSEARCH_PORT=9200 - - MANAGER={{ GLOBALS.manager }} - - extra_hosts: - - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - - binds: - - /opt/so/conf/kibana/etc:/usr/share/kibana/config:rw - - /opt/so/log/kibana:/var/log/kibana:rw - - /opt/so/conf/kibana/customdashboards:/usr/share/kibana/custdashboards:ro - - /sys/fs/cgroup:/sys/fs/cgroup:ro - - port_bindings: - {% for BINDING in DOCKER.containers['so-kibana'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - watch: - - file: kibanaconfig - -append_so-kibana_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-kibana +{% from 'kibana/map.jinja' import KIBANAMERGED %} +include: +{% if KIBANAMERGED.enabled %} + - kibana.enabled + - kibana.so_config_load + - kibana.so_securitySolution_load + - kibana.so_dashboard_load {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - kibana.disabled {% endif %} diff --git a/salt/kibana/map.jinja b/salt/kibana/map.jinja new file mode 100644 index 000000000..bd333f1c4 --- /dev/null +++ b/salt/kibana/map.jinja @@ -0,0 +1,23 @@ +{# 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 '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']}) %} + +{% do KIBANADEFAULTS.kibana.config.elasticsearch.update({'username': salt['pillar.get']('elasticsearch:auth:users:so_kibana_user:user'), 'password': salt['pillar.get']('elasticsearch:auth:users:so_kibana_user:pass')}) %} + +{% do KIBANADEFAULTS.kibana.config.xpack.fleet.update({'registryUrl': 'http://' ~ GLOBALS.manager_ip ~ ':8080'}) %} + +{% if salt['pillar.get']('kibana:secrets') %} + {% do KIBANADEFAULTS.kibana.config.xpack.update({'encryptedSavedObjects': {'encryptionKey': pillar['kibana']['secrets']['encryptedSavedObjects']['encryptionKey']}}) %} + {% do KIBANADEFAULTS.kibana.config.xpack.security.update({'encryptionKey': pillar['kibana']['secrets']['security']['encryptionKey']}) %} + {% do KIBANADEFAULTS.kibana.config.xpack.update({'reporting': {'encryptionKey': pillar['kibana']['secrets']['reporting']['encryptionKey']}}) %} +{% endif %} + +{% set KIBANAMERGED = salt['pillar.get']('kibana', default=KIBANADEFAULTS.kibana, merge=True) %} diff --git a/salt/kibana/so_config_load.sls b/salt/kibana/so_config_load.sls index ea9655688..84c17deca 100644 --- a/salt/kibana/so_config_load.sls +++ b/salt/kibana/so_config_load.sls @@ -4,7 +4,7 @@ # Elastic License 2.0. include: - - kibana + - kibana.enabled config_saved_objects: file.managed: diff --git a/salt/kibana/so_dashboard_load.sls b/salt/kibana/so_dashboard_load.sls index 26cc13f83..08fb48da7 100644 --- a/salt/kibana/so_dashboard_load.sls +++ b/salt/kibana/so_dashboard_load.sls @@ -5,7 +5,7 @@ {% set HIGHLANDER = salt['pillar.get']('global:highlander', False) %} include: - - kibana + - kibana.enabled dashboard_saved_objects_template: file.managed: diff --git a/salt/kibana/so_savedobjects_defaults.sls b/salt/kibana/so_savedobjects_defaults.sls index 135053c68..c9fe61ac6 100644 --- a/salt/kibana/so_savedobjects_defaults.sls +++ b/salt/kibana/so_savedobjects_defaults.sls @@ -4,7 +4,7 @@ # Elastic License 2.0. include: - - kibana + - kibana.enabled - kibana.so_config_load - kibana.so_securitySolution_load - kibana.so_dashboard_load diff --git a/salt/kibana/so_securitySolution_load.sls b/salt/kibana/so_securitySolution_load.sls index 0f72adcda..fe57f5a73 100644 --- a/salt/kibana/so_securitySolution_load.sls +++ b/salt/kibana/so_securitySolution_load.sls @@ -4,7 +4,7 @@ # Elastic License 2.0. include: - - kibana + - kibana.enabled securitySolution_saved_objects: file.managed: diff --git a/salt/kibana/soc_kibana.yaml b/salt/kibana/soc_kibana.yaml index 331e7716f..c95512b58 100644 --- a/salt/kibana/soc_kibana.yaml +++ b/salt/kibana/soc_kibana.yaml @@ -1,4 +1,7 @@ kibana: + enabled: + description: You can enable or disable Kibana. + helpLink: kibana.html config: elasticsearch: requestTimeout: diff --git a/salt/kibana/sostatus.sls b/salt/kibana/sostatus.sls new file mode 100644 index 000000000..9bab0efe8 --- /dev/null +++ b/salt/kibana/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-kibana_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-kibana + - unless: grep -q so-kibana /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 0195cdb5c..eeaea1209 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -216,7 +216,7 @@ function add_sensor_to_minion() { echo " af-packet:" >> $PILLARFILE echo " threads: '$CORECOUNT'" >> $PILLARFILE echo "pcap:" >> $PILLARFILE - echo " enabled: True" >> $PILLARFILE + echo " enabled: True" >> $PILLARFILE echo " " >> $PILLARFILE } diff --git a/salt/pcap/sostatus.sls b/salt/pcap/sostatus.sls index 41ff1a183..4eebbfb0e 100644 --- a/salt/pcap/sostatus.sls +++ b/salt/pcap/sostatus.sls @@ -1,7 +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. #} +# 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 %} diff --git a/salt/top.sls b/salt/top.sls index f30de8763..6ebd0340d 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set REDIS = salt['pillar.get']('redis:enabled', True) %} {% set STRELKA = salt['pillar.get']('strelka:enabled', '0') %} @@ -74,10 +73,8 @@ base: - healthcheck - mysql - elasticsearch - {%- if KIBANA %} - elastic-fleet-package-registry - - kibana.so_savedobjects_defaults - {%- endif %} + - kibana - pcap - suricata - zeek @@ -120,10 +117,8 @@ base: {%- if REDIS %} - redis {%- endif %} - {%- if KIBANA %} - elastic-fleet-package-registry - - kibana.so_savedobjects_defaults - {%- endif %} + - kibana - curator - elastalert - utility @@ -158,10 +153,8 @@ base: {%- if REDIS %} - redis {%- endif %} - {%- if KIBANA %} - elastic-fleet-package-registry - - kibana.so_savedobjects_defaults - {%- endif %} + - kibana - pcap - suricata - zeek @@ -216,10 +209,8 @@ base: - redis {%- endif %} - curator - {%- if KIBANA %} - elastic-fleet-package-registry - - kibana.so_savedobjects_defaults - {%- endif %} + - kibana - elastalert - utility - soctopus @@ -269,10 +260,8 @@ base: - suricata.manager - pcap - elasticsearch - {%- if KIBANA %} - elastic-fleet-package-registry - - kibana.so_savedobjects_defaults - {%- endif %} + - kibana - utility - suricata - zeek From 4dc0f06331ba2ae2e0ef71b2f25848ce28cd61c1 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 16:51:41 -0400 Subject: [PATCH 19/68] add add_kibana_to_minion to so-minion --- salt/manager/tools/sbin/so-minion | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index eeaea1209..bb657d29d 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -220,7 +220,6 @@ function add_sensor_to_minion() { echo " " >> $PILLARFILE } -# Add basic host info to the minion file function add_playbook_to_minion() { printf '%s\n'\ "playbook:"\ @@ -228,7 +227,6 @@ function add_playbook_to_minion() { " " >> $PILLARFILE } -# Add basic host info to the minion file function add_elastalert_to_minion() { printf '%s\n'\ "elastalert:"\ @@ -236,6 +234,13 @@ function add_elastalert_to_minion() { " " >> $PILLARFILE } +function add_kibana_to_minion() { + printf '%s\n'\ + "kibana:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -284,6 +289,7 @@ function createEVAL() { add_logstash_to_minion add_sensor_to_minion add_elastalert_to_minion + add_kibana_to_minion } function createSTANDALONE() { @@ -292,6 +298,7 @@ function createSTANDALONE() { add_sensor_to_minion add_playbook_to_minion add_elastalert_to_minion + add_kibana_to_minion } function createMANAGER() { @@ -299,6 +306,7 @@ function createMANAGER() { add_logstash_to_minion add_playbook_to_minion add_elastalert_to_minion + add_kibana_to_minion } function createMANAGERSEARCH() { @@ -306,6 +314,14 @@ function createMANAGERSEARCH() { add_logstash_to_minion add_playbook_to_minion add_elastalert_to_minion + add_kibana_to_minion +} + +function createIMPORT() { + add_elasticsearch_to_minion + add_logstash_to_minion + add_sensor_to_minion + add_kibana_to_minion } function createFLEET() { @@ -320,12 +336,6 @@ function createIDH() { add_idh_to_minion } -function createIMPORT() { - add_elasticsearch_to_minion - add_logstash_to_minion - add_sensor_to_minion -} - function createHEAVYNODE() { add_elasticsearch_to_minion add_logstash_to_minion From 38d69701a439379a42a82a896215f8e3c6934899 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 17:09:00 -0400 Subject: [PATCH 20/68] fix require --- salt/kibana/so_dashboard_load.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/kibana/so_dashboard_load.sls b/salt/kibana/so_dashboard_load.sls index 08fb48da7..3222eabc6 100644 --- a/salt/kibana/so_dashboard_load.sls +++ b/salt/kibana/so_dashboard_load.sls @@ -27,7 +27,7 @@ so-kibana-dashboard-load: - name: /usr/sbin/so-kibana-config-load -i /opt/so/conf/kibana/saved_objects.ndjson.template - cwd: /opt/so - require: - - sls: kibana + - sls: kibana.enabled - file: dashboard_saved_objects_template {%- if HIGHLANDER %} dashboard_saved_objects_template_hl: @@ -50,6 +50,6 @@ so-kibana-dashboard-load_hl: - name: /usr/sbin/so-kibana-config-load -i /opt/so/conf/kibana/hl.ndjson.template - cwd: /opt/so - require: - - sls: kibana + - sls: kibana.enabled - file: dashboard_saved_objects_template_hl {%- endif %} From 2322ed4b6d45b556042fa599717e590b4e984a7f Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 9 May 2023 17:13:36 -0400 Subject: [PATCH 21/68] fix require --- salt/kibana/so_config_load.sls | 2 +- salt/kibana/so_securitySolution_load.sls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/kibana/so_config_load.sls b/salt/kibana/so_config_load.sls index 84c17deca..a443e960b 100644 --- a/salt/kibana/so_config_load.sls +++ b/salt/kibana/so_config_load.sls @@ -25,5 +25,5 @@ so-kibana-config-load: - name: /usr/sbin/so-kibana-config-load -i /opt/so/conf/kibana/config_saved_objects.ndjson.template - cwd: /opt/so - require: - - sls: kibana + - sls: kibana.enabled - file: config_saved_objects diff --git a/salt/kibana/so_securitySolution_load.sls b/salt/kibana/so_securitySolution_load.sls index fe57f5a73..5599b7b88 100644 --- a/salt/kibana/so_securitySolution_load.sls +++ b/salt/kibana/so_securitySolution_load.sls @@ -25,5 +25,5 @@ so-kibana-securitySolution_saved_objects-load: - name: /usr/sbin/so-kibana-config-load -u /opt/so/conf/kibana/securitySolution_saved_objects.ndjson.template - cwd: /opt/so - require: - - sls: kibana + - sls: kibana.enabled - file: securitySolution_saved_objects From c5e57630143ab0080d31a3135fa6d86fd74fbf6e Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 09:55:20 -0400 Subject: [PATCH 22/68] uncomment so-kibana in so-status --- salt/kibana/enabled.sls | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/salt/kibana/enabled.sls b/salt/kibana/enabled.sls index 8d81beb56..8f7091a0f 100644 --- a/salt/kibana/enabled.sls +++ b/salt/kibana/enabled.sls @@ -39,6 +39,11 @@ so-kibana: - watch: - file: kibanaconfig +delete_so-kibana_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-kibana$ + {% else %} {{sls}}_state_not_allowed: From a0ce46e7029f2c9662a7fe69086bcc52e7fb82ef Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 11:16:03 -0400 Subject: [PATCH 23/68] enable/disable logstash in ui --- salt/allowed_states.map.jinja | 3 +- salt/logstash/config.sls | 153 ++++++++++++++++++++ salt/logstash/defaults.yaml | 1 + salt/logstash/disabled.sls | 27 ++++ salt/logstash/enabled.sls | 100 +++++++++++++ salt/logstash/init.sls | 232 +----------------------------- salt/logstash/map.jinja | 5 + salt/logstash/soc_logstash.yaml | 3 + salt/logstash/sostatus.sls | 21 +++ salt/manager/tools/sbin/so-minion | 8 +- salt/top.sls | 13 -- 11 files changed, 320 insertions(+), 246 deletions(-) create mode 100644 salt/logstash/config.sls create mode 100644 salt/logstash/disabled.sls create mode 100644 salt/logstash/enabled.sls create mode 100644 salt/logstash/sostatus.sls diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index a932692cf..1165a80f8 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set CURATOR = salt['pillar.get']('curator:enabled', True) %} {% set REDIS = salt['pillar.get']('redis:enabled', True) %} {% set STRELKA = salt['pillar.get']('strelka:enabled', '0') %} @@ -252,7 +251,7 @@ {% do allowed_states.append('redis') %} {% endif %} - {% if LOGSTASH and grains.role in ['so-helixsensor', 'so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-receiver'] %} + {% if grains.role in ['so-helixsensor', 'so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-receiver'] %} {% do allowed_states.append('logstash') %} {% endif %} diff --git a/salt/logstash/config.sls b/salt/logstash/config.sls new file mode 100644 index 000000000..6ff33ff1a --- /dev/null +++ b/salt/logstash/config.sls @@ -0,0 +1,153 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'logstash/map.jinja' import LOGSTASH_MERGED %} +{% set ASSIGNED_PIPELINES = LOGSTASH_MERGED.assigned_pipelines.roles[GLOBALS.role.split('-')[1]] %} + +include: + - ssl + {% if GLOBALS.role not in ['so-receiver','so-fleet'] %} + - elasticsearch + {% endif %} + +# Create the logstash group +logstashgroup: + group.present: + - name: logstash + - gid: 931 + +# Add the logstash user for the jog4j settings +logstash: + user.present: + - uid: 931 + - gid: 931 + - home: /opt/so/conf/logstash + +lslibdir: + file.absent: + - name: /opt/so/conf/logstash/lib + +logstash_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://logstash/tools/sbin + - user: 931 + - group: 939 + - file_mode: 755 + +#logstash_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://logstash/tools/sbin_jinja +# - user: 931 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +lsetcdir: + file.directory: + - name: /opt/so/conf/logstash/etc + - user: 931 + - group: 939 + - makedirs: True + +lspipelinedir: + file.directory: + - name: /opt/so/conf/logstash/pipelines + - user: 931 + - group: 939 + +{% for assigned_pipeline in ASSIGNED_PIPELINES %} + {% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %} +ls_pipeline_{{assigned_pipeline}}_{{CONFIGFILE.split('.')[0] | replace("/","_") }}: + file.managed: + - source: salt://logstash/pipelines/config/{{CONFIGFILE}} + {% if 'jinja' in CONFIGFILE.split('.')[-1] %} + - name: /opt/so/conf/logstash/pipelines/{{assigned_pipeline}}/{{CONFIGFILE.split('/')[1] | replace(".jinja", "")}} + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} + ES_USER: "{{ salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:user', '') }}" + ES_PASS: "{{ salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:pass', '') }}" + THREADS: {{ LOGSTASH_MERGED.config.pipeline_x_workers }} + BATCH: {{ LOGSTASH_MERGED.config.pipeline_x_batch_x_size }} + {% else %} + - name: /opt/so/conf/logstash/pipelines/{{assigned_pipeline}}/{{CONFIGFILE.split('/')[1]}} + {% endif %} + - user: 931 + - group: 939 + - mode: 660 + - makedirs: True + - show_changes: False + {% endfor %} + +ls_pipeline_{{assigned_pipeline}}: + file.directory: + - name: /opt/so/conf/logstash/pipelines/{{assigned_pipeline}} + - user: 931 + - group: 939 + - require: + {% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %} + - file: ls_pipeline_{{assigned_pipeline}}_{{CONFIGFILE.split('.')[0] | replace("/","_") }} + {% endfor %} + - clean: True +{% endfor %} + +# Copy down all the configs +lspipelinesyml: + file.managed: + - name: /opt/so/conf/logstash/etc/pipelines.yml + - source: salt://logstash/etc/pipelines.yml.jinja + - template: jinja + - defaults: + ASSIGNED_PIPELINES: {{ ASSIGNED_PIPELINES }} + +lsetcsync: + file.recurse: + - name: /opt/so/conf/logstash/etc + - source: salt://logstash/etc + - user: 931 + - group: 939 + - template: jinja + - clean: True + - exclude_pat: pipelines* + - defaults: + LOGSTASH_MERGED: {{ LOGSTASH_MERGED }} + +# Create the import directory +importdir: + file.directory: + - name: /nsm/import + - user: 931 + - group: 939 + - makedirs: True + +# Create the logstash data directory +nsmlsdir: + file.directory: + - name: /nsm/logstash/tmp + - user: 931 + - group: 939 + - makedirs: True + +# Create the log directory +lslogdir: + file.directory: + - name: /opt/so/log/logstash + - user: 931 + - group: 939 + - makedirs: True + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/logstash/defaults.yaml b/salt/logstash/defaults.yaml index d253a6b51..b29f3277e 100644 --- a/salt/logstash/defaults.yaml +++ b/salt/logstash/defaults.yaml @@ -1,4 +1,5 @@ logstash: + enabled: False assigned_pipelines: roles: standalone: diff --git a/salt/logstash/disabled.sls b/salt/logstash/disabled.sls new file mode 100644 index 000000000..76901b60a --- /dev/null +++ b/salt/logstash/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - logstash.sostatus + +so-logstash: + docker_container.absent: + - force: True + +so-logstash_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-logstash$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/logstash/enabled.sls b/salt/logstash/enabled.sls new file mode 100644 index 000000000..2f5a46323 --- /dev/null +++ b/salt/logstash/enabled.sls @@ -0,0 +1,100 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'logstash/map.jinja' import LOGSTASH_MERGED %} +{% from 'logstash/map.jinja' import REDIS_NODES %} +{% set lsheap = LOGSTASH_MERGED.settings.lsheap %} + +include: + - logstash.config + - logstash.sostatus + +so-logstash: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-logstash:{{ GLOBALS.so_version }} + - hostname: so-logstash + - name: so-logstash + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-logstash'].ip }} + - user: logstash + - extra_hosts: {{ REDIS_NODES }} + - environment: + - LS_JAVA_OPTS=-Xms{{ lsheap }} -Xmx{{ lsheap }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-logstash'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - binds: + - /opt/so/conf/elasticsearch/templates/:/templates/:ro + - /opt/so/conf/logstash/etc/:/usr/share/logstash/config/:ro + - /opt/so/conf/logstash/pipelines:/usr/share/logstash/pipelines:ro + - /opt/so/rules:/etc/nsm/rules:ro + - /nsm/import:/nsm/import:ro + - /nsm/logstash:/usr/share/logstash/data:rw + - /opt/so/log/logstash:/var/log/logstash:rw + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - /opt/so/conf/logstash/etc/certs:/usr/share/logstash/certs:ro + {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} + - /etc/pki/filebeat.crt:/usr/share/logstash/filebeat.crt:ro + - /etc/pki/filebeat.p8:/usr/share/logstash/filebeat.key:ro + {% endif %} + {% if GLOBALS.role in ['so-manager', 'so-managersearch', 'so-standalone', 'so-import', 'so-eval','so-fleet'] %} + - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt:/usr/share/logstash/elasticfleet-logstash.crt:ro + - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8:/usr/share/logstash/elasticfleet-logstash.key:ro + {% endif %} + {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} + - /etc/pki/ca.crt:/usr/share/filebeat/ca.crt:ro + {% else %} + - /etc/ssl/certs/intca.crt:/usr/share/filebeat/ca.crt:ro + {% endif %} + {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-searchnode'] %} + - /opt/so/conf/ca/cacerts:/etc/pki/ca-trust/extracted/java/cacerts:ro + - /opt/so/conf/ca/tls-ca-bundle.pem:/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem:ro + {% endif %} + {% if GLOBALS.role == 'so-eval' %} + - /nsm/zeek:/nsm/zeek:ro + - /nsm/suricata:/suricata:ro + - /opt/so/log/fleet/:/osquery/logs:ro + - /opt/so/log/strelka:/strelka:ro + {% endif %} + - watch: + - file: lsetcsync + {% for assigned_pipeline in LOGSTASH_MERGED.assigned_pipelines.roles[GLOBALS.role.split('-')[1]] %} + - file: ls_pipeline_{{assigned_pipeline}} + {% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %} + - file: ls_pipeline_{{assigned_pipeline}}_{{CONFIGFILE.split('.')[0] | replace("/","_") }} + {% endfor %} + {% endfor %} + - require: + {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} + - x509: etc_filebeat_crt + {% endif %} + {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} + - x509: pki_public_ca_crt + {% else %} + - x509: trusttheca + {% endif %} + {% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} + - file: cacertz + - file: capemz + {% endif %} + +delete_so-logstash_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-logstash$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/logstash/init.sls b/salt/logstash/init.sls index 7072ed46d..62b2a2ebb 100644 --- a/salt/logstash/init.sls +++ b/salt/logstash/init.sls @@ -3,237 +3,11 @@ # 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 in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'logstash/map.jinja' import REDIS_NODES %} {% from 'logstash/map.jinja' import LOGSTASH_MERGED %} -# Logstash Section - Decide which pillar to use -{% set lsheap = LOGSTASH_MERGED.settings.lsheap %} -{% if GLOBALS.role in ['so-eval','so-managersearch', 'so-manager', 'so-standalone'] %} - {% set nodetype = GLOBALS.role %} -{% endif %} - -{% set ASSIGNED_PIPELINES = LOGSTASH_MERGED.assigned_pipelines.roles[GLOBALS.role.split('-')[1]] %} -{% set DOCKER_OPTIONS = LOGSTASH_MERGED.docker_options %} - include: - - ssl - {% if GLOBALS.role not in ['so-receiver','so-fleet'] %} - - elasticsearch - {% endif %} - -# Create the logstash group -logstashgroup: - group.present: - - name: logstash - - gid: 931 - -# Add the logstash user for the jog4j settings -logstash: - user.present: - - uid: 931 - - gid: 931 - - home: /opt/so/conf/logstash - -lslibdir: - file.absent: - - name: /opt/so/conf/logstash/lib - -logstash_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://logstash/tools/sbin - - user: 931 - - group: 939 - - file_mode: 755 - -#logstash_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://logstash/tools/sbin_jinja -# - user: 931 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -lsetcdir: - file.directory: - - name: /opt/so/conf/logstash/etc - - user: 931 - - group: 939 - - makedirs: True - -lspipelinedir: - file.directory: - - name: /opt/so/conf/logstash/pipelines - - user: 931 - - group: 939 - -{% for assigned_pipeline in ASSIGNED_PIPELINES %} - {% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %} -ls_pipeline_{{assigned_pipeline}}_{{CONFIGFILE.split('.')[0] | replace("/","_") }}: - file.managed: - - source: salt://logstash/pipelines/config/{{CONFIGFILE}} - {% if 'jinja' in CONFIGFILE.split('.')[-1] %} - - name: /opt/so/conf/logstash/pipelines/{{assigned_pipeline}}/{{CONFIGFILE.split('/')[1] | replace(".jinja", "")}} - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} - ES_USER: "{{ salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:user', '') }}" - ES_PASS: "{{ salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:pass', '') }}" - THREADS: {{ LOGSTASH_MERGED.config.pipeline_x_workers }} - BATCH: {{ LOGSTASH_MERGED.config.pipeline_x_batch_x_size }} - {% else %} - - name: /opt/so/conf/logstash/pipelines/{{assigned_pipeline}}/{{CONFIGFILE.split('/')[1]}} - {% endif %} - - user: 931 - - group: 939 - - mode: 660 - - makedirs: True - - show_changes: False - {% endfor %} - -ls_pipeline_{{assigned_pipeline}}: - file.directory: - - name: /opt/so/conf/logstash/pipelines/{{assigned_pipeline}} - - user: 931 - - group: 939 - - require: - {% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %} - - file: ls_pipeline_{{assigned_pipeline}}_{{CONFIGFILE.split('.')[0] | replace("/","_") }} - {% endfor %} - - clean: True -{% endfor %} - -# Copy down all the configs -lspipelinesyml: - file.managed: - - name: /opt/so/conf/logstash/etc/pipelines.yml - - source: salt://logstash/etc/pipelines.yml.jinja - - template: jinja - - defaults: - ASSIGNED_PIPELINES: {{ ASSIGNED_PIPELINES }} - -lsetcsync: - file.recurse: - - name: /opt/so/conf/logstash/etc - - source: salt://logstash/etc - - user: 931 - - group: 939 - - template: jinja - - clean: True - - exclude_pat: pipelines* - - defaults: - LOGSTASH_MERGED: {{ LOGSTASH_MERGED }} - -# Create the import directory -importdir: - file.directory: - - name: /nsm/import - - user: 931 - - group: 939 - - makedirs: True - -# Create the logstash data directory -nsmlsdir: - file.directory: - - name: /nsm/logstash/tmp - - user: 931 - - group: 939 - - makedirs: True - -# Create the log directory -lslogdir: - file.directory: - - name: /opt/so/log/logstash - - user: 931 - - group: 939 - - makedirs: True - -so-logstash: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-logstash:{{ GLOBALS.so_version }} - - hostname: so-logstash - - name: so-logstash - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-logstash'].ip }} - - user: logstash - - extra_hosts: {{ REDIS_NODES }} - - environment: - - LS_JAVA_OPTS=-Xms{{ lsheap }} -Xmx{{ lsheap }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-logstash'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - binds: - - /opt/so/conf/elasticsearch/templates/:/templates/:ro - - /opt/so/conf/logstash/etc/:/usr/share/logstash/config/:ro - - /opt/so/conf/logstash/pipelines:/usr/share/logstash/pipelines:ro - - /opt/so/rules:/etc/nsm/rules:ro - - /nsm/import:/nsm/import:ro - - /nsm/logstash:/usr/share/logstash/data:rw - - /opt/so/log/logstash:/var/log/logstash:rw - - /sys/fs/cgroup:/sys/fs/cgroup:ro - - /opt/so/conf/logstash/etc/certs:/usr/share/logstash/certs:ro - {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} - - /etc/pki/filebeat.crt:/usr/share/logstash/filebeat.crt:ro - - /etc/pki/filebeat.p8:/usr/share/logstash/filebeat.key:ro - {% endif %} - {% if GLOBALS.role in ['so-manager', 'so-managersearch', 'so-standalone', 'so-import', 'so-eval','so-fleet'] %} - - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.crt:/usr/share/logstash/elasticfleet-logstash.crt:ro - - /opt/so/conf/elastic-fleet/certs/elasticfleet-logstash.p8:/usr/share/logstash/elasticfleet-logstash.key:ro - {% endif %} - {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - - /etc/pki/ca.crt:/usr/share/filebeat/ca.crt:ro - {% else %} - - /etc/ssl/certs/intca.crt:/usr/share/filebeat/ca.crt:ro - {% endif %} - {% if GLOBALS.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-searchnode'] %} - - /opt/so/conf/ca/cacerts:/etc/pki/ca-trust/extracted/java/cacerts:ro - - /opt/so/conf/ca/tls-ca-bundle.pem:/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem:ro - {% endif %} - {%- if GLOBALS.role == 'so-eval' %} - - /nsm/zeek:/nsm/zeek:ro - - /nsm/suricata:/suricata:ro - - /opt/so/log/fleet/:/osquery/logs:ro - - /opt/so/log/strelka:/strelka:ro - {%- endif %} - - watch: - - file: lsetcsync - {% for assigned_pipeline in LOGSTASH_MERGED.assigned_pipelines.roles[GLOBALS.role.split('-')[1]] %} - - file: ls_pipeline_{{assigned_pipeline}} - {% for CONFIGFILE in LOGSTASH_MERGED.defined_pipelines[assigned_pipeline] %} - - file: ls_pipeline_{{assigned_pipeline}}_{{CONFIGFILE.split('.')[0] | replace("/","_") }} - {% endfor %} - {% endfor %} - - require: - {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-heavynode', 'so-receiver'] %} - - x509: etc_filebeat_crt - {% endif %} - {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} - {% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - - file: cacertz - - file: capemz - {% endif %} - -append_so-logstash_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-logstash - +{% if LOGSTASH_MERGED.enabled %} + - logstash.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - logstash.disabled {% endif %} diff --git a/salt/logstash/map.jinja b/salt/logstash/map.jinja index c4ad5d96a..69e102e78 100644 --- a/salt/logstash/map.jinja +++ b/salt/logstash/map.jinja @@ -1,3 +1,8 @@ +{# 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 'vars/globals.map.jinja' import GLOBALS %} {% import_yaml 'logstash/defaults.yaml' as LOGSTASH_DEFAULTS %} {% set LOGSTASH_MERGED = salt['pillar.get']('logstash', LOGSTASH_DEFAULTS.logstash, merge=True) %} diff --git a/salt/logstash/soc_logstash.yaml b/salt/logstash/soc_logstash.yaml index e41ff000f..cbb1eef8b 100644 --- a/salt/logstash/soc_logstash.yaml +++ b/salt/logstash/soc_logstash.yaml @@ -1,4 +1,7 @@ logstash: + enabled: + description: You can enable or disable Logstash. + helpLink: logstash.html assigned_pipelines: roles: standalone: &assigned_pipelines diff --git a/salt/logstash/sostatus.sls b/salt/logstash/sostatus.sls new file mode 100644 index 000000000..e42e5ebe0 --- /dev/null +++ b/salt/logstash/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-logstash_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-logstash + - unless: grep -q so-logstash /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index bb657d29d..a7fd3a19d 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -165,6 +165,7 @@ function add_logstash_to_minion() { # Create the logstash advanced pillar printf '%s\n'\ "logstash:"\ + " enabled: True"\ " config:"\ " pipeline_x_workers: $CPUCORES"\ " settings:"\ @@ -241,6 +242,7 @@ function add_kibana_to_minion() { " " >> $PILLARFILE } + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -286,7 +288,6 @@ function apply_ES_state() { } function createEVAL() { add_elasticsearch_to_minion - add_logstash_to_minion add_sensor_to_minion add_elastalert_to_minion add_kibana_to_minion @@ -319,7 +320,6 @@ function createMANAGERSEARCH() { function createIMPORT() { add_elasticsearch_to_minion - add_logstash_to_minion add_sensor_to_minion add_kibana_to_minion } @@ -353,6 +353,10 @@ function createSEARCHNODE() { apply_ES_state } +function createRECEIVER() { + add_logstash_to_minion +} + function testConnection() { retry 15 3 "salt '$MINION_ID' test.ping" True diff --git a/salt/top.sls b/salt/top.sls index 6ebd0340d..95f599f04 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set REDIS = salt['pillar.get']('redis:enabled', True) %} {% set STRELKA = salt['pillar.get']('strelka:enabled', '0') %} {% import_yaml 'salt/minion.defaults.yaml' as saltversion %} @@ -111,9 +110,7 @@ base: - suricata.manager - mysql - elasticsearch - {%- if LOGSTASH %} - logstash - {%- endif %} {%- if REDIS %} - redis {%- endif %} @@ -147,9 +144,7 @@ base: - healthcheck - mysql - elasticsearch - {%- if LOGSTASH %} - logstash - {%- endif %} {%- if REDIS %} - redis {%- endif %} @@ -177,9 +172,7 @@ base: - telegraf - firewall - elasticsearch - {%- if LOGSTASH %} - logstash - {%- endif %} - elasticfleet.install_agent_grid - docker_clean @@ -202,9 +195,7 @@ base: - suricata.manager - mysql - elasticsearch - {%- if LOGSTASH %} - logstash - {%- endif %} {%- if REDIS %} - redis {%- endif %} @@ -226,9 +217,7 @@ base: - telegraf - firewall - elasticsearch - {%- if LOGSTASH %} - logstash - {%- endif %} {%- if REDIS %} - redis {%- endif %} @@ -274,9 +263,7 @@ base: - sensoroni - telegraf - firewall - {%- if LOGSTASH %} - logstash - {%- endif %} {%- if REDIS %} - redis {%- endif %} From ce1f75aab6625268efedc7a7cd8eb26040a78c74 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 11:19:00 -0400 Subject: [PATCH 24/68] fix indent for description and helplink --- salt/logstash/soc_logstash.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/logstash/soc_logstash.yaml b/salt/logstash/soc_logstash.yaml index cbb1eef8b..64884ce91 100644 --- a/salt/logstash/soc_logstash.yaml +++ b/salt/logstash/soc_logstash.yaml @@ -1,7 +1,7 @@ logstash: enabled: - description: You can enable or disable Logstash. - helpLink: logstash.html + description: You can enable or disable Logstash. + helpLink: logstash.html assigned_pipelines: roles: standalone: &assigned_pipelines From 1b9ed1c72b19ae66976c2ccf77b13f28ea388cc5 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 11:24:14 -0400 Subject: [PATCH 25/68] uncomment so-playbook when enabled --- salt/playbook/enabled.sls | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/salt/playbook/enabled.sls b/salt/playbook/enabled.sls index b83184628..22da3c0ff 100644 --- a/salt/playbook/enabled.sls +++ b/salt/playbook/enabled.sls @@ -46,6 +46,11 @@ so-playbook: - {{ BINDING }} {% endfor %} +delete_so-playbook_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-playbook$ + so-playbook-sync_cron: cron.present: - name: /usr/sbin/so-playbook-sync > /opt/so/log/playbook/sync.log 2>&1 From 02e1a29f0c650c200dbf650a15a63a92ab4120a1 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 11:54:21 -0400 Subject: [PATCH 26/68] configure redis in ui --- salt/allowed_states.map.jinja | 6 +- salt/manager/tools/sbin/so-minion | 11 ++++ salt/redis/config.sls | 68 ++++++++++++++++++++ salt/redis/defaults.yaml | 1 + salt/redis/disabled.sls | 27 ++++++++ salt/redis/enabled.sls | 62 ++++++++++++++++++ salt/redis/etc/redis.conf.jinja | 6 +- salt/redis/init.sls | 103 ++---------------------------- salt/redis/map.jinja | 7 ++ salt/redis/soc_redis.yaml | 3 + salt/redis/sostatus.sls | 21 ++++++ salt/top.sls | 13 ---- 12 files changed, 209 insertions(+), 119 deletions(-) create mode 100644 salt/redis/config.sls create mode 100644 salt/redis/disabled.sls create mode 100644 salt/redis/enabled.sls create mode 100644 salt/redis/map.jinja create mode 100644 salt/redis/sostatus.sls diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 1165a80f8..882e33576 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -247,15 +247,11 @@ {% do allowed_states.append('playbook') %} {% endif %} - {% if (REDIS !=0) and grains.role in ['so-eval'] %} - {% do allowed_states.append('redis') %} - {% endif %} - {% if grains.role in ['so-helixsensor', 'so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-receiver'] %} {% do allowed_states.append('logstash') %} {% endif %} - {% if REDIS and grains.role in ['so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-receiver'] %} + {% if REDIS and grains.role in ['so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-receiver', 'so-eval'] %} {% do allowed_states.append('redis') %} {% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index a7fd3a19d..6f28057e1 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -242,6 +242,12 @@ function add_kibana_to_minion() { " " >> $PILLARFILE } +function add_redis_to_minion() { + printf '%s\n'\ + "redis:"\ + " enabled: True"\ + " " >> $PILLARFILE +} function create_fleet_policy() { @@ -300,6 +306,7 @@ function createSTANDALONE() { add_playbook_to_minion add_elastalert_to_minion add_kibana_to_minion + add_redis_to_minion } function createMANAGER() { @@ -308,6 +315,7 @@ function createMANAGER() { add_playbook_to_minion add_elastalert_to_minion add_kibana_to_minion + add_redis_to_minion } function createMANAGERSEARCH() { @@ -316,6 +324,7 @@ function createMANAGERSEARCH() { add_playbook_to_minion add_elastalert_to_minion add_kibana_to_minion + add_redis_to_minion } function createIMPORT() { @@ -340,6 +349,7 @@ function createHEAVYNODE() { add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion + add_redis_to_minion } function createSENSOR() { @@ -355,6 +365,7 @@ function createSEARCHNODE() { function createRECEIVER() { add_logstash_to_minion + add_redis_to_minion } diff --git a/salt/redis/config.sls b/salt/redis/config.sls new file mode 100644 index 000000000..d698040f8 --- /dev/null +++ b/salt/redis/config.sls @@ -0,0 +1,68 @@ +# 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 %} +{% from 'redis/map.jinja' import REDISMERGED %} + +include: + - ssl + +# Redis Setup +redisconfdir: + file.directory: + - name: /opt/so/conf/redis/etc + - user: 939 + - group: 939 + - makedirs: True + +redisworkdir: + file.directory: + - name: /opt/so/conf/redis/working + - user: 939 + - group: 939 + - makedirs: True + +redislogdir: + file.directory: + - name: /opt/so/log/redis + - user: 939 + - group: 939 + - makedirs: True + +redisconf: + file.managed: + - name: /opt/so/conf/redis/etc/redis.conf + - source: salt://redis/etc/redis.conf.jinja + - user: 939 + - group: 939 + - template: jinja + - defaults: + REDISMERGED: {{ REDISMERGED }} + +redis_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://redis/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +redis_sbin_jinja: + file.recurse: + - name: /usr/sbin + - source: salt://redis/tools/sbin_jinja + - user: 939 + - group: 939 + - file_mode: 755 + - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/redis/defaults.yaml b/salt/redis/defaults.yaml index ede78ad6b..913ebe7a0 100644 --- a/salt/redis/defaults.yaml +++ b/salt/redis/defaults.yaml @@ -1,4 +1,5 @@ redis: + enabled: False config: bind: '0.0.0.0' protected-mode: 'yes' diff --git a/salt/redis/disabled.sls b/salt/redis/disabled.sls new file mode 100644 index 000000000..09cb9f1fd --- /dev/null +++ b/salt/redis/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - redis.sostatus + +so-redis: + docker_container.absent: + - force: True + +so-redis_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-redis$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/redis/enabled.sls b/salt/redis/enabled.sls new file mode 100644 index 000000000..26f95e59f --- /dev/null +++ b/salt/redis/enabled.sls @@ -0,0 +1,62 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - redis.config + - redis.sostatus + +so-redis: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }} + - hostname: so-redis + - user: socore + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-redis'].ip }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-redis'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - binds: + - /opt/so/log/redis:/var/log/redis:rw + - /opt/so/conf/redis/etc/redis.conf:/usr/local/etc/redis/redis.conf:ro + - /opt/so/conf/redis/working:/redis:rw + - /etc/pki/redis.crt:/certs/redis.crt:ro + - /etc/pki/redis.key:/certs/redis.key:ro + {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} + - /etc/pki/ca.crt:/certs/ca.crt:ro + {% else %} + - /etc/ssl/certs/intca.crt:/certs/ca.crt:ro + {% endif %} + - entrypoint: "redis-server /usr/local/etc/redis/redis.conf" + - watch: + - file: /opt/so/conf/redis/etc + - require: + - file: redisconf + - x509: redis_crt + - x509: redis_key + {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} + - x509: pki_public_ca_crt + {% else %} + - x509: trusttheca + {% endif %} + +delete_so-redis_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-redis$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/redis/etc/redis.conf.jinja b/salt/redis/etc/redis.conf.jinja index c3291c3e8..cb6d8abd8 100644 --- a/salt/redis/etc/redis.conf.jinja +++ b/salt/redis/etc/redis.conf.jinja @@ -1,5 +1,7 @@ -{%- import_yaml 'redis/defaults.yaml' as REDISDEFAULTS %} -{%- set REDISMERGED = salt['pillar.get']('redis', default=REDISDEFAULTS.redis, merge=true) %} +{# 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. #} {%- for k, v in REDISMERGED.config.items() %} {%- if v is iterable and v is not string %} diff --git a/salt/redis/init.sls b/salt/redis/init.sls index 5806d99f3..2f7f38dcc 100644 --- a/salt/redis/init.sls +++ b/salt/redis/init.sls @@ -3,106 +3,11 @@ # 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 in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'redis/map.jinja' import REDISMERGED %} include: - - ssl - -# Redis Setup -redisconfdir: - file.directory: - - name: /opt/so/conf/redis/etc - - user: 939 - - group: 939 - - makedirs: True - -redisworkdir: - file.directory: - - name: /opt/so/conf/redis/working - - user: 939 - - group: 939 - - makedirs: True - -redislogdir: - file.directory: - - name: /opt/so/log/redis - - user: 939 - - group: 939 - - makedirs: True - -redisconf: - file.managed: - - name: /opt/so/conf/redis/etc/redis.conf - - source: salt://redis/etc/redis.conf.jinja - - user: 939 - - group: 939 - - template: jinja - -redis_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://redis/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -redis_sbin_jinja: - file.recurse: - - name: /usr/sbin - - source: salt://redis/tools/sbin_jinja - - user: 939 - - group: 939 - - file_mode: 755 - - template: jinja - -so-redis: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }} - - hostname: so-redis - - user: socore - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-redis'].ip }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-redis'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - binds: - - /opt/so/log/redis:/var/log/redis:rw - - /opt/so/conf/redis/etc/redis.conf:/usr/local/etc/redis/redis.conf:ro - - /opt/so/conf/redis/working:/redis:rw - - /etc/pki/redis.crt:/certs/redis.crt:ro - - /etc/pki/redis.key:/certs/redis.key:ro - {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - - /etc/pki/ca.crt:/certs/ca.crt:ro - {% else %} - - /etc/ssl/certs/intca.crt:/certs/ca.crt:ro - {% endif %} - - entrypoint: "redis-server /usr/local/etc/redis/redis.conf" - - watch: - - file: /opt/so/conf/redis/etc - - require: - - file: redisconf - - x509: redis_crt - - x509: redis_key - {% if grains['role'] in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import'] %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} - -append_so-redis_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-redis - +{% if REDISMERGED.enabled %} + - redis.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - redis.disabled {% endif %} diff --git a/salt/redis/map.jinja b/salt/redis/map.jinja new file mode 100644 index 000000000..576a7c658 --- /dev/null +++ b/salt/redis/map.jinja @@ -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 'redis/defaults.yaml' as REDISDEFAULTS %} +{% set REDISMERGED = salt['pillar.get']('redis', REDISDEFAULTS.redis, merge=True) %} diff --git a/salt/redis/soc_redis.yaml b/salt/redis/soc_redis.yaml index 5f5ac3da5..45c63ffd3 100644 --- a/salt/redis/soc_redis.yaml +++ b/salt/redis/soc_redis.yaml @@ -1,4 +1,7 @@ redis: + enabled: + description: You can enable or disable Redis. + helpLink: redis.html config: bind: description: The IP address to bind to. diff --git a/salt/redis/sostatus.sls b/salt/redis/sostatus.sls new file mode 100644 index 000000000..8ac26250c --- /dev/null +++ b/salt/redis/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-redis_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-redis + - unless: grep -q so-redis /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/top.sls b/salt/top.sls index 95f599f04..9941f0077 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set REDIS = salt['pillar.get']('redis:enabled', True) %} {% set STRELKA = salt['pillar.get']('strelka:enabled', '0') %} {% import_yaml 'salt/minion.defaults.yaml' as saltversion %} {% set saltversion = saltversion.salt.minion.version %} @@ -85,9 +84,7 @@ base: - utility - soctopus - playbook - {%- if REDIS != 0 %} - redis - {%- endif %} - elasticfleet - docker_clean @@ -111,9 +108,7 @@ base: - mysql - elasticsearch - logstash - {%- if REDIS %} - redis - {%- endif %} - elastic-fleet-package-registry - kibana - curator @@ -145,9 +140,7 @@ base: - mysql - elasticsearch - logstash - {%- if REDIS %} - redis - {%- endif %} - elastic-fleet-package-registry - kibana - pcap @@ -196,9 +189,7 @@ base: - mysql - elasticsearch - logstash - {%- if REDIS %} - redis - {%- endif %} - curator - elastic-fleet-package-registry - kibana @@ -218,9 +209,7 @@ base: - firewall - elasticsearch - logstash - {%- if REDIS %} - redis - {%- endif %} - curator {%- if STRELKA %} - strelka @@ -264,9 +253,7 @@ base: - telegraf - firewall - logstash - {%- if REDIS %} - redis - {%- endif %} - elasticfleet.install_agent_grid - docker_clean From 54c9a3ec71420d3a2b66c5cfea57c11028a28aae Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 15:50:07 -0400 Subject: [PATCH 27/68] enable/disable each strelka container in ui --- salt/manager/init.sls | 19 +- salt/manager/tools/sbin/so-minion | 72 ++++ salt/strelka/backend/config.sls | 69 ++++ salt/strelka/backend/disabled.sls | 27 ++ salt/strelka/backend/enabled.sls | 41 ++ .../files}/backend.yaml.jinja | 0 .../files}/logging.yaml.jinja | 0 .../files}/passwords.dat.jinja | 0 .../files}/taste/taste.yara | 0 salt/strelka/backend/init.sls | 13 + salt/strelka/backend/sostatus.sls | 21 + salt/strelka/config.sls | 61 +++ salt/strelka/coordinator/config.sls | 19 + salt/strelka/coordinator/disabled.sls | 27 ++ salt/strelka/coordinator/enabled.sls | 41 ++ salt/strelka/coordinator/init.sls | 13 + salt/strelka/coordinator/sostatus.sls | 21 + salt/strelka/defaults.yaml | 21 +- salt/strelka/filestream/config.sls | 108 +++++ salt/strelka/filestream/disabled.sls | 27 ++ salt/strelka/filestream/enabled.sls | 38 ++ .../files}/filestream.yaml.jinja | 0 salt/strelka/filestream/init.sls | 13 + salt/strelka/filestream/sostatus.sls | 21 + salt/strelka/frontend/config.sls | 36 ++ salt/strelka/frontend/disabled.sls | 27 ++ salt/strelka/frontend/enabled.sls | 45 ++ .../files}/frontend.yaml.jinja | 0 salt/strelka/frontend/init.sls | 13 + salt/strelka/frontend/sostatus.sls | 21 + salt/strelka/gatekeeper/config.sls | 19 + salt/strelka/gatekeeper/disabled.sls | 27 ++ salt/strelka/gatekeeper/enabled.sls | 41 ++ salt/strelka/gatekeeper/init.sls | 13 + salt/strelka/gatekeeper/sostatus.sls | 21 + salt/strelka/init.sls | 388 ++---------------- salt/strelka/manager/config.sls | 31 ++ salt/strelka/manager/disabled.sls | 27 ++ salt/strelka/manager/enabled.sls | 39 ++ .../files}/manager.yaml.jinja | 0 salt/strelka/manager/init.sls | 13 + salt/strelka/manager/sostatus.sls | 21 + salt/strelka/soc_strelka.yaml | 33 +- 43 files changed, 1119 insertions(+), 368 deletions(-) create mode 100644 salt/strelka/backend/config.sls create mode 100644 salt/strelka/backend/disabled.sls create mode 100644 salt/strelka/backend/enabled.sls rename salt/strelka/{files/backend => backend/files}/backend.yaml.jinja (100%) rename salt/strelka/{files/backend => backend/files}/logging.yaml.jinja (100%) rename salt/strelka/{files/backend => backend/files}/passwords.dat.jinja (100%) rename salt/strelka/{files/backend => backend/files}/taste/taste.yara (100%) create mode 100644 salt/strelka/backend/init.sls create mode 100644 salt/strelka/backend/sostatus.sls create mode 100644 salt/strelka/config.sls create mode 100644 salt/strelka/coordinator/config.sls create mode 100644 salt/strelka/coordinator/disabled.sls create mode 100644 salt/strelka/coordinator/enabled.sls create mode 100644 salt/strelka/coordinator/init.sls create mode 100644 salt/strelka/coordinator/sostatus.sls create mode 100644 salt/strelka/filestream/config.sls create mode 100644 salt/strelka/filestream/disabled.sls create mode 100644 salt/strelka/filestream/enabled.sls rename salt/strelka/{files/filestream => filestream/files}/filestream.yaml.jinja (100%) create mode 100644 salt/strelka/filestream/init.sls create mode 100644 salt/strelka/filestream/sostatus.sls create mode 100644 salt/strelka/frontend/config.sls create mode 100644 salt/strelka/frontend/disabled.sls create mode 100644 salt/strelka/frontend/enabled.sls rename salt/strelka/{files/frontend => frontend/files}/frontend.yaml.jinja (100%) create mode 100644 salt/strelka/frontend/init.sls create mode 100644 salt/strelka/frontend/sostatus.sls create mode 100644 salt/strelka/gatekeeper/config.sls create mode 100644 salt/strelka/gatekeeper/disabled.sls create mode 100644 salt/strelka/gatekeeper/enabled.sls create mode 100644 salt/strelka/gatekeeper/init.sls create mode 100644 salt/strelka/gatekeeper/sostatus.sls create mode 100644 salt/strelka/manager/config.sls create mode 100644 salt/strelka/manager/disabled.sls create mode 100644 salt/strelka/manager/enabled.sls rename salt/strelka/{files/manager => manager/files}/manager.yaml.jinja (100%) create mode 100644 salt/strelka/manager/init.sls create mode 100644 salt/strelka/manager/sostatus.sls diff --git a/salt/manager/init.sls b/salt/manager/init.sls index 47867edaf..372813649 100644 --- a/salt/manager/init.sls +++ b/salt/manager/init.sls @@ -5,10 +5,11 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'strelka/map.jinja' import STRELKAMERGED %} -{% import_yaml 'manager/defaults.yaml' as MANAGERDEFAULTS %} -{% set MANAGERMERGED = salt['pillar.get']('manager', MANAGERDEFAULTS.manager, merge=true) %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'strelka/map.jinja' import STRELKAMERGED %} +{% import_yaml 'manager/defaults.yaml' as MANAGERDEFAULTS %} +{% set MANAGERMERGED = salt['pillar.get']('manager', MANAGERDEFAULTS.manager, merge=true) %} +{% from 'strelka/map.jinja' import STRELKAMERGED %} include: - salt.minion @@ -81,6 +82,16 @@ socore_own_saltstack: - user - group +{% if STRELKAMERGED.rules.enabled %} +strelkarepos: + file.managed: + - name: /opt/so/conf/strelka/repos.txt + - source: salt://strelka/rules/repos.txt.jinja + - template: jinja + - defaults: + STRELKAREPOS: {{ STRELKAMERGED.rules.repos }} +{% endif %} + yara_update_script: file.managed: - name: /usr/sbin/so-yara-update diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 6f28057e1..864b714d6 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -249,6 +249,54 @@ function add_redis_to_minion() { " " >> $PILLARFILE } +function add_strelka_backend_to_minion() { + printf '%s\n'\ + "strelka:"\ + " backend:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + +function add_strelka_filestream_to_minion() { + printf '%s\n'\ + "strelka:"\ + " filestream:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + +function add_strelka_frontend_to_minion() { + printf '%s\n'\ + "strelka:"\ + " frontend:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + +function add_strelka_manager_to_minion() { + printf '%s\n'\ + "strelka:"\ + " manager:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + +function add_strelka_coordinator_to_minion() { + printf '%s\n'\ + "strelka:"\ + " coordinator:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + +function add_strelka_gatekeeper_to_minion() { + printf '%s\n'\ + "strelka:"\ + " gatekeeper:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -295,6 +343,12 @@ function apply_ES_state() { function createEVAL() { add_elasticsearch_to_minion add_sensor_to_minion + add_strelka_backend_to_minion + add_strelka_filestream_to_minion + add_strelka_frontend_to_minion + add_strelka_manager_to_minion + add_strelka_coordinator_to_minion + add_strelka_gatekeeper_to_minion add_elastalert_to_minion add_kibana_to_minion } @@ -303,6 +357,12 @@ function createSTANDALONE() { add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion + add_strelka_backend_to_minion + add_strelka_filestream_to_minion + add_strelka_frontend_to_minion + add_strelka_manager_to_minion + add_strelka_coordinator_to_minion + add_strelka_gatekeeper_to_minion add_playbook_to_minion add_elastalert_to_minion add_kibana_to_minion @@ -349,11 +409,23 @@ function createHEAVYNODE() { add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion + add_strelka_backend_to_minion + add_strelka_filestream_to_minion + add_strelka_frontend_to_minion + add_strelka_manager_to_minion + add_strelka_coordinator_to_minion + add_strelka_gatekeeper_to_minion add_redis_to_minion } function createSENSOR() { add_sensor_to_minion + add_strelka_backend_to_minion + add_strelka_filestream_to_minion + add_strelka_frontend_to_minion + add_strelka_manager_to_minion + add_strelka_coordinator_to_minion + add_strelka_gatekeeper_to_minion } function createSEARCHNODE() { diff --git a/salt/strelka/backend/config.sls b/salt/strelka/backend/config.sls new file mode 100644 index 000000000..d51debb1b --- /dev/null +++ b/salt/strelka/backend/config.sls @@ -0,0 +1,69 @@ +# 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 %} +{% from 'strelka/map.jinja' import STRELKAMERGED %} + +include: + - strelka.config + - strelka.backend.sostatus + +backend_backend_config: + file.managed: + - name: /opt/so/conf/strelka/backend/backend.yaml + - source: salt://strelka/backend/files/backend.yaml.jinja + - template: jinja + - user: 939 + - group: 939 + - makedirs: True + - defaults: + BACKENDCONFIG: {{ STRELKAMERGED.backend.config.backend }} + +backend_logging_config: + file.managed: + - name: /opt/so/conf/strelka/backend/logging.yaml + - source: salt://strelka/backend/files/logging.yaml.jinja + - template: jinja + - user: 939 + - group: 939 + - defaults: + LOGGINGCONFIG: {{ STRELKAMERGED.backend.config.logging }} + +backend_passwords: + file.managed: + - name: /opt/so/conf/strelka/backend/passwords.dat + - source: salt://strelka/backend/files/passwords.dat.jinja + - template: jinja + - user: 939 + - group: 939 + - defaults: + PASSWORDS: {{ STRELKAMERGED.backend.config.passwords }} + +backend_taste: + file.managed: + - name: /opt/so/conf/strelka/backend/taste/taste.yara + - source: salt://strelka/backend/files/taste/taste.yara + - makedirs: True + - user: 939 + - group: 939 + +{% if STRELKAMERGED.rules.enabled %} +strelkarules: + file.recurse: + - name: /opt/so/conf/strelka/rules + - source: salt://strelka/rules + - user: 939 + - group: 939 + - clean: True +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/backend/disabled.sls b/salt/strelka/backend/disabled.sls new file mode 100644 index 000000000..fcf9136c6 --- /dev/null +++ b/salt/strelka/backend/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - strelka.backend.sostatus + +so-strelka-backend: + docker_container.absent: + - force: True + +so-strelka-backend_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-backend$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/backend/enabled.sls b/salt/strelka/backend/enabled.sls new file mode 100644 index 000000000..2ba998e30 --- /dev/null +++ b/salt/strelka/backend/enabled.sls @@ -0,0 +1,41 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - strelka.backend.config + - strelka.backend.sostatus + +strelka_backend: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-backend:{{ GLOBALS.so_version }} + - binds: + - /opt/so/conf/strelka/backend/:/etc/strelka/:ro + - /opt/so/conf/strelka/rules/:/etc/yara/:ro + - name: so-strelka-backend + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-strelka-backend'].ip }} + - command: strelka-backend + - extra_hosts: + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + - restart_policy: on-failure + +delete_so-strelka-backend_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-backend$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/files/backend/backend.yaml.jinja b/salt/strelka/backend/files/backend.yaml.jinja similarity index 100% rename from salt/strelka/files/backend/backend.yaml.jinja rename to salt/strelka/backend/files/backend.yaml.jinja diff --git a/salt/strelka/files/backend/logging.yaml.jinja b/salt/strelka/backend/files/logging.yaml.jinja similarity index 100% rename from salt/strelka/files/backend/logging.yaml.jinja rename to salt/strelka/backend/files/logging.yaml.jinja diff --git a/salt/strelka/files/backend/passwords.dat.jinja b/salt/strelka/backend/files/passwords.dat.jinja similarity index 100% rename from salt/strelka/files/backend/passwords.dat.jinja rename to salt/strelka/backend/files/passwords.dat.jinja diff --git a/salt/strelka/files/backend/taste/taste.yara b/salt/strelka/backend/files/taste/taste.yara similarity index 100% rename from salt/strelka/files/backend/taste/taste.yara rename to salt/strelka/backend/files/taste/taste.yara diff --git a/salt/strelka/backend/init.sls b/salt/strelka/backend/init.sls new file mode 100644 index 000000000..253544c98 --- /dev/null +++ b/salt/strelka/backend/init.sls @@ -0,0 +1,13 @@ +# 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 'strelka/map.jinja' import STRELKAMERGED %} + +include: +{% if STRELKAMERGED.backend.enabled %} + - strelka.backend.enabled +{% else %} + - strelka.backend.disabled +{% endif %} diff --git a/salt/strelka/backend/sostatus.sls b/salt/strelka/backend/sostatus.sls new file mode 100644 index 000000000..6de50cfdc --- /dev/null +++ b/salt/strelka/backend/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-strelka-backend_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-strelka-backend + - unless: grep -q so-strelka-backend /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/config.sls b/salt/strelka/config.sls new file mode 100644 index 000000000..aa51e4b03 --- /dev/null +++ b/salt/strelka/config.sls @@ -0,0 +1,61 @@ +# 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 %} + +# Strelka config +strelkaconfdir: + file.directory: + - name: /opt/so/conf/strelka + - user: 939 + - group: 939 + - makedirs: True + +strelkarulesdir: + file.directory: + - name: /opt/so/conf/strelka/rules + - user: 939 + - group: 939 + - makedirs: True + +strelkadatadir: + file.directory: + - name: /nsm/strelka + - user: 939 + - group: 939 + - makedirs: True + +strelkalogdir: + file.directory: + - name: /nsm/strelka/log + - user: 939 + - group: 939 + - makedirs: True + +strelka_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://strelka/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#strelka_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://strelka/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/coordinator/config.sls b/salt/strelka/coordinator/config.sls new file mode 100644 index 000000000..55cb4239c --- /dev/null +++ b/salt/strelka/coordinator/config.sls @@ -0,0 +1,19 @@ +# 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 %} + +include: + - strelka.config + - strelka.coordinator.sostatus + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/coordinator/disabled.sls b/salt/strelka/coordinator/disabled.sls new file mode 100644 index 000000000..4ac20fe0f --- /dev/null +++ b/salt/strelka/coordinator/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - strelka.coordinator.sostatus + +so-strelka-coordinator: + docker_container.absent: + - force: True + +so-strelka-coordinator_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-coordinator$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/coordinator/enabled.sls b/salt/strelka/coordinator/enabled.sls new file mode 100644 index 000000000..9f2627344 --- /dev/null +++ b/salt/strelka/coordinator/enabled.sls @@ -0,0 +1,41 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - strelka.coordinator.config + - strelka.coordinator.sostatus + +strelka_coordinator: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }} + - name: so-strelka-coordinator + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-strelka-coordinator'].ip }} + - entrypoint: redis-server --save "" --appendonly no + - extra_hosts: + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-strelka-coordinator'].port_bindings %} + - {{ BINDING }} + {% endfor %} + +delete_so-strelka-coordinator_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-coordinator$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/coordinator/init.sls b/salt/strelka/coordinator/init.sls new file mode 100644 index 000000000..bad4c0a48 --- /dev/null +++ b/salt/strelka/coordinator/init.sls @@ -0,0 +1,13 @@ +# 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 'strelka/map.jinja' import STRELKAMERGED %} + +include: +{% if STRELKAMERGED.coordinator.enabled %} + - strelka.coordinator.enabled +{% else %} + - strelka.coordinator.disabled +{% endif %} diff --git a/salt/strelka/coordinator/sostatus.sls b/salt/strelka/coordinator/sostatus.sls new file mode 100644 index 000000000..dbc124993 --- /dev/null +++ b/salt/strelka/coordinator/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-strelka-coordinator_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-strelka-coordinator + - unless: grep -q so-strelka-coordinator /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/defaults.yaml b/salt/strelka/defaults.yaml index bcef0fd9b..6a0b1c2b5 100644 --- a/salt/strelka/defaults.yaml +++ b/salt/strelka/defaults.yaml @@ -1,6 +1,7 @@ strelka: - config: - backend: + backend: + enabled: False + config: backend: logging_cfg: '/etc/strelka/logging.yaml' limits: @@ -493,7 +494,9 @@ strelka: passwords: - infected - password - filestream: + filestream: + enabled: False + config: conn: server: 'HOST:57314' cert: '' @@ -514,7 +517,9 @@ strelka: report: 5s delta: 5s staging: '/nsm/strelka/staging' - frontend: + frontend: + enabled: False + config: server: ":57314" coordinator: addr: 'HOST:6380' @@ -525,10 +530,16 @@ strelka: ttl: 1h response: log: "/var/log/strelka/strelka.log" - manager: + manager: + enabled: False + config: coordinator: addr: 'HOST:6380' db: 0 + coordinator: + enabled: False + gatekeeper: + enabled: False rules: enabled: True repos: diff --git a/salt/strelka/filestream/config.sls b/salt/strelka/filestream/config.sls new file mode 100644 index 000000000..a215967ee --- /dev/null +++ b/salt/strelka/filestream/config.sls @@ -0,0 +1,108 @@ +# 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 %} +{% from 'strelka/map.jinja' import STRELKAMERGED %} +{% from 'strelka/map.jinja' import filecheck_runas %} + +include: + - strelka.config + - strelka.filestream.sostatus + +strelkaprocessed: + file.directory: + - name: /nsm/strelka/processed + - user: 939 + - group: 939 + - makedirs: True + +strelkastaging: + file.directory: + - name: /nsm/strelka/staging + - user: 939 + - group: 939 + - makedirs: True + +strelkaunprocessed: + file.directory: + - name: /nsm/strelka/unprocessed + - user: 939 + - group: 939 + - mode: 775 + - makedirs: True + +filestream_config: + file.managed: + - name: /opt/so/conf/strelka/filestream/filestream.yaml + - source: salt://strelka/filestream/files/filestream.yaml.jinja + - template: jinja + - user: 939 + - group: 939 + - makedirs: True + - defaults: + FILESTREAMCONFIG: {{ STRELKAMERGED.filestream.config }} + +# Filecheck Section +filecheck_logdir: + file.directory: + - name: /opt/so/log/strelka + - user: 939 + - group: 939 + - mode: 775 + - makedirs: True + +filecheck_history: + file.directory: + - name: /nsm/strelka/history + - user: 939 + - group: 939 + - mode: 775 + - makedirs: True + +filecheck_conf: + file.managed: + - name: /opt/so/conf/strelka/filecheck.yaml + - source: salt://strelka/filecheck/filecheck.yaml.jinja + - template: jinja + - defaults: + FILECHECKCONFIG: {{ STRELKAMERGED.filecheck }} + +filecheck_script: + file.managed: + - name: /opt/so/conf/strelka/filecheck + - source: salt://strelka/filecheck/filecheck + - user: 939 + - group: 939 + - mode: 755 + +filecheck_restart: + cmd.run: + - name: pkill -f "python3 /opt/so/conf/strelka/filecheck" + - hide_output: True + - success_retcodes: [0,1] + - onchanges: + - file: filecheck_script + +filecheck_run: + cron.present: + - name: 'ps -ef | grep filecheck | grep -v grep > /dev/null 2>&1 || python3 /opt/so/conf/strelka/filecheck >> /opt/so/log/strelka/filecheck_stdout.log 2>&1 &' + - identifier: filecheck_run + - user: {{ filecheck_runas }} + +filcheck_history_clean: + cron.present: + - name: '/usr/bin/find /nsm/strelka/history/ -type f -mtime +2 -exec rm {} + > /dev/null 2>&1' + - identifier: filecheck_history_clean + - minute: '33' +# End Filecheck Section + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/filestream/disabled.sls b/salt/strelka/filestream/disabled.sls new file mode 100644 index 000000000..162e310a9 --- /dev/null +++ b/salt/strelka/filestream/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - strelka.filestream.sostatus + +so-strelka-filestream: + docker_container.absent: + - force: True + +so-strelka-filestream_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-filestream$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/filestream/enabled.sls b/salt/strelka/filestream/enabled.sls new file mode 100644 index 000000000..e798629c4 --- /dev/null +++ b/salt/strelka/filestream/enabled.sls @@ -0,0 +1,38 @@ +# 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 %} + +include: + - strelka.filestream.config + - strelka.filestream.sostatus + +strelka_filestream: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-filestream:{{ GLOBALS.so_version }} + - binds: + - /opt/so/conf/strelka/filestream/:/etc/strelka/:ro + - /nsm/strelka:/nsm/strelka + - name: so-strelka-filestream + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-strelka-filestream'].ip }} + - command: strelka-filestream + - extra_hosts: + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + +delete_so-strelka-filestream_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-filestream$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/files/filestream/filestream.yaml.jinja b/salt/strelka/filestream/files/filestream.yaml.jinja similarity index 100% rename from salt/strelka/files/filestream/filestream.yaml.jinja rename to salt/strelka/filestream/files/filestream.yaml.jinja diff --git a/salt/strelka/filestream/init.sls b/salt/strelka/filestream/init.sls new file mode 100644 index 000000000..79b471891 --- /dev/null +++ b/salt/strelka/filestream/init.sls @@ -0,0 +1,13 @@ +# 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 'strelka/map.jinja' import STRELKAMERGED %} + +include: +{% if STRELKAMERGED.filestream.enabled %} + - strelka.filestream.enabled +{% else %} + - strelka.filestream.disabled +{% endif %} diff --git a/salt/strelka/filestream/sostatus.sls b/salt/strelka/filestream/sostatus.sls new file mode 100644 index 000000000..cb292a459 --- /dev/null +++ b/salt/strelka/filestream/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-strelka-filestream_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-strelka-filestream + - unless: grep -q so-strelka-filestream /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/frontend/config.sls b/salt/strelka/frontend/config.sls new file mode 100644 index 000000000..e06994b10 --- /dev/null +++ b/salt/strelka/frontend/config.sls @@ -0,0 +1,36 @@ +# 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 %} +{% from 'strelka/map.jinja' import STRELKAMERGED %} + +include: + - strelka.config + - strelka.frontend.sostatus + +# Check to see if Strelka frontend port is available +strelkaportavailable: + cmd.run: + - name: netstat -utanp | grep ":57314" | grep -qvE 'docker|TIME_WAIT' && PROCESS=$(netstat -utanp | grep ":57314" | uniq) && echo "Another process ($PROCESS) appears to be using port 57314. Please terminate this process, or reboot to ensure a clean state so that Strelka can start properly." && exit 1 || exit 0 + +frontend_config: + file.managed: + - name: /opt/so/conf/strelka/frontend/frontend.yaml + - source: salt://strelka/frontend/files/frontend.yaml.jinja + - template: jinja + - user: 939 + - group: 939 + - makedirs: True + - defaults: + FRONTENDCONFIG: {{ STRELKAMERGED.frontend.config }} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/frontend/disabled.sls b/salt/strelka/frontend/disabled.sls new file mode 100644 index 000000000..66f6c898c --- /dev/null +++ b/salt/strelka/frontend/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - strelka.frontend.sostatus + +so-strelka-frontend: + docker_container.absent: + - force: True + +so-strelka-frontend_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-frontend$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/frontend/enabled.sls b/salt/strelka/frontend/enabled.sls new file mode 100644 index 000000000..28b7dc19c --- /dev/null +++ b/salt/strelka/frontend/enabled.sls @@ -0,0 +1,45 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - strelka.frontend.config + - strelka.frontend.sostatus + +strelka_frontend: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-frontend:{{ GLOBALS.so_version }} + - binds: + - /opt/so/conf/strelka/frontend/:/etc/strelka/:ro + - /nsm/strelka/log/:/var/log/strelka/:rw + - privileged: True + - name: so-strelka-frontend + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-strelka-frontend'].ip }} + - command: strelka-frontend + - extra_hosts: + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-strelka-frontend'].port_bindings %} + - {{ BINDING }} + {% endfor %} + +delete_so-strelka-frontend_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-frontend$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/files/frontend/frontend.yaml.jinja b/salt/strelka/frontend/files/frontend.yaml.jinja similarity index 100% rename from salt/strelka/files/frontend/frontend.yaml.jinja rename to salt/strelka/frontend/files/frontend.yaml.jinja diff --git a/salt/strelka/frontend/init.sls b/salt/strelka/frontend/init.sls new file mode 100644 index 000000000..980746dfd --- /dev/null +++ b/salt/strelka/frontend/init.sls @@ -0,0 +1,13 @@ +# 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 'strelka/map.jinja' import STRELKAMERGED %} + +include: +{% if STRELKAMERGED.frontend.enabled %} + - strelka.frontend.enabled +{% else %} + - strelka.frontend.disabled +{% endif %} diff --git a/salt/strelka/frontend/sostatus.sls b/salt/strelka/frontend/sostatus.sls new file mode 100644 index 000000000..a1ab76312 --- /dev/null +++ b/salt/strelka/frontend/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-strelka-frontend_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-strelka-frontend + - unless: grep -q so-strelka-frontend /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/gatekeeper/config.sls b/salt/strelka/gatekeeper/config.sls new file mode 100644 index 000000000..069813f9d --- /dev/null +++ b/salt/strelka/gatekeeper/config.sls @@ -0,0 +1,19 @@ +# 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 %} + +include: + - strelka.config + - strelka.gatekeeper.sostatus + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/gatekeeper/disabled.sls b/salt/strelka/gatekeeper/disabled.sls new file mode 100644 index 000000000..8f49d383c --- /dev/null +++ b/salt/strelka/gatekeeper/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - strelka.gatekeeper.sostatus + +so-strelka-gatekeeper: + docker_container.absent: + - force: True + +so-strelka-gatekeeper_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-gatekeeper$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/gatekeeper/enabled.sls b/salt/strelka/gatekeeper/enabled.sls new file mode 100644 index 000000000..326fb752f --- /dev/null +++ b/salt/strelka/gatekeeper/enabled.sls @@ -0,0 +1,41 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - strelka.gatekeeper.config + - strelka.gatekeeper.sostatus + +strelka_gatekeeper: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }} + - name: so-strelka-gatekeeper + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-strelka-gatekeeper'].ip }} + - entrypoint: redis-server --save "" --appendonly no --maxmemory-policy allkeys-lru + - extra_hosts: + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-strelka-gatekeeper'].port_bindings %} + - {{ BINDING }} + {% endfor %} + +delete_so-strelka-gatekeeper_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-gatekeeper$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/gatekeeper/init.sls b/salt/strelka/gatekeeper/init.sls new file mode 100644 index 000000000..33ece563a --- /dev/null +++ b/salt/strelka/gatekeeper/init.sls @@ -0,0 +1,13 @@ +# 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 'strelka/map.jinja' import STRELKAMERGED %} + +include: +{% if STRELKAMERGED.gatekeeper.enabled %} + - strelka.gatekeeper.enabled +{% else %} + - strelka.gatekeeper.disabled +{% endif %} diff --git a/salt/strelka/gatekeeper/sostatus.sls b/salt/strelka/gatekeeper/sostatus.sls new file mode 100644 index 000000000..db6c6416e --- /dev/null +++ b/salt/strelka/gatekeeper/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-strelka-gatekeeper_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-strelka-gatekeeper + - unless: grep -q so-strelka-gatekeeper /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/init.sls b/salt/strelka/init.sls index 6b7a2bbd2..a60612087 100644 --- a/salt/strelka/init.sls +++ b/salt/strelka/init.sls @@ -3,361 +3,41 @@ # 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 in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} - {% from 'strelka/map.jinja' import STRELKAMERGED %} -{% from 'strelka/map.jinja' import filecheck_runas %} - -# Strelka config -strelkaconfdir: - file.directory: - - name: /opt/so/conf/strelka - - user: 939 - - group: 939 - - makedirs: True - -strelkarulesdir: - file.directory: - - name: /opt/so/conf/strelka/rules - - user: 939 - - group: 939 - - makedirs: True - -backend_backend_config: - file.managed: - - name: /opt/so/conf/strelka/backend/backend.yaml - - source: salt://strelka/files/backend/backend.yaml.jinja - - template: jinja - - user: 939 - - group: 939 - - makedirs: True - - defaults: - BACKENDCONFIG: {{ STRELKAMERGED.config.backend.backend }} - -backend_logging_config: - file.managed: - - name: /opt/so/conf/strelka/backend/logging.yaml - - source: salt://strelka/files/backend/logging.yaml.jinja - - template: jinja - - user: 939 - - group: 939 - - defaults: - LOGGINGCONFIG: {{ STRELKAMERGED.config.backend.logging }} - -backend_passwords: - file.managed: - - name: /opt/so/conf/strelka/backend/passwords.dat - - source: salt://strelka/files/backend/passwords.dat.jinja - - template: jinja - - user: 939 - - group: 939 - - defaults: - PASSWORDS: {{ STRELKAMERGED.config.backend.passwords }} - -strelka_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://strelka/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#strelka_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://strelka/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -backend_taste: - file.managed: - - name: /opt/so/conf/strelka/backend/taste/taste.yara - - source: salt://strelka/files/backend/taste/taste.yara - - makedirs: True - - user: 939 - - group: 939 - -filestream_config: - file.managed: - - name: /opt/so/conf/strelka/filestream/filestream.yaml - - source: salt://strelka/files/filestream/filestream.yaml.jinja - - template: jinja - - user: 939 - - group: 939 - - makedirs: True - - defaults: - FILESTREAMCONFIG: {{ STRELKAMERGED.config.filestream }} - -frontend_config: - file.managed: - - name: /opt/so/conf/strelka/frontend/frontend.yaml - - source: salt://strelka/files/frontend/frontend.yaml.jinja - - template: jinja - - user: 939 - - group: 939 - - makedirs: True - - defaults: - FRONTENDCONFIG: {{ STRELKAMERGED.config.frontend }} - -manager_config: - file.managed: - - name: /opt/so/conf/strelka/manager/manager.yaml - - source: salt://strelka/files/manager/manager.yaml.jinja - - template: jinja - - user: 939 - - group: 939 - - makedirs: True - - defaults: - MANAGERCONFIG: {{ STRELKAMERGED.config.manager }} - -{% if STRELKAMERGED.rules.enabled %} - -strelkarules: - file.recurse: - - name: /opt/so/conf/strelka/rules - - source: salt://strelka/rules - - user: 939 - - group: 939 - - clean: True - -{% if grains['role'] in GLOBALS.manager_roles %} -strelkarepos: - file.managed: - - name: /opt/so/conf/strelka/repos.txt - - source: salt://strelka/rules/repos.txt.jinja - - template: jinja - - defaults: - STRELKAREPOS: {{ STRELKAMERGED.rules.repos }} - -{% endif %} -{% endif %} - -strelkadatadir: - file.directory: - - name: /nsm/strelka - - user: 939 - - group: 939 - - makedirs: True - -strelkalogdir: - file.directory: - - name: /nsm/strelka/log - - user: 939 - - group: 939 - - makedirs: True - -strelkaprocessed: - file.directory: - - name: /nsm/strelka/processed - - user: 939 - - group: 939 - - makedirs: True - -strelkastaging: - file.directory: - - name: /nsm/strelka/staging - - user: 939 - - group: 939 - - makedirs: True - -strelkaunprocessed: - file.directory: - - name: /nsm/strelka/unprocessed - - user: 939 - - group: 939 - - mode: 775 - - makedirs: True - -# Check to see if Strelka frontend port is available -strelkaportavailable: - cmd.run: - - name: netstat -utanp | grep ":57314" | grep -qvE 'docker|TIME_WAIT' && PROCESS=$(netstat -utanp | grep ":57314" | uniq) && echo "Another process ($PROCESS) appears to be using port 57314. Please terminate this process, or reboot to ensure a clean state so that Strelka can start properly." && exit 1 || exit 0 - -# Filecheck Section -filecheck_logdir: - file.directory: - - name: /opt/so/log/strelka - - user: 939 - - group: 939 - - mode: 775 - - makedirs: True - -filecheck_history: - file.directory: - - name: /nsm/strelka/history - - user: 939 - - group: 939 - - mode: 775 - - makedirs: True - -filecheck_conf: - file.managed: - - name: /opt/so/conf/strelka/filecheck.yaml - - source: salt://strelka/filecheck/filecheck.yaml.jinja - - template: jinja - - defaults: - FILECHECKCONFIG: {{ STRELKAMERGED.filecheck }} - -filecheck_script: - file.managed: - - name: /opt/so/conf/strelka/filecheck - - source: salt://strelka/filecheck/filecheck - - user: 939 - - group: 939 - - mode: 755 - -filecheck_restart: - cmd.run: - - name: pkill -f "python3 /opt/so/conf/strelka/filecheck" - - hide_output: True - - success_retcodes: [0,1] - - onchanges: - - file: filecheck_script - -filecheck_run: - cron.present: - - name: 'ps -ef | grep filecheck | grep -v grep > /dev/null 2>&1 || python3 /opt/so/conf/strelka/filecheck >> /opt/so/log/strelka/filecheck_stdout.log 2>&1 &' - - identifier: filecheck_run - - user: {{ filecheck_runas }} - -filcheck_history_clean: - cron.present: - - name: '/usr/bin/find /nsm/strelka/history/ -type f -mtime +2 -exec rm {} + > /dev/null 2>&1' - - identifier: filecheck_history_clean - - minute: '33' -# End Filecheck Section - - -strelka_coordinator: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }} - - name: so-strelka-coordinator - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-strelka-coordinator'].ip }} - - entrypoint: redis-server --save "" --appendonly no - - extra_hosts: - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-strelka-coordinator'].port_bindings %} - - {{ BINDING }} - {% endfor %} - -append_so-strelka-coordinator_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-strelka-coordinator - -strelka_gatekeeper: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-redis:{{ GLOBALS.so_version }} - - name: so-strelka-gatekeeper - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-strelka-gatekeeper'].ip }} - - entrypoint: redis-server --save "" --appendonly no --maxmemory-policy allkeys-lru - - extra_hosts: - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-strelka-gatekeeper'].port_bindings %} - - {{ BINDING }} - {% endfor %} - -append_so-strelka-gatekeeper_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-strelka-gatekeeper - -strelka_frontend: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-frontend:{{ GLOBALS.so_version }} - - binds: - - /opt/so/conf/strelka/frontend/:/etc/strelka/:ro - - /nsm/strelka/log/:/var/log/strelka/:rw - - privileged: True - - name: so-strelka-frontend - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-strelka-frontend'].ip }} - - command: strelka-frontend - - extra_hosts: - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-strelka-frontend'].port_bindings %} - - {{ BINDING }} - {% endfor %} - -append_so-strelka-frontend_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-strelka-frontend - -strelka_backend: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-backend:{{ GLOBALS.so_version }} - - binds: - - /opt/so/conf/strelka/backend/:/etc/strelka/:ro - - /opt/so/conf/strelka/rules/:/etc/yara/:ro - - name: so-strelka-backend - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-strelka-backend'].ip }} - - command: strelka-backend - - extra_hosts: - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - - restart_policy: on-failure - -append_so-strelka-backend_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-strelka-backend - -strelka_manager: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-manager:{{ GLOBALS.so_version }} - - binds: - - /opt/so/conf/strelka/manager/:/etc/strelka/:ro - - name: so-strelka-manager - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-strelka-manager'].ip }} - - command: strelka-manager - - extra_hosts: - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - -append_so-strelka-manager_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-strelka-manager - -strelka_filestream: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-filestream:{{ GLOBALS.so_version }} - - binds: - - /opt/so/conf/strelka/filestream/:/etc/strelka/:ro - - /nsm/strelka:/nsm/strelka - - name: so-strelka-filestream - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-strelka-filestream'].ip }} - - command: strelka-filestream - - extra_hosts: - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - -append_so-strelka-filestream_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-strelka-filestream +include: +{% if STRELKAMERGED.coordinator.enabled %} + - strelka.coordinator.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - strelka.coordinator.disabled +{% endif %} + +{% if STRELKAMERGED.gatekeeper.enabled %} + - strelka.gatekeeper.enabled +{% else %} + - strelka.gatekeeper.disabled +{% endif %} + +{% if STRELKAMERGED.frontend.enabled %} + - strelka.frontend.enabled +{% else %} + - strelka.frontend.disabled +{% endif %} + +{% if STRELKAMERGED.backend.enabled %} + - strelka.backend.enabled +{% else %} + - strelka.backend.disabled +{% endif %} + +{% if STRELKAMERGED.manager.enabled %} + - strelka.manager.enabled +{% else %} + - strelka.manager.disabled +{% endif %} + +{% if STRELKAMERGED.filestream.enabled %} + - strelka.filestream.enabled +{% else %} + - strelka.filestream.disabled {% endif %} diff --git a/salt/strelka/manager/config.sls b/salt/strelka/manager/config.sls new file mode 100644 index 000000000..a99bdb27a --- /dev/null +++ b/salt/strelka/manager/config.sls @@ -0,0 +1,31 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} +{% from 'strelka/map.jinja' import STRELKAMERGED %} + +include: + - strelka.config + - strelka.manager.sostatus + +manager_config: + file.managed: + - name: /opt/so/conf/strelka/manager/manager.yaml + - source: salt://strelka/manager/files/manager.yaml.jinja + - template: jinja + - user: 939 + - group: 939 + - makedirs: True + - defaults: + MANAGERCONFIG: {{ STRELKAMERGED.manager.config }} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/manager/disabled.sls b/salt/strelka/manager/disabled.sls new file mode 100644 index 000000000..0826166ad --- /dev/null +++ b/salt/strelka/manager/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - strelka.manager.sostatus + +so-strelka-manager: + docker_container.absent: + - force: True + +so-strelka-manager_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-manager$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/manager/enabled.sls b/salt/strelka/manager/enabled.sls new file mode 100644 index 000000000..0c78c9dcb --- /dev/null +++ b/salt/strelka/manager/enabled.sls @@ -0,0 +1,39 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - strelka.manager.config + - strelka.manager.sostatus + +strelka_manager: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-strelka-manager:{{ GLOBALS.so_version }} + - binds: + - /opt/so/conf/strelka/manager/:/etc/strelka/:ro + - name: so-strelka-manager + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-strelka-manager'].ip }} + - command: strelka-manager + - extra_hosts: + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + +delete_so-strelka-manager_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-strelka-manager$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/files/manager/manager.yaml.jinja b/salt/strelka/manager/files/manager.yaml.jinja similarity index 100% rename from salt/strelka/files/manager/manager.yaml.jinja rename to salt/strelka/manager/files/manager.yaml.jinja diff --git a/salt/strelka/manager/init.sls b/salt/strelka/manager/init.sls new file mode 100644 index 000000000..2b479751c --- /dev/null +++ b/salt/strelka/manager/init.sls @@ -0,0 +1,13 @@ +# 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 'strelka/map.jinja' import STRELKAMERGED %} + +include: +{% if STRELKAMERGED.manager.enabled %} + - strelka.manager.enabled +{% else %} + - strelka.manager.disabled +{% endif %} diff --git a/salt/strelka/manager/sostatus.sls b/salt/strelka/manager/sostatus.sls new file mode 100644 index 000000000..5e42093f5 --- /dev/null +++ b/salt/strelka/manager/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-strelka-manager_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-strelka-manager + - unless: grep -q so-strelka-manager /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/strelka/soc_strelka.yaml b/salt/strelka/soc_strelka.yaml index dbe949817..5cdf442d5 100644 --- a/salt/strelka/soc_strelka.yaml +++ b/salt/strelka/soc_strelka.yaml @@ -1,6 +1,9 @@ strelka: - config: - backend: + backend: + enabled: + description: You can enable or disable Strelka backend. + helpLink: strelka.html + config: backend: logging_cfg: description: Path to the Python logging configuration. @@ -398,7 +401,11 @@ strelka: global: False helpLink: strelka.html multiline: True - filestream: + filestream: + enabled: + description: You can enable or disable Strelka filestream. + helpLink: strelka.html + config: conn: server: description: Network address of the frontend server. @@ -488,7 +495,11 @@ strelka: global: False helpLink: strelka.html advanced: True - frontend: + frontend: + enabled: + description: You can enable or disable Strelka frontend. + helpLink: strelka.html + config: server: description: Network address of the frontend server. readonly: False @@ -534,7 +545,11 @@ strelka: global: False helpLink: strelka.html advanced: True - manager: + manager: + enabled: + description: You can enable or disable Strelka manager. + helpLink: strelka.html + config: coordinator: addr: description: Network address of the coordinator. @@ -548,6 +563,14 @@ strelka: global: False helpLink: strelka.html advanced: True + coordinator: + enabled: + description: You can enable or disable Strelka coordinator. + helpLink: strelka.html + gatekeeper: + enabled: + description: You can enable or disable Strelka gatekeeper. + helpLink: strelka.html rules: enabled: description: Boolean that determines if yara rules sync from the Salt manager to the backend nodes. From c91fb438bb7991084e0391bfe1e0ce278a5ea8cd Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 15:53:28 -0400 Subject: [PATCH 28/68] update map file with new strelka format --- salt/strelka/map.jinja | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/salt/strelka/map.jinja b/salt/strelka/map.jinja index 5df15aa59..7ab3d76f5 100644 --- a/salt/strelka/map.jinja +++ b/salt/strelka/map.jinja @@ -2,20 +2,20 @@ {% import_yaml 'strelka/defaults.yaml' as STRELKADEFAULTS %} {% set HOST = GLOBALS.hostname %} -{% set backend_coordinator_port = STRELKADEFAULTS.strelka.config.backend.backend.coordinator.addr.split(':')[1] %} -{% do STRELKADEFAULTS.strelka.config.backend.backend.coordinator.update({'addr': HOST ~ ':' ~ backend_coordinator_port}) %} +{% set backend_coordinator_port = STRELKADEFAULTS.strelka.backend.config.backend.coordinator.addr.split(':')[1] %} +{% do STRELKADEFAULTS.strelka.backend.config.backend.coordinator.update({'addr': HOST ~ ':' ~ backend_coordinator_port}) %} -{% set filestream_conn_port = STRELKADEFAULTS.strelka.config.filestream.conn.server.split(':')[1] %} -{% do STRELKADEFAULTS.strelka.config.filestream.conn.update({'server': HOST ~ ':' ~ filestream_conn_port}) %} +{% set filestream_conn_port = STRELKADEFAULTS.strelka.filestream.config.conn.server.split(':')[1] %} +{% do STRELKADEFAULTS.strelka.filestream.config.conn.update({'server': HOST ~ ':' ~ filestream_conn_port}) %} -{% set frontend_coordinator_port = STRELKADEFAULTS.strelka.config.frontend.coordinator.addr.split(':')[1] %} -{% do STRELKADEFAULTS.strelka.config.frontend.coordinator.update({'addr': HOST ~ ':' ~ frontend_coordinator_port}) %} +{% set frontend_coordinator_port = STRELKADEFAULTS.strelka.frontend.config.coordinator.addr.split(':')[1] %} +{% do STRELKADEFAULTS.strelka.frontend.config.coordinator.update({'addr': HOST ~ ':' ~ frontend_coordinator_port}) %} -{% set frontend_gatekeeper_port = STRELKADEFAULTS.strelka.config.frontend.gatekeeper.addr.split(':')[1] %} -{% do STRELKADEFAULTS.strelka.config.frontend.gatekeeper.update({'addr': HOST ~ ':' ~ frontend_gatekeeper_port}) %} +{% set frontend_gatekeeper_port = STRELKADEFAULTS.strelka.frontend.config.gatekeeper.addr.split(':')[1] %} +{% do STRELKADEFAULTS.strelka.frontend.config.gatekeeper.update({'addr': HOST ~ ':' ~ frontend_gatekeeper_port}) %} -{% set manager_coordinator_port = STRELKADEFAULTS.strelka.config.manager.coordinator.addr.split(':')[1] %} -{% do STRELKADEFAULTS.strelka.config.manager.coordinator.update({'addr': HOST ~ ':' ~ manager_coordinator_port}) %} +{% set manager_coordinator_port = STRELKADEFAULTS.strelka.manager.config.coordinator.addr.split(':')[1] %} +{% do STRELKADEFAULTS.strelka.manager.config.coordinator.update({'addr': HOST ~ ':' ~ manager_coordinator_port}) %} {% if GLOBALS.md_engine == "SURICATA" %} {% set extract_path = '/nsm/suricata/extracted' %} From 5b06aa518e80d7094e451c301dd5794ab5275cb8 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 15:55:21 -0400 Subject: [PATCH 29/68] makedirs if needed --- salt/manager/init.sls | 1 + 1 file changed, 1 insertion(+) diff --git a/salt/manager/init.sls b/salt/manager/init.sls index 372813649..2eef1259b 100644 --- a/salt/manager/init.sls +++ b/salt/manager/init.sls @@ -90,6 +90,7 @@ strelkarepos: - template: jinja - defaults: STRELKAREPOS: {{ STRELKAMERGED.rules.repos }} + - makedirs: True {% endif %} yara_update_script: From 4e4034e054531704df429241164d55714733922f Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 15:59:10 -0400 Subject: [PATCH 30/68] cleanup strelka in top and allowed_states --- salt/allowed_states.map.jinja | 6 ++---- salt/top.sls | 9 --------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 882e33576..53796ea23 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -4,8 +4,6 @@ # Elastic License 2.0. {% set CURATOR = salt['pillar.get']('curator:enabled', True) %} -{% set REDIS = salt['pillar.get']('redis:enabled', True) %} -{% set STRELKA = salt['pillar.get']('strelka:enabled', '0') %} {% set ISAIRGAP = salt['pillar.get']('global:airgap', False) %} {% import_yaml 'salt/minion.defaults.yaml' as saltversion %} {% set saltversion = saltversion.salt.minion.version %} @@ -218,7 +216,7 @@ {% do allowed_states.append('zeek') %} {%- endif %} - {% if STRELKA and grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %} + {% if grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %} {% do allowed_states.append('strelka') %} {% endif %} @@ -251,7 +249,7 @@ {% do allowed_states.append('logstash') %} {% endif %} - {% if REDIS and grains.role in ['so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-receiver', 'so-eval'] %} + {% if grains.role in ['so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-receiver', 'so-eval'] %} {% do allowed_states.append('redis') %} {% endif %} diff --git a/salt/top.sls b/salt/top.sls index 9941f0077..229557575 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set STRELKA = salt['pillar.get']('strelka:enabled', '0') %} {% import_yaml 'salt/minion.defaults.yaml' as saltversion %} {% set saltversion = saltversion.salt.minion.version %} {% set INSTALLEDSALTVERSION = grains.saltversion %} @@ -45,9 +44,7 @@ base: - suricata - healthcheck - zeek - {%- if STRELKA %} - strelka - {%- endif %} - docker_clean - elasticfleet.install_agent_grid @@ -76,9 +73,7 @@ base: - pcap - suricata - zeek - {%- if STRELKA %} - strelka - {%- endif %} - curator - elastalert - utility @@ -146,9 +141,7 @@ base: - pcap - suricata - zeek - {%- if STRELKA %} - strelka - {%- endif %} - curator - elastalert - utility @@ -211,9 +204,7 @@ base: - logstash - redis - curator - {%- if STRELKA %} - strelka - {%- endif %} - pcap - suricata - zeek From 06a049222696ef3361c885a62128cbddd3c439a7 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 10 May 2023 16:04:53 -0400 Subject: [PATCH 31/68] import DOCKER and GLOBALS for filestream enabled --- salt/strelka/filestream/enabled.sls | 2 ++ 1 file changed, 2 insertions(+) diff --git a/salt/strelka/filestream/enabled.sls b/salt/strelka/filestream/enabled.sls index e798629c4..6c6ee0b97 100644 --- a/salt/strelka/filestream/enabled.sls +++ b/salt/strelka/filestream/enabled.sls @@ -5,6 +5,8 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} include: - strelka.filestream.config From c74b440922df340cfcc657ccbc097bb1f4db78d3 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 10:17:28 -0400 Subject: [PATCH 32/68] configure and enable/disable curator in ui --- salt/allowed_states.map.jinja | 1 - salt/curator/config.sls | 81 ++++++++++++ salt/curator/defaults.yaml | 198 +++++++++++++++--------------- salt/curator/disabled.sls | 35 ++++++ salt/curator/enabled.sls | 71 +++++++++++ salt/curator/files/curator.yml | 6 +- salt/curator/init.sls | 145 +--------------------- salt/curator/map.jinja | 21 +--- salt/curator/soc_curator.yaml | 108 ++++++++++++++++ salt/curator/sostatus.sls | 21 ++++ salt/manager/tools/sbin/so-minion | 68 +++------- 11 files changed, 443 insertions(+), 312 deletions(-) create mode 100644 salt/curator/config.sls create mode 100644 salt/curator/disabled.sls create mode 100644 salt/curator/enabled.sls create mode 100644 salt/curator/soc_curator.yaml create mode 100644 salt/curator/sostatus.sls diff --git a/salt/allowed_states.map.jinja b/salt/allowed_states.map.jinja index 53796ea23..e7a9a0491 100644 --- a/salt/allowed_states.map.jinja +++ b/salt/allowed_states.map.jinja @@ -3,7 +3,6 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% set CURATOR = salt['pillar.get']('curator:enabled', True) %} {% set ISAIRGAP = salt['pillar.get']('global:airgap', False) %} {% import_yaml 'salt/minion.defaults.yaml' as saltversion %} {% set saltversion = saltversion.salt.minion.version %} diff --git a/salt/curator/config.sls b/salt/curator/config.sls new file mode 100644 index 000000000..89ff53b2a --- /dev/null +++ b/salt/curator/config.sls @@ -0,0 +1,81 @@ +# 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 %} +{% from "curator/map.jinja" import CURATORMERGED %} + +# Create the group +curatorgroup: + group.present: + - name: curator + - gid: 934 + +# Add user +curator: + user.present: + - uid: 934 + - gid: 934 + - home: /opt/so/conf/curator + - createhome: False + +# Create the log directory +curlogdir: + file.directory: + - name: /opt/so/log/curator + - user: 934 + - group: 939 + +curactiondir: + file.directory: + - name: /opt/so/conf/curator/action + - user: 934 + - group: 939 + - makedirs: True + +actionconfs: + file.recurse: + - name: /opt/so/conf/curator/action + - source: salt://curator/files/action + - user: 934 + - group: 939 + - template: jinja + - defaults: + CURATORMERGED: {{ CURATORMERGED.elasticsearch.index_settings }} + +curconf: + file.managed: + - name: /opt/so/conf/curator/curator.yml + - source: salt://curator/files/curator.yml + - user: 934 + - group: 939 + - mode: 660 + - template: jinja + - show_changes: False + +curator_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://curator/tools/sbin + - user: 934 + - group: 939 + - file_mode: 755 + +curator_sbin_jinja: + file.recurse: + - name: /usr/sbin + - source: salt://curator/tools/sbin_jinja + - user: 934 + - group: 939 + - file_mode: 755 + - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/curator/defaults.yaml b/salt/curator/defaults.yaml index e1333c3a6..eb518264f 100644 --- a/salt/curator/defaults.yaml +++ b/salt/curator/defaults.yaml @@ -1,98 +1,100 @@ -elasticsearch: - index_settings: - logs-import-so: - close: 73000 - delete: 73001 - logs-strelka-so: - close: 30 - delete: 365 - logs-suricata-so: - close: 30 - delete: 365 - logs-syslog-so: - close: 30 - delete: 365 - logs-zeek-so: - close: 30 - delete: 365 - logs-elastic_agent-metricbeat-default: - close: 30 - delete: 365 - logs-elastic_agent-osquerybeat-default: - close: 30 - delete: 365 - logs-elastic_agent-fleet_server-default: - close: 30 - delete: 365 - logs-elastic_agent-filebeat-default: - close: 30 - delete: 365 - logs-elastic_agent-default: - close: 30 - delete: 365 - logs-system-auth-default: - close: 30 - delete: 365 - logs-system-application-default: - close: 30 - delete: 365 - logs-system-security-default: - close: 30 - delete: 365 - logs-system-system-default: - close: 30 - delete: 365 - logs-system-syslog-default: - close: 30 - delete: 365 - logs-windows-powershell-default: - close: 30 - delete: 365 - logs-windows-sysmon_operational-default: - close: 30 - delete: 365 - so-beats: - close: 30 - delete: 365 - so-elasticsearch: - close: 30 - delete: 365 - so-firewall: - close: 30 - delete: 365 - so-ids: - close: 30 - delete: 365 - so-import: - close: 73000 - delete: 73001 - so-kratos: - close: 30 - delete: 365 - so-kibana: - close: 30 - delete: 365 - so-logstash: - close: 30 - delete: 365 - so-netflow: - close: 30 - delete: 365 - so-osquery: - close: 30 - delete: 365 - so-ossec: - close: 30 - delete: 365 - so-redis: - close: 30 - delete: 365 - so-strelka: - close: 30 - delete: 365 - so-syslog: - close: 30 - delete: 365 - so-zeek: - close: 30 - delete: 365 +curator: + enabled: False + elasticsearch: + index_settings: + logs-import-so: + close: 73000 + delete: 73001 + logs-strelka-so: + close: 30 + delete: 365 + logs-suricata-so: + close: 30 + delete: 365 + logs-syslog-so: + close: 30 + delete: 365 + logs-zeek-so: + close: 30 + delete: 365 + logs-elastic_agent-metricbeat-default: + close: 30 + delete: 365 + logs-elastic_agent-osquerybeat-default: + close: 30 + delete: 365 + logs-elastic_agent-fleet_server-default: + close: 30 + delete: 365 + logs-elastic_agent-filebeat-default: + close: 30 + delete: 365 + logs-elastic_agent-default: + close: 30 + delete: 365 + logs-system-auth-default: + close: 30 + delete: 365 + logs-system-application-default: + close: 30 + delete: 365 + logs-system-security-default: + close: 30 + delete: 365 + logs-system-system-default: + close: 30 + delete: 365 + logs-system-syslog-default: + close: 30 + delete: 365 + logs-windows-powershell-default: + close: 30 + delete: 365 + logs-windows-sysmon_operational-default: + close: 30 + delete: 365 + so-beats: + close: 30 + delete: 365 + so-elasticsearch: + close: 30 + delete: 365 + so-firewall: + close: 30 + delete: 365 + so-ids: + close: 30 + delete: 365 + so-import: + close: 73000 + delete: 73001 + so-kratos: + close: 30 + delete: 365 + so-kibana: + close: 30 + delete: 365 + so-logstash: + close: 30 + delete: 365 + so-netflow: + close: 30 + delete: 365 + so-osquery: + close: 30 + delete: 365 + so-ossec: + close: 30 + delete: 365 + so-redis: + close: 30 + delete: 365 + so-strelka: + close: 30 + delete: 365 + so-syslog: + close: 30 + delete: 365 + so-zeek: + close: 30 + delete: 365 diff --git a/salt/curator/disabled.sls b/salt/curator/disabled.sls new file mode 100644 index 000000000..acf9e3701 --- /dev/null +++ b/salt/curator/disabled.sls @@ -0,0 +1,35 @@ +# 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 %} + +include: + - curator.sostatus + +so-curator: + docker_container.absent: + - force: True + +so-curator_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-curator$ + +so-curator-cluster-close: + cron.absent: + - identifier: so-curator-cluster-close + +so-curator-cluster-delete: + cron.absent: + - identifier: so-curator-cluster-delete + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/curator/enabled.sls b/salt/curator/enabled.sls new file mode 100644 index 000000000..b60058692 --- /dev/null +++ b/salt/curator/enabled.sls @@ -0,0 +1,71 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} + +include: + - curator.config + - curator.sostatus + +so-curator: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-curator:{{ GLOBALS.so_version }} + - start: True + - hostname: curator + - name: so-curator + - user: curator + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-curator'].ip }} + - interactive: True + - tty: True + - binds: + - /opt/so/conf/curator/curator.yml:/etc/curator/config/curator.yml:ro + - /opt/so/conf/curator/action/:/etc/curator/action:ro + - /opt/so/log/curator:/var/log/curator:rw + - require: + - file: actionconfs + - file: curconf + - file: curlogdir + - watch: + - file: curconf + +delete_so-curator_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-curator$ + +so-curator-cluster-close: + cron.present: + - name: /usr/sbin/so-curator-cluster-close > /opt/so/log/curator/cron-close.log 2>&1 + - identifier: so-curator-cluster-close + - user: root + - minute: '2' + - hour: '*/1' + - daymonth: '*' + - month: '*' + - dayweek: '*' + +so-curator-cluster-delete: + cron.present: + - name: /usr/sbin/so-curator-cluster-delete > /opt/so/log/curator/cron-cluster-delete.log 2>&1 + - identifier: so-curator-cluster-delete + - user: root + - minute: '*/5' + - hour: '*' + - daymonth: '*' + - month: '*' + - dayweek: '*' + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/curator/files/curator.yml b/salt/curator/files/curator.yml index 549310d73..4ea1dddf7 100644 --- a/salt/curator/files/curator.yml +++ b/salt/curator/files/curator.yml @@ -4,9 +4,9 @@ # Elastic License 2.0. {% from 'vars/globals.map.jinja' import GLOBALS %} -{% if grains['role'] in ['so-searchnode', 'so-heavynode'] %} +{% if GLOBALS.role in ['so-searchnode', 'so-heavynode'] %} {%- set elasticsearch = GLOBALS.node_ip -%} -{% elif grains['role'] in ['so-eval', 'so-managersearch', 'so-standalone', 'so-manager'] %} +{% elif GLOBALS.role in ['so-eval', 'so-managersearch', 'so-standalone', 'so-manager'] %} {%- set elasticsearch = GLOBALS.manager_ip -%} {%- endif %} {%- set ES_USER = salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:user', '') %} @@ -30,10 +30,8 @@ elasticsearch: id: api_key: master_only: False -{%- if salt['pillar.get']('elasticsearch:auth:enabled') is sameas true %} username: "{{ ES_USER }}" password: "{{ ES_PASS }}" -{%- endif %} logging: loglevel: INFO diff --git a/salt/curator/init.sls b/salt/curator/init.sls index eaa5639ff..201195b60 100644 --- a/salt/curator/init.sls +++ b/salt/curator/init.sls @@ -3,146 +3,11 @@ # 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 in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from "curator/map.jinja" import CURATOROPTIONS %} -{% from "curator/map.jinja" import CURATORMERGED %} -{% set REMOVECURATORCRON = False %} - -# Curator -# Create the group -curatorgroup: - group.present: - - name: curator - - gid: 934 - -# Add user -curator: - user.present: - - uid: 934 - - gid: 934 - - home: /opt/so/conf/curator - - createhome: False - -# Create the log directory -curlogdir: - file.directory: - - name: /opt/so/log/curator - - user: 934 - - group: 939 - -curactiondir: - file.directory: - - name: /opt/so/conf/curator/action - - user: 934 - - group: 939 - - makedirs: True - -actionconfs: - file.recurse: - - name: /opt/so/conf/curator/action - - source: salt://curator/files/action - - user: 934 - - group: 939 - - template: jinja - - defaults: - CURATORMERGED: {{ CURATORMERGED }} - -curconf: - file.managed: - - name: /opt/so/conf/curator/curator.yml - - source: salt://curator/files/curator.yml - - user: 934 - - group: 939 - - mode: 660 - - template: jinja - - show_changes: False - -curator_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://curator/tools/sbin - - user: 934 - - group: 939 - - file_mode: 755 - -curator_sbin_jinja: - file.recurse: - - name: /usr/sbin - - source: salt://curator/tools/sbin_jinja - - user: 934 - - group: 939 - - file_mode: 755 - - template: jinja - -so-curator: - docker_container.{{ CURATOROPTIONS.status }}: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-curator:{{ GLOBALS.so_version }} - - start: {{ CURATOROPTIONS.start }} - - hostname: curator - - name: so-curator - - user: curator - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-curator'].ip }} - - interactive: True - - tty: True - - binds: - - /opt/so/conf/curator/curator.yml:/etc/curator/config/curator.yml:ro - - /opt/so/conf/curator/action/:/etc/curator/action:ro - - /opt/so/log/curator:/var/log/curator:rw - - require: - - file: actionconfs - - file: curconf - - file: curlogdir - - watch: - - file: curconf - -append_so-curator_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-curator - - unless: grep -q so-curator /opt/so/conf/so-status/so-status.conf - {% if not CURATOROPTIONS.start %} -so-curator_so-status.disabled: - file.comment: - - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-curator$ - {% else %} -delete_so-curator_so-status.disabled: - file.uncomment: - - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-curator$ - {% endif %} - -so-curator-cluster-close: - cron.present: - - name: /usr/sbin/so-curator-cluster-close > /opt/so/log/curator/cron-close.log 2>&1 - - identifier: so-curator-cluster-close - - user: root - - minute: '2' - - hour: '*/1' - - daymonth: '*' - - month: '*' - - dayweek: '*' - -so-curator-cluster-delete: - cron.present: - - name: /usr/sbin/so-curator-cluster-delete > /opt/so/log/curator/cron-cluster-delete.log 2>&1 - - identifier: so-curator-cluster-delete - - user: root - - minute: '*/5' - - hour: '*' - - daymonth: '*' - - month: '*' - - dayweek: '*' +{% from 'curator/map.jinja' import CURATORMERGED %} +include: +{% if CURATORMERGED.enabled %} + - curator.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - curator.disabled {% endif %} diff --git a/salt/curator/map.jinja b/salt/curator/map.jinja index 65d9f580d..517209635 100644 --- a/salt/curator/map.jinja +++ b/salt/curator/map.jinja @@ -1,18 +1,7 @@ -{% set CURATOROPTIONS = {} %} -{% set ENABLED = salt['pillar.get']('curator:enabled', True) %} -{% do CURATOROPTIONS.update({'manage_sostatus': True}) %} - -# don't start the docker container if curator is disabled via pillar -{% if not ENABLED %} - {% do CURATOROPTIONS.update({'start': False}) %} - {% do CURATOROPTIONS.update({'status': 'absent'}) %} - {% if (TRUECLUSTER and grains.id.split('_')|last == 'searchnode') or (not TRUECLUSTER and grains.id.split('_')|last == 'manager') %} - {% do CURATOROPTIONS.update({'manage_sostatus': False}) %} - {% endif %} -{% else %} - {% do CURATOROPTIONS.update({'start': True}) %} - {% do CURATOROPTIONS.update({'status': 'running'}) %} -{% endif %} +{# 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 'curator/defaults.yaml' as CURATORDEFAULTS %} -{% set CURATORMERGED = salt['pillar.get']('elasticsearch:index_settings', CURATORDEFAULTS.elasticsearch.index_settings, merge=true) %} +{% set CURATORMERGED = salt['pillar.get']('curator', CURATORDEFAULTS.curator, merge=true) %} diff --git a/salt/curator/soc_curator.yaml b/salt/curator/soc_curator.yaml new file mode 100644 index 000000000..5e5b1fcc6 --- /dev/null +++ b/salt/curator/soc_curator.yaml @@ -0,0 +1,108 @@ +curator: + enabled: + description: You can enable or disable Curator. + helpLink: curator.html + elasticsearch: + index_settings: + logs-import-so: + close: &close + description: Age, in days, when Curator closes the index. + helpLink: curator.html + forcedType: int + delete: &delete + description: Age, in days, when Curator deletes the index. + helpLink: curator.html + forcedType: int + logs-strelka-so: + close: *close + delete: *delete + logs-suricata-so: + close: *close + delete: *delete + logs-syslog-so: + close: *close + delete: *delete + logs-zeek-so: + close: *close + delete: *delete + logs-elastic_agent-metricbeat-default: + close: *close + delete: *delete + logs-elastic_agent-osquerybeat-default: + close: *close + delete: *delete + logs-elastic_agent-fleet_server-default: + close: *close + delete: *delete + logs-elastic_agent-filebeat-default: + close: *close + delete: *delete + logs-elastic_agent-default: + close: *close + delete: *delete + logs-system-auth-default: + close: *close + delete: *delete + logs-system-application-default: + close: *close + delete: *delete + logs-system-security-default: + close: *close + delete: *delete + logs-system-system-default: + close: *close + delete: *delete + logs-system-syslog-default: + close: *close + delete: *delete + logs-windows-powershell-default: + close: *close + delete: *delete + logs-windows-sysmon_operational-default: + close: *close + delete: *delete + so-beats: + close: *close + delete: *delete + so-elasticsearch: + close: *close + delete: *delete + so-firewall: + close: *close + delete: *delete + so-ids: + close: *close + delete: *delete + so-import: + close: *close + delete: *delete + so-kratos: + close: *close + delete: *delete + so-kibana: + close: *close + delete: *delete + so-logstash: + close: *close + delete: *delete + so-netflow: + close: *close + delete: *delete + so-osquery: + close: *close + delete: *delete + so-ossec: + close: *close + delete: *delete + so-redis: + close: *close + delete: *delete + so-strelka: + close: *close + delete: *delete + so-syslog: + close: *close + delete: *delete + so-zeek: + close: *close + delete: *delete diff --git a/salt/curator/sostatus.sls b/salt/curator/sostatus.sls new file mode 100644 index 000000000..de6459a6d --- /dev/null +++ b/salt/curator/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-curator_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-curator + - unless: grep -q so-curator /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 864b714d6..b5198f955 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -249,51 +249,28 @@ function add_redis_to_minion() { " " >> $PILLARFILE } -function add_strelka_backend_to_minion() { +function add_strelka_strelka_to_minion() { printf '%s\n'\ "strelka:"\ " backend:"\ " enabled: True"\ - " " >> $PILLARFILE -} - -function add_strelka_filestream_to_minion() { - printf '%s\n'\ - "strelka:"\ " filestream:"\ " enabled: True"\ - " " >> $PILLARFILE -} - -function add_strelka_frontend_to_minion() { - printf '%s\n'\ - "strelka:"\ " frontend:"\ " enabled: True"\ - " " >> $PILLARFILE -} - -function add_strelka_manager_to_minion() { - printf '%s\n'\ - "strelka:"\ " manager:"\ " enabled: True"\ - " " >> $PILLARFILE -} - -function add_strelka_coordinator_to_minion() { - printf '%s\n'\ - "strelka:"\ " coordinator:"\ + " enabled: True"\ + " gatekeeper:"\ " enabled: True"\ " " >> $PILLARFILE } -function add_strelka_gatekeeper_to_minion() { +function add_curator_to_minion() { printf '%s\n'\ - "strelka:"\ - " gatekeeper:"\ - " enabled: True"\ + "curator:"\ + " enabled: True"\ " " >> $PILLARFILE } @@ -343,30 +320,22 @@ function apply_ES_state() { function createEVAL() { add_elasticsearch_to_minion add_sensor_to_minion - add_strelka_backend_to_minion - add_strelka_filestream_to_minion - add_strelka_frontend_to_minion - add_strelka_manager_to_minion - add_strelka_coordinator_to_minion - add_strelka_gatekeeper_to_minion + add_strelka_strelka_to_minion add_elastalert_to_minion add_kibana_to_minion + add_curator_to_minion } function createSTANDALONE() { add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion - add_strelka_backend_to_minion - add_strelka_filestream_to_minion - add_strelka_frontend_to_minion - add_strelka_manager_to_minion - add_strelka_coordinator_to_minion - add_strelka_gatekeeper_to_minion + add_strelka_strelka_to_minion add_playbook_to_minion add_elastalert_to_minion add_kibana_to_minion add_redis_to_minion + add_curator_to_minion } function createMANAGER() { @@ -376,6 +345,7 @@ function createMANAGER() { add_elastalert_to_minion add_kibana_to_minion add_redis_to_minion + add_curator_to_minion } function createMANAGERSEARCH() { @@ -385,6 +355,7 @@ function createMANAGERSEARCH() { add_elastalert_to_minion add_kibana_to_minion add_redis_to_minion + add_curator_to_minion } function createIMPORT() { @@ -409,23 +380,14 @@ function createHEAVYNODE() { add_elasticsearch_to_minion add_logstash_to_minion add_sensor_to_minion - add_strelka_backend_to_minion - add_strelka_filestream_to_minion - add_strelka_frontend_to_minion - add_strelka_manager_to_minion - add_strelka_coordinator_to_minion - add_strelka_gatekeeper_to_minion + add_strelka_strelka_to_minion add_redis_to_minion + add_curator_to_minion } function createSENSOR() { add_sensor_to_minion - add_strelka_backend_to_minion - add_strelka_filestream_to_minion - add_strelka_frontend_to_minion - add_strelka_manager_to_minion - add_strelka_coordinator_to_minion - add_strelka_gatekeeper_to_minion + add_strelka_strelka_to_minion } function createSEARCHNODE() { From 20f706f1651d633b7c6671468e3e54411376f30c Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 12:12:25 -0400 Subject: [PATCH 33/68] enable/disable telegraf in ui --- salt/manager/tools/sbin/so-minion | 18 ++++ salt/strelka/map.jinja | 5 + salt/telegraf/config.map.jinja | 3 - salt/telegraf/config.sls | 91 +++++++++++++++++++ salt/telegraf/defaults.yaml | 1 + salt/telegraf/disabled.sls | 27 ++++++ salt/telegraf/enabled.sls | 76 ++++++++++++++++ salt/telegraf/etc/telegraf.conf | 14 +-- salt/telegraf/init.sls | 146 ++---------------------------- salt/telegraf/map.jinja | 7 ++ salt/telegraf/soc_telegraf.yaml | 3 + salt/telegraf/sostatus.sls | 21 +++++ 12 files changed, 265 insertions(+), 147 deletions(-) delete mode 100644 salt/telegraf/config.map.jinja create mode 100644 salt/telegraf/config.sls create mode 100644 salt/telegraf/disabled.sls create mode 100644 salt/telegraf/enabled.sls create mode 100644 salt/telegraf/map.jinja create mode 100644 salt/telegraf/sostatus.sls diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index b5198f955..9b7923403 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -274,6 +274,13 @@ function add_curator_to_minion() { " " >> $PILLARFILE } +function add_telegraf_to_minion() { + printf '%s\n'\ + "telegraf:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -324,6 +331,7 @@ function createEVAL() { add_elastalert_to_minion add_kibana_to_minion add_curator_to_minion + add_telegraf_to_minion } function createSTANDALONE() { @@ -336,6 +344,7 @@ function createSTANDALONE() { add_kibana_to_minion add_redis_to_minion add_curator_to_minion + add_telegraf_to_minion } function createMANAGER() { @@ -346,6 +355,7 @@ function createMANAGER() { add_kibana_to_minion add_redis_to_minion add_curator_to_minion + add_telegraf_to_minion } function createMANAGERSEARCH() { @@ -356,12 +366,14 @@ function createMANAGERSEARCH() { add_kibana_to_minion add_redis_to_minion add_curator_to_minion + add_telegraf_to_minion } function createIMPORT() { add_elasticsearch_to_minion add_sensor_to_minion add_kibana_to_minion + add_telegraf_to_minion } function createFLEET() { @@ -370,10 +382,12 @@ function createFLEET() { create_fleet_policy update_fleet_host_urls update_logstash_outputs + add_telegraf_to_minion } function createIDH() { add_idh_to_minion + add_telegraf_to_minion } function createHEAVYNODE() { @@ -383,16 +397,19 @@ function createHEAVYNODE() { add_strelka_strelka_to_minion add_redis_to_minion add_curator_to_minion + add_telegraf_to_minion } function createSENSOR() { add_sensor_to_minion add_strelka_strelka_to_minion + add_telegraf_to_minion } function createSEARCHNODE() { add_elasticsearch_to_minion add_logstash_to_minion + add_telegraf_to_minion updateMine apply_ES_state } @@ -400,6 +417,7 @@ function createSEARCHNODE() { function createRECEIVER() { add_logstash_to_minion add_redis_to_minion + add_telegraf_to_minion } diff --git a/salt/strelka/map.jinja b/salt/strelka/map.jinja index 7ab3d76f5..646f7a746 100644 --- a/salt/strelka/map.jinja +++ b/salt/strelka/map.jinja @@ -1,3 +1,8 @@ +{# 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 'vars/globals.map.jinja' import GLOBALS %} {% import_yaml 'strelka/defaults.yaml' as STRELKADEFAULTS %} {% set HOST = GLOBALS.hostname %} diff --git a/salt/telegraf/config.map.jinja b/salt/telegraf/config.map.jinja deleted file mode 100644 index 4ac4597a4..000000000 --- a/salt/telegraf/config.map.jinja +++ /dev/null @@ -1,3 +0,0 @@ -{% import_yaml 'telegraf/defaults.yaml' as TGDEFAULTS %} - -{% set TGMERGED = salt['pillar.get']('telegraf', TGDEFAULTS.telegraf, merge=True) %} diff --git a/salt/telegraf/config.sls b/salt/telegraf/config.sls new file mode 100644 index 000000000..1cc7ceed0 --- /dev/null +++ b/salt/telegraf/config.sls @@ -0,0 +1,91 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'telegraf/map.jinja' import TELEGRAFMERGED %} + +include: + - ssl + +# add Telegraf to monitor all the things +tgraflogdir: + file.directory: + - name: /opt/so/log/telegraf + - makedirs: True + - user: 939 + - group: 939 + - recurse: + - user + - group + +tgrafetcdir: + file.directory: + - name: /opt/so/conf/telegraf/etc + - makedirs: True + +tgrafetsdir: + file.directory: + - name: /opt/so/conf/telegraf/scripts + - makedirs: True + +tgrafsyncscripts: + file.recurse: + - name: /opt/so/conf/telegraf/scripts + - user: root + - group: 939 + - file_mode: 770 + - template: jinja + - source: salt://telegraf/scripts + {% if GLOBALS.md_engine == 'SURICATA' %} + - exclude_pat: zeekcaptureloss.sh + {% endif %} + +telegraf_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://telegraf/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#telegraf_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://telegraf/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +tgrafconf: + file.managed: + - name: /opt/so/conf/telegraf/etc/telegraf.conf + - user: 939 + - group: 939 + - mode: 660 + - template: jinja + - source: salt://telegraf/etc/telegraf.conf + - show_changes: False + - defaults: + GLOBALS: {{ GLOBALS }} + TELEGRAFMERGED: {{ TELEGRAFMERGED }} + +# this file will be read by telegraf to send node details (management interface, monitor interface, etc) +# into influx +node_config: + file.managed: + - name: /opt/so/conf/telegraf/node_config.json + - source: salt://telegraf/node_config.json.jinja + - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/telegraf/defaults.yaml b/salt/telegraf/defaults.yaml index a0cc8095f..63d437763 100644 --- a/salt/telegraf/defaults.yaml +++ b/salt/telegraf/defaults.yaml @@ -1,4 +1,5 @@ telegraf: + enabled: False config: interval: '30s' metric_batch_size: 1000 diff --git a/salt/telegraf/disabled.sls b/salt/telegraf/disabled.sls new file mode 100644 index 000000000..05a3c472e --- /dev/null +++ b/salt/telegraf/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + -telegraf.sostatus + +so-telegraf: + docker_container.absent: + - force: True + +so-telegraf_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-telegraf$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/telegraf/enabled.sls b/salt/telegraf/enabled.sls new file mode 100644 index 000000000..04459d7ff --- /dev/null +++ b/salt/telegraf/enabled.sls @@ -0,0 +1,76 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - telegraf.config + - telegraf.sostatus + +so-telegraf: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-telegraf:{{ GLOBALS.so_version }} + - user: 939 + - group_add: 939,920 + - environment: + - HOST_PROC=/host/proc + - HOST_ETC=/host/etc + - HOST_SYS=/host/sys + - HOST_MOUNT_PREFIX=/host + - GODEBUG=x509ignoreCN=0 + - network_mode: host + - init: True + - binds: + - /opt/so/log/telegraf:/var/log/telegraf:rw + - /opt/so/conf/telegraf/etc/telegraf.conf:/etc/telegraf/telegraf.conf:ro + - /opt/so/conf/telegraf/node_config.json:/etc/telegraf/node_config.json:ro + - /var/run/utmp:/var/run/utmp:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + - /:/host/root:ro + - /sys:/host/sys:ro + - /proc:/host/proc:ro + - /nsm:/host/nsm:ro + - /etc:/host/etc:ro + {% if GLOBALS.role in ['so-manager', 'so-eval', 'so-managersearch' ] %} + - /etc/pki/ca.crt:/etc/telegraf/ca.crt:ro + {% else %} + - /etc/ssl/certs/intca.crt:/etc/telegraf/ca.crt:ro + {% endif %} + - /etc/pki/influxdb.crt:/etc/telegraf/telegraf.crt:ro + - /etc/pki/influxdb.key:/etc/telegraf/telegraf.key:ro + - /opt/so/conf/telegraf/scripts:/scripts:ro + - /opt/so/log/stenographer:/var/log/stenographer:ro + - /opt/so/log/suricata:/var/log/suricata:ro + - /opt/so/log/raid:/var/log/raid:ro + - /opt/so/log/sostatus:/var/log/sostatus:ro + - watch: + - file: tgrafconf + - file: tgrafsyncscripts + - file: node_config + - require: + - file: tgrafconf + - file: node_config + {% if GLOBALS.role in ['so-manager', 'so-eval', 'so-managersearch' ] %} + - x509: pki_public_ca_crt + {% else %} + - x509: trusttheca + {% endif %} + - x509: influxdb_crt + - x509: influxdb_key + +delete_so-telegraf_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-telegraf$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/telegraf/etc/telegraf.conf b/salt/telegraf/etc/telegraf.conf index f2a89baf4..596f40b88 100644 --- a/salt/telegraf/etc/telegraf.conf +++ b/salt/telegraf/etc/telegraf.conf @@ -14,7 +14,7 @@ # Configuration for telegraf agent [agent] ## Default data collection interval for all inputs - interval = "{{ TGMERGED.config.interval }}" + interval = "{{ TELEGRAFMERGED.config.interval }}" ## Rounds collection interval to 'interval' ## ie, if interval="10s" then always collect on :00, :10, :20, etc. round_interval = true @@ -22,27 +22,27 @@ ## Telegraf will send metrics to outputs in batches of at most ## metric_batch_size metrics. ## This controls the size of writes that Telegraf sends to output plugins. - metric_batch_size = {{ TGMERGED.config.metric_batch_size }} + metric_batch_size = {{ TELEGRAFMERGED.config.metric_batch_size }} ## For failed writes, telegraf will cache metric_buffer_limit metrics for each ## output, and will flush this buffer on a successful write. Oldest metrics ## are dropped first when this buffer fills. ## This buffer only fills when writes fail to output plugin(s). - metric_buffer_limit = {{ TGMERGED.config.metric_buffer_limit }} + metric_buffer_limit = {{ TELEGRAFMERGED.config.metric_buffer_limit }} ## Collection jitter is used to jitter the collection by a random amount. ## Each plugin will sleep for a random time within jitter before collecting. ## This can be used to avoid many plugins querying things like sysfs at the ## same time, which can have a measurable effect on the system. - collection_jitter = "{{ TGMERGED.config.collection_jitter }}" + collection_jitter = "{{ TELEGRAFMERGED.config.collection_jitter }}" ## Default flushing interval for all outputs. Maximum flush_interval will be ## flush_interval + flush_jitter - flush_interval = "{{ TGMERGED.config.flush_interval }}" + flush_interval = "{{ TELEGRAFMERGED.config.flush_interval }}" ## Jitter the flush interval by a random amount. This is primarily to avoid ## large write spikes for users running a large number of telegraf instances. ## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s - flush_jitter = "{{ TGMERGED.config.flush_jitter }}" + flush_jitter = "{{ TELEGRAFMERGED.config.flush_jitter }}" ## By default or when set to "0s", precision will be set to the same ## timestamp order as the collection interval, with the maximum being 1s. @@ -55,7 +55,7 @@ ## Logging configuration: ## Run telegraf with debug log messages. - debug = {{ TGMERGED.config.debug }} + debug = {{ TELEGRAFMERGED.config.debug }} ## Run telegraf in quiet mode (error log messages only). quiet = false ## Specify the log file name. The empty string means to log to stderr. diff --git a/salt/telegraf/init.sls b/salt/telegraf/init.sls index f14ef14e4..ef5a600ab 100644 --- a/salt/telegraf/init.sls +++ b/salt/telegraf/init.sls @@ -1,141 +1,13 @@ -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'telegraf/config.map.jinja' import TGMERGED %} +# 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 'telegraf/map.jinja' import TELEGRAFMERGED %} include: - - ssl - -# add Telegraf to monitor all the things -tgraflogdir: - file.directory: - - name: /opt/so/log/telegraf - - makedirs: True - - user: 939 - - group: 939 - - recurse: - - user - - group - -tgrafetcdir: - file.directory: - - name: /opt/so/conf/telegraf/etc - - makedirs: True - -tgrafetsdir: - file.directory: - - name: /opt/so/conf/telegraf/scripts - - makedirs: True - -tgrafsyncscripts: - file.recurse: - - name: /opt/so/conf/telegraf/scripts - - user: root - - group: 939 - - file_mode: 770 - - template: jinja - - source: salt://telegraf/scripts -{% if GLOBALS.md_engine == 'SURICATA' %} - - exclude_pat: zeekcaptureloss.sh -{% endif %} - -telegraf_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://telegraf/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#telegraf_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://telegraf/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -tgrafconf: - file.managed: - - name: /opt/so/conf/telegraf/etc/telegraf.conf - - user: 939 - - group: 939 - - mode: 660 - - template: jinja - - source: salt://telegraf/etc/telegraf.conf - - show_changes: False - - defaults: - GLOBALS: {{ GLOBALS }} - TGMERGED: {{ TGMERGED }} - -# this file will be read by telegraf to send node details (management interface, monitor interface, etc) -# into influx -node_config: - file.managed: - - name: /opt/so/conf/telegraf/node_config.json - - source: salt://telegraf/node_config.json.jinja - - template: jinja - -so-telegraf: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-telegraf:{{ GLOBALS.so_version }} - - user: 939 - - group_add: 939,920 - - environment: - - HOST_PROC=/host/proc - - HOST_ETC=/host/etc - - HOST_SYS=/host/sys - - HOST_MOUNT_PREFIX=/host - - GODEBUG=x509ignoreCN=0 - - network_mode: host - - init: True - - binds: - - /opt/so/log/telegraf:/var/log/telegraf:rw - - /opt/so/conf/telegraf/etc/telegraf.conf:/etc/telegraf/telegraf.conf:ro - - /opt/so/conf/telegraf/node_config.json:/etc/telegraf/node_config.json:ro - - /var/run/utmp:/var/run/utmp:ro - - /var/run/docker.sock:/var/run/docker.sock:ro - - /:/host/root:ro - - /sys:/host/sys:ro - - /proc:/host/proc:ro - - /nsm:/host/nsm:ro - - /etc:/host/etc:ro - {% if grains['role'] == 'so-manager' or grains['role'] == 'so-eval' or grains['role'] == 'so-managersearch' %} - - /etc/pki/ca.crt:/etc/telegraf/ca.crt:ro - {% else %} - - /etc/ssl/certs/intca.crt:/etc/telegraf/ca.crt:ro - {% endif %} - - /etc/pki/influxdb.crt:/etc/telegraf/telegraf.crt:ro - - /etc/pki/influxdb.key:/etc/telegraf/telegraf.key:ro - - /opt/so/conf/telegraf/scripts:/scripts:ro - - /opt/so/log/stenographer:/var/log/stenographer:ro - - /opt/so/log/suricata:/var/log/suricata:ro - - /opt/so/log/raid:/var/log/raid:ro - - /opt/so/log/sostatus:/var/log/sostatus:ro - - watch: - - file: tgrafconf - - file: tgrafsyncscripts - - file: node_config - - require: - - file: tgrafconf - - file: node_config - {% if grains['role'] == 'so-manager' or grains['role'] == 'so-eval' or grains['role'] == 'so-managersearch' %} - - x509: pki_public_ca_crt - {% else %} - - x509: trusttheca - {% endif %} - - x509: influxdb_crt - - x509: influxdb_key -append_so-telegraf_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-telegraf - +{% if TELEGRAFMERGED.enabled %} + - telegraf.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - telegraf.disabled {% endif %} diff --git a/salt/telegraf/map.jinja b/salt/telegraf/map.jinja new file mode 100644 index 000000000..f1412d3ac --- /dev/null +++ b/salt/telegraf/map.jinja @@ -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 'telegraf/defaults.yaml' as TELEGRAFDEFAULTS %} +{% set TELEGRAFMERGED = salt['pillar.get']('telegraf', TELEGRAFDEFAULTS.telegraf, merge=True) %} diff --git a/salt/telegraf/soc_telegraf.yaml b/salt/telegraf/soc_telegraf.yaml index f64811632..a688ea2a3 100644 --- a/salt/telegraf/soc_telegraf.yaml +++ b/salt/telegraf/soc_telegraf.yaml @@ -1,4 +1,7 @@ telegraf: + enabled: + description: You can enable or disable Telegraf. + helpLink: telegraf.html config: interval: description: Data collection interval. diff --git a/salt/telegraf/sostatus.sls b/salt/telegraf/sostatus.sls new file mode 100644 index 000000000..2eb69cf5e --- /dev/null +++ b/salt/telegraf/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-telegraf_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-telegraf + - unless: grep -q so-telegraf /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From f41c75c633546da07280931ed3cf2384c7439b92 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 12:14:30 -0400 Subject: [PATCH 34/68] fix include --- salt/telegraf/disabled.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/telegraf/disabled.sls b/salt/telegraf/disabled.sls index 05a3c472e..004d3d928 100644 --- a/salt/telegraf/disabled.sls +++ b/salt/telegraf/disabled.sls @@ -7,7 +7,7 @@ {% if sls.split('.')[0] in allowed_states %} include: - -telegraf.sostatus + - telegraf.sostatus so-telegraf: docker_container.absent: From 63cea88c1dbabf0daed8f9f0c8a2a14adb3fd9be Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 12:43:06 -0400 Subject: [PATCH 35/68] enable/disable influxdb in ui --- salt/influxdb/config.sls | 96 +++++++++++++++++ salt/influxdb/defaults.yaml | 3 +- salt/influxdb/disabled.sls | 32 ++++++ salt/influxdb/enabled.sls | 87 ++++++++++++++++ salt/influxdb/init.sls | 166 ++---------------------------- salt/influxdb/map.jinja | 9 +- salt/influxdb/soc_influxdb.yaml | 5 +- salt/influxdb/sostatus.sls | 21 ++++ salt/manager/tools/sbin/so-minion | 12 +++ salt/zeek/disabled.sls | 1 - salt/zeek/enabled.sls | 1 - 11 files changed, 269 insertions(+), 164 deletions(-) create mode 100644 salt/influxdb/config.sls create mode 100644 salt/influxdb/disabled.sls create mode 100644 salt/influxdb/enabled.sls create mode 100644 salt/influxdb/sostatus.sls diff --git a/salt/influxdb/config.sls b/salt/influxdb/config.sls new file mode 100644 index 000000000..54e20b713 --- /dev/null +++ b/salt/influxdb/config.sls @@ -0,0 +1,96 @@ +# 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 %} +{% from 'influxdb/map.jinja' import INFLUXMERGED %} + +include: + - salt.minion + - ssl + +# Influx DB +influxconfdir: + file.directory: + - name: /opt/so/conf/influxdb + - makedirs: True + +influxlogdir: + file.directory: + - name: /opt/so/log/influxdb + - dir_mode: 755 + - user: 939 + - group: 939 + - makedirs: True + +influxdbdir: + file.directory: + - name: /nsm/influxdb + - makedirs: True + +influxdb_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://influxdb/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#influxdb_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://influxdb/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +influxdbconf: + file.managed: + - name: /opt/so/conf/influxdb/config.yaml + - source: salt://influxdb/config.yaml.jinja + - user: 939 + - group: 939 + - template: jinja + - defaults: + INFLUXMERGED: {{ INFLUXMERGED }} + +influxdbbucketsconf: + file.managed: + - name: /opt/so/conf/influxdb/buckets.json + - source: salt://influxdb/buckets.json.jinja + - user: 939 + - group: 939 + - template: jinja + - defaults: + INFLUXMERGED: {{ INFLUXMERGED }} + +influxdb-templates: + file.recurse: + - name: /opt/so/conf/influxdb/templates + - source: salt://influxdb/templates + - user: 939 + - group: 939 + - template: jinja + - clean: True + - defaults: + INFLUXMERGED: {{ INFLUXMERGED }} + +influxdb_curl_config: + file.managed: + - name: /opt/so/conf/influxdb/curl.config + - source: salt://influxdb/curl.config.jinja + - mode: 600 + - template: jinja + - show_changes: False + - makedirs: True + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/influxdb/defaults.yaml b/salt/influxdb/defaults.yaml index 373f6a603..29088fea9 100644 --- a/salt/influxdb/defaults.yaml +++ b/salt/influxdb/defaults.yaml @@ -1,4 +1,5 @@ influxdb: + enabled: False config: assets-path: /ui bolt-path: /var/lib/influxdb2/influxd.bolt @@ -74,4 +75,4 @@ influxdb: shard_duration: 604800 downsample: so_long_term: - resolution: 5m \ No newline at end of file + resolution: 5m diff --git a/salt/influxdb/disabled.sls b/salt/influxdb/disabled.sls new file mode 100644 index 000000000..edf27d7b1 --- /dev/null +++ b/salt/influxdb/disabled.sls @@ -0,0 +1,32 @@ +# 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 %} + +include: + - influxdb.sostatus + +so-influxdb: + docker_container.absent: + - force: True + +so-influxdb_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-influxdb$ + +get_influxdb_size: + cron.absent: + - identifier: get_influxdb_size + - user: root + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/influxdb/enabled.sls b/salt/influxdb/enabled.sls new file mode 100644 index 000000000..209406932 --- /dev/null +++ b/salt/influxdb/enabled.sls @@ -0,0 +1,87 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% set PASSWORD = salt['pillar.get']('secrets:influx_pass') %} +{% set TOKEN = salt['pillar.get']('influxdb:token') %} + +include: + - influxdb.config + - influxdb.sostatus + +so-influxdb: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-influxdb:{{ GLOBALS.so_version }} + - hostname: influxdb + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-influxdb'].ip }} + - environment: + - INFLUXD_CONFIG_PATH=/conf + - INFLUXDB_HTTP_LOG_ENABLED=false + - DOCKER_INFLUXDB_INIT_MODE=setup + - DOCKER_INFLUXDB_INIT_USERNAME=so + - DOCKER_INFLUXDB_INIT_PASSWORD={{ PASSWORD }} + - DOCKER_INFLUXDB_INIT_ORG=Security Onion + - DOCKER_INFLUXDB_INIT_BUCKET=telegraf/so_short_term + - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN={{ TOKEN }} + - binds: + - /opt/so/log/influxdb/:/log:rw + - /opt/so/conf/influxdb/config.yaml:/conf/config.yaml:ro + - /nsm/influxdb:/var/lib/influxdb2:rw + - /etc/pki/influxdb.crt:/conf/influxdb.crt:ro + - /etc/pki/influxdb.key:/conf/influxdb.key:ro + - port_bindings: + {% for BINDING in DOCKER.containers['so-influxdb'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - watch: + - file: influxdbconf + - require: + - file: influxdbconf + - x509: influxdb_key + - x509: influxdb_crt + +delete_so-influxdb_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-influxdb$ + +influxdb-setup: + cmd.run: + - name: /usr/sbin/so-influxdb-manage setup &>> /opt/so/log/influxdb/setup.log + - require: + - file: influxdbbucketsconf + - file: influxdb_curl_config + - docker_container: so-influxdb + +metrics_link_file: + cmd.run: + - name: so-influxdb-manage dashboardpath "Security Onion Performance" > /opt/so/saltstack/local/salt/influxdb/metrics_link.txt + - require: + - docker_container: so-influxdb + +# Install cron job to determine size of influxdb for telegraf +get_influxdb_size: + cron.present: + - name: 'du -s -k /nsm/influxdb | cut -f1 > /opt/so/log/telegraf/influxdb_size.log 2>&1' + - identifier: get_influxdb_size + - user: root + - minute: '*/1' + - hour: '*' + - daymonth: '*' + - month: '*' + - dayweek: '*' + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/influxdb/init.sls b/salt/influxdb/init.sls index 7e10a6798..55f0b9650 100644 --- a/salt/influxdb/init.sls +++ b/salt/influxdb/init.sls @@ -1,163 +1,13 @@ -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'influxdb/map.jinja' import INFLUXMERGED %} +# 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 grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-eval', 'so-import'] %} -{% set PASSWORD = salt['pillar.get']('secrets:influx_pass') %} -{% set TOKEN = salt['pillar.get']('influxdb:token') %} +{% from 'influxdb/map.jinja' import INFLUXDBMERGED %} include: - - salt.minion - - ssl - -# Influx DB -influxconfdir: - file.directory: - - name: /opt/so/conf/influxdb - - makedirs: True - -influxlogdir: - file.directory: - - name: /opt/so/log/influxdb - - dir_mode: 755 - - user: 939 - - group: 939 - - makedirs: True - -influxdbdir: - file.directory: - - name: /nsm/influxdb - - makedirs: True - -influxdb_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://influxdb/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#influxdb_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://influxdb/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -influxdbconf: - file.managed: - - name: /opt/so/conf/influxdb/config.yaml - - source: salt://influxdb/config.yaml.jinja - - user: 939 - - group: 939 - - template: jinja - - defaults: - INFLUXMERGED: {{ INFLUXMERGED }} - -influxdbbucketsconf: - file.managed: - - name: /opt/so/conf/influxdb/buckets.json - - source: salt://influxdb/buckets.json.jinja - - user: 939 - - group: 939 - - template: jinja - - defaults: - INFLUXMERGED: {{ INFLUXMERGED }} - -influxdb-templates: - file.recurse: - - name: /opt/so/conf/influxdb/templates - - source: salt://influxdb/templates - - user: 939 - - group: 939 - - template: jinja - - clean: True - - defaults: - INFLUXMERGED: {{ INFLUXMERGED }} - -influxdb_curl_config: - file.managed: - - name: /opt/so/conf/influxdb/curl.config - - source: salt://influxdb/curl.config.jinja - - mode: 600 - - template: jinja - - show_changes: False - - makedirs: True - -so-influxdb: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-influxdb:{{ GLOBALS.so_version }} - - hostname: influxdb - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-influxdb'].ip }} - - environment: - - INFLUXD_CONFIG_PATH=/conf - - INFLUXDB_HTTP_LOG_ENABLED=false - - DOCKER_INFLUXDB_INIT_MODE=setup - - DOCKER_INFLUXDB_INIT_USERNAME=so - - DOCKER_INFLUXDB_INIT_PASSWORD={{ PASSWORD }} - - DOCKER_INFLUXDB_INIT_ORG=Security Onion - - DOCKER_INFLUXDB_INIT_BUCKET=telegraf/so_short_term - - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN={{ TOKEN }} - - binds: - - /opt/so/log/influxdb/:/log:rw - - /opt/so/conf/influxdb/config.yaml:/conf/config.yaml:ro - - /nsm/influxdb:/var/lib/influxdb2:rw - - /etc/pki/influxdb.crt:/conf/influxdb.crt:ro - - /etc/pki/influxdb.key:/conf/influxdb.key:ro - - port_bindings: - {% for BINDING in DOCKER.containers['so-influxdb'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - watch: - - file: influxdbconf - - require: - - file: influxdbconf - - x509: influxdb_key - - x509: influxdb_crt - -append_so-influxdb_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-influxdb - -influxdb-setup: - cmd.run: - - name: /usr/sbin/so-influxdb-manage setup &>> /opt/so/log/influxdb/setup.log - - require: - - file: influxdbbucketsconf - - file: influxdb_curl_config - - docker_container: so-influxdb - -metrics_link_file: - cmd.run: - - name: so-influxdb-manage dashboardpath "Security Onion Performance" > /opt/so/saltstack/local/salt/influxdb/metrics_link.txt - - require: - - docker_container: so-influxdb - -# Install cron job to determine size of influxdb for telegraf -get_influxdb_size: - cron.present: - - name: 'du -s -k /nsm/influxdb | cut -f1 > /opt/so/log/telegraf/influxdb_size.log 2>&1' - - identifier: get_influxdb_size - - user: root - - minute: '*/1' - - hour: '*' - - daymonth: '*' - - month: '*' - - dayweek: '*' - -{% endif %} - +{% if INFLUXDBMERGED.enabled %} + - influxdb.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - influxdb.disabled {% endif %} diff --git a/salt/influxdb/map.jinja b/salt/influxdb/map.jinja index ecbdd1306..beb810f05 100644 --- a/salt/influxdb/map.jinja +++ b/salt/influxdb/map.jinja @@ -1,2 +1,7 @@ -{%- import_yaml 'influxdb/defaults.yaml' as INFLUXDEFAULTS %} -{%- set INFLUXMERGED = salt['pillar.get']('influxdb', default=INFLUXDEFAULTS.influxdb, merge=true) %} +{# 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 'influxdb/defaults.yaml' as INFLUXDEFAULTS %} +{% set INFLUXMERGED = salt['pillar.get']('influxdb', default=INFLUXDEFAULTS.influxdb, merge=true) %} diff --git a/salt/influxdb/soc_influxdb.yaml b/salt/influxdb/soc_influxdb.yaml index 7f6ceb316..42566a0a8 100644 --- a/salt/influxdb/soc_influxdb.yaml +++ b/salt/influxdb/soc_influxdb.yaml @@ -1,4 +1,7 @@ influxdb: + enabled: + description: You can enable or disable InfluxDB. + helpLink: influxdb.html config: assets-path: description: Path to the InfluxDB user interface assets located inside the so-influxdb container. @@ -352,4 +355,4 @@ influxdb: resolution: description: Amount of time to turn into a single data point. global: True - helpLink: influxdb.html \ No newline at end of file + helpLink: influxdb.html diff --git a/salt/influxdb/sostatus.sls b/salt/influxdb/sostatus.sls new file mode 100644 index 000000000..dd55053c5 --- /dev/null +++ b/salt/influxdb/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-influxdb_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-influxdb + - unless: grep -q so-influxdb /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 9b7923403..e8e92bb71 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -281,6 +281,13 @@ function add_telegraf_to_minion() { " " >> $PILLARFILE } +function add_influxdb_to_minion() { + printf '%s\n'\ + "influxdb:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -332,6 +339,7 @@ function createEVAL() { add_kibana_to_minion add_curator_to_minion add_telegraf_to_minion + add_influxdb_to_minion } function createSTANDALONE() { @@ -345,6 +353,7 @@ function createSTANDALONE() { add_redis_to_minion add_curator_to_minion add_telegraf_to_minion + add_influxdb_to_minion } function createMANAGER() { @@ -356,6 +365,7 @@ function createMANAGER() { add_redis_to_minion add_curator_to_minion add_telegraf_to_minion + add_influxdb_to_minion } function createMANAGERSEARCH() { @@ -367,6 +377,7 @@ function createMANAGERSEARCH() { add_redis_to_minion add_curator_to_minion add_telegraf_to_minion + add_influxdb_to_minion } function createIMPORT() { @@ -374,6 +385,7 @@ function createIMPORT() { add_sensor_to_minion add_kibana_to_minion add_telegraf_to_minion + add_influxdb_to_minion } function createFLEET() { diff --git a/salt/zeek/disabled.sls b/salt/zeek/disabled.sls index 3cc3d88b7..5011331bf 100644 --- a/salt/zeek/disabled.sls +++ b/salt/zeek/disabled.sls @@ -20,7 +20,6 @@ so-zeek_so-status.disabled: zeekpacketlosscron: cron.absent: - - name: /usr/local/bin/packetloss.sh - identifier: zeekpacketlosscron - user: root diff --git a/salt/zeek/enabled.sls b/salt/zeek/enabled.sls index d2fc9fbc3..611402fbc 100644 --- a/salt/zeek/enabled.sls +++ b/salt/zeek/enabled.sls @@ -5,7 +5,6 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} - {% from 'vars/globals.map.jinja' import GLOBALS %} include: From b80dd996ccb3a52fa8768a9c62171fe4e47a4819 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 12:46:05 -0400 Subject: [PATCH 36/68] fix import --- salt/influxdb/init.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/influxdb/init.sls b/salt/influxdb/init.sls index 55f0b9650..33b4c3e37 100644 --- a/salt/influxdb/init.sls +++ b/salt/influxdb/init.sls @@ -3,10 +3,10 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% from 'influxdb/map.jinja' import INFLUXDBMERGED %} +{% from 'influxdb/map.jinja' import INFLUXMERGED %} include: -{% if INFLUXDBMERGED.enabled %} +{% if INFLUXMERGED.enabled %} - influxdb.enabled {% else %} - influxdb.disabled From 6ce9561ba75405ff764e296dee7e010adbabaa30 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 13:15:26 -0400 Subject: [PATCH 37/68] enabled/disable nginx via ui --- salt/manager/tools/sbin/so-minion | 15 +++ salt/nginx/config.sls | 110 ++++++++++++++++++++ salt/nginx/defaults.yaml | 5 +- salt/nginx/disabled.sls | 27 +++++ salt/nginx/enabled.sls | 69 +++++++++++++ salt/nginx/init.sls | 161 ++---------------------------- salt/nginx/map.jinja | 7 ++ salt/nginx/soc_nginx.yaml | 3 + salt/nginx/sostatus.sls | 21 ++++ 9 files changed, 264 insertions(+), 154 deletions(-) create mode 100644 salt/nginx/config.sls create mode 100644 salt/nginx/disabled.sls create mode 100644 salt/nginx/enabled.sls create mode 100644 salt/nginx/map.jinja create mode 100644 salt/nginx/sostatus.sls diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index e8e92bb71..97e183f2a 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -288,6 +288,13 @@ function add_influxdb_to_minion() { " " >> $PILLARFILE } +function add_nginx_to_minion() { + printf '%s\n'\ + "nginx:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -340,6 +347,7 @@ function createEVAL() { add_curator_to_minion add_telegraf_to_minion add_influxdb_to_minion + add_nginx_to_minion } function createSTANDALONE() { @@ -354,6 +362,7 @@ function createSTANDALONE() { add_curator_to_minion add_telegraf_to_minion add_influxdb_to_minion + add_nginx_to_minion } function createMANAGER() { @@ -366,6 +375,7 @@ function createMANAGER() { add_curator_to_minion add_telegraf_to_minion add_influxdb_to_minion + add_nginx_to_minion } function createMANAGERSEARCH() { @@ -378,6 +388,7 @@ function createMANAGERSEARCH() { add_curator_to_minion add_telegraf_to_minion add_influxdb_to_minion + add_nginx_to_minion } function createIMPORT() { @@ -386,6 +397,7 @@ function createIMPORT() { add_kibana_to_minion add_telegraf_to_minion add_influxdb_to_minion + add_nginx_to_minion } function createFLEET() { @@ -410,18 +422,21 @@ function createHEAVYNODE() { add_redis_to_minion add_curator_to_minion add_telegraf_to_minion + add_nginx_to_minion } function createSENSOR() { add_sensor_to_minion add_strelka_strelka_to_minion add_telegraf_to_minion + add_nginx_to_minion } function createSEARCHNODE() { add_elasticsearch_to_minion add_logstash_to_minion add_telegraf_to_minion + add_nginx_to_minion updateMine apply_ES_state } diff --git a/salt/nginx/config.sls b/salt/nginx/config.sls new file mode 100644 index 000000000..814bef815 --- /dev/null +++ b/salt/nginx/config.sls @@ -0,0 +1,110 @@ +# 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 %} + +include: + - ssl + +# Drop the correct nginx config based on role +nginxconfdir: + file.directory: + - name: /opt/so/conf/nginx/html + - user: 939 + - group: 939 + - makedirs: True + +nginxhtml: + file.recurse: + - name: /opt/so/conf/nginx/html + - source: salt://nginx/html/ + - user: 939 + - group: 939 + +nginxconf: + file.managed: + - name: /opt/so/conf/nginx/nginx.conf + - user: 939 + - group: 939 + - template: jinja + - source: salt://nginx/etc/nginx.conf + - show_changes: False + +nginxlogdir: + file.directory: + - name: /opt/so/log/nginx/ + - user: 939 + - group: 939 + - makedirs: True + +nginxtmp: + file.directory: + - name: /opt/so/tmp/nginx/tmp + - user: 939 + - group: 939 + - makedirs: True + +navigatorconfig: + file.managed: + - name: /opt/so/conf/navigator/navigator_config.json + - source: salt://nginx/files/navigator_config.json + - user: 939 + - group: 939 + - makedirs: True + - template: jinja + +navigatordefaultlayer: + file.managed: + - name: /opt/so/conf/navigator/nav_layer_playbook.json + - source: salt://nginx/files/nav_layer_playbook.json + - user: 939 + - group: 939 + - makedirs: True + - replace: False + - template: jinja + +navigatorpreattack: + file.managed: + - name: /opt/so/conf/navigator/pre-attack.json + - source: salt://nginx/files/pre-attack.json + - user: 939 + - group: 939 + - makedirs: True + - replace: False + +navigatorenterpriseattack: + file.managed: + - name: /opt/so/conf/navigator/enterprise-attack.json + - source: salt://nginx/files/enterprise-attack.json + - user: 939 + - group: 939 + - makedirs: True + - replace: False + +nginx_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://nginx/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#nginx_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://nginx/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/nginx/defaults.yaml b/salt/nginx/defaults.yaml index cf051274b..66ba64d2d 100644 --- a/salt/nginx/defaults.yaml +++ b/salt/nginx/defaults.yaml @@ -1,3 +1,4 @@ nginx: - config: - replace_cert: False \ No newline at end of file + enabled: False + config: + replace_cert: False diff --git a/salt/nginx/disabled.sls b/salt/nginx/disabled.sls new file mode 100644 index 000000000..1e94a7a3b --- /dev/null +++ b/salt/nginx/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - nginx.sostatus + +so-nginx: + docker_container.absent: + - force: True + +so-nginx_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-nginx$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/nginx/enabled.sls b/salt/nginx/enabled.sls new file mode 100644 index 000000000..592388cf6 --- /dev/null +++ b/salt/nginx/enabled.sls @@ -0,0 +1,69 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} + +include: + - nginx.config + - nginx.sostatus + +so-nginx: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-nginx:{{ GLOBALS.so_version }} + - hostname: so-nginx + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-nginx'].ip }} + - extra_hosts: + - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} + - binds: + - /opt/so/conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - /opt/so/log/nginx/:/var/log/nginx:rw + - /opt/so/tmp/nginx/:/var/lib/nginx:rw + - /opt/so/tmp/nginx/:/run:rw + - /opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/:/opt/socore/html/packages + - /nsm/elastic-fleet/artifacts/:/opt/socore/html/artifacts + {% if grains.role in ['so-manager', 'so-managersearch', 'so-eval', 'so-standalone', 'so-import'] %} + - /etc/pki/managerssl.crt:/etc/pki/nginx/server.crt:ro + - /etc/pki/managerssl.key:/etc/pki/nginx/server.key:ro + # ATT&CK Navigator binds + - /opt/so/conf/navigator/navigator_config.json:/opt/socore/html/navigator/assets/config.json:ro + - /opt/so/conf/navigator/nav_layer_playbook.json:/opt/socore/html/navigator/assets/playbook.json:ro + - /opt/so/conf/navigator/enterprise-attack.json:/opt/socore/html/navigator/assets/enterprise-attack.json:ro + - /opt/so/conf/navigator/pre-attack.json:/opt/socore/html/navigator/assets/pre-attack.json:ro + - /nsm/repo:/opt/socore/html/repo:ro + {% endif %} + - cap_add: NET_BIND_SERVICE + - port_bindings: + {% for BINDING in DOCKER.containers['so-nginx'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - watch: + - file: nginxconf + - file: nginxconfdir + - require: + - file: nginxconf + {% if grains.role in ['so-manager', 'so-managersearch', 'so-eval', 'so-standalone', 'so-import'] %} + - x509: managerssl_key + - x509: managerssl_crt + - file: navigatorconfig + - file: navigatordefaultlayer + {% endif %} + +delete_so-nginx_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-nginx$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/nginx/init.sls b/salt/nginx/init.sls index c66af0837..9869aa5d7 100644 --- a/salt/nginx/init.sls +++ b/salt/nginx/init.sls @@ -1,156 +1,13 @@ -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} +# 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 'nginx/map.jinja' import NGINXMERGED %} include: - - ssl - -# Drop the correct nginx config based on role -nginxconfdir: - file.directory: - - name: /opt/so/conf/nginx/html - - user: 939 - - group: 939 - - makedirs: True - -nginxhtml: - file.recurse: - - name: /opt/so/conf/nginx/html - - source: salt://nginx/html/ - - user: 939 - - group: 939 - -nginxconf: - file.managed: - - name: /opt/so/conf/nginx/nginx.conf - - user: 939 - - group: 939 - - template: jinja - - source: salt://nginx/etc/nginx.conf - - show_changes: False - -nginxlogdir: - file.directory: - - name: /opt/so/log/nginx/ - - user: 939 - - group: 939 - - makedirs: True - -nginxtmp: - file.directory: - - name: /opt/so/tmp/nginx/tmp - - user: 939 - - group: 939 - - makedirs: True - -navigatorconfig: - file.managed: - - name: /opt/so/conf/navigator/navigator_config.json - - source: salt://nginx/files/navigator_config.json - - user: 939 - - group: 939 - - makedirs: True - - template: jinja - -navigatordefaultlayer: - file.managed: - - name: /opt/so/conf/navigator/nav_layer_playbook.json - - source: salt://nginx/files/nav_layer_playbook.json - - user: 939 - - group: 939 - - makedirs: True - - replace: False - - template: jinja - -navigatorpreattack: - file.managed: - - name: /opt/so/conf/navigator/pre-attack.json - - source: salt://nginx/files/pre-attack.json - - user: 939 - - group: 939 - - makedirs: True - - replace: False - -navigatorenterpriseattack: - file.managed: - - name: /opt/so/conf/navigator/enterprise-attack.json - - source: salt://nginx/files/enterprise-attack.json - - user: 939 - - group: 939 - - makedirs: True - - replace: False - -nginx_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://nginx/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#nginx_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://nginx/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -so-nginx: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-nginx:{{ GLOBALS.so_version }} - - hostname: so-nginx - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-nginx'].ip }} - - extra_hosts: - - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - - binds: - - /opt/so/conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - - /opt/so/log/nginx/:/var/log/nginx:rw - - /opt/so/tmp/nginx/:/var/lib/nginx:rw - - /opt/so/tmp/nginx/:/run:rw - - /opt/so/saltstack/local/salt/elasticfleet/files/so_agent-installers/:/opt/socore/html/packages - - /nsm/elastic-fleet/artifacts/:/opt/socore/html/artifacts - {% if grains.role in ['so-manager', 'so-managersearch', 'so-eval', 'so-standalone', 'so-import'] %} - - /etc/pki/managerssl.crt:/etc/pki/nginx/server.crt:ro - - /etc/pki/managerssl.key:/etc/pki/nginx/server.key:ro - # ATT&CK Navigator binds - - /opt/so/conf/navigator/navigator_config.json:/opt/socore/html/navigator/assets/config.json:ro - - /opt/so/conf/navigator/nav_layer_playbook.json:/opt/socore/html/navigator/assets/playbook.json:ro - - /opt/so/conf/navigator/enterprise-attack.json:/opt/socore/html/navigator/assets/enterprise-attack.json:ro - - /opt/so/conf/navigator/pre-attack.json:/opt/socore/html/navigator/assets/pre-attack.json:ro - - /nsm/repo:/opt/socore/html/repo:ro - - {% endif %} - - cap_add: NET_BIND_SERVICE - - port_bindings: - {% for BINDING in DOCKER.containers['so-nginx'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - watch: - - file: nginxconf - - file: nginxconfdir - - require: - - file: nginxconf - {% if grains.role in ['so-manager', 'so-managersearch', 'so-eval', 'so-standalone', 'so-import'] %} - - x509: managerssl_key - - x509: managerssl_crt - - file: navigatorconfig - - file: navigatordefaultlayer - {% endif %} - -append_so-nginx_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-nginx - +{% if NGINXMERGED.enabled %} + - nginx.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - nginx.disabled {% endif %} diff --git a/salt/nginx/map.jinja b/salt/nginx/map.jinja new file mode 100644 index 000000000..cf2812c5e --- /dev/null +++ b/salt/nginx/map.jinja @@ -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 'nginx/defaults.yaml' as NGINXDEFAULTS %} +{% set NGINXMERGED = salt['pillar.get']('nginx', NGINXDEFAULTS.nginx, merge=True) %} diff --git a/salt/nginx/soc_nginx.yaml b/salt/nginx/soc_nginx.yaml index b78550c2b..4a3642f93 100644 --- a/salt/nginx/soc_nginx.yaml +++ b/salt/nginx/soc_nginx.yaml @@ -1,4 +1,7 @@ nginx: + enabled: + description: You can enable or disable Nginx. + helpLink: nginx.html config: replace_cert: description: Enable this if you would like to replace the Security Onion Certificate with your own. diff --git a/salt/nginx/sostatus.sls b/salt/nginx/sostatus.sls new file mode 100644 index 000000000..bea5757fa --- /dev/null +++ b/salt/nginx/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-nginx_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-nginx + - unless: grep -q so-nginx /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From 03e7636a18587cb4b571a74513915b0bc5304779 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 13:19:16 -0400 Subject: [PATCH 38/68] include nginx.config in soctopus --- salt/soctopus/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/soctopus/init.sls b/salt/soctopus/init.sls index 6470d1163..467617a54 100644 --- a/salt/soctopus/init.sls +++ b/salt/soctopus/init.sls @@ -4,7 +4,7 @@ {% from 'vars/globals.map.jinja' import GLOBALS %} include: - - nginx + - nginx.config soctopusdir: file.directory: From a3b97b40ba6994d138ced415e9bf99367f4014de Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 13:57:08 -0400 Subject: [PATCH 39/68] enabled/disable soctopus in ui --- salt/manager/tools/sbin/so-minion | 11 +++ salt/nginx/soc_nginx.yaml | 1 + salt/soctopus/config.sls | 88 +++++++++++++++++++++ salt/soctopus/defaults.yaml | 2 + salt/soctopus/disabled.sls | 27 +++++++ salt/soctopus/enabled.sls | 54 +++++++++++++ salt/soctopus/init.sls | 122 +++--------------------------- salt/soctopus/map.jinja | 7 ++ salt/soctopus/soc_soctopus.yaml | 5 +- salt/soctopus/sostatus.sls | 21 +++++ 10 files changed, 224 insertions(+), 114 deletions(-) create mode 100644 salt/soctopus/config.sls create mode 100644 salt/soctopus/defaults.yaml create mode 100644 salt/soctopus/disabled.sls create mode 100644 salt/soctopus/enabled.sls create mode 100644 salt/soctopus/map.jinja create mode 100644 salt/soctopus/sostatus.sls diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 97e183f2a..3d5bd7352 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -295,6 +295,13 @@ function add_nginx_to_minion() { " " >> $PILLARFILE } +function add_soctopus_to_minion() { + printf '%s\n'\ + "soctopus:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -348,6 +355,7 @@ function createEVAL() { add_telegraf_to_minion add_influxdb_to_minion add_nginx_to_minion + add_soctopus_to_minion } function createSTANDALONE() { @@ -363,6 +371,7 @@ function createSTANDALONE() { add_telegraf_to_minion add_influxdb_to_minion add_nginx_to_minion + add_soctopus_to_minion } function createMANAGER() { @@ -376,6 +385,7 @@ function createMANAGER() { add_telegraf_to_minion add_influxdb_to_minion add_nginx_to_minion + add_soctopus_to_minion } function createMANAGERSEARCH() { @@ -389,6 +399,7 @@ function createMANAGERSEARCH() { add_telegraf_to_minion add_influxdb_to_minion add_nginx_to_minion + add_soctopus_to_minion } function createIMPORT() { diff --git a/salt/nginx/soc_nginx.yaml b/salt/nginx/soc_nginx.yaml index 4a3642f93..66110a62f 100644 --- a/salt/nginx/soc_nginx.yaml +++ b/salt/nginx/soc_nginx.yaml @@ -1,6 +1,7 @@ nginx: enabled: description: You can enable or disable Nginx. + advanced: True helpLink: nginx.html config: replace_cert: diff --git a/salt/soctopus/config.sls b/salt/soctopus/config.sls new file mode 100644 index 000000000..35b55d296 --- /dev/null +++ b/salt/soctopus/config.sls @@ -0,0 +1,88 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - nginx.config + +soctopusdir: + file.directory: + - name: /opt/so/conf/soctopus/sigma-import + - user: 939 + - group: 939 + - makedirs: True + +soctopus-sync: + file.recurse: + - name: /opt/so/conf/soctopus/templates + - source: salt://soctopus/files/templates + - user: 939 + - group: 939 + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} + +soctopusconf: + file.managed: + - name: /opt/so/conf/soctopus/SOCtopus.conf + - source: salt://soctopus/files/SOCtopus.conf + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + - show_changes: False + - defaults: + GLOBALS: {{ GLOBALS }} + +soctopuslogdir: + file.directory: + - name: /opt/so/log/soctopus + - user: 939 + - group: 939 + +playbookrulesdir: + file.directory: + - name: /opt/so/rules/elastalert/playbook + - user: 939 + - group: 939 + - makedirs: True + +playbookrulessync: + file.recurse: + - name: /opt/so/rules/elastalert/playbook + - source: salt://soctopus/files/templates + - user: 939 + - group: 939 + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} + +soctopus_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://soctopus/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#soctopus_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://soctopus/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/soctopus/defaults.yaml b/salt/soctopus/defaults.yaml new file mode 100644 index 000000000..cb7f286ae --- /dev/null +++ b/salt/soctopus/defaults.yaml @@ -0,0 +1,2 @@ +soctopus: + enabled: False diff --git a/salt/soctopus/disabled.sls b/salt/soctopus/disabled.sls new file mode 100644 index 000000000..9293a9d71 --- /dev/null +++ b/salt/soctopus/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - soctopus.sostatus + +so-soctopus: + docker_container.absent: + - force: True + +so-soctopus_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-soctopus$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/soctopus/enabled.sls b/salt/soctopus/enabled.sls new file mode 100644 index 000000000..9c2ee4de7 --- /dev/null +++ b/salt/soctopus/enabled.sls @@ -0,0 +1,54 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} + +include: + - soctopus.config + - soctopus.sostatus + +so-soctopus: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-soctopus:{{ GLOBALS.so_version }} + - hostname: soctopus + - name: so-soctopus + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-soctopus'].ip }} + - binds: + - /opt/so/conf/soctopus/SOCtopus.conf:/SOCtopus/SOCtopus.conf:ro + - /opt/so/log/soctopus/:/var/log/SOCtopus/:rw + - /opt/so/rules/elastalert/playbook:/etc/playbook-rules:rw + - /opt/so/conf/navigator/nav_layer_playbook.json:/etc/playbook/nav_layer_playbook.json:rw + - /opt/so/conf/soctopus/sigma-import/:/SOCtopus/sigma-import/:rw + {% if GLOBALS.airgap %} + - /nsm/repo/rules/sigma:/soctopus/sigma + {% endif %} + - port_bindings: + {% for BINDING in DOCKER.containers['so-soctopus'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - extra_hosts: + - {{GLOBALS.url_base}}:{{GLOBALS.manager_ip}} + - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} + - require: + - file: soctopusconf + - file: navigatordefaultlayer + +delete_so-soctopus_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-soctopus$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/soctopus/init.sls b/salt/soctopus/init.sls index 467617a54..c9359a68c 100644 --- a/salt/soctopus/init.sls +++ b/salt/soctopus/init.sls @@ -1,117 +1,13 @@ -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} +# 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 'soctopus/map.jinja' import SOCTOPUSMERGED %} include: - - nginx.config - -soctopusdir: - file.directory: - - name: /opt/so/conf/soctopus/sigma-import - - user: 939 - - group: 939 - - makedirs: True - -soctopus-sync: - file.recurse: - - name: /opt/so/conf/soctopus/templates - - source: salt://soctopus/files/templates - - user: 939 - - group: 939 - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} - -soctopusconf: - file.managed: - - name: /opt/so/conf/soctopus/SOCtopus.conf - - source: salt://soctopus/files/SOCtopus.conf - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - - show_changes: False - - defaults: - GLOBALS: {{ GLOBALS }} - -soctopuslogdir: - file.directory: - - name: /opt/so/log/soctopus - - user: 939 - - group: 939 - -playbookrulesdir: - file.directory: - - name: /opt/so/rules/elastalert/playbook - - user: 939 - - group: 939 - - makedirs: True - -playbookrulessync: - file.recurse: - - name: /opt/so/rules/elastalert/playbook - - source: salt://soctopus/files/templates - - user: 939 - - group: 939 - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} - -soctopus_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://soctopus/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#soctopus_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://soctopus/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -so-soctopus: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-soctopus:{{ GLOBALS.so_version }} - - hostname: soctopus - - name: so-soctopus - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-soctopus'].ip }} - - binds: - - /opt/so/conf/soctopus/SOCtopus.conf:/SOCtopus/SOCtopus.conf:ro - - /opt/so/log/soctopus/:/var/log/SOCtopus/:rw - - /opt/so/rules/elastalert/playbook:/etc/playbook-rules:rw - - /opt/so/conf/navigator/nav_layer_playbook.json:/etc/playbook/nav_layer_playbook.json:rw - - /opt/so/conf/soctopus/sigma-import/:/SOCtopus/sigma-import/:rw - {% if GLOBALS.airgap %} - - /nsm/repo/rules/sigma:/soctopus/sigma - {% endif %} - - port_bindings: - {% for BINDING in DOCKER.containers['so-soctopus'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - extra_hosts: - - {{GLOBALS.url_base}}:{{GLOBALS.manager_ip}} - - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - - require: - - file: soctopusconf - - file: navigatordefaultlayer - -append_so-soctopus_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-soctopus - +{% if SOCTOPUSMERGED.enabled %} + - soctopus.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - soctopus.disabled {% endif %} diff --git a/salt/soctopus/map.jinja b/salt/soctopus/map.jinja new file mode 100644 index 000000000..07df21dbb --- /dev/null +++ b/salt/soctopus/map.jinja @@ -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 'soctopus/defaults.yaml' as SOCTOPUSDEFAULTS %} +{% set SOCTOPUSMERGED = salt['pillar.get']('soctopus', SOCTOPUSDEFAULTS.soctopus, merge=True) %} diff --git a/salt/soctopus/soc_soctopus.yaml b/salt/soctopus/soc_soctopus.yaml index 033405345..51a3a5c52 100644 --- a/salt/soctopus/soc_soctopus.yaml +++ b/salt/soctopus/soc_soctopus.yaml @@ -1,7 +1,10 @@ soctopus: + enabled: + description: You can enable or disable SOCtopus. + helpLink: soctopus.html playbook: rulesets: description: List of playbook rulesets. advanced: True helplink: soctopus.html - global: True \ No newline at end of file + global: True diff --git a/salt/soctopus/sostatus.sls b/salt/soctopus/sostatus.sls new file mode 100644 index 000000000..8a888235e --- /dev/null +++ b/salt/soctopus/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-soctopus_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-soctopus + - unless: grep -q so-soctopus /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From 8e18986671e0467682271fcaedb857ed8faf1ad2 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 15:33:16 -0400 Subject: [PATCH 40/68] enabled/disable soc in ui --- salt/manager/tools/sbin/so-minion | 16 +- salt/soc/config.sls | 115 + salt/soc/defaults.map.jinja | 21 +- salt/soc/defaults.yaml | 3490 +++++++++++++++-------------- salt/soc/disabled.sls | 31 + salt/soc/enabled.sls | 68 + salt/soc/files/soc/soc.json.jinja | 2 +- salt/soc/init.sls | 163 +- salt/soc/merged.map.jinja | 43 +- salt/soc/soc_soc.yaml | 428 ++-- salt/soc/sostatus.sls | 21 + 11 files changed, 2256 insertions(+), 2142 deletions(-) create mode 100644 salt/soc/config.sls create mode 100644 salt/soc/disabled.sls create mode 100644 salt/soc/enabled.sls create mode 100644 salt/soc/sostatus.sls diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 3d5bd7352..4e5f97678 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -302,6 +302,13 @@ function add_soctopus_to_minion() { " " >> $PILLARFILE } +function add_soc_to_minion() { + printf '%s\n'\ + "soc:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -356,6 +363,7 @@ function createEVAL() { add_influxdb_to_minion add_nginx_to_minion add_soctopus_to_minion + add_soc_to_minion } function createSTANDALONE() { @@ -372,6 +380,7 @@ function createSTANDALONE() { add_influxdb_to_minion add_nginx_to_minion add_soctopus_to_minion + add_soc_to_minion } function createMANAGER() { @@ -386,6 +395,7 @@ function createMANAGER() { add_influxdb_to_minion add_nginx_to_minion add_soctopus_to_minion + add_soc_to_minion } function createMANAGERSEARCH() { @@ -400,6 +410,7 @@ function createMANAGERSEARCH() { add_influxdb_to_minion add_nginx_to_minion add_soctopus_to_minion + add_soc_to_minion } function createIMPORT() { @@ -409,6 +420,7 @@ function createIMPORT() { add_telegraf_to_minion add_influxdb_to_minion add_nginx_to_minion + add_soc_to_minion } function createFLEET() { @@ -418,6 +430,7 @@ function createFLEET() { update_fleet_host_urls update_logstash_outputs add_telegraf_to_minion + add_nginx_to_minion } function createIDH() { @@ -433,21 +446,18 @@ function createHEAVYNODE() { add_redis_to_minion add_curator_to_minion add_telegraf_to_minion - add_nginx_to_minion } function createSENSOR() { add_sensor_to_minion add_strelka_strelka_to_minion add_telegraf_to_minion - add_nginx_to_minion } function createSEARCHNODE() { add_elasticsearch_to_minion add_logstash_to_minion add_telegraf_to_minion - add_nginx_to_minion updateMine apply_ES_state } diff --git a/salt/soc/config.sls b/salt/soc/config.sls new file mode 100644 index 000000000..399ff72cd --- /dev/null +++ b/salt/soc/config.sls @@ -0,0 +1,115 @@ +# 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 %} + +include: + - manager.sync_es_users + +socdir: + file.directory: + - name: /opt/so/conf/soc + - user: 939 + - group: 939 + - makedirs: True + +socdatadir: + file.directory: + - name: /nsm/soc/jobs + - user: 939 + - group: 939 + - makedirs: True + +soclogdir: + file.directory: + - name: /opt/so/log/soc + - user: 939 + - group: 939 + - makedirs: True + +socsaltdir: + file.directory: + - name: /opt/so/conf/soc/salt + - user: 939 + - group: 939 + - makedirs: True + +socconfig: + file.managed: + - name: /opt/so/conf/soc/soc.json + - source: salt://soc/files/soc/soc.json.jinja + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + - show_changes: False + +socmotd: + file.managed: + - name: /opt/so/conf/soc/motd.md + - source: salt://soc/files/soc/motd.md + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + +socbanner: + file.managed: + - name: /opt/so/conf/soc/banner.md + - source: salt://soc/files/soc/banner.md + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + +soc_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://soc/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#soc_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://soc/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +soccustom: + file.managed: + - name: /opt/so/conf/soc/custom.js + - source: salt://soc/files/soc/custom.js + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + +soccustomroles: + file.managed: + - name: /opt/so/conf/soc/custom_roles + - source: salt://soc/files/soc/custom_roles + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + +socusersroles: + file.exists: + - name: /opt/so/conf/soc/soc_users_roles + - require: + - sls: manager.sync_es_users + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/soc/defaults.map.jinja b/salt/soc/defaults.map.jinja index 85db938cc..9b9606cf2 100644 --- a/salt/soc/defaults.map.jinja +++ b/salt/soc/defaults.map.jinja @@ -1,3 +1,8 @@ +{# 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 'soc/defaults.yaml' as SOCDEFAULTS %} {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'docker/docker.map.jinja' import DOCKER -%} @@ -5,28 +10,28 @@ {% import_text 'influxdb/metrics_link.txt' as METRICS_LINK %} {% for module, application_url in GLOBALS.application_urls.items() %} -{% do SOCDEFAULTS.soc.server.modules[module].update({'hostUrl': application_url}) %} +{% do SOCDEFAULTS.soc.config.server.modules[module].update({'hostUrl': application_url}) %} {% endfor %} {# add nodes from the logstash:nodes pillar to soc.server.modules.elastic.remoteHostUrls #} {% for node_type, minions in salt['pillar.get']('logstash:nodes', {}).items() %} {% for m in minions.keys() %} -{% do SOCDEFAULTS.soc.server.modules.elastic.remoteHostUrls.append(m) %} +{% do SOCDEFAULTS.soc.config.server.modules.elastic.remoteHostUrls.append(m) %} {% endfor %} {% endfor %} -{% do SOCDEFAULTS.soc.server.modules.elastic.update({'username': GLOBALS.elasticsearch.auth.users.so_elastic_user.user, 'password': GLOBALS.elasticsearch.auth.users.so_elastic_user.pass}) %} +{% do SOCDEFAULTS.soc.config.server.modules.elastic.update({'username': GLOBALS.elasticsearch.auth.users.so_elastic_user.user, 'password': GLOBALS.elasticsearch.auth.users.so_elastic_user.pass}) %} -{% do SOCDEFAULTS.soc.server.modules.influxdb.update({'hostUrl': 'https://' ~ GLOBALS.influxdb_host ~ ':8086'}) %} -{% do SOCDEFAULTS.soc.server.modules.influxdb.update({'token': INFLUXDB_TOKEN}) %} -{% for tool in SOCDEFAULTS.soc.server.client.tools %} +{% do SOCDEFAULTS.soc.config.server.modules.influxdb.update({'hostUrl': 'https://' ~ GLOBALS.influxdb_host ~ ':8086'}) %} +{% do SOCDEFAULTS.soc.config.server.modules.influxdb.update({'token': INFLUXDB_TOKEN}) %} +{% for tool in SOCDEFAULTS.soc.config.server.client.tools %} {% if tool.name == "toolInfluxDb" and METRICS_LINK | length > 0 %} {% do tool.update({'link': METRICS_LINK}) %} {% endif %} {% endfor %} -{% do SOCDEFAULTS.soc.server.modules.statickeyauth.update({'anonymousCidr': DOCKER.sorange, 'apiKey': pillar.sensoroni.sensoronikey}) %} +{% do SOCDEFAULTS.soc.config.server.modules.statickeyauth.update({'anonymousCidr': DOCKER.sorange, 'apiKey': pillar.sensoroni.sensoronikey}) %} -{% do SOCDEFAULTS.soc.server.client.case.update({'analyzerNodeId': GLOBALS.hostname}) %} +{% do SOCDEFAULTS.soc.config.server.client.case.update({'analyzerNodeId': GLOBALS.hostname}) %} {% set SOCDEFAULTS = SOCDEFAULTS.soc %} diff --git a/salt/soc/defaults.yaml b/salt/soc/defaults.yaml index 8572ed7ce..adbadc57f 100644 --- a/salt/soc/defaults.yaml +++ b/salt/soc/defaults.yaml @@ -1,1746 +1,1748 @@ soc: - logFilename: /opt/sensoroni/logs/sensoroni-server.log - logLevel: info - actions: - - name: actionHunt - description: actionHuntHelp - icon: fa-crosshairs - target: - links: - - '/#/hunt?q="{value|escape}" | groupby event.module* event.dataset' - - name: actionCorrelate - description: actionCorrelateHelp - icon: fab fa-searchengin - target: '' - links: - - '/#/hunt?q=("{:log.id.fuid}" OR "{:log.id.uid}" OR "{:network.community_id}") | groupby event.module* event.dataset' - - '/#/hunt?q=("{:log.id.fuid}" OR "{:log.id.uid}") | groupby event.module* event.dataset' - - '/#/hunt?q=("{:log.id.fuid}" OR "{:network.community_id}") | groupby event.module* event.dataset' - - '/#/hunt?q=("{:log.id.uid}" OR "{:network.community_id}") | groupby event.module* event.dataset' - - '/#/hunt?q="{:log.id.fuid}" | groupby event.module* event.dataset' - - '/#/hunt?q="{:log.id.uid}" | groupby event.module* event.dataset' - - '/#/hunt?q="{:network.community_id}" | groupby event.module* event.dataset' - - name: actionPcap - description: actionPcapHelp - icon: fa-stream - target: '' - links: - - '/joblookup?esid={:soc_id}&time={:@timestamp}' - - '/joblookup?ncid={:network.community_id}&time={:@timestamp}' - categories: - - hunt - - alerts - - dashboards - - name: actionCyberChef - description: actionCyberChefHelp - icon: fas fa-bread-slice - target: _blank - links: - - '/cyberchef/#input={value|base64}' - - name: actionGoogle - description: actionGoogleHelp - icon: fab fa-google - target: _blank - links: - - 'https://www.google.com/search?q={value}' - - name: actionVirusTotal - description: actionVirusTotalHelp - icon: fa-external-link-alt - target: _blank - links: - - 'https://www.virustotal.com/gui/search/{value}' - eventFields: - default: - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - log.id.uid - - network.community_id - - event.dataset - ':kratos:audit': - - soc_timestamp - - http_request.headers.x-real-ip - - identity_id - - http_request.headers.user-agent - '::conn': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - network.transport - - network.protocol - - log.id.uid - - network.community_id - '::dce_rpc': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - dce_rpc.endpoint - - dce_rpc.named_pipe - - dce_rpc.operation - - log.id.uid - '::dhcp': - - soc_timestamp - - client.address - - server.address - - host.domain - - host.hostname - - dhcp.message_types - - log.id.uid - '::dnp3': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - dnp3.fc_reply - - log.id.uid - '::dnp3_control': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - dnp3.function_code - - dnp3.block_type - - log.id.uid - '::dnp3_objects': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - dnp3.function_code - - dnp3.object_type - - log.id.uid - '::dns': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - network.transport - - dns.query.name - - dns.query.type_name - - dns.response.code_name - - log.id.uid - - network.community_id - '::dpd': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - network.protocol - - observer.analyser - - error.reason - - log.id.uid - '::file': - - soc_timestamp - - source.ip - - destination.ip - - file.name - - file.mime_type - - file.source - - file.bytes.total - - log.id.fuid - - log.id.uid - '::ftp': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - ftp.user - - ftp.command - - ftp.argument - - ftp.reply_code - - file.size - - log.id.uid - '::http': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - http.method - - http.virtual_host - - http.status_code - - http.status_message - - http.request.body.length - - http.response.body.length - - log.id.uid - - network.community_id - '::intel': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - intel.indicator - - intel.indicator_type - - intel.seen_where - - log.id.uid - '::irc': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - irc.username - - irc.nickname - - irc.command.type - - irc.command.value - - irc.command.info - - log.id.uid - '::kerberos': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - kerberos.client - - kerberos.service - - kerberos.request_type - - log.id.uid - '::modbus': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - modbus.function - - log.id.uid - '::mysql': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - mysql.command - - mysql.argument - - mysql.success - - mysql.response - - log.id.uid - '::notice': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - notice.note - - notice.message - - log.id.fuid - - log.id.uid - - network.community_id - '::ntlm': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - ntlm.name - - ntlm.success - - ntlm.server.dns.name - - ntlm.server.nb.name - - ntlm.server.tree.name - - log.id.uid - '::pe': - - soc_timestamp - - file.is_64bit - - file.is_exe - - file.machine - - file.os - - file.subsystem - - log.id.fuid - '::radius': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - log.id.uid - - username - - radius.framed_address - - radius.reply_message - - radius.result - '::rdp': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - rdp.client_build - - client_name - - rdp.cookie - - rdp.encryption_level - - rdp.encryption_method - - rdp.keyboard_layout - - rdp.result - - rdp.security_protocol - - log.id.uid - '::rfb': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - rfb.authentication.method - - rfb.authentication.success - - rfb.share_flag - - rfb.desktop.name - - log.id.uid - '::signatures': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - note - - signature_id - - event_message - - sub_message - - signature_count - - host.count - - log.id.uid - '::sip': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - sip.method - - sip.uri - - sip.request.from - - sip.request.to - - sip.response.from - - sip.response.to - - sip.call_id - - sip.subject - - sip.user_agent - - sip.status_code - - log.id.uid - '::smb_files': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - log.id.fuid - - file.action - - file.path - - file.name - - file.size - - file.prev_name - - log.id.uid - '::smb_mapping': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - smb.path - - smb.service - - smb.share_type - - log.id.uid - '::smtp': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - smtp.from - - smtp.recipient_to - - smtp.subject - - smtp.useragent - - log.id.uid - - network.community_id - '::snmp': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - snmp.community - - snmp.version - - log.id.uid - '::socks': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - socks.name - - socks.request.host - - socks.request.port - - socks.status - - log.id.uid - '::software': - - soc_timestamp - - source.ip - - software.name - - software.type - '::ssh': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - ssh.version - - ssh.hassh_version - - ssh.direction - - ssh.client - - ssh.server - - log.id.uid - '::ssl': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - ssl.server_name - - ssl.certificate.subject - - ssl.validation_status - - ssl.version - - log.id.uid - ':zeek:syslog': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - syslog.facility - - network.protocol - - syslog.severity - - log.id.uid - '::tunnels': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - tunnel_type - - action - - log.id.uid - '::weird': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - weird.name - - log.id.uid - '::x509': - - soc_timestamp - - x509.certificate.subject - - x509.certificate.key.type - - x509.certificate.key.length - - x509.certificate.issuer - - log.id.fuid - '::firewall': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - network.transport - - network.direction - - interface.name - - rule.action - - rule.reason - - network.community_id - ':osquery:': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - source.hostname - - event.dataset - - process.executable - - user.name - ':ossec:': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - rule.name - - rule.level - - rule.category - - process.name - - user.name - - user.escalated - - location - ':strelka:file': - - soc_timestamp - - file.name - - file.size - - hash.md5 - - file.source - - file.mime_type - - log.id.fuid - ':suricata:': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - rule.name - - rule.category - - event.severity_label - - log.id.uid - - network.community_id - ':windows_eventlog:': - - soc_timestamp - - user.name - ':elasticsearch:': - - soc_timestamp - - agent.name - - message - - log.level - - metadata.version - - metadata.pipeline - - event.dataset - ':kibana:': - - soc_timestamp - - host.name - - message - - kibana.log.meta.req.headers.x-real-ip - - event.dataset - '::rootcheck': - - soc_timestamp - - host.name - - metadata.ip_address - - log.full - - event.dataset - - event.module - '::ossec': - - soc_timestamp - - host.name - - metadata.ip_address - - log.full - - event.dataset - - event.module - '::syscollector': - - soc_timestamp - - host.name - - metadata.ip_address - - wazuh.data.type - - log.full - - event.dataset - - event.module - ':syslog:syslog': - - soc_timestamp - - host.name - - metadata.ip_address - - real_message - - syslog.priority - - syslog.application - ':aws:': - - soc_timestamp - - aws.cloudtrail.event_category - - aws.cloudtrail.event_type - - event.provider - - event.action - - event.outcome - - cloud.region - - user.name - - source.ip - - source.geo.region_iso_code - ':squid:': - - soc_timestamp - - url.original - - destination.ip - - destination.geo.country_iso_code - - user.name - - source.ip - ':windows.sysmon_operational:': - - soc_timestamp - - event.action - - process.executable - - user.name - - file.target - - dns.question.name - - winlog.event_data.TargetObject - '::network_connection': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - source.hostname - - event.dataset - - process.executable - - user.name - '::process_terminated': - - soc_timestamp - - process.executable - - process.pid - - winlog.computer_name - '::file_create': - - soc_timestamp - - file.target - - process.executable - - process.pid - - winlog.computer_name - '::registry_value_set': - - soc_timestamp - - winlog.event_data.TargetObject - - process.executable - - process.pid - - winlog.computer_name - '::process_creation': - - soc_timestamp - - process.command_line - - process.pid - - process.parent.executable - - process.working_directory - '::registry_create_delete': - - soc_timestamp - - winlog.event_data.TargetObject - - process.executable - - process.pid - - winlog.computer_name - '::dns_query': - - soc_timestamp - - dns.query.name - - dns.answers.name - - process.executable - - winlog.computer_name - '::file_create_stream_hash': - - soc_timestamp - - file.target - - hash.md5 - - hash.sha256 - - process.executable - - process.pid - - winlog.computer_name - '::bacnet': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - bacnet.bclv.function - - bacnet.result.code - - log.id.uid - '::bacnet_discovery': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - bacnet.vendor - - bacnet.pdu.service - - log.id.uid - '::bacnet_property': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - bacnet.property - - bacnet.pdu.service - - log.id.uid - '::bsap_ip_header': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - bsap.message.type - - bsap.number.messages - - log.id.uid - '::bsap_ip_rdb': - - soc_timestamp - - bsap.application.function - - bsap.application.sub.function - - bsap.vector.variables - - log.id.uid - '::bsap_serial_header': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - bsap.source.function - - bsap.destination.function - - bsap.message.type - - log.id.uid - '::bsap_serial_rdb': - - soc_timestamp - - bsap.rdb.function - - bsap.vector.variables - - log.id.uid - '::cip': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - cip.service - - cip.status_code - - log.id.uid - - event.dataset - '::cip_identity': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - cip.device.type.name - - cip.vendor.name - - log.id.uid - '::cip_io': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - cip.connection.id - - cip.io.data - - log.id.uid - '::cotp': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - cotp.pdu.name - - log.id.uid - '::ecat_arp_info': - - soc_timestamp - - source.ip - - destination.ip - - source.mac - - destination.mac - - ecat.arp.type - '::ecat_aoe_info': - - soc_timestamp - - source.mac - - source.port - - destination.mac - - destination.port - - ecat.command - '::ecat_coe_info': - - soc_timestamp - - ecat.message.number - - ecat.message.type - - ecat.request.response.type - - ecat.index - - ecat.sub.index - '::ecat_dev_info': - - soc_timestamp - - ecat.device.type - - ecat.features - - ecat.ram.size - - ecat.revision - - ecat.slave.address - '::ecat_log_address': - - soc_timestamp - - source.mac - - destination.mac - - ecat.command - '::ecat_registers': - - soc_timestamp - - source.mac - - destination.mac - - ecat.command - - ecat.register.type - '::enip': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - enip.command - - enip.status_code - - log.id.uid - - event.dataset - '::modbus_detailed': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - modbus.function - - log.id.uid - '::opcua_binary': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.identifier_string - - opcua.message_type - - log.id.uid - '::opcua_binary_activate_session': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.link_id - - opcua.identifier_string - - opcua.user_name - - log.id.uid - '::opcua_binary_activate_session_diagnostic_info': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.activate_session_diag_info_link_id - - opcua.diag_info_link_id - - log.id.uid - '::opcua_binary_activate_session_locale_id': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.local_id - - opcua.locale_link_id - - log.id.uid - '::opcua_binary_browse': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.link_id - - opcua.service_type - - log.id.uid - '::opcua_binary_browse_description': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - log.id.uid - '::opcua_binary_browse_response_references': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.node_class - - opcua.display_name_text - - log.id.uid - '::opcua_binary_browse_result': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.response_link_id - - log.id.uid - '::opcua_binary_create_session': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.link_id - - log.id.uid - '::opcua_binary_create_session_endpoints': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.endpoint_link_id - - opcua.endpoint_url - - log.id.uid - '::opcua_binary_create_session_user_token': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.user_token_link_id - - log.id.uid - '::opcua_binary_create_subscription': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.link_id - - log.id.uid - '::opcua_binary_get_endpoints': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.endpoint_url - - opcua.link_id - - log.id.uid - '::opcua_binary_get_endpoints_description': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.endpoint_description_link_id - - opcua.endpoint_uri - - log.id.uid - '::opcua_binary_get_endpoints_user_token': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.user_token_link_id - - opcua.user_token_type - - log.id.uid - '::opcua_binary_read': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.link_id - - opcua.read_results_link_id - - log.id.uid - '::opcua_binary_status_code_detail': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - opcua.info_type_string - - opcua.source_string - - log.id.uid - '::profinet': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - profinet.index - - profinet.operation_type - - log.id.uid - '::profinet_dce_rpc': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - profinet.operation - - log.id.uid - '::s7comm': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - s7.ros.control.name - - s7.function.name - - log.id.uid - '::s7comm_plus': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - s7.opcode.name - - s7.version - - log.id.uid - '::s7comm_read_szl': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - s7.szl_id_name - - s7.return_code_name - - log.id.uid - '::s7comm_upload_download': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - s7.ros.control.name - - s7.function_code - - log.id.uid - '::tds': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - tds.command - - log.id.uid - - event.dataset - '::tds_rpc': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - tds.procedure_name - - log.id.uid - - event.dataset - '::tds_sql_batch': - - soc_timestamp - - source.ip - - source.port - - destination.ip - - destination.port - - tds.header_type - - log.id.uid - - event.dataset - server: - bindAddress: 0.0.0.0:9822 - baseUrl: / - maxPacketCount: 5000 - htmlDir: html - airgapEnabled: false - modules: - cases: soc - filedatastore: - jobDir: jobs - kratos: - hostUrl: - elastic: - hostUrl: - remoteHostUrls: [] - username: - password: - index: '*:so-*,*:endgame-*,*:logs-*' - cacheMs: 300000 - verifyCert: false + enabled: False + config: + logFilename: /opt/sensoroni/logs/sensoroni-server.log + logLevel: info + actions: + - name: actionHunt + description: actionHuntHelp + icon: fa-crosshairs + target: + links: + - '/#/hunt?q="{value|escape}" | groupby event.module* event.dataset' + - name: actionCorrelate + description: actionCorrelateHelp + icon: fab fa-searchengin + target: '' + links: + - '/#/hunt?q=("{:log.id.fuid}" OR "{:log.id.uid}" OR "{:network.community_id}") | groupby event.module* event.dataset' + - '/#/hunt?q=("{:log.id.fuid}" OR "{:log.id.uid}") | groupby event.module* event.dataset' + - '/#/hunt?q=("{:log.id.fuid}" OR "{:network.community_id}") | groupby event.module* event.dataset' + - '/#/hunt?q=("{:log.id.uid}" OR "{:network.community_id}") | groupby event.module* event.dataset' + - '/#/hunt?q="{:log.id.fuid}" | groupby event.module* event.dataset' + - '/#/hunt?q="{:log.id.uid}" | groupby event.module* event.dataset' + - '/#/hunt?q="{:network.community_id}" | groupby event.module* event.dataset' + - name: actionPcap + description: actionPcapHelp + icon: fa-stream + target: '' + links: + - '/joblookup?esid={:soc_id}&time={:@timestamp}' + - '/joblookup?ncid={:network.community_id}&time={:@timestamp}' + categories: + - hunt + - alerts + - dashboards + - name: actionCyberChef + description: actionCyberChefHelp + icon: fas fa-bread-slice + target: _blank + links: + - '/cyberchef/#input={value|base64}' + - name: actionGoogle + description: actionGoogleHelp + icon: fab fa-google + target: _blank + links: + - 'https://www.google.com/search?q={value}' + - name: actionVirusTotal + description: actionVirusTotalHelp + icon: fa-external-link-alt + target: _blank + links: + - 'https://www.virustotal.com/gui/search/{value}' + eventFields: + default: + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - log.id.uid + - network.community_id + - event.dataset + ':kratos:audit': + - soc_timestamp + - http_request.headers.x-real-ip + - identity_id + - http_request.headers.user-agent + '::conn': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - network.transport + - network.protocol + - log.id.uid + - network.community_id + '::dce_rpc': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - dce_rpc.endpoint + - dce_rpc.named_pipe + - dce_rpc.operation + - log.id.uid + '::dhcp': + - soc_timestamp + - client.address + - server.address + - host.domain + - host.hostname + - dhcp.message_types + - log.id.uid + '::dnp3': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - dnp3.fc_reply + - log.id.uid + '::dnp3_control': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - dnp3.function_code + - dnp3.block_type + - log.id.uid + '::dnp3_objects': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - dnp3.function_code + - dnp3.object_type + - log.id.uid + '::dns': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - network.transport + - dns.query.name + - dns.query.type_name + - dns.response.code_name + - log.id.uid + - network.community_id + '::dpd': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - network.protocol + - observer.analyser + - error.reason + - log.id.uid + '::file': + - soc_timestamp + - source.ip + - destination.ip + - file.name + - file.mime_type + - file.source + - file.bytes.total + - log.id.fuid + - log.id.uid + '::ftp': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - ftp.user + - ftp.command + - ftp.argument + - ftp.reply_code + - file.size + - log.id.uid + '::http': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - http.method + - http.virtual_host + - http.status_code + - http.status_message + - http.request.body.length + - http.response.body.length + - log.id.uid + - network.community_id + '::intel': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - intel.indicator + - intel.indicator_type + - intel.seen_where + - log.id.uid + '::irc': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - irc.username + - irc.nickname + - irc.command.type + - irc.command.value + - irc.command.info + - log.id.uid + '::kerberos': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - kerberos.client + - kerberos.service + - kerberos.request_type + - log.id.uid + '::modbus': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - modbus.function + - log.id.uid + '::mysql': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - mysql.command + - mysql.argument + - mysql.success + - mysql.response + - log.id.uid + '::notice': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - notice.note + - notice.message + - log.id.fuid + - log.id.uid + - network.community_id + '::ntlm': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - ntlm.name + - ntlm.success + - ntlm.server.dns.name + - ntlm.server.nb.name + - ntlm.server.tree.name + - log.id.uid + '::pe': + - soc_timestamp + - file.is_64bit + - file.is_exe + - file.machine + - file.os + - file.subsystem + - log.id.fuid + '::radius': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - log.id.uid + - username + - radius.framed_address + - radius.reply_message + - radius.result + '::rdp': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - rdp.client_build + - client_name + - rdp.cookie + - rdp.encryption_level + - rdp.encryption_method + - rdp.keyboard_layout + - rdp.result + - rdp.security_protocol + - log.id.uid + '::rfb': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - rfb.authentication.method + - rfb.authentication.success + - rfb.share_flag + - rfb.desktop.name + - log.id.uid + '::signatures': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - note + - signature_id + - event_message + - sub_message + - signature_count + - host.count + - log.id.uid + '::sip': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - sip.method + - sip.uri + - sip.request.from + - sip.request.to + - sip.response.from + - sip.response.to + - sip.call_id + - sip.subject + - sip.user_agent + - sip.status_code + - log.id.uid + '::smb_files': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - log.id.fuid + - file.action + - file.path + - file.name + - file.size + - file.prev_name + - log.id.uid + '::smb_mapping': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - smb.path + - smb.service + - smb.share_type + - log.id.uid + '::smtp': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - smtp.from + - smtp.recipient_to + - smtp.subject + - smtp.useragent + - log.id.uid + - network.community_id + '::snmp': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - snmp.community + - snmp.version + - log.id.uid + '::socks': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - socks.name + - socks.request.host + - socks.request.port + - socks.status + - log.id.uid + '::software': + - soc_timestamp + - source.ip + - software.name + - software.type + '::ssh': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - ssh.version + - ssh.hassh_version + - ssh.direction + - ssh.client + - ssh.server + - log.id.uid + '::ssl': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - ssl.server_name + - ssl.certificate.subject + - ssl.validation_status + - ssl.version + - log.id.uid + ':zeek:syslog': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - syslog.facility + - network.protocol + - syslog.severity + - log.id.uid + '::tunnels': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - tunnel_type + - action + - log.id.uid + '::weird': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - weird.name + - log.id.uid + '::x509': + - soc_timestamp + - x509.certificate.subject + - x509.certificate.key.type + - x509.certificate.key.length + - x509.certificate.issuer + - log.id.fuid + '::firewall': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - network.transport + - network.direction + - interface.name + - rule.action + - rule.reason + - network.community_id + ':osquery:': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - source.hostname + - event.dataset + - process.executable + - user.name + ':ossec:': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - rule.name + - rule.level + - rule.category + - process.name + - user.name + - user.escalated + - location + ':strelka:file': + - soc_timestamp + - file.name + - file.size + - hash.md5 + - file.source + - file.mime_type + - log.id.fuid + ':suricata:': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - rule.name + - rule.category + - event.severity_label + - log.id.uid + - network.community_id + ':windows_eventlog:': + - soc_timestamp + - user.name + ':elasticsearch:': + - soc_timestamp + - agent.name + - message + - log.level + - metadata.version + - metadata.pipeline + - event.dataset + ':kibana:': + - soc_timestamp + - host.name + - message + - kibana.log.meta.req.headers.x-real-ip + - event.dataset + '::rootcheck': + - soc_timestamp + - host.name + - metadata.ip_address + - log.full + - event.dataset + - event.module + '::ossec': + - soc_timestamp + - host.name + - metadata.ip_address + - log.full + - event.dataset + - event.module + '::syscollector': + - soc_timestamp + - host.name + - metadata.ip_address + - wazuh.data.type + - log.full + - event.dataset + - event.module + ':syslog:syslog': + - soc_timestamp + - host.name + - metadata.ip_address + - real_message + - syslog.priority + - syslog.application + ':aws:': + - soc_timestamp + - aws.cloudtrail.event_category + - aws.cloudtrail.event_type + - event.provider + - event.action + - event.outcome + - cloud.region + - user.name + - source.ip + - source.geo.region_iso_code + ':squid:': + - soc_timestamp + - url.original + - destination.ip + - destination.geo.country_iso_code + - user.name + - source.ip + ':windows.sysmon_operational:': + - soc_timestamp + - event.action + - process.executable + - user.name + - file.target + - dns.question.name + - winlog.event_data.TargetObject + '::network_connection': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - source.hostname + - event.dataset + - process.executable + - user.name + '::process_terminated': + - soc_timestamp + - process.executable + - process.pid + - winlog.computer_name + '::file_create': + - soc_timestamp + - file.target + - process.executable + - process.pid + - winlog.computer_name + '::registry_value_set': + - soc_timestamp + - winlog.event_data.TargetObject + - process.executable + - process.pid + - winlog.computer_name + '::process_creation': + - soc_timestamp + - process.command_line + - process.pid + - process.parent.executable + - process.working_directory + '::registry_create_delete': + - soc_timestamp + - winlog.event_data.TargetObject + - process.executable + - process.pid + - winlog.computer_name + '::dns_query': + - soc_timestamp + - dns.query.name + - dns.answers.name + - process.executable + - winlog.computer_name + '::file_create_stream_hash': + - soc_timestamp + - file.target + - hash.md5 + - hash.sha256 + - process.executable + - process.pid + - winlog.computer_name + '::bacnet': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - bacnet.bclv.function + - bacnet.result.code + - log.id.uid + '::bacnet_discovery': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - bacnet.vendor + - bacnet.pdu.service + - log.id.uid + '::bacnet_property': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - bacnet.property + - bacnet.pdu.service + - log.id.uid + '::bsap_ip_header': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - bsap.message.type + - bsap.number.messages + - log.id.uid + '::bsap_ip_rdb': + - soc_timestamp + - bsap.application.function + - bsap.application.sub.function + - bsap.vector.variables + - log.id.uid + '::bsap_serial_header': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - bsap.source.function + - bsap.destination.function + - bsap.message.type + - log.id.uid + '::bsap_serial_rdb': + - soc_timestamp + - bsap.rdb.function + - bsap.vector.variables + - log.id.uid + '::cip': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - cip.service + - cip.status_code + - log.id.uid + - event.dataset + '::cip_identity': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - cip.device.type.name + - cip.vendor.name + - log.id.uid + '::cip_io': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - cip.connection.id + - cip.io.data + - log.id.uid + '::cotp': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - cotp.pdu.name + - log.id.uid + '::ecat_arp_info': + - soc_timestamp + - source.ip + - destination.ip + - source.mac + - destination.mac + - ecat.arp.type + '::ecat_aoe_info': + - soc_timestamp + - source.mac + - source.port + - destination.mac + - destination.port + - ecat.command + '::ecat_coe_info': + - soc_timestamp + - ecat.message.number + - ecat.message.type + - ecat.request.response.type + - ecat.index + - ecat.sub.index + '::ecat_dev_info': + - soc_timestamp + - ecat.device.type + - ecat.features + - ecat.ram.size + - ecat.revision + - ecat.slave.address + '::ecat_log_address': + - soc_timestamp + - source.mac + - destination.mac + - ecat.command + '::ecat_registers': + - soc_timestamp + - source.mac + - destination.mac + - ecat.command + - ecat.register.type + '::enip': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - enip.command + - enip.status_code + - log.id.uid + - event.dataset + '::modbus_detailed': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - modbus.function + - log.id.uid + '::opcua_binary': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.identifier_string + - opcua.message_type + - log.id.uid + '::opcua_binary_activate_session': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.link_id + - opcua.identifier_string + - opcua.user_name + - log.id.uid + '::opcua_binary_activate_session_diagnostic_info': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.activate_session_diag_info_link_id + - opcua.diag_info_link_id + - log.id.uid + '::opcua_binary_activate_session_locale_id': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.local_id + - opcua.locale_link_id + - log.id.uid + '::opcua_binary_browse': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.link_id + - opcua.service_type + - log.id.uid + '::opcua_binary_browse_description': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - log.id.uid + '::opcua_binary_browse_response_references': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.node_class + - opcua.display_name_text + - log.id.uid + '::opcua_binary_browse_result': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.response_link_id + - log.id.uid + '::opcua_binary_create_session': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.link_id + - log.id.uid + '::opcua_binary_create_session_endpoints': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.endpoint_link_id + - opcua.endpoint_url + - log.id.uid + '::opcua_binary_create_session_user_token': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.user_token_link_id + - log.id.uid + '::opcua_binary_create_subscription': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.link_id + - log.id.uid + '::opcua_binary_get_endpoints': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.endpoint_url + - opcua.link_id + - log.id.uid + '::opcua_binary_get_endpoints_description': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.endpoint_description_link_id + - opcua.endpoint_uri + - log.id.uid + '::opcua_binary_get_endpoints_user_token': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.user_token_link_id + - opcua.user_token_type + - log.id.uid + '::opcua_binary_read': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.link_id + - opcua.read_results_link_id + - log.id.uid + '::opcua_binary_status_code_detail': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - opcua.info_type_string + - opcua.source_string + - log.id.uid + '::profinet': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - profinet.index + - profinet.operation_type + - log.id.uid + '::profinet_dce_rpc': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - profinet.operation + - log.id.uid + '::s7comm': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - s7.ros.control.name + - s7.function.name + - log.id.uid + '::s7comm_plus': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - s7.opcode.name + - s7.version + - log.id.uid + '::s7comm_read_szl': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - s7.szl_id_name + - s7.return_code_name + - log.id.uid + '::s7comm_upload_download': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - s7.ros.control.name + - s7.function_code + - log.id.uid + '::tds': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - tds.command + - log.id.uid + - event.dataset + '::tds_rpc': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - tds.procedure_name + - log.id.uid + - event.dataset + '::tds_sql_batch': + - soc_timestamp + - source.ip + - source.port + - destination.ip + - destination.port + - tds.header_type + - log.id.uid + - event.dataset + server: + bindAddress: 0.0.0.0:9822 + baseUrl: / + maxPacketCount: 5000 + htmlDir: html + airgapEnabled: false + modules: + cases: soc + filedatastore: + jobDir: jobs + kratos: + hostUrl: + elastic: + hostUrl: + remoteHostUrls: [] + username: + password: + index: '*:so-*,*:endgame-*,*:logs-*' + cacheMs: 300000 + verifyCert: false + casesEnabled: true + extractCommonObservables: + - source.ip + - destination.ip + timeoutMs: 300000 + timeShiftMs: 120000 + defaultDurationMs: 1800000 + esSearchOffsetMs: 1800000 + maxLogLength: 1024 + asyncThreshold: 10 + influxdb: + hostUrl: + token: + org: Security Onion + bucket: telegraf/so_short_term + verifyCert: false + salt: + saltPipe: /opt/sensoroni/salt/pipe + sostatus: + refreshIntervalMs: 30000 + offlineThresholdMs: 900000 + statickeyauth: + anonymousCidr: + apiKey: + staticrbac: + roleFiles: + - rbac/permissions + - rbac/roles + - rbac/custom_roles + userFiles: + - rbac/users_roles + client: + docsUrl: /docs/ + cheatsheetUrl: /docs/cheatsheet.pdf + releaseNotesUrl: /docs/release-notes.html + apiTimeoutMs: 300000 + webSocketTimeoutMs: 15000 + tipTimeoutMs: 6000 + cacheExpirationMs: 300000 casesEnabled: true - extractCommonObservables: - - source.ip - - destination.ip - timeoutMs: 300000 - timeShiftMs: 120000 - defaultDurationMs: 1800000 - esSearchOffsetMs: 1800000 - maxLogLength: 1024 - asyncThreshold: 10 - influxdb: - hostUrl: - token: - org: Security Onion - bucket: telegraf/so_short_term - verifyCert: false - salt: - saltPipe: /opt/sensoroni/salt/pipe - sostatus: - refreshIntervalMs: 30000 - offlineThresholdMs: 900000 - statickeyauth: - anonymousCidr: - apiKey: - staticrbac: - roleFiles: - - rbac/permissions - - rbac/roles - - rbac/custom_roles - userFiles: - - rbac/users_roles - client: - docsUrl: /docs/ - cheatsheetUrl: /docs/cheatsheet.pdf - releaseNotesUrl: /docs/release-notes.html - apiTimeoutMs: 300000 - webSocketTimeoutMs: 15000 - tipTimeoutMs: 6000 - cacheExpirationMs: 300000 - casesEnabled: true - inactiveTools: ['toolUnused'] - tools: - - name: toolKibana - description: toolKibanaHelp - icon: fa-external-link-alt - target: so-kibana - link: /kibana/ - - name: toolElasticFleet - description: toolElasticFleet - icon: fa-external-link-alt - target: so-elastic-fleet - link: /kibana/app/fleet/agents - - name: toolOsqueryManager - description: toolOsqueryManager - icon: fa-external-link-alt - target: so-osquery-manager - link: /kibana/app/osquery/live_queries - - name: toolInfluxDb - description: toolInfluxDbHelp - icon: fa-external-link-alt - target: so-influxdb - link: /influxdb - - name: toolCyberchef - description: toolCyberchefHelp - icon: fa-external-link-alt - target: so-cyberchef - link: /cyberchef/ - - name: toolPlaybook - description: toolPlaybookHelp - icon: fa-external-link-alt - target: so-playbook - link: /playbook/projects/detection-playbooks/issues/ - - name: toolNavigator - description: toolNavigatorHelp - icon: fa-external-link-alt - target: so-navigator - link: /navigator/ - hunt: - advanced: true - aggregationActionsEnabled: true - groupItemsPerPage: 10 - groupFetchLimit: 10 - eventItemsPerPage: 10 - eventFetchLimit: 100 - relativeTimeValue: 24 - relativeTimeUnit: 30 - mostRecentlyUsedLimit: 5 - ackEnabled: false - escalateEnabled: true - escalateRelatedEventsEnabled: true - queryBaseFilter: '' - queryToggleFilters: - - name: caseExcludeToggle - filter: 'NOT _index:"*:so-case*"' - enabled: true - queries: - - name: Default Query - description: Show all events grouped by the observer host - query: '* | groupby observer.name' - showSubtitle: true - - name: Log Type - description: Show all events grouped by module and dataset - query: '* | groupby event.module* event.dataset' - showSubtitle: true - - name: SOC - Auth - description: Users authenticated to SOC grouped by IP address and identity - query: 'event.module:kratos AND event.dataset:audit AND msg:authenticated | groupby http_request.headers.x-real-ip identity_id' - showSubtitle: true - - name: SOC - App - description: Logs generated by the Security Onion Console (SOC) server and modules - query: 'event.module: "soc" | groupby event.module* event.dataset* log.level* | groupby agent.name | groupby event.action* | groupby "http.request.method" | groupby "url.path"' - showSubtitle: true - - name: Elastalerts - description: '' - query: '_type:elastalert | groupby rule.name' - showSubtitle: true - - name: Alerts - description: Show all alerts grouped by alert source - query: 'event.dataset: alert | groupby event.module' - showSubtitle: true - - name: NIDS Alerts - description: Show all NIDS alerts grouped by alert - query: 'event.category: network AND event.dataset: alert | groupby rule.category rule.gid rule.uuid rule.name' - showSubtitle: true - - name: Osquery - Live Query - description: Show all Osquery Live Query results - query: 'event.dataset: osquery_manager.result | groupby action_data.id action_data.query | groupby host.hostname' - showSubtitle: true - - name: Sysmon Events - description: Show all Sysmon logs grouped by event type - query: 'event.dataset: windows.sysmon_operational | groupby event.action' - showSubtitle: true - - name: Sysmon Usernames - description: Show all Sysmon logs grouped by username - query: 'event.dataset: windows.sysmon_operational | groupby event.action, user.name.keyword' - showSubtitle: true - - name: Strelka - description: Show all Strelka logs grouped by file type - query: 'event.module:strelka | groupby file.mime_type' - showSubtitle: true - - name: Zeek Notice - description: Show notices from Zeek - query: 'event.dataset:notice | groupby notice.note notice.message' - showSubtitle: true - - name: Connections - description: Connections grouped by IP and Port - query: 'event.dataset:conn | groupby source.ip destination.ip network.protocol destination.port' - showSubtitle: true - - name: Connections - description: Connections grouped by Service - query: 'event.dataset:conn | groupby network.protocol destination.port' - showSubtitle: true - - name: Connections - description: Connections grouped by destination country - query: 'event.dataset:conn | groupby destination.geo.country_name' - showSubtitle: true - - name: Connections - description: Connections grouped by source country - query: 'event.dataset:conn | groupby source.geo.country_name' - showSubtitle: true - - name: DCE_RPC - description: DCE_RPC grouped by operation - query: 'event.dataset:dce_rpc | groupby dce_rpc.operation' - showSubtitle: true - - name: DHCP - description: DHCP leases - query: 'event.dataset:dhcp | groupby host.hostname client.address' - showSubtitle: true - - name: DHCP - description: DHCP grouped by message type - query: 'event.dataset:dhcp | groupby dhcp.message_types' - showSubtitle: true - - name: DNP3 - description: DNP3 grouped by reply - query: 'event.dataset:dnp3 | groupby dnp3.fc_reply' - showSubtitle: true - - name: DNS - description: DNS queries grouped by port - query: 'event.dataset:dns | groupby dns.query.name destination.port' - showSubtitle: true - - name: DNS - description: DNS queries grouped by type - query: 'event.dataset:dns | groupby dns.query.type_name destination.port' - showSubtitle: true - - name: DNS - description: DNS queries grouped by response code - query: 'event.dataset:dns | groupby dns.response.code_name destination.port' - showSubtitle: true - - name: DNS - description: DNS highest registered domain - query: 'event.dataset:dns | groupby dns.highest_registered_domain.keyword destination.port' - showSubtitle: true - - name: DNS - description: DNS grouped by parent domain - query: 'event.dataset:dns | groupby dns.parent_domain.keyword destination.port' - showSubtitle: true - - name: DPD - description: Dynamic Protocol Detection errors - query: 'event.dataset:dpd | groupby error.reason' - showSubtitle: true - - name: Files - description: Files grouped by mimetype - query: 'event.dataset:file | groupby file.mime_type source.ip' - showSubtitle: true - - name: Files - description: Files grouped by source - query: 'event.dataset:file | groupby file.source source.ip' - showSubtitle: true - - name: FTP - description: FTP grouped by command and argument - query: 'event.dataset:ftp | groupby ftp.command ftp.argument' - showSubtitle: true - - name: FTP - description: FTP grouped by username and argument - query: 'event.dataset:ftp | groupby ftp.user ftp.argument' - showSubtitle: true - - name: HTTP - description: HTTP grouped by destination port - query: 'event.dataset:http | groupby destination.port' - showSubtitle: true - - name: HTTP - description: HTTP grouped by status code and message - query: 'event.dataset:http | groupby http.status_code http.status_message' - showSubtitle: true - - name: HTTP - description: HTTP grouped by method and user agent - query: 'event.dataset:http | groupby http.method http.useragent' - showSubtitle: true - - name: HTTP - description: HTTP grouped by virtual host - query: 'event.dataset:http | groupby http.virtual_host' - showSubtitle: true - - name: HTTP - description: HTTP with exe downloads - query: 'event.dataset:http AND (file.resp_mime_types:dosexec OR file.resp_mime_types:executable) | groupby http.virtual_host' - showSubtitle: true - - name: Intel - description: Intel framework hits grouped by indicator - query: 'event.dataset:intel | groupby intel.indicator.keyword' - showSubtitle: true - - name: IRC - description: IRC grouped by command - query: 'event.dataset:irc | groupby irc.command.type' - showSubtitle: true - - name: KERBEROS - description: KERBEROS grouped by service - query: 'event.dataset:kerberos | groupby kerberos.service' - showSubtitle: true - - name: MODBUS - description: MODBUS grouped by function - query: 'event.dataset:modbus | groupby modbus.function' - showSubtitle: true - - name: MYSQL - description: MYSQL grouped by command - query: 'event.dataset:mysql | groupby mysql.command' - showSubtitle: true - - name: NOTICE - description: Zeek notice logs grouped by note and message - query: 'event.dataset:notice | groupby notice.note notice.message' - showSubtitle: true - - name: NTLM - description: NTLM grouped by computer name - query: 'event.dataset:ntlm | groupby ntlm.server.dns.name' - showSubtitle: true - - name: PE - description: PE files list - query: 'event.dataset:pe | groupby file.machine file.os file.subsystem' - showSubtitle: true - - name: RADIUS - description: RADIUS grouped by username - query: 'event.dataset:radius | groupby user.name.keyword' - showSubtitle: true - - name: RDP - description: RDP grouped by client name - query: 'event.dataset:rdp | groupby client.name' - showSubtitle: true - - name: RFB - description: RFB grouped by desktop name - query: 'event.dataset:rfb | groupby rfb.desktop.name.keyword' - showSubtitle: true - - name: Signatures - description: Zeek signatures grouped by signature id - query: 'event.dataset:signatures | groupby signature_id' - showSubtitle: true - - name: SIP - description: SIP grouped by user agent - query: 'event.dataset:sip | groupby client.user_agent' - showSubtitle: true - - name: SMB_Files - description: SMB files grouped by action - query: 'event.dataset:smb_files | groupby file.action' - showSubtitle: true - - name: SMB_Mapping - description: SMB mapping grouped by path - query: 'event.dataset:smb_mapping | groupby smb.path' - showSubtitle: true - - name: SMTP - description: SMTP grouped by subject - query: 'event.dataset:smtp | groupby smtp.subject' - showSubtitle: true - - name: SNMP - description: SNMP grouped by version and string - query: 'event.dataset:snmp | groupby snmp.community snmp.version' - showSubtitle: true - - name: Software - description: List of software seen on the network - query: 'event.dataset:software | groupby software.type software.name' - showSubtitle: true - - name: SSH - description: SSH grouped by version and client - query: 'event.dataset:ssh | groupby ssh.version ssh.client' - showSubtitle: true - - name: SSL - description: SSL grouped by version and server name - query: 'event.dataset:ssl | groupby ssl.version ssl.server_name' - showSubtitle: true - - name: SYSLOG - description: 'SYSLOG grouped by severity and facility ' - query: 'event.dataset:syslog | groupby syslog.severity_label syslog.facility_label' - showSubtitle: true - - name: Tunnel - description: Tunnels grouped by type and action - query: 'event.dataset:tunnel | groupby tunnel.type event.action' - showSubtitle: true - - name: Weird - description: Zeek weird log grouped by name - query: 'event.dataset:weird | groupby weird.name' - showSubtitle: true - - name: x509 - description: x.509 grouped by key length and name - query: 'event.dataset:x509 | groupby x509.certificate.key.length x509.san_dns' - showSubtitle: true - - name: x509 - description: x.509 grouped by name and issuer - query: 'event.dataset:x509 | groupby x509.san_dns x509.certificate.issuer' - showSubtitle: true - - name: x509 - description: x.509 grouped by name and subject - query: 'event.dataset:x509 | groupby x509.san_dns x509.certificate.subject' - showSubtitle: true - - name: Firewall - description: Firewall events grouped by action - query: 'event.dataset:firewall | groupby rule.action' - showSubtitle: true - dashboards: - advanced: true - groupItemsPerPage: 10 - groupFetchLimit: 10 - eventItemsPerPage: 10 - eventFetchLimit: 100 - relativeTimeValue: 24 - relativeTimeUnit: 30 - mostRecentlyUsedLimit: 0 - ackEnabled: false - escalateEnabled: true - escalateRelatedEventsEnabled: true - aggregationActionsEnabled: false - queryBaseFilter: '' - queryToggleFilters: - - name: caseExcludeToggle - filter: 'NOT _index:"*:so-case*"' - enabled: true - queries: - - name: Overview - description: Overview of all events - query: '* | groupby -sankey event.dataset event.category* | groupby -pie event.category | groupby -bar event.module* | groupby event.dataset | groupby event.module* | groupby event.category | groupby observer.name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: SOC Auth - description: SOC (Security Onion Console) authentication logs - query: 'event.module:kratos AND event.dataset:audit AND msg:authenticated | groupby -sankey http_request.headers.x-real-ip identity_id | groupby http_request.headers.x-real-ip | groupby identity_id | groupby http_request.headers.user-agent' - - name: Elastalerts - description: Elastalert logs - query: '_index: "*:elastalert*" | groupby rule_name | groupby alert_info.type' - - name: Alerts - description: Overview of all alerts - query: 'event.dataset:alert | groupby event.module* | groupby rule.name | groupby event.severity | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: NIDS Alerts - description: NIDS (Network Intrusion Detection System) alerts - query: 'event.category:network AND event.dataset:alert | groupby rule.category | groupby -sankey source.ip destination.ip | groupby rule.name | groupby rule.uuid | groupby rule.gid | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: Sysmon Overview - description: Overview of all Sysmon data types - query: 'event.dataset:windows.sysmon_operational | groupby -sankey event.action host.name | groupby -sankey host.name user.name | groupby host.name | groupby event.category event.action | groupby user.name | groupby dns.question.name | groupby process.executable | groupby winlog.event_data.TargetObject | groupby file.name | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: Host Overview - description: Overview of all host data types - query: '((event.category:registry OR event.category:host OR event.category:process OR event.category:driver OR event.category:configuration) OR (event.category:file AND _exists_:process.executable) OR (event.category:network AND _exists_:host.name)) | groupby event.dataset* event.category* event.action* | groupby event.type | groupby host.name | groupby user.name | groupby file.name | groupby process.executable' - - name: Host Registry Changes - description: Windows Registry changes - query: 'event.category: registry | groupby -sankey event.action host.name | groupby event.dataset event.action | groupby host.name | groupby process.executable | groupby registry.path | groupby process.executable registry.path' - - name: Host DNS & Process Mappings - description: DNS queries mapped to originating processes - query: 'event.category: network AND _exists_:process.executable AND (_exists_:dns.question.name OR _exists_:dns.answers.data) | groupby -sankey host.name dns.question.name | groupby event.dataset event.type | groupby host.name | groupby process.executable | groupby dns.question.name | groupby dns.answers.data' - - name: Host Process Activity - description: Process activity captured on an endpoint - query: 'event.category:process | groupby -sankey host.name user.name* | groupby event.dataset event.action | groupby host.name | groupby user.name | groupby process.working_directory | groupby process.executable | groupby process.command_line | groupby process.parent.executable | groupby process.parent.command_line | groupby -sankey process.parent.executable process.executable' - - name: Host File Activity - description: File activity captured on an endpoint - query: 'event.category: file AND _exists_:process.executable | groupby -sankey host.name process.executable | groupby host.name | groupby event.dataset event.action event.type | groupby file.name | groupby process.executable' - - name: Host Network & Process Mappings - description: Network activity mapped to originating processes - query: 'event.category: network AND _exists_:process.executable | groupby -sankey event.action host.name | groupby -sankey host.name user.name | groupby event.dataset* event.type* event.action* | groupby host.name | groupby user.name | groupby dns.question.name | groupby process.executable | groupby winlog.event_data.TargetObject | groupby process.name | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: Strelka - description: Strelka file analysis - query: 'event.module:strelka | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.name' - - name: Zeek Notice - description: Zeek notice logs - query: 'event.dataset:notice | groupby -sankey notice.note destination.ip | groupby notice.note | groupby notice.message | groupby notice.sub_message | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: Connections - description: Network connection metadata - query: 'event.dataset:conn | groupby source.ip | groupby destination.ip | groupby destination.port | groupby -sankey destination.port network.protocol | groupby network.protocol | groupby network.transport | groupby connection.history | groupby connection.state | groupby connection.state_description | groupby source.geo.country_name | groupby destination.geo.country_name | groupby client.ip_bytes | groupby server.ip_bytes | groupby client.oui' - - name: DCE_RPC - description: DCE_RPC (Distributed Computing Environment / Remote Procedure Calls) network metadata - query: 'event.dataset:dce_rpc | groupby -sankey dce_rpc.endpoint dce_rpc.operation | groupby dce_rpc.endpoint | groupby dce_rpc.operation | groupby dce_rpc.named_pipe | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: DHCP - description: DHCP (Dynamic Host Configuration Protocol) leases - query: 'event.dataset:dhcp | groupby host.hostname | groupby dhcp.message_types | groupby -sankey client.address server.address | groupby client.address | groupby server.address | groupby host.domain' - - name: DNS - description: DNS (Domain Name System) queries - query: 'event.dataset:dns | groupby dns.query.name | groupby dns.highest_registered_domain | groupby dns.parent_domain | groupby -sankey source.ip destination.ip | groupby dns.answers.name | groupby dns.query.type_name | groupby dns.response.code_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: DPD - description: DPD (Dynamic Protocol Detection) errors - query: 'event.dataset:dpd | groupby error.reason | groupby network.protocol | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: Files - description: Files seen in network traffic - query: 'event.dataset:file | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.bytes.total | groupby source.ip | groupby destination.ip | groupby destination_geo.organization_name' - - name: FTP - description: FTP (File Transfer Protocol) network metadata - query: 'event.dataset:ftp | groupby -sankey ftp.command destination.ip | groupby ftp.command | groupby ftp.argument | groupby ftp.user | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: HTTP - description: HTTP (Hyper Text Transport Protocol) network metadata - query: 'event.dataset:http | groupby http.method | groupby -sankey http.method http.virtual_host | groupby http.virtual_host | groupby http.uri | groupby http.useragent | groupby http.status_code | groupby http.status_message | groupby file.resp_mime_types | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: Intel - description: Zeek Intel framework hits - query: 'event.dataset:intel | groupby intel.indicator | groupby -sankey source.ip intel.indicator | groupby intel.indicator_type | groupby intel.seen_where | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: IRC - description: IRC (Internet Relay Chat) network metadata - query: 'event.dataset:irc | groupby irc.command.type | groupby -sankey irc.command.type irc.username | groupby irc.username | groupby irc.nickname | groupby irc.command.value | groupby irc.command.info | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: Kerberos - description: Kerberos network metadata - query: 'event.dataset:kerberos | groupby kerberos.service | groupby -sankey kerberos.service destination.ip | groupby kerberos.client | groupby kerberos.request_type | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: MySQL - description: MySQL network metadata - query: 'event.dataset:mysql | groupby mysql.command | groupby -sankey mysql.command destination.ip | groupby mysql.argument | groupby mysql.success | groupby mysql.response | groupby mysql.rows | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: NTLM - description: NTLM (New Technology LAN Manager) network metadata - query: 'event.dataset:ntlm | groupby ntlm.server.dns.name | groupby ntlm.server.nb.name | groupby -sankey source.ip destination.ip | groupby ntlm.server.tree.name | groupby ntlm.success | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: PE - description: PE (Portable Executable) files transferred via network traffic - query: 'event.dataset:pe | groupby file.machine | groupby -sankey file.machine file.os | groupby file.os | groupby file.subsystem | groupby file.section_names | groupby file.is_exe | groupby file.is_64bit' - - name: RADIUS - description: RADIUS (Remote Authentication Dial-In User Service) network metadata - query: 'event.dataset:radius | groupby -sankey user.name.keyword destination.ip | groupby user.name.keyword | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: RDP - description: RDP (Remote Desktop Protocol) network metadata - query: 'event.dataset:rdp | groupby client.name | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: RFB - description: RFB (Remote Frame Buffer) network metadata - query: 'event.dataset:rfb | groupby rfb.desktop.name.keyword | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: Signatures - description: Zeek signatures - query: 'event.dataset:signatures | groupby signature_id' - - name: SIP - description: SIP (Session Initiation Protocol) network metadata - query: 'event.dataset:sip | groupby client.user_agent | groupby sip.method | groupby sip.uri | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: SMB_Files - description: Files transferred via SMB (Server Message Block) - query: 'event.dataset:smb_files | groupby file.action | groupby file.path | groupby file.name | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: SMB_Mapping - description: SMB (Server Message Block) mapping network metadata - query: 'event.dataset:smb_mapping | groupby smb.share_type | groupby smb.path | groupby smb.service | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: SMTP - description: SMTP (Simple Mail Transfer Protocol) network metadata - query: 'event.dataset:smtp | groupby smtp.from | groupby smtp.recipient_to | groupby -sankey source.ip destination.ip | groupby smtp.subject | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: SNMP - description: SNMP (Simple Network Management Protocol) network metadat - query: 'event.dataset:snmp | groupby snmp.community | groupby snmp.version | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: Software - description: Software seen by Zeek via network traffic - query: 'event.dataset:software | groupby -sankey software.type source.ip | groupby software.type | groupby software.name | groupby source.ip' - - name: SSH - description: SSH (Secure Shell) connections seen by Zeek - query: 'event.dataset:ssh | groupby ssh.client | groupby ssh.server | groupby -sankey source.ip destination.ip | groupby ssh.direction | groupby ssh.version | groupby ssh.hassh_version | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: SSL - description: SSL/TLS network metadata - query: 'event.dataset:ssl | groupby ssl.version | groupby ssl.validation_status | groupby -sankey source.ip ssl.server_name | groupby ssl.server_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name | groupby ssl.certificate.issuer | groupby ssl.certificate.subject' - - name: STUN - description: STUN (Session Traversal Utilities for NAT) network metadata - query: 'event.dataset:stun* | groupby -sankey source.ip destination.ip | groupby destination.geo.country_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby event.dataset' - - name: Syslog - description: Syslog logs - query: 'event.dataset:syslog | groupby syslog.severity_label | groupby syslog.facility_label | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby network.protocol' - - name: TDS - description: TDS (Tabular Data Stream) network metadata - query: 'event.dataset:tds* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby tds.command | groupby tds.header_type | groupby tds.procedure_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby tds.query' - - name: Tunnel - description: Tunnels seen by Zeek - query: 'event.dataset:tunnel | groupby -sankey source.ip destination.ip | groupby tunnel.type | groupby event.action | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination.geo.country_name' - - name: Weird - description: Weird network traffic seen by Zeek - query: 'event.dataset:weird | groupby -sankey weird.name destination.ip | groupby weird.name | groupby weird.additional_info | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' - - name: WireGuard - description: WireGuard VPN network metadata - query: 'event.dataset:wireguard | groupby -sankey source.ip destination.ip | groupby destination.geo.country_name | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: x509 - description: x.509 certificates seen by Zeek - query: 'event.dataset:x509 | groupby -sankey x509.certificate.key.length x509.san_dns | groupby x509.certificate.key.length | groupby x509.san_dns | groupby x509.certificate.key.type | groupby x509.certificate.subject | groupby x509.certificate.issuer' - - name: ICS Overview - description: Overview of ICS (Industrial Control Systems) network metadata - query: 'tags:ics | groupby event.dataset | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby source.mac | groupby destination.mac' - - name: ICS BACnet - description: BACnet (Building Automation and Control Networks) network metadata - query: 'event.dataset:bacnet* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS BSAP - description: BSAP (Bristol Standard Asynchronous Protocol) network metadata - query: 'event.dataset:bsap* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS CIP - description: CIP (Common Industrial Protocol) network metadata - query: 'event.dataset:cip* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS COTP - description: COTP (Connection Oriented Transport Protocol) network metadata - query: 'event.dataset:cotp* | groupby -sankey source.ip destination.ip | groupby cotp.pdu.name | groupby cotp.pdu.code | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS DNP3 - description: DNP3 (Distributed Network Protocol) network metadata - query: 'event.dataset:dnp3* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby dnp3.function_code | groupby dnp3.object_type | groupby dnp3.fc_request | groupby dnp3.fc_reply | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS ECAT - description: ECAT (Ethernet for Control Automation Technology) network metadata - query: 'event.dataset:ecat* | groupby -sankey event.dataset source.mac destination.mac | groupby event.dataset | groupby source.mac | groupby destination.mac | groupby ecat.command | groupby ecat.register.type' - - name: ICS ENIP - description: ENIP (Ethernet Industrial Protocol) network metadata - query: 'event.dataset:enip* | groupby -sankey source.ip destination.ip | groupby enip.command | groupby enip.status_code | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS Modbus - description: Modbus network metadata - query: 'event.dataset:modbus* | groupby -sankey event.dataset modbus.function | groupby event.dataset | groupby modbus.function | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS OPC UA - description: OPC UA (Unified Architecture) network metadata - query: 'event.dataset:opcua* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS Profinet - description: Profinet (Process Field Network) network metadata - query: 'event.dataset:profinet* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: ICS S7 - description: S7 (Siemens) network metadata - query: 'event.dataset:s7* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: Firewall - description: Firewall logs - query: 'event.dataset:firewall | groupby -sankey rule.action interface.name | groupby rule.action | groupby interface.name | groupby network.transport | groupby source.ip | groupby destination.ip | groupby destination.port' - - name: VLAN - description: VLAN (Virtual Local Area Network) tagged logs - query: '* AND _exists_:network.vlan.id | groupby network.vlan.id | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby event.dataset | groupby event.module | groupby observer.name | groupby source.geo.country_name | groupby destination.geo.country_name' - - name: GeoIP - Destination Countries - description: GeoIP tagged logs visualized by destination countries - query: '* AND _exists_:destination.geo.country_name | groupby destination.geo.country_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name | groupby event.dataset | groupby event.module' - - name: GeoIP - Destination Organizations - description: GeoIP tagged logs visualized by destination organizations - query: '* AND _exists_:destination_geo.organization_name | groupby destination_geo.organization_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination.geo.country_name | groupby event.dataset | groupby event.module' - - name: GeoIP - Source Countries - description: GeoIP tagged logs visualized by source countries - query: '* AND _exists_:source.geo.country_name | groupby source.geo.country_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby source_geo.organization_name | groupby event.dataset | groupby event.module' - - name: GeoIP - Source Organizations - description: GeoIP tagged logs visualized by source organizations - query: '* AND _exists_:source_geo.organization_name | groupby source_geo.organization_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby source.geo.country_name | groupby event.dataset | groupby event.module' - job: - alerts: - advanced: false - groupItemsPerPage: 50 - groupFetchLimit: 500 - eventItemsPerPage: 50 - eventFetchLimit: 500 - relativeTimeValue: 24 - relativeTimeUnit: 30 - mostRecentlyUsedLimit: 5 - ackEnabled: true - escalateEnabled: true - escalateRelatedEventsEnabled: true - aggregationActionsEnabled: true - eventFields: - default: - - soc_timestamp - - rule.name - - event.severity_label - - source.ip - - source.port - - destination.ip - - destination.port - - rule.gid - - rule.uuid - - rule.category - - rule.rev - ':ossec:': - - soc_timestamp - - rule.name - - event.severity_label - - source.ip - - source.port - - destination.ip - - destination.port - - rule.level - - rule.category - - process.name - - user.name - - user.escalated - - location - - process.name - queryBaseFilter: event.dataset:alert - queryToggleFilters: - - name: acknowledged - filter: event.acknowledged:true - enabled: false - exclusive: true - - name: escalated - filter: event.escalated:true - enabled: false - exclusive: true - enablesToggles: - - acknowledged - queries: - - name: 'Group By Name, Module' - query: '* | groupby rule.name event.module* event.severity_label' - - name: 'Group By Sensor, Source IP/Port, Destination IP/Port, Name' - query: '* | groupby observer.name source.ip source.port destination.ip destination.port rule.name network.community_id event.severity_label' - - name: 'Group By Source IP, Name' - query: '* | groupby source.ip rule.name event.severity_label' - - name: 'Group By Source Port, Name' - query: '* | groupby source.port rule.name event.severity_label' - - name: 'Group By Destination IP, Name' - query: '* | groupby destination.ip rule.name event.severity_label' - - name: 'Group By Destination Port, Name' - query: '* | groupby destination.port rule.name event.severity_label' - - name: Ungroup - query: '*' - cases: - advanced: false - aggregationActionsEnabled: false - groupItemsPerPage: 50 - groupFetchLimit: 100 - eventItemsPerPage: 50 - eventFetchLimit: 500 - relativeTimeValue: 12 - relativeTimeUnit: 60 - mostRecentlyUsedLimit: 5 - ackEnabled: false - escalateEnabled: false - escalateRelatedEventsEnabled: false - viewEnabled: true - createLink: /case/create - eventFields: - default: - - soc_timestamp - - so_case.title - - so_case.status - - so_case.severity - - so_case.assigneeId - - so_case.createTime - queryBaseFilter: '_index:"*:so-case" AND so_kind:case' - queryToggleFilters: [] - queries: - - name: Open Cases - query: 'NOT so_case.status:closed AND NOT so_case.category:template' - - name: Closed Cases - query: 'so_case.status:closed AND NOT so_case.category:template' - - name: My Open Cases - query: 'NOT so_case.status:closed AND NOT so_case.category:template AND so_case.assigneeId:{myId}' - - name: My Closed Cases - query: 'so_case.status:closed AND NOT so_case.category:template AND so_case.assigneeId:{myId}' - - name: Templates - query: 'so_case.category:template' - case: - analyzerNodeId: - mostRecentlyUsedLimit: 5 - renderAbbreviatedCount: 30 - presets: - artifactType: - labels: - - autonomous-system - - domain - - file - - filename - - fqdn - - hash - - ip - - mail - - mail_subject - - other - - regexp - - registry - - uri_path - - url - - user-agent - customEnabled: true - category: - labels: - - general - - template - customEnabled: true - pap: - labels: - - white - - green - - amber - - red - customEnabled: false - severity: - labels: - - low - - medium - - high - - critical - customEnabled: false - status: - labels: - - new - - in progress - - closed - customEnabled: false - tags: - labels: - - false-positive - - confirmed - - pending - customEnabled: true - tlp: - labels: - - clear - - green - - amber - - amber+strict - - red - customEnabled: false + inactiveTools: ['toolUnused'] + tools: + - name: toolKibana + description: toolKibanaHelp + icon: fa-external-link-alt + target: so-kibana + link: /kibana/ + - name: toolElasticFleet + description: toolElasticFleet + icon: fa-external-link-alt + target: so-elastic-fleet + link: /kibana/app/fleet/agents + - name: toolOsqueryManager + description: toolOsqueryManager + icon: fa-external-link-alt + target: so-osquery-manager + link: /kibana/app/osquery/live_queries + - name: toolInfluxDb + description: toolInfluxDbHelp + icon: fa-external-link-alt + target: so-influxdb + link: /influxdb + - name: toolCyberchef + description: toolCyberchefHelp + icon: fa-external-link-alt + target: so-cyberchef + link: /cyberchef/ + - name: toolPlaybook + description: toolPlaybookHelp + icon: fa-external-link-alt + target: so-playbook + link: /playbook/projects/detection-playbooks/issues/ + - name: toolNavigator + description: toolNavigatorHelp + icon: fa-external-link-alt + target: so-navigator + link: /navigator/ + hunt: + advanced: true + aggregationActionsEnabled: true + groupItemsPerPage: 10 + groupFetchLimit: 10 + eventItemsPerPage: 10 + eventFetchLimit: 100 + relativeTimeValue: 24 + relativeTimeUnit: 30 + mostRecentlyUsedLimit: 5 + ackEnabled: false + escalateEnabled: true + escalateRelatedEventsEnabled: true + queryBaseFilter: '' + queryToggleFilters: + - name: caseExcludeToggle + filter: 'NOT _index:"*:so-case*"' + enabled: true + queries: + - name: Default Query + description: Show all events grouped by the observer host + query: '* | groupby observer.name' + showSubtitle: true + - name: Log Type + description: Show all events grouped by module and dataset + query: '* | groupby event.module* event.dataset' + showSubtitle: true + - name: SOC - Auth + description: Users authenticated to SOC grouped by IP address and identity + query: 'event.module:kratos AND event.dataset:audit AND msg:authenticated | groupby http_request.headers.x-real-ip identity_id' + showSubtitle: true + - name: SOC - App + description: Logs generated by the Security Onion Console (SOC) server and modules + query: 'event.module: "soc" | groupby event.module* event.dataset* log.level* | groupby agent.name | groupby event.action* | groupby "http.request.method" | groupby "url.path"' + showSubtitle: true + - name: Elastalerts + description: '' + query: '_type:elastalert | groupby rule.name' + showSubtitle: true + - name: Alerts + description: Show all alerts grouped by alert source + query: 'event.dataset: alert | groupby event.module' + showSubtitle: true + - name: NIDS Alerts + description: Show all NIDS alerts grouped by alert + query: 'event.category: network AND event.dataset: alert | groupby rule.category rule.gid rule.uuid rule.name' + showSubtitle: true + - name: Osquery - Live Query + description: Show all Osquery Live Query results + query: 'event.dataset: osquery_manager.result | groupby action_data.id action_data.query | groupby host.hostname' + showSubtitle: true + - name: Sysmon Events + description: Show all Sysmon logs grouped by event type + query: 'event.dataset: windows.sysmon_operational | groupby event.action' + showSubtitle: true + - name: Sysmon Usernames + description: Show all Sysmon logs grouped by username + query: 'event.dataset: windows.sysmon_operational | groupby event.action, user.name.keyword' + showSubtitle: true + - name: Strelka + description: Show all Strelka logs grouped by file type + query: 'event.module:strelka | groupby file.mime_type' + showSubtitle: true + - name: Zeek Notice + description: Show notices from Zeek + query: 'event.dataset:notice | groupby notice.note notice.message' + showSubtitle: true + - name: Connections + description: Connections grouped by IP and Port + query: 'event.dataset:conn | groupby source.ip destination.ip network.protocol destination.port' + showSubtitle: true + - name: Connections + description: Connections grouped by Service + query: 'event.dataset:conn | groupby network.protocol destination.port' + showSubtitle: true + - name: Connections + description: Connections grouped by destination country + query: 'event.dataset:conn | groupby destination.geo.country_name' + showSubtitle: true + - name: Connections + description: Connections grouped by source country + query: 'event.dataset:conn | groupby source.geo.country_name' + showSubtitle: true + - name: DCE_RPC + description: DCE_RPC grouped by operation + query: 'event.dataset:dce_rpc | groupby dce_rpc.operation' + showSubtitle: true + - name: DHCP + description: DHCP leases + query: 'event.dataset:dhcp | groupby host.hostname client.address' + showSubtitle: true + - name: DHCP + description: DHCP grouped by message type + query: 'event.dataset:dhcp | groupby dhcp.message_types' + showSubtitle: true + - name: DNP3 + description: DNP3 grouped by reply + query: 'event.dataset:dnp3 | groupby dnp3.fc_reply' + showSubtitle: true + - name: DNS + description: DNS queries grouped by port + query: 'event.dataset:dns | groupby dns.query.name destination.port' + showSubtitle: true + - name: DNS + description: DNS queries grouped by type + query: 'event.dataset:dns | groupby dns.query.type_name destination.port' + showSubtitle: true + - name: DNS + description: DNS queries grouped by response code + query: 'event.dataset:dns | groupby dns.response.code_name destination.port' + showSubtitle: true + - name: DNS + description: DNS highest registered domain + query: 'event.dataset:dns | groupby dns.highest_registered_domain.keyword destination.port' + showSubtitle: true + - name: DNS + description: DNS grouped by parent domain + query: 'event.dataset:dns | groupby dns.parent_domain.keyword destination.port' + showSubtitle: true + - name: DPD + description: Dynamic Protocol Detection errors + query: 'event.dataset:dpd | groupby error.reason' + showSubtitle: true + - name: Files + description: Files grouped by mimetype + query: 'event.dataset:file | groupby file.mime_type source.ip' + showSubtitle: true + - name: Files + description: Files grouped by source + query: 'event.dataset:file | groupby file.source source.ip' + showSubtitle: true + - name: FTP + description: FTP grouped by command and argument + query: 'event.dataset:ftp | groupby ftp.command ftp.argument' + showSubtitle: true + - name: FTP + description: FTP grouped by username and argument + query: 'event.dataset:ftp | groupby ftp.user ftp.argument' + showSubtitle: true + - name: HTTP + description: HTTP grouped by destination port + query: 'event.dataset:http | groupby destination.port' + showSubtitle: true + - name: HTTP + description: HTTP grouped by status code and message + query: 'event.dataset:http | groupby http.status_code http.status_message' + showSubtitle: true + - name: HTTP + description: HTTP grouped by method and user agent + query: 'event.dataset:http | groupby http.method http.useragent' + showSubtitle: true + - name: HTTP + description: HTTP grouped by virtual host + query: 'event.dataset:http | groupby http.virtual_host' + showSubtitle: true + - name: HTTP + description: HTTP with exe downloads + query: 'event.dataset:http AND (file.resp_mime_types:dosexec OR file.resp_mime_types:executable) | groupby http.virtual_host' + showSubtitle: true + - name: Intel + description: Intel framework hits grouped by indicator + query: 'event.dataset:intel | groupby intel.indicator.keyword' + showSubtitle: true + - name: IRC + description: IRC grouped by command + query: 'event.dataset:irc | groupby irc.command.type' + showSubtitle: true + - name: KERBEROS + description: KERBEROS grouped by service + query: 'event.dataset:kerberos | groupby kerberos.service' + showSubtitle: true + - name: MODBUS + description: MODBUS grouped by function + query: 'event.dataset:modbus | groupby modbus.function' + showSubtitle: true + - name: MYSQL + description: MYSQL grouped by command + query: 'event.dataset:mysql | groupby mysql.command' + showSubtitle: true + - name: NOTICE + description: Zeek notice logs grouped by note and message + query: 'event.dataset:notice | groupby notice.note notice.message' + showSubtitle: true + - name: NTLM + description: NTLM grouped by computer name + query: 'event.dataset:ntlm | groupby ntlm.server.dns.name' + showSubtitle: true + - name: PE + description: PE files list + query: 'event.dataset:pe | groupby file.machine file.os file.subsystem' + showSubtitle: true + - name: RADIUS + description: RADIUS grouped by username + query: 'event.dataset:radius | groupby user.name.keyword' + showSubtitle: true + - name: RDP + description: RDP grouped by client name + query: 'event.dataset:rdp | groupby client.name' + showSubtitle: true + - name: RFB + description: RFB grouped by desktop name + query: 'event.dataset:rfb | groupby rfb.desktop.name.keyword' + showSubtitle: true + - name: Signatures + description: Zeek signatures grouped by signature id + query: 'event.dataset:signatures | groupby signature_id' + showSubtitle: true + - name: SIP + description: SIP grouped by user agent + query: 'event.dataset:sip | groupby client.user_agent' + showSubtitle: true + - name: SMB_Files + description: SMB files grouped by action + query: 'event.dataset:smb_files | groupby file.action' + showSubtitle: true + - name: SMB_Mapping + description: SMB mapping grouped by path + query: 'event.dataset:smb_mapping | groupby smb.path' + showSubtitle: true + - name: SMTP + description: SMTP grouped by subject + query: 'event.dataset:smtp | groupby smtp.subject' + showSubtitle: true + - name: SNMP + description: SNMP grouped by version and string + query: 'event.dataset:snmp | groupby snmp.community snmp.version' + showSubtitle: true + - name: Software + description: List of software seen on the network + query: 'event.dataset:software | groupby software.type software.name' + showSubtitle: true + - name: SSH + description: SSH grouped by version and client + query: 'event.dataset:ssh | groupby ssh.version ssh.client' + showSubtitle: true + - name: SSL + description: SSL grouped by version and server name + query: 'event.dataset:ssl | groupby ssl.version ssl.server_name' + showSubtitle: true + - name: SYSLOG + description: 'SYSLOG grouped by severity and facility ' + query: 'event.dataset:syslog | groupby syslog.severity_label syslog.facility_label' + showSubtitle: true + - name: Tunnel + description: Tunnels grouped by type and action + query: 'event.dataset:tunnel | groupby tunnel.type event.action' + showSubtitle: true + - name: Weird + description: Zeek weird log grouped by name + query: 'event.dataset:weird | groupby weird.name' + showSubtitle: true + - name: x509 + description: x.509 grouped by key length and name + query: 'event.dataset:x509 | groupby x509.certificate.key.length x509.san_dns' + showSubtitle: true + - name: x509 + description: x.509 grouped by name and issuer + query: 'event.dataset:x509 | groupby x509.san_dns x509.certificate.issuer' + showSubtitle: true + - name: x509 + description: x.509 grouped by name and subject + query: 'event.dataset:x509 | groupby x509.san_dns x509.certificate.subject' + showSubtitle: true + - name: Firewall + description: Firewall events grouped by action + query: 'event.dataset:firewall | groupby rule.action' + showSubtitle: true + dashboards: + advanced: true + groupItemsPerPage: 10 + groupFetchLimit: 10 + eventItemsPerPage: 10 + eventFetchLimit: 100 + relativeTimeValue: 24 + relativeTimeUnit: 30 + mostRecentlyUsedLimit: 0 + ackEnabled: false + escalateEnabled: true + escalateRelatedEventsEnabled: true + aggregationActionsEnabled: false + queryBaseFilter: '' + queryToggleFilters: + - name: caseExcludeToggle + filter: 'NOT _index:"*:so-case*"' + enabled: true + queries: + - name: Overview + description: Overview of all events + query: '* | groupby -sankey event.dataset event.category* | groupby -pie event.category | groupby -bar event.module* | groupby event.dataset | groupby event.module* | groupby event.category | groupby observer.name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: SOC Auth + description: SOC (Security Onion Console) authentication logs + query: 'event.module:kratos AND event.dataset:audit AND msg:authenticated | groupby -sankey http_request.headers.x-real-ip identity_id | groupby http_request.headers.x-real-ip | groupby identity_id | groupby http_request.headers.user-agent' + - name: Elastalerts + description: Elastalert logs + query: '_index: "*:elastalert*" | groupby rule_name | groupby alert_info.type' + - name: Alerts + description: Overview of all alerts + query: 'event.dataset:alert | groupby event.module* | groupby rule.name | groupby event.severity | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: NIDS Alerts + description: NIDS (Network Intrusion Detection System) alerts + query: 'event.category:network AND event.dataset:alert | groupby rule.category | groupby -sankey source.ip destination.ip | groupby rule.name | groupby rule.uuid | groupby rule.gid | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: Sysmon Overview + description: Overview of all Sysmon data types + query: 'event.dataset:windows.sysmon_operational | groupby -sankey event.action host.name | groupby -sankey host.name user.name | groupby host.name | groupby event.category event.action | groupby user.name | groupby dns.question.name | groupby process.executable | groupby winlog.event_data.TargetObject | groupby file.name | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: Host Overview + description: Overview of all host data types + query: '((event.category:registry OR event.category:host OR event.category:process OR event.category:driver OR event.category:configuration) OR (event.category:file AND _exists_:process.executable) OR (event.category:network AND _exists_:host.name)) | groupby event.dataset* event.category* event.action* | groupby event.type | groupby host.name | groupby user.name | groupby file.name | groupby process.executable' + - name: Host Registry Changes + description: Windows Registry changes + query: 'event.category: registry | groupby -sankey event.action host.name | groupby event.dataset event.action | groupby host.name | groupby process.executable | groupby registry.path | groupby process.executable registry.path' + - name: Host DNS & Process Mappings + description: DNS queries mapped to originating processes + query: 'event.category: network AND _exists_:process.executable AND (_exists_:dns.question.name OR _exists_:dns.answers.data) | groupby -sankey host.name dns.question.name | groupby event.dataset event.type | groupby host.name | groupby process.executable | groupby dns.question.name | groupby dns.answers.data' + - name: Host Process Activity + description: Process activity captured on an endpoint + query: 'event.category:process | groupby -sankey host.name user.name* | groupby event.dataset event.action | groupby host.name | groupby user.name | groupby process.working_directory | groupby process.executable | groupby process.command_line | groupby process.parent.executable | groupby process.parent.command_line | groupby -sankey process.parent.executable process.executable' + - name: Host File Activity + description: File activity captured on an endpoint + query: 'event.category: file AND _exists_:process.executable | groupby -sankey host.name process.executable | groupby host.name | groupby event.dataset event.action event.type | groupby file.name | groupby process.executable' + - name: Host Network & Process Mappings + description: Network activity mapped to originating processes + query: 'event.category: network AND _exists_:process.executable | groupby -sankey event.action host.name | groupby -sankey host.name user.name | groupby event.dataset* event.type* event.action* | groupby host.name | groupby user.name | groupby dns.question.name | groupby process.executable | groupby winlog.event_data.TargetObject | groupby process.name | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: Strelka + description: Strelka file analysis + query: 'event.module:strelka | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.name' + - name: Zeek Notice + description: Zeek notice logs + query: 'event.dataset:notice | groupby -sankey notice.note destination.ip | groupby notice.note | groupby notice.message | groupby notice.sub_message | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: Connections + description: Network connection metadata + query: 'event.dataset:conn | groupby source.ip | groupby destination.ip | groupby destination.port | groupby -sankey destination.port network.protocol | groupby network.protocol | groupby network.transport | groupby connection.history | groupby connection.state | groupby connection.state_description | groupby source.geo.country_name | groupby destination.geo.country_name | groupby client.ip_bytes | groupby server.ip_bytes | groupby client.oui' + - name: DCE_RPC + description: DCE_RPC (Distributed Computing Environment / Remote Procedure Calls) network metadata + query: 'event.dataset:dce_rpc | groupby -sankey dce_rpc.endpoint dce_rpc.operation | groupby dce_rpc.endpoint | groupby dce_rpc.operation | groupby dce_rpc.named_pipe | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: DHCP + description: DHCP (Dynamic Host Configuration Protocol) leases + query: 'event.dataset:dhcp | groupby host.hostname | groupby dhcp.message_types | groupby -sankey client.address server.address | groupby client.address | groupby server.address | groupby host.domain' + - name: DNS + description: DNS (Domain Name System) queries + query: 'event.dataset:dns | groupby dns.query.name | groupby dns.highest_registered_domain | groupby dns.parent_domain | groupby -sankey source.ip destination.ip | groupby dns.answers.name | groupby dns.query.type_name | groupby dns.response.code_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: DPD + description: DPD (Dynamic Protocol Detection) errors + query: 'event.dataset:dpd | groupby error.reason | groupby network.protocol | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: Files + description: Files seen in network traffic + query: 'event.dataset:file | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.bytes.total | groupby source.ip | groupby destination.ip | groupby destination_geo.organization_name' + - name: FTP + description: FTP (File Transfer Protocol) network metadata + query: 'event.dataset:ftp | groupby -sankey ftp.command destination.ip | groupby ftp.command | groupby ftp.argument | groupby ftp.user | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: HTTP + description: HTTP (Hyper Text Transport Protocol) network metadata + query: 'event.dataset:http | groupby http.method | groupby -sankey http.method http.virtual_host | groupby http.virtual_host | groupby http.uri | groupby http.useragent | groupby http.status_code | groupby http.status_message | groupby file.resp_mime_types | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: Intel + description: Zeek Intel framework hits + query: 'event.dataset:intel | groupby intel.indicator | groupby -sankey source.ip intel.indicator | groupby intel.indicator_type | groupby intel.seen_where | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: IRC + description: IRC (Internet Relay Chat) network metadata + query: 'event.dataset:irc | groupby irc.command.type | groupby -sankey irc.command.type irc.username | groupby irc.username | groupby irc.nickname | groupby irc.command.value | groupby irc.command.info | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: Kerberos + description: Kerberos network metadata + query: 'event.dataset:kerberos | groupby kerberos.service | groupby -sankey kerberos.service destination.ip | groupby kerberos.client | groupby kerberos.request_type | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: MySQL + description: MySQL network metadata + query: 'event.dataset:mysql | groupby mysql.command | groupby -sankey mysql.command destination.ip | groupby mysql.argument | groupby mysql.success | groupby mysql.response | groupby mysql.rows | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: NTLM + description: NTLM (New Technology LAN Manager) network metadata + query: 'event.dataset:ntlm | groupby ntlm.server.dns.name | groupby ntlm.server.nb.name | groupby -sankey source.ip destination.ip | groupby ntlm.server.tree.name | groupby ntlm.success | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: PE + description: PE (Portable Executable) files transferred via network traffic + query: 'event.dataset:pe | groupby file.machine | groupby -sankey file.machine file.os | groupby file.os | groupby file.subsystem | groupby file.section_names | groupby file.is_exe | groupby file.is_64bit' + - name: RADIUS + description: RADIUS (Remote Authentication Dial-In User Service) network metadata + query: 'event.dataset:radius | groupby -sankey user.name.keyword destination.ip | groupby user.name.keyword | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: RDP + description: RDP (Remote Desktop Protocol) network metadata + query: 'event.dataset:rdp | groupby client.name | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: RFB + description: RFB (Remote Frame Buffer) network metadata + query: 'event.dataset:rfb | groupby rfb.desktop.name.keyword | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: Signatures + description: Zeek signatures + query: 'event.dataset:signatures | groupby signature_id' + - name: SIP + description: SIP (Session Initiation Protocol) network metadata + query: 'event.dataset:sip | groupby client.user_agent | groupby sip.method | groupby sip.uri | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: SMB_Files + description: Files transferred via SMB (Server Message Block) + query: 'event.dataset:smb_files | groupby file.action | groupby file.path | groupby file.name | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: SMB_Mapping + description: SMB (Server Message Block) mapping network metadata + query: 'event.dataset:smb_mapping | groupby smb.share_type | groupby smb.path | groupby smb.service | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: SMTP + description: SMTP (Simple Mail Transfer Protocol) network metadata + query: 'event.dataset:smtp | groupby smtp.from | groupby smtp.recipient_to | groupby -sankey source.ip destination.ip | groupby smtp.subject | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: SNMP + description: SNMP (Simple Network Management Protocol) network metadat + query: 'event.dataset:snmp | groupby snmp.community | groupby snmp.version | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: Software + description: Software seen by Zeek via network traffic + query: 'event.dataset:software | groupby -sankey software.type source.ip | groupby software.type | groupby software.name | groupby source.ip' + - name: SSH + description: SSH (Secure Shell) connections seen by Zeek + query: 'event.dataset:ssh | groupby ssh.client | groupby ssh.server | groupby -sankey source.ip destination.ip | groupby ssh.direction | groupby ssh.version | groupby ssh.hassh_version | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: SSL + description: SSL/TLS network metadata + query: 'event.dataset:ssl | groupby ssl.version | groupby ssl.validation_status | groupby -sankey source.ip ssl.server_name | groupby ssl.server_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name | groupby ssl.certificate.issuer | groupby ssl.certificate.subject' + - name: STUN + description: STUN (Session Traversal Utilities for NAT) network metadata + query: 'event.dataset:stun* | groupby -sankey source.ip destination.ip | groupby destination.geo.country_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby event.dataset' + - name: Syslog + description: Syslog logs + query: 'event.dataset:syslog | groupby syslog.severity_label | groupby syslog.facility_label | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby network.protocol' + - name: TDS + description: TDS (Tabular Data Stream) network metadata + query: 'event.dataset:tds* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby tds.command | groupby tds.header_type | groupby tds.procedure_name | groupby source.ip | groupby destination.ip | groupby destination.port | groupby tds.query' + - name: Tunnel + description: Tunnels seen by Zeek + query: 'event.dataset:tunnel | groupby -sankey source.ip destination.ip | groupby tunnel.type | groupby event.action | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination.geo.country_name' + - name: Weird + description: Weird network traffic seen by Zeek + query: 'event.dataset:weird | groupby -sankey weird.name destination.ip | groupby weird.name | groupby weird.additional_info | groupby source.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name' + - name: WireGuard + description: WireGuard VPN network metadata + query: 'event.dataset:wireguard | groupby -sankey source.ip destination.ip | groupby destination.geo.country_name | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: x509 + description: x.509 certificates seen by Zeek + query: 'event.dataset:x509 | groupby -sankey x509.certificate.key.length x509.san_dns | groupby x509.certificate.key.length | groupby x509.san_dns | groupby x509.certificate.key.type | groupby x509.certificate.subject | groupby x509.certificate.issuer' + - name: ICS Overview + description: Overview of ICS (Industrial Control Systems) network metadata + query: 'tags:ics | groupby event.dataset | groupby -sankey source.ip destination.ip | groupby source.ip | groupby destination.ip | groupby destination.port | groupby source.mac | groupby destination.mac' + - name: ICS BACnet + description: BACnet (Building Automation and Control Networks) network metadata + query: 'event.dataset:bacnet* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS BSAP + description: BSAP (Bristol Standard Asynchronous Protocol) network metadata + query: 'event.dataset:bsap* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS CIP + description: CIP (Common Industrial Protocol) network metadata + query: 'event.dataset:cip* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS COTP + description: COTP (Connection Oriented Transport Protocol) network metadata + query: 'event.dataset:cotp* | groupby -sankey source.ip destination.ip | groupby cotp.pdu.name | groupby cotp.pdu.code | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS DNP3 + description: DNP3 (Distributed Network Protocol) network metadata + query: 'event.dataset:dnp3* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby dnp3.function_code | groupby dnp3.object_type | groupby dnp3.fc_request | groupby dnp3.fc_reply | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS ECAT + description: ECAT (Ethernet for Control Automation Technology) network metadata + query: 'event.dataset:ecat* | groupby -sankey event.dataset source.mac destination.mac | groupby event.dataset | groupby source.mac | groupby destination.mac | groupby ecat.command | groupby ecat.register.type' + - name: ICS ENIP + description: ENIP (Ethernet Industrial Protocol) network metadata + query: 'event.dataset:enip* | groupby -sankey source.ip destination.ip | groupby enip.command | groupby enip.status_code | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS Modbus + description: Modbus network metadata + query: 'event.dataset:modbus* | groupby -sankey event.dataset modbus.function | groupby event.dataset | groupby modbus.function | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS OPC UA + description: OPC UA (Unified Architecture) network metadata + query: 'event.dataset:opcua* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS Profinet + description: Profinet (Process Field Network) network metadata + query: 'event.dataset:profinet* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: ICS S7 + description: S7 (Siemens) network metadata + query: 'event.dataset:s7* | groupby -sankey event.dataset source.ip destination.ip | groupby event.dataset | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: Firewall + description: Firewall logs + query: 'event.dataset:firewall | groupby -sankey rule.action interface.name | groupby rule.action | groupby interface.name | groupby network.transport | groupby source.ip | groupby destination.ip | groupby destination.port' + - name: VLAN + description: VLAN (Virtual Local Area Network) tagged logs + query: '* AND _exists_:network.vlan.id | groupby network.vlan.id | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby event.dataset | groupby event.module | groupby observer.name | groupby source.geo.country_name | groupby destination.geo.country_name' + - name: GeoIP - Destination Countries + description: GeoIP tagged logs visualized by destination countries + query: '* AND _exists_:destination.geo.country_name | groupby destination.geo.country_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination_geo.organization_name | groupby event.dataset | groupby event.module' + - name: GeoIP - Destination Organizations + description: GeoIP tagged logs visualized by destination organizations + query: '* AND _exists_:destination_geo.organization_name | groupby destination_geo.organization_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby destination.geo.country_name | groupby event.dataset | groupby event.module' + - name: GeoIP - Source Countries + description: GeoIP tagged logs visualized by source countries + query: '* AND _exists_:source.geo.country_name | groupby source.geo.country_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby source_geo.organization_name | groupby event.dataset | groupby event.module' + - name: GeoIP - Source Organizations + description: GeoIP tagged logs visualized by source organizations + query: '* AND _exists_:source_geo.organization_name | groupby source_geo.organization_name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby source.geo.country_name | groupby event.dataset | groupby event.module' + job: + alerts: + advanced: false + groupItemsPerPage: 50 + groupFetchLimit: 500 + eventItemsPerPage: 50 + eventFetchLimit: 500 + relativeTimeValue: 24 + relativeTimeUnit: 30 + mostRecentlyUsedLimit: 5 + ackEnabled: true + escalateEnabled: true + escalateRelatedEventsEnabled: true + aggregationActionsEnabled: true + eventFields: + default: + - soc_timestamp + - rule.name + - event.severity_label + - source.ip + - source.port + - destination.ip + - destination.port + - rule.gid + - rule.uuid + - rule.category + - rule.rev + ':ossec:': + - soc_timestamp + - rule.name + - event.severity_label + - source.ip + - source.port + - destination.ip + - destination.port + - rule.level + - rule.category + - process.name + - user.name + - user.escalated + - location + - process.name + queryBaseFilter: event.dataset:alert + queryToggleFilters: + - name: acknowledged + filter: event.acknowledged:true + enabled: false + exclusive: true + - name: escalated + filter: event.escalated:true + enabled: false + exclusive: true + enablesToggles: + - acknowledged + queries: + - name: 'Group By Name, Module' + query: '* | groupby rule.name event.module* event.severity_label' + - name: 'Group By Sensor, Source IP/Port, Destination IP/Port, Name' + query: '* | groupby observer.name source.ip source.port destination.ip destination.port rule.name network.community_id event.severity_label' + - name: 'Group By Source IP, Name' + query: '* | groupby source.ip rule.name event.severity_label' + - name: 'Group By Source Port, Name' + query: '* | groupby source.port rule.name event.severity_label' + - name: 'Group By Destination IP, Name' + query: '* | groupby destination.ip rule.name event.severity_label' + - name: 'Group By Destination Port, Name' + query: '* | groupby destination.port rule.name event.severity_label' + - name: Ungroup + query: '*' + cases: + advanced: false + aggregationActionsEnabled: false + groupItemsPerPage: 50 + groupFetchLimit: 100 + eventItemsPerPage: 50 + eventFetchLimit: 500 + relativeTimeValue: 12 + relativeTimeUnit: 60 + mostRecentlyUsedLimit: 5 + ackEnabled: false + escalateEnabled: false + escalateRelatedEventsEnabled: false + viewEnabled: true + createLink: /case/create + eventFields: + default: + - soc_timestamp + - so_case.title + - so_case.status + - so_case.severity + - so_case.assigneeId + - so_case.createTime + queryBaseFilter: '_index:"*:so-case" AND so_kind:case' + queryToggleFilters: [] + queries: + - name: Open Cases + query: 'NOT so_case.status:closed AND NOT so_case.category:template' + - name: Closed Cases + query: 'so_case.status:closed AND NOT so_case.category:template' + - name: My Open Cases + query: 'NOT so_case.status:closed AND NOT so_case.category:template AND so_case.assigneeId:{myId}' + - name: My Closed Cases + query: 'so_case.status:closed AND NOT so_case.category:template AND so_case.assigneeId:{myId}' + - name: Templates + query: 'so_case.category:template' + case: + analyzerNodeId: + mostRecentlyUsedLimit: 5 + renderAbbreviatedCount: 30 + presets: + artifactType: + labels: + - autonomous-system + - domain + - file + - filename + - fqdn + - hash + - ip + - mail + - mail_subject + - other + - regexp + - registry + - uri_path + - url + - user-agent + customEnabled: true + category: + labels: + - general + - template + customEnabled: true + pap: + labels: + - white + - green + - amber + - red + customEnabled: false + severity: + labels: + - low + - medium + - high + - critical + customEnabled: false + status: + labels: + - new + - in progress + - closed + customEnabled: false + tags: + labels: + - false-positive + - confirmed + - pending + customEnabled: true + tlp: + labels: + - clear + - green + - amber + - amber+strict + - red + customEnabled: false diff --git a/salt/soc/disabled.sls b/salt/soc/disabled.sls new file mode 100644 index 000000000..70b03596f --- /dev/null +++ b/salt/soc/disabled.sls @@ -0,0 +1,31 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} + +include: + - soc.sostatus + +so-soc: + docker_container.absent: + - force: True + +so-soc_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-soc$ + +salt-relay: + cron.absent: + - identifier: salt-relay + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/soc/enabled.sls b/salt/soc/enabled.sls new file mode 100644 index 000000000..2e4528080 --- /dev/null +++ b/salt/soc/enabled.sls @@ -0,0 +1,68 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'soc/merged.map.jinja' import DOCKER_EXTRA_HOSTS %} + +include: + - soc.config + - soc.sostatus + +so-soc: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-soc:{{ GLOBALS.so_version }} + - hostname: soc + - name: so-soc + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-soc'].ip }} + - binds: + - /nsm/soc/jobs:/opt/sensoroni/jobs:rw + - /opt/so/log/soc/:/opt/sensoroni/logs/:rw + - /opt/so/conf/soc/soc.json:/opt/sensoroni/sensoroni.json:ro + - /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/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 + - /opt/so/conf/soc/salt:/opt/sensoroni/salt:rw + - /opt/so/saltstack:/opt/so/saltstack:rw + - extra_hosts: {{ DOCKER_EXTRA_HOSTS }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-soc'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - watch: + - file: /opt/so/conf/soc/* + - require: + - file: socdatadir + - file: soclogdir + - file: socconfig + - file: socmotd + - file: socbanner + - file: soccustom + - file: soccustomroles + - file: socusersroles + +delete_so-soc_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-soc$ + +salt-relay: + cron.present: + - name: 'ps -ef | grep salt-relay.sh | grep -v grep > /dev/null 2>&1 || /opt/so/saltstack/default/salt/soc/files/bin/salt-relay.sh >> /opt/so/log/soc/salt-relay.log 2>&1 &' + - identifier: salt-relay + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/soc/files/soc/soc.json.jinja b/salt/soc/files/soc/soc.json.jinja index 101959758..91c96d58f 100644 --- a/salt/soc/files/soc/soc.json.jinja +++ b/salt/soc/files/soc/soc.json.jinja @@ -1,2 +1,2 @@ {% from 'soc/merged.map.jinja' import SOCMERGED -%} -{{ SOCMERGED | json(sort_keys=True, indent=4 * ' ') }} +{{ SOCMERGED.config | json(sort_keys=True, indent=4 * ' ') }} diff --git a/salt/soc/init.sls b/salt/soc/init.sls index 8c3ed5104..a7feb059a 100644 --- a/salt/soc/init.sls +++ b/salt/soc/init.sls @@ -1,160 +1,13 @@ -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} +# 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 'vars/globals.map.jinja' import GLOBALS %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'soc/merged.map.jinja' import DOCKER_EXTRA_HOSTS %} +{% from 'soc/config.map.jinja' import SOCMERGED %} include: - - manager.sync_es_users - -socdir: - file.directory: - - name: /opt/so/conf/soc - - user: 939 - - group: 939 - - makedirs: True - -socdatadir: - file.directory: - - name: /nsm/soc/jobs - - user: 939 - - group: 939 - - makedirs: True - -soclogdir: - file.directory: - - name: /opt/so/log/soc - - user: 939 - - group: 939 - - makedirs: True - -socsaltdir: - file.directory: - - name: /opt/so/conf/soc/salt - - user: 939 - - group: 939 - - makedirs: True - -socconfig: - file.managed: - - name: /opt/so/conf/soc/soc.json - - source: salt://soc/files/soc/soc.json.jinja - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - - show_changes: False - -socmotd: - file.managed: - - name: /opt/so/conf/soc/motd.md - - source: salt://soc/files/soc/motd.md - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - -socbanner: - file.managed: - - name: /opt/so/conf/soc/banner.md - - source: salt://soc/files/soc/banner.md - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - -soc_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://soc/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#soc_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://soc/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -soccustom: - file.managed: - - name: /opt/so/conf/soc/custom.js - - source: salt://soc/files/soc/custom.js - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - -soccustomroles: - file.managed: - - name: /opt/so/conf/soc/custom_roles - - source: salt://soc/files/soc/custom_roles - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - -socusersroles: - file.exists: - - name: /opt/so/conf/soc/soc_users_roles - - require: - - sls: manager.sync_es_users - -salt-relay: - cron.present: - - name: 'ps -ef | grep salt-relay.sh | grep -v grep > /dev/null 2>&1 || /opt/so/saltstack/default/salt/soc/files/bin/salt-relay.sh >> /opt/so/log/soc/salt-relay.log 2>&1 &' - - identifier: salt-relay - -so-soc: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-soc:{{ GLOBALS.so_version }} - - hostname: soc - - name: so-soc - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-soc'].ip }} - - binds: - - /nsm/soc/jobs:/opt/sensoroni/jobs:rw - - /opt/so/log/soc/:/opt/sensoroni/logs/:rw - - /opt/so/conf/soc/soc.json:/opt/sensoroni/sensoroni.json:ro - - /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/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 - - /opt/so/conf/soc/salt:/opt/sensoroni/salt:rw - - /opt/so/saltstack:/opt/so/saltstack:rw - - extra_hosts: {{ DOCKER_EXTRA_HOSTS }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-soc'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - watch: - - file: /opt/so/conf/soc/* - - require: - - file: socdatadir - - file: soclogdir - - file: socconfig - - file: socmotd - - file: socbanner - - file: soccustom - - file: soccustomroles - - file: socusersroles - -append_so-soc_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-soc - +{% if SOCMERGED.enabled %} + - soc.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - soc.disabled {% endif %} diff --git a/salt/soc/merged.map.jinja b/salt/soc/merged.map.jinja index 9589e9897..dc2f889bb 100644 --- a/salt/soc/merged.map.jinja +++ b/salt/soc/merged.map.jinja @@ -1,3 +1,8 @@ +{# 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 'vars/globals.map.jinja' import GLOBALS %} {% from 'soc/defaults.map.jinja' import SOCDEFAULTS with context %} {% from 'logstash/map.jinja' import LOGSTASH_NODES %} @@ -6,14 +11,14 @@ {% set SOCMERGED = salt['pillar.get']('soc', SOCDEFAULTS, merge=true) %} -{# if SOCMERGED.server.modules.cases == httpcase details come from the soc pillar #} -{% if SOCMERGED.server.modules.cases != 'soc' %} -{% do SOCMERGED.server.modules.elastic.update({'casesEnabled': false}) %} -{% do SOCMERGED.server.client.update({'casesEnabled': false}) %} -{% do SOCMERGED.server.client.hunt.update({'escalateRelatedEventsEnabled': false}) %} -{% do SOCMERGED.server.client.alerts.update({'escalateRelatedEventsEnabled': false}) %} -{% if SOCMERGED.server.modules.cases == 'elasticcases' %} -{% do SOCMERGED.server.modules.update({ +{# if SOCMERGED.config.server.modules.cases == httpcase details come from the soc pillar #} +{% if SOCMERGED.config.server.modules.cases != 'soc' %} +{% do SOCMERGED.config.server.modules.elastic.update({'casesEnabled': false}) %} +{% do SOCMERGED.config.server.client.update({'casesEnabled': false}) %} +{% do SOCMERGED.config.server.client.hunt.update({'escalateRelatedEventsEnabled': false}) %} +{% do SOCMERGED.config.server.client.alerts.update({'escalateRelatedEventsEnabled': false}) %} +{% if SOCMERGED.config.server.modules.cases == 'elasticcases' %} +{% do SOCMERGED.config.server.modules.update({ 'elasticcases': { 'hostUrl': 'https://' ~ GLOBALS.manager_ip ~ ':5601', 'username': GLOBALS.elasticsearch.auth.users.so_elastic_user.user, @@ -23,13 +28,13 @@ {% endif %} {% endif %} {# since cases is not a valid soc config item and only used for the map files, remove it from being placed in the config #} -{% do SOCMERGED.server.modules.pop('cases') %} +{% do SOCMERGED.config.server.modules.pop('cases') %} {% if pillar.manager.playbook == 0 %} -{% do SOCMERGED.server.client.inactiveTools.append('toolPlaybook') %} +{% do SOCMERGED.config.server.client.inactiveTools.append('toolPlaybook') %} {% endif %} -{% set standard_actions = SOCMERGED.pop('actions') %} +{% set standard_actions = SOCMERGED.config.pop('actions') %} {% if pillar.global.endgamehost is defined %} {% set endgame_dict = { "name": "Endgame", @@ -42,12 +47,12 @@ {% do standard_actions.append(endgame_dict) %} {% endif %} -{% do SOCMERGED.server.client.hunt.update({'actions': standard_actions}) %} -{% do SOCMERGED.server.client.dashboards.update({'actions': standard_actions}) %} -{% do SOCMERGED.server.client.update({'job': {'actions': standard_actions}}) %} -{% do SOCMERGED.server.client.alerts.update({'actions': standard_actions}) %} -{% do SOCMERGED.server.client.cases.update({'actions': standard_actions}) %} +{% do SOCMERGED.config.server.client.hunt.update({'actions': standard_actions}) %} +{% do SOCMERGED.config.server.client.dashboards.update({'actions': standard_actions}) %} +{% do SOCMERGED.config.server.client.update({'job': {'actions': standard_actions}}) %} +{% do SOCMERGED.config.server.client.alerts.update({'actions': standard_actions}) %} +{% do SOCMERGED.config.server.client.cases.update({'actions': standard_actions}) %} -{% set standard_eventFields = SOCMERGED.pop('eventFields') %} -{% do SOCMERGED.server.client.hunt.update({'eventFields': standard_eventFields}) %} -{% do SOCMERGED.server.client.dashboards.update({'eventFields': standard_eventFields}) %} +{% set standard_eventFields = SOCMERGED.config.pop('eventFields') %} +{% do SOCMERGED.config.server.client.hunt.update({'eventFields': standard_eventFields}) %} +{% do SOCMERGED.config.server.client.dashboards.update({'eventFields': standard_eventFields}) %} diff --git a/salt/soc/soc_soc.yaml b/salt/soc/soc_soc.yaml index 17737abe4..6551b632b 100644 --- a/salt/soc/soc_soc.yaml +++ b/salt/soc/soc_soc.yaml @@ -1,224 +1,228 @@ soc: - licenseKey: - title: License Key - description: Optional Security Onion license key to unlock enterprise features. - global: True - logLevel: - title: Log Level - description: The SOC log level, useful for enabling debug logging for advanced troubleshooting. Allowed values are debug, info, warn, error. The SOC log is available at /opt/so/log/soc/sensoroni-server.log. - global: True - regex: ^(info|debug|warn|error)$ - files: - soc: - banner__md: - title: Login Banner - description: Customize the login page with a specific markdown-formatted message. - file: True - global: True - syntax: md - helpLink: soc-customization.html - motd__md: - title: Overview Page - description: Customize the overview page with specific markdown-formatted content. Images can be used but must be hosted from another host that is accessible by the user's browser. - file: True - global: True - syntax: md - helpLink: soc-customization.html - custom__js: - title: Custom Javascript - description: Customize SOC UI behavior with custom Javascript code. Custom Javascript not provided by Security Onion Solutions is unsupported, and should be removed prior to requesting support and prior to performing upgrades. - file: True - global: True - advanced: True - helpLink: soc-customization.html - custom_roles: - title: Custom Roles - description: Customize role and permission mappings. Changing this setting requires a complete understanding of the SOC RBAC system. - file: True - global: True - advanced: True - helpLink: soc-customization.html - actions: - description: A list of actions a user can take from the SOC UI against a hunt, alert, and other records. The action must be defined in JSON object format, and contain a "name" key and "links" key. The links is a list of URLs, where the most suitable URL in the list will be the selected URL when the user clicks the action. - global: True - eventFields: - default: - description: The list of fields to show as columns in the Hunt/Dashboards event table, when no other specific mapping applies. Mappings are defined by the format ":event.module:event.dataset". + enabled: + description: You can enable or disable SOC. + advanced: True + config: + licenseKey: + title: License Key + description: Optional Security Onion license key to unlock enterprise features. global: True - advanced: True - server: - srvKey: - description: Unique key for protecting the integrity of user submitted data via the web browser. + logLevel: + title: Log Level + description: The SOC log level, useful for enabling debug logging for advanced troubleshooting. Allowed values are debug, info, warn, error. The SOC log is available at /opt/so/log/soc/sensoroni-server.log. global: True - sensitive: True - advanced: True - maxPacketCount: - description: Maximum number of packets to show in the PCAP viewer. Larger values can cause more resource utilization on both the SOC server and the browser. - global: True - advanced: True - modules: - elastic: - index: - description: Comma-separated list of indices or index patterns (wildcard "*" supported) that SOC will search for records. + regex: ^(info|debug|warn|error)$ + files: + soc: + banner__md: + title: Login Banner + description: Customize the login page with a specific markdown-formatted message. + file: True + global: True + syntax: md + helpLink: soc-customization.html + motd__md: + title: Overview Page + description: Customize the overview page with specific markdown-formatted content. Images can be used but must be hosted from another host that is accessible by the user's browser. + file: True + global: True + syntax: md + helpLink: soc-customization.html + custom__js: + title: Custom Javascript + description: Customize SOC UI behavior with custom Javascript code. Custom Javascript not provided by Security Onion Solutions is unsupported, and should be removed prior to requesting support and prior to performing upgrades. + file: True global: True advanced: True - cacheMs: - description: Duration (in milliseconds) to cache the Elasticsearch index field data to minimize repeated requests for this typically static information. + helpLink: soc-customization.html + custom_roles: + title: Custom Roles + description: Customize role and permission mappings. Changing this setting requires a complete understanding of the SOC RBAC system. + file: True global: True advanced: True - timeoutMs: - description: Duration (in milliseconds) to wait for a response from the Elasticsearch host before giving up and showing an error on the SOC UI. + helpLink: soc-customization.html + actions: + description: A list of actions a user can take from the SOC UI against a hunt, alert, and other records. The action must be defined in JSON object format, and contain a "name" key and "links" key. The links is a list of URLs, where the most suitable URL in the list will be the selected URL when the user clicks the action. + global: True + eventFields: + default: + description: The list of fields to show as columns in the Hunt/Dashboards event table, when no other specific mapping applies. Mappings are defined by the format ":event.module:event.dataset". + global: True + advanced: True + server: + srvKey: + description: Unique key for protecting the integrity of user submitted data via the web browser. + global: True + sensitive: True + advanced: True + maxPacketCount: + description: Maximum number of packets to show in the PCAP viewer. Larger values can cause more resource utilization on both the SOC server and the browser. + global: True + advanced: True + modules: + elastic: + index: + description: Comma-separated list of indices or index patterns (wildcard "*" supported) that SOC will search for records. + global: True + advanced: True + cacheMs: + description: Duration (in milliseconds) to cache the Elasticsearch index field data to minimize repeated requests for this typically static information. + global: True + advanced: True + timeoutMs: + description: Duration (in milliseconds) to wait for a response from the Elasticsearch host before giving up and showing an error on the SOC UI. + global: True + advanced: True + casesEnabled: + description: Set to true if the SOC case management module, natively integrated with Elasticsearch, should be enabled. + global: True + advanced: True + extractCommonObservables: + description: List of indexed fields to automatically extract into a case observable, when attaching related events to a case. + global: True + timeShiftMs: + description: Duration (in milliseconds) to further expand the PCAP time range when querying PCAP data related to an event. This duration is added to the normal duration value (see defaultDurationMs). + global: True + advanced: True + defaultDurationMs: + description: Duration (in milliseconds) to add before and after the event's timestamp, when querying PCAP data related to the event. If the PCAP-related event record itself has an event.duration value, it will be used instead of this default. + global: True + advanced: True + esSearchOffsetMs: + description: Duration (in milliseconds) to add before and after the selected event's timestamp, when looking up PCAP-related events in order to pivot to PCAP. + global: True + advanced: True + maxLogLength: + description: The maximum length of an Elasticsearch related log line that is output to the Sensoroni log file. This prevents massive Elasticsearch responses from being dumped into the text log file on disk. + global: True + advanced: True + asyncThreshold: + description: Maximum number of events that can be acknowledged synchronously. When acknowledging large numbers of events, where the count exceeds this value, the acknowledge update will be performed in the background, as it can take several minutes to complete. + global: True + advanced: True + sostatus: + refreshIntervalMs: + description: Duration (in milliseconds) between refreshes of the grid status. Shortening this duration may not have expected results, as the backend systems feeding this sostatus data will continue their updates as scheduled. + global: True + advanced: True + offlineThresholdMs: + description: Duration (in milliseconds) that must elapse after a grid node fails to check-in before the node will be marked offline (fault). + global: True + advanced: True + client: + apiTimeoutMs: + description: Duration (in milliseconds) to wait for a response from the SOC server API before giving up and showing an error on the SOC UI. + global: True + advanced: True + webSocketTimeoutMs: + description: Duration (in milliseconds) to wait for a response from the SOC server websocket before giving up and reconnecting. + global: True + advanced: True + tipTimeoutMs: + description: Duration (in milliseconds) to show the popup tips, which typically indicate a successful operation. + global: True + cacheExpirationMs: + description: Duration (in milliseconds) of cached data within the browser, including users and settings. global: True advanced: True casesEnabled: - description: Set to true if the SOC case management module, natively integrated with Elasticsearch, should be enabled. + description: Set to true to enable case management in SOC. + global: True + inactiveTools: + description: List of external tools to remove from the SOC UI. + global: True + tools: + description: List of available external tools visible in the SOC UI. Each tool is defined in JSON object notation, and must include the "name" key and "link" key, where the link is the tool's URL. global: True advanced: True - extractCommonObservables: - description: List of indexed fields to automatically extract into a case observable, when attaching related events to a case. - global: True - timeShiftMs: - description: Duration (in milliseconds) to further expand the PCAP time range when querying PCAP data related to an event. This duration is added to the normal duration value (see defaultDurationMs). - global: True - advanced: True - defaultDurationMs: - description: Duration (in milliseconds) to add before and after the event's timestamp, when querying PCAP data related to the event. If the PCAP-related event record itself has an event.duration value, it will be used instead of this default. - global: True - advanced: True - esSearchOffsetMs: - description: Duration (in milliseconds) to add before and after the selected event's timestamp, when looking up PCAP-related events in order to pivot to PCAP. - global: True - advanced: True - maxLogLength: - description: The maximum length of an Elasticsearch related log line that is output to the Sensoroni log file. This prevents massive Elasticsearch responses from being dumped into the text log file on disk. - global: True - advanced: True - asyncThreshold: - description: Maximum number of events that can be acknowledged synchronously. When acknowledging large numbers of events, where the count exceeds this value, the acknowledge update will be performed in the background, as it can take several minutes to complete. - global: True - advanced: True - sostatus: - refreshIntervalMs: - description: Duration (in milliseconds) between refreshes of the grid status. Shortening this duration may not have expected results, as the backend systems feeding this sostatus data will continue their updates as scheduled. - global: True - advanced: True - offlineThresholdMs: - description: Duration (in milliseconds) that must elapse after a grid node fails to check-in before the node will be marked offline (fault). - global: True - advanced: True - client: - apiTimeoutMs: - description: Duration (in milliseconds) to wait for a response from the SOC server API before giving up and showing an error on the SOC UI. - global: True - advanced: True - webSocketTimeoutMs: - description: Duration (in milliseconds) to wait for a response from the SOC server websocket before giving up and reconnecting. - global: True - advanced: True - tipTimeoutMs: - description: Duration (in milliseconds) to show the popup tips, which typically indicate a successful operation. - global: True - cacheExpirationMs: - description: Duration (in milliseconds) of cached data within the browser, including users and settings. - global: True - advanced: True - casesEnabled: - description: Set to true to enable case management in SOC. - global: True - inactiveTools: - description: List of external tools to remove from the SOC UI. - global: True - tools: - description: List of available external tools visible in the SOC UI. Each tool is defined in JSON object notation, and must include the "name" key and "link" key, where the link is the tool's URL. - global: True - advanced: True - hunt: &appSettings - groupItemsPerPage: - description: Default number of aggregations to show per page. Larger values consume more vertical area in the SOC UI. - global: True - groupFetchLimit: - description: Default maximum number of aggregations to retrieve per search. Larger values consume more bandwidth and server resources. - global: True - eventItemsPerPage: - description: Default number of items to show per page. Larger values consume more vertical area in the SOC UI. - global: True - eventFetchLimit: - description: Default maximum number of items to retrieve per search. Larger values consume more bandwidth and server resources. - global: True - relativeTimeValue: - description: The duration of time to look backwards when searching for items. Used in combination with the relativeTimeUnit setting. - global: True - relativeTimeUnit: - description: The unit of time for the relativeTimeValue setting. Possible values are 10 (seconds), 20 (minutes), 30 (hours), 40 (days), 50 (weeks), and 60 (months). - global: True - mostRecentlyUsedLimit: - description: Number of items to show in the most recently used queries list. Larger values cause default queries to be located further down the list. - global: True - queries: - description: List of default queries to show in the query list. Each query is represented in JSON object notation, and must include the "name" key and "query" key. - global: True - alerts: *appSettings - cases: *appSettings - dashboards: *appSettings - case: - analyzerNodeId: - description: The node ID on which analyzers will be executed. - global: True - advanced: True - mostRecentlyUsedLimit: - description: Number of items to show in the most recently used queries list. Larger values cause default queries to be located further down the list. - global: True - renderAbbreviatedCount: - description: When the number of case related items exceeds this number, the middle section of the results will be hidden from view, avoiding unnecessary scrolling. - global: True - advanced: True - presets: - artifactType: - labels: - description: List of available artifact types. Some of these default types have special characteristics and related functionality, built into SOC. - global: True - customEnabled: - description: Set to true to allow users add their own artifact types directly in the SOC UI. - global: True - category: - labels: - description: List of available case categories. - global: True - customEnabled: - description: Set to true to allow users add their own categories directly in the SOC UI. - global: True - pap: - labels: - description: List of available PAP (Permissible Actions Protocol) values. - global: True - customEnabled: - description: Set to true to allow users add their own PAP values directly in the SOC UI. - global: True - severity: - labels: - description: List of available case severities. - global: True - customEnabled: - description: Set to true to allow users add their own severities directly in the SOC UI. - global: True - status: - labels: - description: List of available case statuses. Some statuses have specifial characteristics and related functionality built into SOC. - global: True - customEnabled: - description: Set to true to allow users add their own case statuses directly in the SOC UI. - global: True - tags: - labels: - description: List of available tags. - global: True - customEnabled: - description: Set to true to allow users add their own tags directly in the SOC UI. - global: True - tlp: - labels: - description: List of available TLP (Traffic Light Protocol) values. - global: True - customEnabled: - description: Set to true to allow users add their own TLP values directly in the SOC UI. - global: True + hunt: &appSettings + groupItemsPerPage: + description: Default number of aggregations to show per page. Larger values consume more vertical area in the SOC UI. + global: True + groupFetchLimit: + description: Default maximum number of aggregations to retrieve per search. Larger values consume more bandwidth and server resources. + global: True + eventItemsPerPage: + description: Default number of items to show per page. Larger values consume more vertical area in the SOC UI. + global: True + eventFetchLimit: + description: Default maximum number of items to retrieve per search. Larger values consume more bandwidth and server resources. + global: True + relativeTimeValue: + description: The duration of time to look backwards when searching for items. Used in combination with the relativeTimeUnit setting. + global: True + relativeTimeUnit: + description: The unit of time for the relativeTimeValue setting. Possible values are 10 (seconds), 20 (minutes), 30 (hours), 40 (days), 50 (weeks), and 60 (months). + global: True + mostRecentlyUsedLimit: + description: Number of items to show in the most recently used queries list. Larger values cause default queries to be located further down the list. + global: True + queries: + description: List of default queries to show in the query list. Each query is represented in JSON object notation, and must include the "name" key and "query" key. + global: True + alerts: *appSettings + cases: *appSettings + dashboards: *appSettings + case: + analyzerNodeId: + description: The node ID on which analyzers will be executed. + global: True + advanced: True + mostRecentlyUsedLimit: + description: Number of items to show in the most recently used queries list. Larger values cause default queries to be located further down the list. + global: True + renderAbbreviatedCount: + description: When the number of case related items exceeds this number, the middle section of the results will be hidden from view, avoiding unnecessary scrolling. + global: True + advanced: True + presets: + artifactType: + labels: + description: List of available artifact types. Some of these default types have special characteristics and related functionality, built into SOC. + global: True + customEnabled: + description: Set to true to allow users add their own artifact types directly in the SOC UI. + global: True + category: + labels: + description: List of available case categories. + global: True + customEnabled: + description: Set to true to allow users add their own categories directly in the SOC UI. + global: True + pap: + labels: + description: List of available PAP (Permissible Actions Protocol) values. + global: True + customEnabled: + description: Set to true to allow users add their own PAP values directly in the SOC UI. + global: True + severity: + labels: + description: List of available case severities. + global: True + customEnabled: + description: Set to true to allow users add their own severities directly in the SOC UI. + global: True + status: + labels: + description: List of available case statuses. Some statuses have specifial characteristics and related functionality built into SOC. + global: True + customEnabled: + description: Set to true to allow users add their own case statuses directly in the SOC UI. + global: True + tags: + labels: + description: List of available tags. + global: True + customEnabled: + description: Set to true to allow users add their own tags directly in the SOC UI. + global: True + tlp: + labels: + description: List of available TLP (Traffic Light Protocol) values. + global: True + customEnabled: + description: Set to true to allow users add their own TLP values directly in the SOC UI. + global: True diff --git a/salt/soc/sostatus.sls b/salt/soc/sostatus.sls new file mode 100644 index 000000000..67640ea4d --- /dev/null +++ b/salt/soc/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-soc_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-soc + - unless: grep -q so-soc /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From fa1a428133006dc5c8038df960623f308babcf99 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 15:36:20 -0400 Subject: [PATCH 41/68] fix import --- salt/soc/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/soc/init.sls b/salt/soc/init.sls index a7feb059a..64531d814 100644 --- a/salt/soc/init.sls +++ b/salt/soc/init.sls @@ -3,7 +3,7 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% from 'soc/config.map.jinja' import SOCMERGED %} +{% from 'soc/merged.map.jinja' import SOCMERGED %} include: {% if SOCMERGED.enabled %} From e342dae8186a88eb52bf8d2721c25e952e7b8826 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 11 May 2023 16:14:52 -0400 Subject: [PATCH 42/68] put srvKey under soc:config:server --- setup/so-functions | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/so-functions b/setup/so-functions index 1a96d4bd0..992e7f2cb 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1400,8 +1400,9 @@ soc_pillar() { touch $adv_soc_pillar_file printf '%s\n'\ "soc:"\ - " server:"\ - " srvKey: '$SOCSRVKEY'"\ + " config:"\ + " server:"\ + " srvKey: '$SOCSRVKEY'"\ "" > "$soc_pillar_file" } From 00d1ca0b62a3e8677954aef1373d8716f708e7be Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 14:26:46 -0400 Subject: [PATCH 43/68] configure and enable/disable sensoroni via ui --- salt/manager/tools/sbin/so-minion | 30 ++++++++-- salt/sensoroni/config.sls | 60 ++++++++++++++++++++ salt/sensoroni/defaults.yaml | 11 ++++ salt/sensoroni/disabled.sls | 16 ++++++ salt/sensoroni/enabled.sls | 32 +++++++++++ salt/sensoroni/files/sensoroni.json | 32 +++-------- salt/sensoroni/init.sls | 88 ++++------------------------- salt/sensoroni/map.jinja | 7 +++ salt/sensoroni/soc_sensoroni.yaml | 50 ++++++++++------ salt/sensoroni/sostatus.sls | 10 ++++ salt/vars/globals.map.jinja | 3 +- 11 files changed, 216 insertions(+), 123 deletions(-) create mode 100644 salt/sensoroni/config.sls create mode 100644 salt/sensoroni/defaults.yaml create mode 100644 salt/sensoroni/disabled.sls create mode 100644 salt/sensoroni/enabled.sls create mode 100644 salt/sensoroni/map.jinja create mode 100644 salt/sensoroni/sostatus.sls diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 4e5f97678..8b23dcd44 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -182,7 +182,9 @@ function add_analyst_to_minion() { " gui:"\ " enabled: true"\ "sensoroni:"\ - " node_description: '${NODE_DESCRIPTION//\'/''}'" >> $PILLARFILE + " enabled: True"\ + " config:"\ + " node_description: '${NODE_DESCRIPTION//\'/''}'" >> $PILLARFILE } # Add basic host info to the minion file @@ -195,12 +197,25 @@ function add_host_to_minion() { # Add sensoroni specific information - Can we pull node_adrees from the host pillar? function add_sensoroni_to_minion() { - printf '%s\n'\ "sensoroni:"\ - " node_description: '${NODE_DESCRIPTION//\'/''}'"\ + " enabled: True"\ + " config:"\ + " node_description: '${NODE_DESCRIPTION//\'/''}'"\ " " >> $PILLARFILE -} +} + +# Add sensoroni specific information - Can we pull node_adrees from the host pillar? +function add_sensoroni_with_analyze_to_minion() { + printf '%s\n'\ + "sensoroni:"\ + " enabled: True"\ + " config:"\ + " analyze:"\ + " enabled: True"\ + " node_description: '${NODE_DESCRIPTION//\'/''}'"\ + " " >> $PILLARFILE +} # Sensor settings for the minion pillar function add_sensor_to_minion() { @@ -506,7 +521,12 @@ if [[ "$OPERATION" = 'add' || "$OPERATION" = 'setup' ]]; then fi create_minion_files add_host_to_minion - add_sensoroni_to_minion + managers=("EVAL" "STANDALONE" "IMPORT" "MANAGER" "MANAGERSEARCH") + if echo "${managers[@]}" | grep -qw "$NODETYPE"; then + add_sensoroni_with_analyze_to_minion + else + add_sensoroni_to_minion + fi create$NODETYPE echo "Minion file created for $MINION_ID" fi diff --git a/salt/sensoroni/config.sls b/salt/sensoroni/config.sls new file mode 100644 index 000000000..0024ca962 --- /dev/null +++ b/salt/sensoroni/config.sls @@ -0,0 +1,60 @@ +# 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. + +sensoroniconfdir: + file.directory: + - name: /opt/so/conf/sensoroni + - user: 939 + - group: 939 + - makedirs: True + +sensoroniagentconf: + file.managed: + - name: /opt/so/conf/sensoroni/sensoroni.json + - source: salt://sensoroni/files/sensoroni.json + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + +analyzersdir: + file.directory: + - name: /opt/so/conf/sensoroni/analyzers + - user: 939 + - group: 939 + - makedirs: True + +sensoronilog: + file.directory: + - name: /opt/so/log/sensoroni + - user: 939 + - group: 939 + - makedirs: True + +analyzerscripts: + file.recurse: + - name: /opt/so/conf/sensoroni/analyzers + - user: 939 + - group: 939 + - file_mode: 755 + - template: jinja + - source: salt://sensoroni/files/analyzers + +sensoroni_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://sensoroni/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#sensoroni_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://sensoroni/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja diff --git a/salt/sensoroni/defaults.yaml b/salt/sensoroni/defaults.yaml new file mode 100644 index 000000000..96e4e9abb --- /dev/null +++ b/salt/sensoroni/defaults.yaml @@ -0,0 +1,11 @@ +sensoroni: + enabled: False + config: + analyze: + enabled: False + analyze_timeout_ms: 900000 + analyze_parallel_limit: 5 + node_checkin_interval_ms: 10000 + node_description: + sensoronikey: + soc_host: diff --git a/salt/sensoroni/disabled.sls b/salt/sensoroni/disabled.sls new file mode 100644 index 000000000..ff4f4a49b --- /dev/null +++ b/salt/sensoroni/disabled.sls @@ -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. + +include: + - sensoroni.sostatus + +so-sensoroni: + docker_container.absent: + - force: True + +so-zeek_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-sensoroni$ diff --git a/salt/sensoroni/enabled.sls b/salt/sensoroni/enabled.sls new file mode 100644 index 000000000..9dbdf3eba --- /dev/null +++ b/salt/sensoroni/enabled.sls @@ -0,0 +1,32 @@ +# 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 'vars/globals.map.jinja' import GLOBALS %} + +include: + - sensoroni.config + - sensoroni.sostatus + +so-sensoroni: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-soc:{{ GLOBALS.so_version }} + - network_mode: host + - binds: + - /opt/so/conf/steno/certs:/etc/stenographer/certs:rw + - /nsm/pcap:/nsm/pcap:rw + - /nsm/import:/nsm/import:rw + - /nsm/pcapout:/nsm/pcapout:rw + - /opt/so/conf/sensoroni/sensoroni.json:/opt/sensoroni/sensoroni.json:ro + - /opt/so/conf/sensoroni/analyzers:/opt/sensoroni/analyzers:rw + - /opt/so/log/sensoroni:/opt/sensoroni/logs:rw + - watch: + - file: /opt/so/conf/sensoroni/sensoroni.json + - require: + - file: sensoroniagentconf + +delete_so-zeek_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-sensoroni$ diff --git a/salt/sensoroni/files/sensoroni.json b/salt/sensoroni/files/sensoroni.json index 4b545f5e0..05bb63171 100644 --- a/salt/sensoroni/files/sensoroni.json +++ b/salt/sensoroni/files/sensoroni.json @@ -1,43 +1,29 @@ -{%- from 'vars/globals.map.jinja' import GLOBALS -%} -{%- set ANALYZE_TIMEOUT_MS = salt['pillar.get']('sensoroni:analyze_timeout_ms', 900000) %} -{%- set ANALYZE_PARALLEL_LIMIT = salt['pillar.get']('sensoroni:analyze_parallel_limit', 5) %} -{%- set CHECKININTERVALMS = salt['pillar.get']('sensoroni:node_checkin_interval_ms', 10000) %} -{%- set ROLE = grains.id.split('_') | last %} -{%- if ROLE in ['eval', 'standalone', 'sensor', 'heavynode'] %} -{%- set STENODEFAULT = True %} -{%- else %} -{%- set STENODEFAULT = False %} -{%- endif %} -{%- set STENOENABLED = salt['pillar.get']('steno:enabled', STENODEFAULT) %} -{%- if ROLE in ['eval', 'standalone', 'import', 'manager', 'managersearch'] %} -{%- set ANALYZEDEFAULT = True %} -{%- else %} -{%- set ANALYZEDEFAULT = False %} -{%- endif %} -{%- set ANALYZEENABLED = salt['pillar.get']('sensoroni:analyze_enabled', ANALYZEDEFAULT) %} +{%- from 'vars/globals.map.jinja' import GLOBALS %} +{%- from 'sensoroni/map.jinja' import SENSORONIMERGED %} +{%- from 'pcap/config.map.jinja' import PCAPMERGED %} { "logFilename": "/opt/sensoroni/logs/sensoroni.log", "logLevel":"info", "agent": { "nodeId": "{{ GLOBALS.hostname | lower }}", "role": "{{ GLOBALS.role }}", - "description": {{ GLOBALS.description | tojson }}, + "description": {{ SENSORONIMERGED.config.node_description | tojson }}, "address": "{{ GLOBALS.node_ip }}", "model": "{{ GLOBALS.so_model }}", - "pollIntervalMs": {{ CHECKININTERVALMS if CHECKININTERVALMS else 10000 }}, + "pollIntervalMs": {{ SENSORONIMERGED.config.node_checkin_interval_ms }}, "serverUrl": "https://{{ GLOBALS.url_base }}/sensoroniagents", "verifyCert": false, "modules": { -{%- if ANALYZEENABLED %} +{%- if SENSORONIMERGED.config.analyze.enabled %} "analyze": { - "timeoutMs": {{ ANALYZE_TIMEOUT_MS }}, - "parallelLimit": {{ ANALYZE_PARALLEL_LIMIT }} + "timeoutMs": {{ SENSORONIMERGED.config.analyze_timeout_ms }}, + "parallelLimit": {{ SENSORONIMERGED.config.analyze_parallel_limit }} }, {%- endif %} "importer": {}, "statickeyauth": { "apiKey": "{{ GLOBALS.sensoroni_key }}" -{%- if STENOENABLED %} +{%- if PCAPMERGED.enabled %} }, "stenoquery": { "executablePath": "/opt/sensoroni/scripts/stenoquery.sh", diff --git a/salt/sensoroni/init.sls b/salt/sensoroni/init.sls index df6b99948..98d13ca15 100644 --- a/salt/sensoroni/init.sls +++ b/salt/sensoroni/init.sls @@ -1,79 +1,13 @@ -{% from 'vars/globals.map.jinja' import GLOBALS %} +# 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. -sensoroniconfdir: - file.directory: - - name: /opt/so/conf/sensoroni - - user: 939 - - group: 939 - - makedirs: True +{% from 'sensoroni/map.jinja' import SENSORONIMERGED %} -sensoroniagentconf: - file.managed: - - name: /opt/so/conf/sensoroni/sensoroni.json - - source: salt://sensoroni/files/sensoroni.json - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - -analyzersdir: - file.directory: - - name: /opt/so/conf/sensoroni/analyzers - - user: 939 - - group: 939 - - makedirs: True - -sensoronilog: - file.directory: - - name: /opt/so/log/sensoroni - - user: 939 - - group: 939 - - makedirs: True - -analyzerscripts: - file.recurse: - - name: /opt/so/conf/sensoroni/analyzers - - user: 939 - - group: 939 - - file_mode: 755 - - template: jinja - - source: salt://sensoroni/files/analyzers - -sensoroni_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://sensoroni/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#sensoroni_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://sensoroni/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -so-sensoroni: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-soc:{{ GLOBALS.so_version }} - - network_mode: host - - binds: - - /opt/so/conf/steno/certs:/etc/stenographer/certs:rw - - /nsm/pcap:/nsm/pcap:rw - - /nsm/import:/nsm/import:rw - - /nsm/pcapout:/nsm/pcapout:rw - - /opt/so/conf/sensoroni/sensoroni.json:/opt/sensoroni/sensoroni.json:ro - - /opt/so/conf/sensoroni/analyzers:/opt/sensoroni/analyzers:rw - - /opt/so/log/sensoroni:/opt/sensoroni/logs:rw - - watch: - - file: /opt/so/conf/sensoroni/sensoroni.json - - require: - - file: sensoroniagentconf - -append_so-sensoroni_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-sensoroni +include: +{% if SENSORONIMERGED.enabled %} + - sensoroni.enabled +{% else %} + - sensoroni.disabled +{% endif %} diff --git a/salt/sensoroni/map.jinja b/salt/sensoroni/map.jinja new file mode 100644 index 000000000..228daa910 --- /dev/null +++ b/salt/sensoroni/map.jinja @@ -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 'sensoroni/defaults.yaml' as SENSORONIDEFAULTS %} +{% set SENSORONIMERGED = salt['pillar.get']('sensoroni', SENSORONIDEFAULTS.sensoroni, merge=True) %} diff --git a/salt/sensoroni/soc_sensoroni.yaml b/salt/sensoroni/soc_sensoroni.yaml index 6f6a75452..af6760f07 100644 --- a/salt/sensoroni/soc_sensoroni.yaml +++ b/salt/sensoroni/soc_sensoroni.yaml @@ -1,19 +1,37 @@ sensoroni: - node_checkin_interval_ms: - description: Interval in ms to checkin to the soc_host. + enabled: + description: Enable or disable Sensoroni. advanced: True helpLink: sensoroni.html - node_description: - description: Description of the specific node. - helpLink: sensoroni.html - sensoronikey: - description: Shared key for sensoroni authentication. - helpLink: sensoroni.html - global: True - sensitive: True - advanced: True - soc_host: - description: Host for sensoroni agents to connect to. - helpLink: sensoroni.html - global: True - advanced: True \ No newline at end of file + config: + analyze: + enabled: + description: Enable or disable the analyzer. + advanced: True + helpLink: sensoroni.html + analyze_timeout_ms: + description: Timeout period for the analyzer. + advanced: True + helpLink: sensoroni.html + analyze_parallel_limit: + description: Parallel limit for the analyzer. + advanced: True + helpLink: sensoroni.html + node_checkin_interval_ms: + description: Interval in ms to checkin to the soc_host. + advanced: True + helpLink: sensoroni.html + node_description: + description: Description of the specific node. + helpLink: sensoroni.html + sensoronikey: + description: Shared key for sensoroni authentication. + helpLink: sensoroni.html + global: True + sensitive: True + advanced: True + soc_host: + description: Host for sensoroni agents to connect to. + helpLink: sensoroni.html + global: True + advanced: True diff --git a/salt/sensoroni/sostatus.sls b/salt/sensoroni/sostatus.sls new file mode 100644 index 000000000..97d918e9d --- /dev/null +++ b/salt/sensoroni/sostatus.sls @@ -0,0 +1,10 @@ +# 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. + +append_so-zeek_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-sensoroni + - unless: grep -q so-sensoroni /opt/so/conf/so-status/so-status.conf diff --git a/salt/vars/globals.map.jinja b/salt/vars/globals.map.jinja index 578432799..a56fad571 100644 --- a/salt/vars/globals.map.jinja +++ b/salt/vars/globals.map.jinja @@ -26,8 +26,7 @@ 'so_docker_range': DOCKER.sorange, 'url_base': INIT.PILLAR.global.url_base, 'so_model': INIT.GRAINS.get('sosmodel',''), - 'description': INIT.PILLAR.sensoroni.get('node_description',''), - 'sensoroni_key': INIT.PILLAR.sensoroni.sensoronikey, + 'sensoroni_key': INIT.PILLAR.sensoroni.config.sensoronikey, 'os': INIT.GRAINS.os, 'application_urls': {}, 'manager_roles': [ From 05a81596e52931a856fe6fd790fa5564efc7e9a2 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 14:38:39 -0400 Subject: [PATCH 44/68] place and access sensoronikey from sensoroni.config --- salt/soc/defaults.map.jinja | 2 +- setup/so-functions | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/salt/soc/defaults.map.jinja b/salt/soc/defaults.map.jinja index 9b9606cf2..d816752c0 100644 --- a/salt/soc/defaults.map.jinja +++ b/salt/soc/defaults.map.jinja @@ -30,7 +30,7 @@ {% endif %} {% endfor %} -{% do SOCDEFAULTS.soc.config.server.modules.statickeyauth.update({'anonymousCidr': DOCKER.sorange, 'apiKey': pillar.sensoroni.sensoronikey}) %} +{% do SOCDEFAULTS.soc.config.server.modules.statickeyauth.update({'anonymousCidr': DOCKER.sorange, 'apiKey': pillar.sensoroni.config.sensoronikey}) %} {% do SOCDEFAULTS.soc.config.server.client.case.update({'analyzerNodeId': GLOBALS.hostname}) %} diff --git a/setup/so-functions b/setup/so-functions index 992e7f2cb..a51af57b1 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1496,9 +1496,10 @@ create_sensoroni_pillar() { printf '%s\n'\ "sensoroni:"\ - " node_checkin_interval_ms: $NODE_CHECKIN_INTERVAL_MS"\ - " sensoronikey: '$SENSORONIKEY'"\ - " soc_host: '$REDIRECTIT'" > $sensoroni_pillar_file + " config:"\ + " node_checkin_interval_ms: $NODE_CHECKIN_INTERVAL_MS"\ + " sensoronikey: '$SENSORONIKEY'"\ + " soc_host: '$REDIRECTIT'" > $sensoroni_pillar_file } From d1f7e5f4a7e6467dea5f44785c372cb223c7ccae Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 14:57:55 -0400 Subject: [PATCH 45/68] fix and rename timeout_ms and parallel_limit --- salt/sensoroni/defaults.yaml | 4 ++-- salt/sensoroni/files/sensoroni.json | 4 ++-- salt/sensoroni/soc_sensoroni.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/salt/sensoroni/defaults.yaml b/salt/sensoroni/defaults.yaml index 96e4e9abb..88b207d45 100644 --- a/salt/sensoroni/defaults.yaml +++ b/salt/sensoroni/defaults.yaml @@ -3,8 +3,8 @@ sensoroni: config: analyze: enabled: False - analyze_timeout_ms: 900000 - analyze_parallel_limit: 5 + timeout_ms: 900000 + parallel_limit: 5 node_checkin_interval_ms: 10000 node_description: sensoronikey: diff --git a/salt/sensoroni/files/sensoroni.json b/salt/sensoroni/files/sensoroni.json index 05bb63171..59ce500e3 100644 --- a/salt/sensoroni/files/sensoroni.json +++ b/salt/sensoroni/files/sensoroni.json @@ -16,8 +16,8 @@ "modules": { {%- if SENSORONIMERGED.config.analyze.enabled %} "analyze": { - "timeoutMs": {{ SENSORONIMERGED.config.analyze_timeout_ms }}, - "parallelLimit": {{ SENSORONIMERGED.config.analyze_parallel_limit }} + "timeoutMs": {{ SENSORONIMERGED.config.analyze.timeout_ms }}, + "parallelLimit": {{ SENSORONIMERGED.config.analyze.parallel_limit }} }, {%- endif %} "importer": {}, diff --git a/salt/sensoroni/soc_sensoroni.yaml b/salt/sensoroni/soc_sensoroni.yaml index af6760f07..859a60d0c 100644 --- a/salt/sensoroni/soc_sensoroni.yaml +++ b/salt/sensoroni/soc_sensoroni.yaml @@ -9,11 +9,11 @@ sensoroni: description: Enable or disable the analyzer. advanced: True helpLink: sensoroni.html - analyze_timeout_ms: + timeout_ms: description: Timeout period for the analyzer. advanced: True helpLink: sensoroni.html - analyze_parallel_limit: + parallel_limit: description: Parallel limit for the analyzer. advanced: True helpLink: sensoroni.html From aa2f168b73c6d6115edb9a43aef28faa1fec5912 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 15:12:12 -0400 Subject: [PATCH 46/68] make node_description a string --- salt/sensoroni/defaults.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/sensoroni/defaults.yaml b/salt/sensoroni/defaults.yaml index 88b207d45..b29b8cebf 100644 --- a/salt/sensoroni/defaults.yaml +++ b/salt/sensoroni/defaults.yaml @@ -6,6 +6,6 @@ sensoroni: timeout_ms: 900000 parallel_limit: 5 node_checkin_interval_ms: 10000 - node_description: + node_description: '' sensoronikey: soc_host: From b06610088a9f3a4211aa405eba97bc76d10f04ed Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 15:15:21 -0400 Subject: [PATCH 47/68] fix so-status state names --- salt/sensoroni/disabled.sls | 2 +- salt/sensoroni/enabled.sls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/sensoroni/disabled.sls b/salt/sensoroni/disabled.sls index ff4f4a49b..4822406f9 100644 --- a/salt/sensoroni/disabled.sls +++ b/salt/sensoroni/disabled.sls @@ -10,7 +10,7 @@ so-sensoroni: docker_container.absent: - force: True -so-zeek_so-status.disabled: +so-sensoroni_so-status.disabled: file.comment: - name: /opt/so/conf/so-status/so-status.conf - regex: ^so-sensoroni$ diff --git a/salt/sensoroni/enabled.sls b/salt/sensoroni/enabled.sls index 9dbdf3eba..e506de49d 100644 --- a/salt/sensoroni/enabled.sls +++ b/salt/sensoroni/enabled.sls @@ -26,7 +26,7 @@ so-sensoroni: - require: - file: sensoroniagentconf -delete_so-zeek_so-status.disabled: +delete_so-sensoroni_so-status.disabled: file.uncomment: - name: /opt/so/conf/so-status/so-status.conf - regex: ^so-sensoroni$ From 0860b1501e237cae2ef80f8804836f3c642684f0 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 15:17:51 -0400 Subject: [PATCH 48/68] fix so-status state name --- salt/sensoroni/sostatus.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/sensoroni/sostatus.sls b/salt/sensoroni/sostatus.sls index 97d918e9d..fac2dac4d 100644 --- a/salt/sensoroni/sostatus.sls +++ b/salt/sensoroni/sostatus.sls @@ -3,7 +3,7 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -append_so-zeek_so-status.conf: +append_so-sensoroni_so-status.conf: file.append: - name: /opt/so/conf/so-status/so-status.conf - text: so-sensoroni From 277ad61920f5b9d0bb084ad4fd31134a4efc9978 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 15:49:13 -0400 Subject: [PATCH 49/68] enabled/disable registry in ui --- salt/manager/tools/sbin/so-minion | 12 ++++++++++++ salt/registry/config.sls | 0 salt/registry/defaults.yaml | 0 salt/registry/disabled.sls | 27 +++++++++++++++++++++++++++ salt/registry/enabled.sls | 0 salt/registry/map.jinja | 0 salt/registry/soc_registry.yaml | 0 salt/registry/sostatus.sls | 21 +++++++++++++++++++++ 8 files changed, 60 insertions(+) create mode 100644 salt/registry/config.sls create mode 100644 salt/registry/defaults.yaml create mode 100644 salt/registry/disabled.sls create mode 100644 salt/registry/enabled.sls create mode 100644 salt/registry/map.jinja create mode 100644 salt/registry/soc_registry.yaml create mode 100644 salt/registry/sostatus.sls diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 8b23dcd44..601a23682 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -324,6 +324,13 @@ function add_soc_to_minion() { " " >> $PILLARFILE } +function add_registry_to_minion() { + printf '%s\n'\ + "registry:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -379,6 +386,7 @@ function createEVAL() { add_nginx_to_minion add_soctopus_to_minion add_soc_to_minion + add_registry_to_minion } function createSTANDALONE() { @@ -396,6 +404,7 @@ function createSTANDALONE() { add_nginx_to_minion add_soctopus_to_minion add_soc_to_minion + add_registry_to_minion } function createMANAGER() { @@ -411,6 +420,7 @@ function createMANAGER() { add_nginx_to_minion add_soctopus_to_minion add_soc_to_minion + add_registry_to_minion } function createMANAGERSEARCH() { @@ -426,6 +436,7 @@ function createMANAGERSEARCH() { add_nginx_to_minion add_soctopus_to_minion add_soc_to_minion + add_registry_to_minion } function createIMPORT() { @@ -436,6 +447,7 @@ function createIMPORT() { add_influxdb_to_minion add_nginx_to_minion add_soc_to_minion + add_registry_to_minion } function createFLEET() { diff --git a/salt/registry/config.sls b/salt/registry/config.sls new file mode 100644 index 000000000..e69de29bb diff --git a/salt/registry/defaults.yaml b/salt/registry/defaults.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/salt/registry/disabled.sls b/salt/registry/disabled.sls new file mode 100644 index 000000000..3029b6e37 --- /dev/null +++ b/salt/registry/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - registry.sostatus + +so-registry: + docker_container.absent: + - force: True + +so-registry_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-registry$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/registry/enabled.sls b/salt/registry/enabled.sls new file mode 100644 index 000000000..e69de29bb diff --git a/salt/registry/map.jinja b/salt/registry/map.jinja new file mode 100644 index 000000000..e69de29bb diff --git a/salt/registry/soc_registry.yaml b/salt/registry/soc_registry.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/salt/registry/sostatus.sls b/salt/registry/sostatus.sls new file mode 100644 index 000000000..f4e5e5e24 --- /dev/null +++ b/salt/registry/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-registry_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-registry + - unless: grep -q so-registry /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From 4440ecd43390283c98fec08dbf0251ca18b8416f Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 15:51:00 -0400 Subject: [PATCH 50/68] enabled/disable registry in ui --- salt/registry/config.sls | 46 ++++++++++++++++++ salt/registry/defaults.yaml | 2 + salt/registry/enabled.sls | 55 ++++++++++++++++++++++ salt/registry/init.sls | 83 ++++----------------------------- salt/registry/map.jinja | 7 +++ salt/registry/soc_registry.yaml | 4 ++ 6 files changed, 124 insertions(+), 73 deletions(-) diff --git a/salt/registry/config.sls b/salt/registry/config.sls index e69de29bb..098633829 100644 --- a/salt/registry/config.sls +++ b/salt/registry/config.sls @@ -0,0 +1,46 @@ +# 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 %} + +include: + - ssl + +# Create the config directory for the docker registry +dockerregistryconfdir: + file.directory: + - name: /opt/so/conf/docker-registry/etc + - user: 939 + - group: 939 + - makedirs: True + +dockerregistrydir: + file.directory: + - name: /nsm/docker-registry/docker + - user: 939 + - group: 939 + - makedirs: True + +dockerregistrylogdir: + file.directory: + - name: /opt/so/log/docker-registry + - user: 939 + - group: 939 + - makedirs: true + +# Copy the config +dockerregistryconf: + file.managed: + - name: /opt/so/conf/docker-registry/etc/config.yml + - source: salt://registry/etc/config.yml + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/registry/defaults.yaml b/salt/registry/defaults.yaml index e69de29bb..f6d2b2946 100644 --- a/salt/registry/defaults.yaml +++ b/salt/registry/defaults.yaml @@ -0,0 +1,2 @@ +registry: + enabled: False diff --git a/salt/registry/enabled.sls b/salt/registry/enabled.sls index e69de29bb..fc0e07441 100644 --- a/salt/registry/enabled.sls +++ b/salt/registry/enabled.sls @@ -0,0 +1,55 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} + +include: + - registry.config + - registry.sostatus + +# Install the registry container +so-dockerregistry: + docker_container.running: + - image: ghcr.io/security-onion-solutions/registry:latest + - hostname: so-registry + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-dockerregistry'].ip }} + - restart_policy: always + - port_bindings: + {% for BINDING in DOCKER.containers['so-dockerregistry'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - binds: + - /opt/so/conf/docker-registry/etc/config.yml:/etc/docker/registry/config.yml:ro + - /opt/so/conf/docker-registry:/var/lib/registry:rw + - /nsm/docker-registry/docker:/var/lib/registry/docker:rw + - /etc/pki/registry.crt:/etc/pki/registry.crt:ro + - /etc/pki/registry.key:/etc/pki/registry.key:ro + - client_timeout: 180 + - environment: + - HOME=/root + - retry: + attempts: 5 + interval: 30 + - require: + - file: dockerregistryconf + - x509: registry_crt + - x509: registry_key + +delete_so-registry_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-registry$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/registry/init.sls b/salt/registry/init.sls index cb8035e44..b2b5912f2 100644 --- a/salt/registry/init.sls +++ b/salt/registry/init.sls @@ -1,77 +1,14 @@ -{% from 'allowed_states.map.jinja' import allowed_states %} -{% if sls in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} + +# 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 'registry/map.jinja' import REGISTRYMERGED %} include: - - ssl - -# Create the config directory for the docker registry -dockerregistryconfdir: - file.directory: - - name: /opt/so/conf/docker-registry/etc - - user: 939 - - group: 939 - - makedirs: True - -dockerregistrydir: - file.directory: - - name: /nsm/docker-registry/docker - - user: 939 - - group: 939 - - makedirs: True - -dockerregistrylogdir: - file.directory: - - name: /opt/so/log/docker-registry - - user: 939 - - group: 939 - - makedirs: true - -# Copy the config -dockerregistryconf: - file.managed: - - name: /opt/so/conf/docker-registry/etc/config.yml - - source: salt://registry/etc/config.yml - -# Install the registry container -so-dockerregistry: - docker_container.running: - - image: ghcr.io/security-onion-solutions/registry:latest - - hostname: so-registry - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-dockerregistry'].ip }} - - restart_policy: always - - port_bindings: - {% for BINDING in DOCKER.containers['so-dockerregistry'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - binds: - - /opt/so/conf/docker-registry/etc/config.yml:/etc/docker/registry/config.yml:ro - - /opt/so/conf/docker-registry:/var/lib/registry:rw - - /nsm/docker-registry/docker:/var/lib/registry/docker:rw - - /etc/pki/registry.crt:/etc/pki/registry.crt:ro - - /etc/pki/registry.key:/etc/pki/registry.key:ro - - client_timeout: 180 - - environment: - - HOME=/root - - retry: - attempts: 5 - interval: 30 - - require: - - file: dockerregistryconf - - x509: registry_crt - - x509: registry_key - -append_so-dockerregistry_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-dockerregistry - +{% if REGISTRYMERGED.enabled %} + - registry.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - registry.disabled {% endif %} diff --git a/salt/registry/map.jinja b/salt/registry/map.jinja index e69de29bb..d8b18b231 100644 --- a/salt/registry/map.jinja +++ b/salt/registry/map.jinja @@ -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 'registry/defaults.yaml' as REGISTRYDEFAULTS with context %} +{% set REGISTRYMERGED = salt['pillar.get']('registry', REGISTRYDEFAULTS.registry, merge=True) %} diff --git a/salt/registry/soc_registry.yaml b/salt/registry/soc_registry.yaml index e69de29bb..7fc3a161f 100644 --- a/salt/registry/soc_registry.yaml +++ b/salt/registry/soc_registry.yaml @@ -0,0 +1,4 @@ +registry: + enabled: + description: You can enable or disable the registry. + advanced: True From 57371ffe5af3edc557a3480102d896bbb3b1583e Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 16:05:23 -0400 Subject: [PATCH 51/68] fix so-status for dockerregistry --- salt/registry/disabled.sls | 4 ++-- salt/registry/enabled.sls | 4 ++-- salt/registry/sostatus.sls | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/salt/registry/disabled.sls b/salt/registry/disabled.sls index 3029b6e37..4c0b3edda 100644 --- a/salt/registry/disabled.sls +++ b/salt/registry/disabled.sls @@ -13,10 +13,10 @@ so-registry: docker_container.absent: - force: True -so-registry_so-status.disabled: +so-dockerregistry_so-status.disabled: file.comment: - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-registry$ + - regex: ^so-dockerregistry$ {% else %} diff --git a/salt/registry/enabled.sls b/salt/registry/enabled.sls index fc0e07441..0ce3ee318 100644 --- a/salt/registry/enabled.sls +++ b/salt/registry/enabled.sls @@ -41,10 +41,10 @@ so-dockerregistry: - x509: registry_crt - x509: registry_key -delete_so-registry_so-status.disabled: +delete_so-dockerregistry_so-status.disabled: file.uncomment: - name: /opt/so/conf/so-status/so-status.conf - - regex: ^so-registry$ + - regex: ^so-dockerregistry$ {% else %} diff --git a/salt/registry/sostatus.sls b/salt/registry/sostatus.sls index f4e5e5e24..ddfd187fd 100644 --- a/salt/registry/sostatus.sls +++ b/salt/registry/sostatus.sls @@ -6,11 +6,11 @@ {% from 'allowed_states.map.jinja' import allowed_states %} {% if sls.split('.')[0] in allowed_states %} -append_so-registry_so-status.conf: +append_so-dockerregistry_so-status.conf: file.append: - name: /opt/so/conf/so-status/so-status.conf - - text: so-registry - - unless: grep -q so-registry /opt/so/conf/so-status/so-status.conf + - text: so-dockerregistry + - unless: grep -q so-dockerregistry /opt/so/conf/so-status/so-status.conf {% else %} From e27e690bc889c66bce7c32480f2fddb1dfe8d058 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 16:07:49 -0400 Subject: [PATCH 52/68] fix disabled for registry --- salt/registry/disabled.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/registry/disabled.sls b/salt/registry/disabled.sls index 4c0b3edda..ac0a56d95 100644 --- a/salt/registry/disabled.sls +++ b/salt/registry/disabled.sls @@ -9,7 +9,7 @@ include: - registry.sostatus -so-registry: +so-dockerregistry: docker_container.absent: - force: True From 2a39f5f0b58bf2caa2301d7ceb941787544a5f11 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 16:27:18 -0400 Subject: [PATCH 53/68] enabled/disable mysql in ui --- salt/manager/tools/sbin/so-minion | 11 +++ salt/mysql/config.sls | 93 +++++++++++++++++++++ salt/mysql/defaults.yaml | 2 + salt/mysql/disabled.sls | 27 ++++++ salt/mysql/enabled.sls | 66 +++++++++++++++ salt/mysql/init.sls | 132 ++---------------------------- salt/mysql/map.jinja | 7 ++ salt/mysql/soc_mysql.yaml | 4 + salt/mysql/sostatus.sls | 21 +++++ 9 files changed, 237 insertions(+), 126 deletions(-) create mode 100644 salt/mysql/config.sls create mode 100644 salt/mysql/defaults.yaml create mode 100644 salt/mysql/disabled.sls create mode 100644 salt/mysql/enabled.sls create mode 100644 salt/mysql/map.jinja create mode 100644 salt/mysql/soc_mysql.yaml create mode 100644 salt/mysql/sostatus.sls diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 601a23682..3ec17f79f 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -331,6 +331,13 @@ function add_registry_to_minion() { " " >> $PILLARFILE } +function add_mysql_to_minion() { + printf '%s\n'\ + "mysql:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -387,6 +394,7 @@ function createEVAL() { add_soctopus_to_minion add_soc_to_minion add_registry_to_minion + add_mysql_to_minion } function createSTANDALONE() { @@ -405,6 +413,7 @@ function createSTANDALONE() { add_soctopus_to_minion add_soc_to_minion add_registry_to_minion + add_mysql_to_minion } function createMANAGER() { @@ -421,6 +430,7 @@ function createMANAGER() { add_soctopus_to_minion add_soc_to_minion add_registry_to_minion + add_mysql_to_minion } function createMANAGERSEARCH() { @@ -437,6 +447,7 @@ function createMANAGERSEARCH() { add_soctopus_to_minion add_soc_to_minion add_registry_to_minion + add_mysql_to_minion } function createIMPORT() { diff --git a/salt/mysql/config.sls b/salt/mysql/config.sls new file mode 100644 index 000000000..d8788c7c9 --- /dev/null +++ b/salt/mysql/config.sls @@ -0,0 +1,93 @@ +# 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 %} +{% set MYSQLPASS = salt['pillar.get']('secrets:mysql') %} + +# MySQL Setup +mysqlpkgs: + pkg.installed: + - skip_suggestions: False + - pkgs: + {% if grains['os'] != 'Rocky' %} + {% if grains['oscodename'] == 'bionic' %} + - python3-mysqldb + {% elif grains['oscodename'] == 'focal' %} + - python3-mysqldb + {% endif %} + {% else %} + - python3-mysqlclient + {% endif %} + +mysqletcdir: + file.directory: + - name: /opt/so/conf/mysql/etc + - user: 939 + - group: 939 + - makedirs: True + +mysqlpiddir: + file.directory: + - name: /opt/so/conf/mysql/pid + - user: 939 + - group: 939 + - makedirs: True + +mysqlcnf: + file.managed: + - name: /opt/so/conf/mysql/etc/my.cnf + - source: salt://mysql/etc/my.cnf + - user: 939 + - group: 939 + +mysqlpass: + file.managed: + - name: /opt/so/conf/mysql/etc/mypass + - source: salt://mysql/etc/mypass + - user: 939 + - group: 939 + - template: jinja + - defaults: + MYSQLPASS: {{ MYSQLPASS }} + +mysqllogdir: + file.directory: + - name: /opt/so/log/mysql + - user: 939 + - group: 939 + - makedirs: True + +mysqldatadir: + file.directory: + - name: /nsm/mysql + - user: 939 + - group: 939 + - makedirs: True + +mysql_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://mysql/tools/sbin + - user: 939 + - group: 939 + - file_mode: 755 + +#mysql_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://mysql/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/mysql/defaults.yaml b/salt/mysql/defaults.yaml new file mode 100644 index 000000000..87d8cef25 --- /dev/null +++ b/salt/mysql/defaults.yaml @@ -0,0 +1,2 @@ +mysql: + enabled: False diff --git a/salt/mysql/disabled.sls b/salt/mysql/disabled.sls new file mode 100644 index 000000000..805a755e4 --- /dev/null +++ b/salt/mysql/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - mysql.sostatus + +so-mysql: + docker_container.absent: + - force: True + +so-mysql_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-mysql$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/mysql/enabled.sls b/salt/mysql/enabled.sls new file mode 100644 index 000000000..12112121f --- /dev/null +++ b/salt/mysql/enabled.sls @@ -0,0 +1,66 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set MYSQLPASS = salt['pillar.get']('secrets:mysql') %} + +include: + - mysql.config + - mysql.sostatus + +{% if MYSQLPASS == None %} + +mysql_password_none: + test.configurable_test_state: + - changes: False + - result: False + - comment: "MySQL Password Error - Not Starting MySQL" + +{% else %} + +so-mysql: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-mysql:{{ GLOBALS.so_version }} + - hostname: so-mysql + - user: socore + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-mysql'].ip }} + - extra_hosts: + - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-mysql'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - environment: + - MYSQL_ROOT_HOST={{ GLOBALS.so_docker_bip }} + - MYSQL_ROOT_PASSWORD=/etc/mypass + - binds: + - /opt/so/conf/mysql/etc/my.cnf:/etc/my.cnf:ro + - /opt/so/conf/mysql/etc/mypass:/etc/mypass + - /nsm/mysql:/var/lib/mysql:rw + - /opt/so/log/mysql:/var/log/mysql:rw + - watch: + - /opt/so/conf/mysql/etc + - require: + - file: mysqlcnf + - file: mysqlpass +{% endif %} + +delete_so-mysql_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-mysql$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/mysql/init.sls b/salt/mysql/init.sls index 1c0ca70c0..48e4f558c 100644 --- a/salt/mysql/init.sls +++ b/salt/mysql/init.sls @@ -1,134 +1,14 @@ + # 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 in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{%- set MYSQLPASS = salt['pillar.get']('secrets:mysql') %} - -# MySQL Setup -mysqlpkgs: - pkg.installed: - - skip_suggestions: False - - pkgs: - {% if grains['os'] != 'Rocky' %} - {% if grains['oscodename'] == 'bionic' %} - - python3-mysqldb - {% elif grains['oscodename'] == 'focal' %} - - python3-mysqldb - {% endif %} - {% else %} - - python3-mysqlclient - {% endif %} - -mysqletcdir: - file.directory: - - name: /opt/so/conf/mysql/etc - - user: 939 - - group: 939 - - makedirs: True - -mysqlpiddir: - file.directory: - - name: /opt/so/conf/mysql/pid - - user: 939 - - group: 939 - - makedirs: True - -mysqlcnf: - file.managed: - - name: /opt/so/conf/mysql/etc/my.cnf - - source: salt://mysql/etc/my.cnf - - user: 939 - - group: 939 - -mysqlpass: - file.managed: - - name: /opt/so/conf/mysql/etc/mypass - - source: salt://mysql/etc/mypass - - user: 939 - - group: 939 - - template: jinja - - defaults: - MYSQLPASS: {{ MYSQLPASS }} - -mysqllogdir: - file.directory: - - name: /opt/so/log/mysql - - user: 939 - - group: 939 - - makedirs: True - -mysqldatadir: - file.directory: - - name: /nsm/mysql - - user: 939 - - group: 939 - - makedirs: True - -mysql_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://mysql/tools/sbin - - user: 939 - - group: 939 - - file_mode: 755 - -#mysql_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://mysql/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -{% if MYSQLPASS == None %} - -mysql_password_none: - test.configurable_test_state: - - changes: False - - result: False - - comment: "MySQL Password Error - Not Starting MySQL" +{% from 'mysql/map.jinja' import MYSQLMERGED %} +include: +{% if MYSQLMERGED.enabled %} + - mysql.enabled {% else %} - -so-mysql: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-mysql:{{ GLOBALS.so_version }} - - hostname: so-mysql - - user: socore - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-mysql'].ip }} - - extra_hosts: - - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-mysql'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - environment: - - MYSQL_ROOT_HOST={{ GLOBALS.so_docker_bip }} - - MYSQL_ROOT_PASSWORD=/etc/mypass - - binds: - - /opt/so/conf/mysql/etc/my.cnf:/etc/my.cnf:ro - - /opt/so/conf/mysql/etc/mypass:/etc/mypass - - /nsm/mysql:/var/lib/mysql:rw - - /opt/so/log/mysql:/var/log/mysql:rw - - watch: - - /opt/so/conf/mysql/etc - - require: - - file: mysqlcnf - - file: mysqlpass -{% endif %} - -{% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - mysql.disabled {% endif %} diff --git a/salt/mysql/map.jinja b/salt/mysql/map.jinja new file mode 100644 index 000000000..dd9a6474e --- /dev/null +++ b/salt/mysql/map.jinja @@ -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 'mysql/defaults.yaml' as MYSQLDEFAULTS with context %} +{% set MYSQLMERGED = salt['pillar.get']('mysql', MYSQLDEFAULTS.mysql, merge=True) %} diff --git a/salt/mysql/soc_mysql.yaml b/salt/mysql/soc_mysql.yaml new file mode 100644 index 000000000..4be816d90 --- /dev/null +++ b/salt/mysql/soc_mysql.yaml @@ -0,0 +1,4 @@ +mysql: + enabled: + description: You can enable or disable MySQL. + advanced: True diff --git a/salt/mysql/sostatus.sls b/salt/mysql/sostatus.sls new file mode 100644 index 000000000..2f5dbba06 --- /dev/null +++ b/salt/mysql/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-mysql_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-mysql + - unless: grep -q so-mysql /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} From b71b4225c471b046c6c9f343c5f7b0b9efcd8b3e Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 16:53:18 -0400 Subject: [PATCH 54/68] enabled/disable kratos in ui --- salt/kratos/config.sls | 71 +++++++++++++++++ salt/kratos/defaults.yaml | 1 + salt/kratos/disabled.sls | 27 +++++++ salt/kratos/enabled.sls | 69 ++++++++++++++++ salt/kratos/files/kratos.yaml.jinja | 15 +--- salt/kratos/init.sls | 117 ++-------------------------- salt/kratos/map.jinja | 19 +++++ salt/kratos/soc_kratos.yaml | 4 + salt/kratos/sostatus.sls | 21 +++++ salt/manager/tools/sbin/so-minion | 12 +++ 10 files changed, 230 insertions(+), 126 deletions(-) create mode 100644 salt/kratos/config.sls create mode 100644 salt/kratos/disabled.sls create mode 100644 salt/kratos/enabled.sls create mode 100644 salt/kratos/map.jinja create mode 100644 salt/kratos/sostatus.sls diff --git a/salt/kratos/config.sls b/salt/kratos/config.sls new file mode 100644 index 000000000..55949ea3c --- /dev/null +++ b/salt/kratos/config.sls @@ -0,0 +1,71 @@ +# 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 %} +{% from "kratos/map.jinja" import KRATOSMERGED %} + +# Add Kratos Group +kratosgroup: + group.present: + - name: kratos + - gid: 928 + +# Add Kratos user +kratos: + user.present: + - uid: 928 + - gid: 928 + - home: /opt/so/conf/kratos + +kratosdir: + file.directory: + - name: /nsm/kratos + - user: 928 + - group: 928 + - mode: 700 + - makedirs: True + +kratosdbdir: + file.directory: + - name: /nsm/kratos/db + - user: 928 + - group: 928 + - mode: 700 + - makedirs: True + +kratoslogdir: + file.directory: + - name: /opt/so/log/kratos + - user: 928 + - group: 928 + - makedirs: True + +kratosschema: + file.managed: + - name: /opt/so/conf/kratos/schema.json + - source: salt://kratos/files/schema.json + - user: 928 + - group: 928 + - mode: 600 + +kratosconfig: + file.managed: + - name: /opt/so/conf/kratos/kratos.yaml + - source: salt://kratos/files/kratos.yaml.jinja + - user: 928 + - group: 928 + - mode: 600 + - template: jinja + - defaults: + KRATOSMERGED: {{ KRATOSMERGED }} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kratos/defaults.yaml b/salt/kratos/defaults.yaml index 8f7a72b00..e0317ed37 100644 --- a/salt/kratos/defaults.yaml +++ b/salt/kratos/defaults.yaml @@ -1,4 +1,5 @@ kratos: + enabled: False config: session: lifespan: 24h diff --git a/salt/kratos/disabled.sls b/salt/kratos/disabled.sls new file mode 100644 index 000000000..0ab998273 --- /dev/null +++ b/salt/kratos/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - kratos.sostatus + +so-kratos: + docker_container.absent: + - force: True + +so-kratos_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-kratos$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kratos/enabled.sls b/salt/kratos/enabled.sls new file mode 100644 index 000000000..9358c9349 --- /dev/null +++ b/salt/kratos/enabled.sls @@ -0,0 +1,69 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - kratos.config + - kratos.sostatus + +so-kratos: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kratos:{{ GLOBALS.so_version }} + - hostname: kratos + - name: so-kratos + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-kratos'].ip }} + - binds: + - /opt/so/conf/kratos/schema.json:/kratos-conf/schema.json:ro + - /opt/so/conf/kratos/kratos.yaml:/kratos-conf/kratos.yaml:ro + - /opt/so/log/kratos/:/kratos-log:rw + - /nsm/kratos/db:/kratos-data:rw + - port_bindings: + {% for BINDING in DOCKER.containers['so-kratos'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - restart_policy: unless-stopped + - watch: + - file: kratosschema + - file: kratosconfig + - require: + - file: kratosschema + - file: kratosconfig + - file: kratoslogdir + - file: kratosdir + +delete_so-kratos_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-kratos$ + +wait_for_kratos: + http.wait_for_successful_query: + - name: 'http://{{ GLOBALS.manager }}:4434/' + - ssl: True + - verify_ssl: False + - status: + - 200 + - 301 + - 302 + - 404 + - status_type: list + - wait_for: 300 + - request_interval: 10 + - require: + - docker_container: so-kratos + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/kratos/files/kratos.yaml.jinja b/salt/kratos/files/kratos.yaml.jinja index fc67a1db8..e31ec0313 100644 --- a/salt/kratos/files/kratos.yaml.jinja +++ b/salt/kratos/files/kratos.yaml.jinja @@ -1,14 +1 @@ -{%- import_yaml 'kratos/defaults.yaml' as KRATOSDEFAULTS %} - -{%- do KRATOSDEFAULTS.kratos.config.selfservice.flows.settings.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.settings.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.selfservice.flows.verification.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.verification.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.selfservice.flows.login.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.login.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.selfservice.flows.error.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.error.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.selfservice.flows.registration.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.registration.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.selfservice.update({'default_browser_return_url': KRATOSDEFAULTS.kratos.config.selfservice.default_browser_return_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.serve.public.update({'base_url': KRATOSDEFAULTS.kratos.config.serve.public.base_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.serve.admin.update({'base_url': KRATOSDEFAULTS.kratos.config.serve.admin.base_url | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- do KRATOSDEFAULTS.kratos.config.courier.smtp.update({'connection_uri': KRATOSDEFAULTS.kratos.config.courier.smtp.connection_uri | replace("URL_BASE", GLOBALS.url_base)}) %} -{%- set KRATOSMERGED = salt['pillar.get']('kratos:config', default=KRATOSDEFAULTS.kratos.config, merge=true) %} - -{{- KRATOSMERGED | yaml(false) }} +{{ KRATOSMERGED.config | yaml(false) }} diff --git a/salt/kratos/init.sls b/salt/kratos/init.sls index c52ae15f8..7351fb0f3 100644 --- a/salt/kratos/init.sls +++ b/salt/kratos/init.sls @@ -3,118 +3,11 @@ # 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 in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} - -# Add Kratos Group -kratosgroup: - group.present: - - name: kratos - - gid: 928 - -# Add Kratos user -kratos: - user.present: - - uid: 928 - - gid: 928 - - home: /opt/so/conf/kratos - -kratosdir: - file.directory: - - name: /nsm/kratos - - user: 928 - - group: 928 - - mode: 700 - - makedirs: True - -kratosdbdir: - file.directory: - - name: /nsm/kratos/db - - user: 928 - - group: 928 - - mode: 700 - - makedirs: True - -kratoslogdir: - file.directory: - - name: /opt/so/log/kratos - - user: 928 - - group: 928 - - makedirs: True - -kratosschema: - file.managed: - - name: /opt/so/conf/kratos/schema.json - - source: salt://kratos/files/schema.json - - user: 928 - - group: 928 - - mode: 600 - -kratosconfig: - file.managed: - - name: /opt/so/conf/kratos/kratos.yaml - - source: salt://kratos/files/kratos.yaml.jinja - - user: 928 - - group: 928 - - mode: 600 - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} - -so-kratos: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kratos:{{ GLOBALS.so_version }} - - hostname: kratos - - name: so-kratos - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-kratos'].ip }} - - binds: - - /opt/so/conf/kratos/schema.json:/kratos-conf/schema.json:ro - - /opt/so/conf/kratos/kratos.yaml:/kratos-conf/kratos.yaml:ro - - /opt/so/log/kratos/:/kratos-log:rw - - /nsm/kratos/db:/kratos-data:rw - - port_bindings: - {% for BINDING in DOCKER.containers['so-kratos'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - restart_policy: unless-stopped - - watch: - - file: kratosschema - - file: kratosconfig - - require: - - file: kratosschema - - file: kratosconfig - - file: kratoslogdir - - file: kratosdir - -append_so-kratos_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-kratos - -wait_for_kratos: - http.wait_for_successful_query: - - name: 'http://{{ GLOBALS.manager }}:4434/' - - ssl: True - - verify_ssl: False - - status: - - 200 - - 301 - - 302 - - 404 - - status_type: list - - wait_for: 300 - - request_interval: 10 - - require: - - docker_container: so-kratos +{% from 'kratos/config.map.jinja' import KRATOSMERGED %} +include: +{% if KRATOSMERGED.enabled %} + - kratos.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - kratos.disabled {% endif %} diff --git a/salt/kratos/map.jinja b/salt/kratos/map.jinja new file mode 100644 index 000000000..1cdc4337b --- /dev/null +++ b/salt/kratos/map.jinja @@ -0,0 +1,19 @@ +{# 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 'vars/globals.map.jinja' import GLOBALS %} +{% import_yaml 'kratos/defaults.yaml' as KRATOSDEFAULTS %} + +{% do KRATOSDEFAULTS.kratos.config.selfservice.flows.settings.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.settings.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.selfservice.flows.verification.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.verification.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.selfservice.flows.login.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.login.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.selfservice.flows.error.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.error.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.selfservice.flows.registration.update({'ui_url': KRATOSDEFAULTS.kratos.config.selfservice.flows.registration.ui_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.selfservice.update({'default_browser_return_url': KRATOSDEFAULTS.kratos.config.selfservice.default_browser_return_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.serve.public.update({'base_url': KRATOSDEFAULTS.kratos.config.serve.public.base_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.serve.admin.update({'base_url': KRATOSDEFAULTS.kratos.config.serve.admin.base_url | replace("URL_BASE", GLOBALS.url_base)}) %} +{% do KRATOSDEFAULTS.kratos.config.courier.smtp.update({'connection_uri': KRATOSDEFAULTS.kratos.config.courier.smtp.connection_uri | replace("URL_BASE", GLOBALS.url_base)}) %} + +{% set KRATOSMERGED = salt['pillar.get']('kratos', default=KRATOSDEFAULTS.kratos, merge=true) %} diff --git a/salt/kratos/soc_kratos.yaml b/salt/kratos/soc_kratos.yaml index d2555bf11..1eb9bef40 100644 --- a/salt/kratos/soc_kratos.yaml +++ b/salt/kratos/soc_kratos.yaml @@ -1,4 +1,8 @@ kratos: + enabled: + description: You can enable or disable Kratos. + advanced: True + helpLink: kratos.html config: session: lifespan: diff --git a/salt/kratos/sostatus.sls b/salt/kratos/sostatus.sls new file mode 100644 index 000000000..cf736d8f7 --- /dev/null +++ b/salt/kratos/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-kratos_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-kratos + - unless: grep -q so-kratos /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 3ec17f79f..4941367de 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -338,6 +338,13 @@ function add_mysql_to_minion() { " " >> $PILLARFILE } +function add_kratos_to_minion() { + printf '%s\n'\ + "kratos:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -395,6 +402,7 @@ function createEVAL() { add_soc_to_minion add_registry_to_minion add_mysql_to_minion + add_kratos_to_minion } function createSTANDALONE() { @@ -414,6 +422,7 @@ function createSTANDALONE() { add_soc_to_minion add_registry_to_minion add_mysql_to_minion + add_kratos_to_minion } function createMANAGER() { @@ -431,6 +440,7 @@ function createMANAGER() { add_soc_to_minion add_registry_to_minion add_mysql_to_minion + add_kratos_to_minion } function createMANAGERSEARCH() { @@ -448,6 +458,7 @@ function createMANAGERSEARCH() { add_soc_to_minion add_registry_to_minion add_mysql_to_minion + add_kratos_to_minion } function createIMPORT() { @@ -459,6 +470,7 @@ function createIMPORT() { add_nginx_to_minion add_soc_to_minion add_registry_to_minion + add_kratos_to_minion } function createFLEET() { From b033f0d20f3cac5c0a69132c332e166559f002e7 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 12 May 2023 16:57:31 -0400 Subject: [PATCH 55/68] fix import --- salt/kratos/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/kratos/init.sls b/salt/kratos/init.sls index 7351fb0f3..9cacfae3c 100644 --- a/salt/kratos/init.sls +++ b/salt/kratos/init.sls @@ -3,7 +3,7 @@ # https://securityonion.net/license; you may not use this file except in compliance with the # Elastic License 2.0. -{% from 'kratos/config.map.jinja' import KRATOSMERGED %} +{% from 'kratos/map.jinja' import KRATOSMERGED %} include: {% if KRATOSMERGED.enabled %} From 3f8e15d16f8ca57cf366b2b8ea3deb33f023bd1c Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 09:41:44 -0400 Subject: [PATCH 56/68] enabled/disable elaticfleet in ui --- salt/elasticfleet/config.sls | 60 ++++++++++ salt/elasticfleet/defaults.yaml | 8 ++ salt/elasticfleet/disabled.sls | 27 +++++ salt/elasticfleet/enabled.sls | 62 ++++++++++ salt/elasticfleet/init.sls | 107 ++---------------- salt/elasticfleet/map.jinja | 7 ++ salt/elasticfleet/soc_elasticfleet.yaml | 52 +++++---- salt/elasticfleet/sostatus.sls | 21 ++++ .../tools/sbin_jinja/so-elastic-fleet-setup | 11 +- salt/manager/tools/sbin/so-minion | 5 +- 10 files changed, 230 insertions(+), 130 deletions(-) create mode 100644 salt/elasticfleet/config.sls create mode 100644 salt/elasticfleet/defaults.yaml create mode 100644 salt/elasticfleet/disabled.sls create mode 100644 salt/elasticfleet/enabled.sls create mode 100644 salt/elasticfleet/map.jinja create mode 100644 salt/elasticfleet/sostatus.sls diff --git a/salt/elasticfleet/config.sls b/salt/elasticfleet/config.sls new file mode 100644 index 000000000..29aa7eb30 --- /dev/null +++ b/salt/elasticfleet/config.sls @@ -0,0 +1,60 @@ +# 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 %} + +# Add EA Group +elasticsagentgroup: + group.present: + - name: elastic-agent + - gid: 947 + +# Add EA user +elastic-agent: + user.present: + - uid: 947 + - gid: 947 + - home: /opt/so/conf/elastic-fleet + - createhome: False + +elasticfleet_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://elasticfleet/tools/sbin + - user: 947 + - group: 939 + - file_mode: 755 + +elasticfleet_sbin_jinja: + file.recurse: + - name: /usr/sbin + - source: salt://elasticfleet/tools/sbin_jinja + - user: 947 + - group: 939 + - file_mode: 755 + - template: jinja + +eaconfdir: + file.directory: + - name: /opt/so/conf/elastic-fleet + - user: 947 + - group: 939 + - makedirs: True + +eastatedir: + file.directory: + - name: /opt/so/conf/elastic-fleet/state + - user: 947 + - group: 939 + - makedirs: True + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticfleet/defaults.yaml b/salt/elasticfleet/defaults.yaml new file mode 100644 index 000000000..d29e08f9a --- /dev/null +++ b/salt/elasticfleet/defaults.yaml @@ -0,0 +1,8 @@ +elasticfleet: + enabled: False + config: + server: + endpoints_enrollment: '' + es_token: '' + grid_enrollment: '' + url: '' diff --git a/salt/elasticfleet/disabled.sls b/salt/elasticfleet/disabled.sls new file mode 100644 index 000000000..1b3f69bc4 --- /dev/null +++ b/salt/elasticfleet/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - elasticfleet.sostatus + +so-elastic-fleet: + docker_container.absent: + - force: True + +so-elastic-fleet_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elastic-fleet$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticfleet/enabled.sls b/salt/elasticfleet/enabled.sls new file mode 100644 index 000000000..a3982e760 --- /dev/null +++ b/salt/elasticfleet/enabled.sls @@ -0,0 +1,62 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{# This value is generated during node install and stored in minion pillar #} +{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:config:server:es_token','') %} + +include: + - elasticfleet.config + - elasticfleet.sostatus + +{% if SERVICETOKEN != '' %} +so-elastic-fleet: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent:{{ GLOBALS.so_version }} + - name: so-elastic-fleet + - hostname: FleetServer-{{ GLOBALS.hostname }} + - detach: True + - user: 947 + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-elastic-fleet'].ip }} + - extra_hosts: + - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-elastic-fleet'].port_bindings %} + - {{ BINDING }} + {% endfor %} + - binds: + - /etc/pki:/etc/pki:ro + #- /opt/so/conf/elastic-fleet/state:/usr/share/elastic-agent/state:rw + - environment: + - FLEET_SERVER_ENABLE=true + - FLEET_URL=https://{{ GLOBALS.node_ip }}:8220 + - FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200 + - FLEET_SERVER_SERVICE_TOKEN={{ SERVICETOKEN }} + - FLEET_SERVER_POLICY_ID=FleetServer_{{ GLOBALS.hostname }} + - FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/tls/certs/intca.crt + - FLEET_SERVER_CERT=/etc/pki/elasticfleet.crt + - FLEET_SERVER_CERT_KEY=/etc/pki/elasticfleet.key + - FLEET_CA=/etc/pki/tls/certs/intca.crt +{% endif %} + +delete_so-elastic-fleet_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elastic-fleet$ + + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticfleet/init.sls b/salt/elasticfleet/init.sls index 9476c3b94..c46ca157c 100644 --- a/salt/elasticfleet/init.sls +++ b/salt/elasticfleet/init.sls @@ -1,104 +1,13 @@ # 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; 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 in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'docker/docker.map.jinja' import DOCKER %} +# 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. -# These values are generated during node install and stored in minion pillar -{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:server:es_token','') %} -#{% set FLEETSERVERPOLICY = salt['pillar.get']('elasticfleet:server:server_policy','so-manager') %} -#{% set FLEETURL = salt['pillar.get']('elasticfleet:server:url') %} - -# Add EA Group -elasticsagentgroup: - group.present: - - name: elastic-agent - - gid: 947 - -# Add EA user -elastic-agent: - user.present: - - uid: 947 - - gid: 947 - - home: /opt/so/conf/elastic-fleet - - createhome: False - -elasticfleet_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://elasticfleet/tools/sbin - - user: 947 - - group: 939 - - file_mode: 755 - -elasticfleet_sbin_jinja: - file.recurse: - - name: /usr/sbin - - source: salt://elasticfleet/tools/sbin_jinja - - user: 947 - - group: 939 - - file_mode: 755 - - template: jinja - -eaconfdir: - file.directory: - - name: /opt/so/conf/elastic-fleet - - user: 947 - - group: 939 - - makedirs: True - -eastatedir: - file.directory: - - name: /opt/so/conf/elastic-fleet/state - - user: 947 - - group: 939 - - makedirs: True - - - {% if SERVICETOKEN != '' %} -so-elastic-fleet: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent:{{ GLOBALS.so_version }} - - name: so-elastic-fleet - - hostname: FleetServer-{{ GLOBALS.hostname }} - - detach: True - - user: 947 - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-elastic-fleet'].ip }} - - extra_hosts: - - {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }} - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-elastic-fleet'].port_bindings %} - - {{ BINDING }} - {% endfor %} - - binds: - - /etc/pki:/etc/pki:ro - #- /opt/so/conf/elastic-fleet/state:/usr/share/elastic-agent/state:rw - - environment: - - FLEET_SERVER_ENABLE=true - - FLEET_URL=https://{{ GLOBALS.node_ip }}:8220 - - FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200 - - FLEET_SERVER_SERVICE_TOKEN={{ SERVICETOKEN }} - - FLEET_SERVER_POLICY_ID=FleetServer_{{ GLOBALS.hostname }} - - FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/tls/certs/intca.crt - - FLEET_SERVER_CERT=/etc/pki/elasticfleet.crt - - FLEET_SERVER_CERT_KEY=/etc/pki/elasticfleet.key - - FLEET_CA=/etc/pki/tls/certs/intca.crt - {% endif %} - -append_so-elastic-fleet_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-elastic-fleet +{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %} +include: +{% if ELASTICFLEETMERGED.enabled %} + - elasticfleet.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - elasticfleet.disabled {% endif %} diff --git a/salt/elasticfleet/map.jinja b/salt/elasticfleet/map.jinja new file mode 100644 index 000000000..09c3497d0 --- /dev/null +++ b/salt/elasticfleet/map.jinja @@ -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 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %} +{% set ELASTICFLEETMERGED = salt['pillar.get']('elasticfleet', ELASTICFLEETDEFAULTS.elasticfleet, merge=True) %} diff --git a/salt/elasticfleet/soc_elasticfleet.yaml b/salt/elasticfleet/soc_elasticfleet.yaml index 4d523c548..61ac222b5 100644 --- a/salt/elasticfleet/soc_elasticfleet.yaml +++ b/salt/elasticfleet/soc_elasticfleet.yaml @@ -1,25 +1,29 @@ elasticfleet: - server: - endpoints_enrollment: - description: Endpoint enrollment key. - global: True - helpLink: elastic-fleet.html - sensitive: True - advanced: True - es_token: - description: Elastic auth token. - global: True - helpLink: elastic-fleet.html - sensitive: True - advanced: True - grid_enrollment: - description: Grid enrollment key. - global: True - helpLink: elastic-fleet.html - sensitive: True - advanced: True - url: - description: Agent connection URL. - global: True - helpLink: elastic-fleet.html - advanced: True \ No newline at end of file + enabled: + description: You can enable or disable Elastic Fleet. + helpLink: elastic-fleet.html + config: + server: + endpoints_enrollment: + description: Endpoint enrollment key. + global: True + helpLink: elastic-fleet.html + sensitive: True + advanced: True + es_token: + description: Elastic auth token. + global: True + helpLink: elastic-fleet.html + sensitive: True + advanced: True + grid_enrollment: + description: Grid enrollment key. + global: True + helpLink: elastic-fleet.html + sensitive: True + advanced: True + url: + description: Agent connection URL. + global: True + helpLink: elastic-fleet.html + advanced: True diff --git a/salt/elasticfleet/sostatus.sls b/salt/elasticfleet/sostatus.sls new file mode 100644 index 000000000..964abe929 --- /dev/null +++ b/salt/elasticfleet/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-elastic-fleet_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-elastic-fleet + - unless: grep -q so-elastic-fleet /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup index 8005def18..71d76be69 100755 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup @@ -81,10 +81,11 @@ GRIDNODESENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "loc pillar_file=/opt/so/saltstack/local/pillar/minions/{{ GLOBALS.minion_id }}.sls printf '%s\n'\ "elasticfleet:"\ - " server:"\ - " es_token: '$ESTOKEN'"\ - " endpoints_enrollment: '$ENDPOINTSENROLLMENTOKEN'"\ - " grid_enrollment: '$GRIDNODESENROLLMENTOKEN'"\ + " config:"\ + " server:"\ + " es_token: '$ESTOKEN'"\ + " endpoints_enrollment: '$ENDPOINTSENROLLMENTOKEN'"\ + " grid_enrollment: '$GRIDNODESENROLLMENTOKEN'"\ "" >> "$pillar_file" #Store Grid Nodes Enrollment token in Global pillar @@ -98,4 +99,4 @@ salt-call state.apply elasticfleet queue=True # Generate installers & install Elastic Agent on the node so-elastic-agent-gen-installers -salt-call state.apply elasticfleet.install_agent_grid queue=True \ No newline at end of file +salt-call state.apply elasticfleet.install_agent_grid queue=True diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 4941367de..8ac8207b7 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -143,8 +143,9 @@ function add_fleet_to_minion() { # Write out settings to minion file printf '%s\n'\ "elasticfleet:"\ - " server:"\ - " es_token: '$ESTOKEN'"\ + " config:"\ + " server:"\ + " es_token: '$ESTOKEN'"\ " " >> $PILLARFILE } From 0cee5b54a15b18672ba041d5f4eff300690a7557 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 10:00:15 -0400 Subject: [PATCH 57/68] make advnaced --- salt/elasticfleet/soc_elasticfleet.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/salt/elasticfleet/soc_elasticfleet.yaml b/salt/elasticfleet/soc_elasticfleet.yaml index 61ac222b5..e8bf03ad1 100644 --- a/salt/elasticfleet/soc_elasticfleet.yaml +++ b/salt/elasticfleet/soc_elasticfleet.yaml @@ -1,6 +1,7 @@ elasticfleet: enabled: description: You can enable or disable Elastic Fleet. + advanced: True helpLink: elastic-fleet.html config: server: From 997e6c141a34391493c7a15d9b635284c5b94202 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 10:19:15 -0400 Subject: [PATCH 58/68] enable/disable idstools in ui --- salt/idstools/config.sls | 42 +++++++++++++++++ salt/idstools/defaults.yaml | 3 +- salt/idstools/disabled.sls | 31 ++++++++++++ salt/idstools/enabled.sls | 55 ++++++++++++++++++++++ salt/idstools/etc/rulecat.conf | 5 +- salt/idstools/init.sls | 78 +++---------------------------- salt/idstools/map.jinja | 7 +++ salt/idstools/soc_idstools.yaml | 2 + salt/idstools/sostatus.sls | 21 +++++++++ salt/manager/tools/sbin/so-minion | 13 +++++- 10 files changed, 180 insertions(+), 77 deletions(-) create mode 100644 salt/idstools/config.sls create mode 100644 salt/idstools/disabled.sls create mode 100644 salt/idstools/enabled.sls create mode 100644 salt/idstools/map.jinja create mode 100644 salt/idstools/sostatus.sls diff --git a/salt/idstools/config.sls b/salt/idstools/config.sls new file mode 100644 index 000000000..94692ee9f --- /dev/null +++ b/salt/idstools/config.sls @@ -0,0 +1,42 @@ +# 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 %} + +include: + - idstools.sync_files + +idstoolslogdir: + file.directory: + - name: /opt/so/log/idstools + - user: 939 + - group: 939 + - makedirs: True + +idstools_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://idstools/tools/sbin + - user: 934 + - group: 939 + - file_mode: 755 + +#idstools_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://idstools/tools/sbin_jinja +# - user: 934 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/idstools/defaults.yaml b/salt/idstools/defaults.yaml index e937ebc2d..1be100cec 100644 --- a/salt/idstools/defaults.yaml +++ b/salt/idstools/defaults.yaml @@ -1,4 +1,5 @@ idstools: + enabled: False config: urls: [] ruleset: ETOPEN @@ -6,4 +7,4 @@ idstools: sids: enabled: [] disabled: [] - modify: [] \ No newline at end of file + modify: [] diff --git a/salt/idstools/disabled.sls b/salt/idstools/disabled.sls new file mode 100644 index 000000000..ab0e10d7a --- /dev/null +++ b/salt/idstools/disabled.sls @@ -0,0 +1,31 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} + +include: + - idstools.sostatus + +so-idstools: + docker_container.absent: + - force: True + +so-idstools_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-idstools$ + +so-rule-update: + cron.absent: + - identifier: so-rule-update + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/idstools/enabled.sls b/salt/idstools/enabled.sls new file mode 100644 index 000000000..b56d6c2e5 --- /dev/null +++ b/salt/idstools/enabled.sls @@ -0,0 +1,55 @@ +# 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 %} +{% from 'docker/docker.map.jinja' import DOCKER %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% set proxy = salt['pillar.get']('manager:proxy') %} + +include: + - idstools.config + - idstools.sostatus + +so-idstools: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-idstools:{{ GLOBALS.so_version }} + - hostname: so-idstools + - user: socore + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-idstools'].ip }} + {% if proxy %} + - environment: + - http_proxy={{ proxy }} + - https_proxy={{ proxy }} + - no_proxy={{ salt['pillar.get']('manager:no_proxy') }} + {% endif %} + - binds: + - /opt/so/conf/idstools/etc:/opt/so/idstools/etc:ro + - /opt/so/rules/nids:/opt/so/rules/nids:rw + - watch: + - file: idstoolsetcsync + +delete_so-idstools_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-idstools$ + +so-rule-update: + cron.present: + - name: /usr/sbin/so-rule-update > /opt/so/log/idstools/download.log 2>&1 + - identifier: so-rule-update + - user: root + - minute: '1' + - hour: '7' + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/idstools/etc/rulecat.conf b/salt/idstools/etc/rulecat.conf index fad421243..b4142632b 100644 --- a/salt/idstools/etc/rulecat.conf +++ b/salt/idstools/etc/rulecat.conf @@ -1,6 +1,5 @@ {%- from 'vars/globals.map.jinja' import GLOBALS %} -{%- import_yaml 'idstools/defaults.yaml' as IDSTOOLSDEFAULTS %} -{%- set IDSTOOLSMERGED = salt['pillar.get']('idstools', IDSTOOLSDEFAULTS.idstools, merge=True) %} +{%- from 'idstools/map.jinja' import IDSTOOLSMERGED %} {%- if GLOBALS.airgap is sameas true -%} --merged=/opt/so/rules/nids/all.rules --local=/opt/so/rules/nids/local.rules @@ -35,4 +34,4 @@ {%- for URL in IDSTOOLSMERGED.config.urls %} --url={{ URL }} {%- endfor %} -{%- endif %} \ No newline at end of file +{%- endif %} diff --git a/salt/idstools/init.sls b/salt/idstools/init.sls index 7ad22e58b..ac1d51717 100644 --- a/salt/idstools/init.sls +++ b/salt/idstools/init.sls @@ -2,78 +2,12 @@ # 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 in allowed_states %} -{% from 'docker/docker.map.jinja' import DOCKER %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% set proxy = salt['pillar.get']('manager:proxy') %} + +{% from 'idstools/map.jinja' import IDSTOOLSMERGED %} include: - - idstools.sync_files - -# IDSTools Setup - -idstoolslogdir: - file.directory: - - name: /opt/so/log/idstools - - user: 939 - - group: 939 - - makedirs: True - -idstools_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://idstools/tools/sbin - - user: 934 - - group: 939 - - file_mode: 755 - -#idstools_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://idstools/tools/sbin_jinja -# - user: 934 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -so-rule-update: - cron.present: - - name: /usr/sbin/so-rule-update > /opt/so/log/idstools/download.log 2>&1 - - identifier: so-rule-update - - user: root - - minute: '1' - - hour: '7' - -so-idstools: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-idstools:{{ GLOBALS.so_version }} - - hostname: so-idstools - - user: socore - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-idstools'].ip }} - {% if proxy %} - - environment: - - http_proxy={{ proxy }} - - https_proxy={{ proxy }} - - no_proxy={{ salt['pillar.get']('manager:no_proxy') }} - {% endif %} - - binds: - - /opt/so/conf/idstools/etc:/opt/so/idstools/etc:ro - - /opt/so/rules/nids:/opt/so/rules/nids:rw - - watch: - - file: idstoolsetcsync - -append_so-idstools_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-idstools - +{% if IDSTOOLSMERGED.enabled %} + - idstools.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - -{% endif%} + - idstools.disabled +{% endif %} diff --git a/salt/idstools/map.jinja b/salt/idstools/map.jinja new file mode 100644 index 000000000..97d12279b --- /dev/null +++ b/salt/idstools/map.jinja @@ -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 'idstools/defaults.yaml' as IDSTOOLSDEFAULTS with context %} +{% set IDSTOOLSMERGED = salt['pillar.get']('idstools', IDSTOOLSDEFAULTS.idstools, merge=True) %} diff --git a/salt/idstools/soc_idstools.yaml b/salt/idstools/soc_idstools.yaml index e0ad6ba98..2147cec0e 100644 --- a/salt/idstools/soc_idstools.yaml +++ b/salt/idstools/soc_idstools.yaml @@ -1,4 +1,6 @@ idstools: + enabled: + description: You can enable or disable IDSTools. config: oinkcode: description: Enter your registration/oink code for paid NIDS rulesets. diff --git a/salt/idstools/sostatus.sls b/salt/idstools/sostatus.sls new file mode 100644 index 000000000..408b10742 --- /dev/null +++ b/salt/idstools/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-idstools_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-idstools + - unless: grep -q so-idstools /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 8ac8207b7..be423ef2b 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -149,7 +149,6 @@ function add_fleet_to_minion() { " " >> $PILLARFILE } - # Add IDH Services info to the minion file function add_idh_to_minion() { printf '%s\n'\ @@ -346,6 +345,13 @@ function add_kratos_to_minion() { " " >> $PILLARFILE } +function add_idstools_to_minion() { + printf '%s\n'\ + "idstools:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -404,6 +410,7 @@ function createEVAL() { add_registry_to_minion add_mysql_to_minion add_kratos_to_minion + add_idstools_to_minion } function createSTANDALONE() { @@ -424,6 +431,7 @@ function createSTANDALONE() { add_registry_to_minion add_mysql_to_minion add_kratos_to_minion + add_idstools_to_minion } function createMANAGER() { @@ -442,6 +450,7 @@ function createMANAGER() { add_registry_to_minion add_mysql_to_minion add_kratos_to_minion + add_idstools_to_minion } function createMANAGERSEARCH() { @@ -460,6 +469,7 @@ function createMANAGERSEARCH() { add_registry_to_minion add_mysql_to_minion add_kratos_to_minion + add_idstools_to_minion } function createIMPORT() { @@ -472,6 +482,7 @@ function createIMPORT() { add_soc_to_minion add_registry_to_minion add_kratos_to_minion + add_idstools_to_minion } function createFLEET() { From 1a1bcb3526f152b3b68fb6704372f1a6019f642a Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 10:53:39 -0400 Subject: [PATCH 59/68] enable/disable idh via ui --- salt/idh/config.sls | 85 +++++++++++++++++++++++ salt/idh/defaults.yaml | 3 +- salt/idh/disabled.sls | 27 ++++++++ salt/idh/enabled.sls | 39 +++++++++++ salt/idh/init.sls | 100 ++------------------------- salt/idh/opencanary_config.map.jinja | 1 + salt/idh/soc_idh.yaml | 3 + salt/idh/sostatus.sls | 21 ++++++ salt/manager/tools/sbin/so-minion | 1 + 9 files changed, 183 insertions(+), 97 deletions(-) create mode 100644 salt/idh/config.sls create mode 100644 salt/idh/disabled.sls create mode 100644 salt/idh/enabled.sls create mode 100644 salt/idh/sostatus.sls diff --git a/salt/idh/config.sls b/salt/idh/config.sls new file mode 100644 index 000000000..dcde9c8e5 --- /dev/null +++ b/salt/idh/config.sls @@ -0,0 +1,85 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'idh/opencanary_config.map.jinja' import RESTRICTIDHSERVICES %} +{% from 'idh/opencanary_config.map.jinja' import OPENCANARYCONFIG %} + +include: + - idh.openssh.config + - firewall + +# If True, block IDH Services from accepting connections on Managment IP +{% if RESTRICTIDHSERVICES %} + {% from 'idh/opencanary_config.map.jinja' import IDH_SERVICES %} + + {% for service in IDH_SERVICES %} + {% if service in ["smnp","ntp", "tftp"] %} + {% set proto = 'udp' %} + {% else %} + {% set proto = 'tcp' %} + {% endif %} +block_mgt_ip_idh_services_{{ proto }}_{{ OPENCANARYCONFIG[service~'_x_port'] }} : + iptables.insert: + - table: filter + - chain: INPUT + - jump: DROP + - position: 1 + - proto: {{ proto }} + - dport: {{ OPENCANARYCONFIG[service~'_x_port'] }} + - destination: {{ GLOBALS.node_ip }} + {% endfor %} +{% endif %} + +# Create a config directory +idhconfdir: + file.directory: + - name: /opt/so/conf/idh + - user: 939 + - group: 939 + - makedirs: True + +# Create a log directory +idhlogdir: + file.directory: + - name: /nsm/idh + - user: 939 + - group: 939 + - makedirs: True + +opencanary_config: + file.managed: + - name: /opt/so/conf/idh/opencanary.conf + - source: salt://idh/idh.conf.jinja + - template: jinja + - defaults: + OPENCANARYCONFIG: {{ OPENCANARYCONFIG }} + +idh_sbin: + file.recurse: + - name: /usr/sbin + - source: salt://idh/tools/sbin + - user: 934 + - group: 939 + - file_mode: 755 + +#idh_sbin_jinja: +# file.recurse: +# - name: /usr/sbin +# - source: salt://idh/tools/sbin_jinja +# - user: 939 +# - group: 939 +# - file_mode: 755 +# - template: jinja + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/idh/defaults.yaml b/salt/idh/defaults.yaml index b0c4d6904..a97931801 100644 --- a/salt/idh/defaults.yaml +++ b/salt/idh/defaults.yaml @@ -1,5 +1,6 @@ idh: - restrict_management_ip: false + enabled: False + restrict_management_ip: False openssh: enable: true config: diff --git a/salt/idh/disabled.sls b/salt/idh/disabled.sls new file mode 100644 index 000000000..253dcc3a1 --- /dev/null +++ b/salt/idh/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - idh.sostatus + +so-idh: + docker_container.absent: + - force: True + +so-idh_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-idh$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/idh/enabled.sls b/salt/idh/enabled.sls new file mode 100644 index 000000000..82bee138b --- /dev/null +++ b/salt/idh/enabled.sls @@ -0,0 +1,39 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + +include: + - idh.config + - idh.sostatus + +so-idh: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-idh:{{ GLOBALS.so_version }} + - name: so-idh + - detach: True + - network_mode: host + - binds: + - /nsm/idh:/var/tmp:rw + - /opt/so/conf/idh/opencanary.conf:/etc/opencanaryd/opencanary.conf:ro + - watch: + - file: opencanary_config + - require: + - file: opencanary_config + +delete_so-idh_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-idh$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/idh/init.sls b/salt/idh/init.sls index 895cd61ac..8f2cea37b 100644 --- a/salt/idh/init.sls +++ b/salt/idh/init.sls @@ -3,103 +3,11 @@ # 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 in allowed_states %} -{% import_yaml 'docker/defaults.yaml' as DOCKERDEFAULTS %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'idh/opencanary_config.map.jinja' import RESTRICTIDHSERVICES %} -{% from 'idh/opencanary_config.map.jinja' import OPENCANARYCONFIG %} +{% from 'idh/opencanary_config.map.jinja' import IDHMERGED %} include: - - idh.openssh.config - - firewall - -# If True, block IDH Services from accepting connections on Managment IP -{% if RESTRICTIDHSERVICES %} - {% from 'idh/opencanary_config.map.jinja' import IDH_SERVICES %} - - {% for service in IDH_SERVICES %} - {% if service in ["smnp","ntp", "tftp"] %} - {% set proto = 'udp' %} - {% else %} - {% set proto = 'tcp' %} - {% endif %} -block_mgt_ip_idh_services_{{ proto }}_{{ OPENCANARYCONFIG[service~'_x_port'] }} : - iptables.insert: - - table: filter - - chain: INPUT - - jump: DROP - - position: 1 - - proto: {{ proto }} - - dport: {{ OPENCANARYCONFIG[service~'_x_port'] }} - - destination: {{ GLOBALS.node_ip }} - {% endfor %} -{% endif %} - -# Create a config directory -temp: - file.directory: - - name: /opt/so/conf/idh - - user: 939 - - group: 939 - - makedirs: True - -# Create a log directory -configdir: - file.directory: - - name: /nsm/idh - - user: 939 - - group: 939 - - makedirs: True - -opencanary_config: - file.managed: - - name: /opt/so/conf/idh/opencanary.conf - - source: salt://idh/idh.conf.jinja - - template: jinja - - defaults: - OPENCANARYCONFIG: {{ OPENCANARYCONFIG }} - -idh_sbin: - file.recurse: - - name: /usr/sbin - - source: salt://idh/tools/sbin - - user: 934 - - group: 939 - - file_mode: 755 - -#idh_sbin_jinja: -# file.recurse: -# - name: /usr/sbin -# - source: salt://idh/tools/sbin_jinja -# - user: 939 -# - group: 939 -# - file_mode: 755 -# - template: jinja - -so-idh: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-idh:{{ GLOBALS.so_version }} - - name: so-idh - - detach: True - - network_mode: host - - binds: - - /nsm/idh:/var/tmp:rw - - /opt/so/conf/idh/opencanary.conf:/etc/opencanaryd/opencanary.conf:ro - - watch: - - file: opencanary_config - - require: - - file: opencanary_config - -append_so-idh_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-idh - +{% if IDHMERGED.enabled %} + - idh.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - idh.disabled {% endif %} diff --git a/salt/idh/opencanary_config.map.jinja b/salt/idh/opencanary_config.map.jinja index a8b85adbf..420cc7f79 100644 --- a/salt/idh/opencanary_config.map.jinja +++ b/salt/idh/opencanary_config.map.jinja @@ -20,6 +20,7 @@ {% set IDH_PORTGROUPS = {} %} {% import_yaml "idh/defaults.yaml" as IDHCONFIG with context %} +{% set IDHMERGED = salt['pillar.get']('idh', IDHCONFIG.idh, merge=True) %} {% set RESTRICTIDHSERVICES = salt['pillar.get']('idh:restrict_management_ip', default=IDHCONFIG.idh.restrict_management_ip) %} {% set OPENCANARYCONFIG = salt['pillar.get']('idh:opencanary:config', default=IDHCONFIG.idh.opencanary.config, merge=True) %} {# update skinlist to skin.list to avoid issues with SOC UI config #} diff --git a/salt/idh/soc_idh.yaml b/salt/idh/soc_idh.yaml index 60d0203f5..f792812e4 100644 --- a/salt/idh/soc_idh.yaml +++ b/salt/idh/soc_idh.yaml @@ -1,4 +1,7 @@ idh: + enabled: + description: You can enable or disable IDH. + helpLink: idh.html opencanary: config: logger: diff --git a/salt/idh/sostatus.sls b/salt/idh/sostatus.sls new file mode 100644 index 000000000..e5b9da705 --- /dev/null +++ b/salt/idh/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-idh_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-idh + - unless: grep -q so-idh /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index be423ef2b..5bd205015 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -153,6 +153,7 @@ function add_fleet_to_minion() { function add_idh_to_minion() { printf '%s\n'\ "idh:"\ + " enabled: True"\ " restrict_management_ip: $IDH_MGTRESTRICT"\ " services:" >> "$PILLARFILE" IFS=',' read -ra IDH_SERVICES_ARRAY <<< "$IDH_SERVICES" From ba2392997b1f9cbb1cf5b50b473374560abcc8a6 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 11:14:21 -0400 Subject: [PATCH 60/68] enabled/disable elastic-fleet-package-registry via ui --- .../elastic-fleet-package-registry/config.sls | 29 ++++++++++ .../defaults.yaml | 2 + .../disabled.sls | 27 +++++++++ .../enabled.sls | 43 +++++++++++++++ salt/elastic-fleet-package-registry/init.sls | 55 +++---------------- salt/elastic-fleet-package-registry/map.jinja | 7 +++ .../soc_elastic-fleet-package-registry.yaml | 4 ++ .../sostatus.sls | 21 +++++++ salt/manager/tools/sbin/so-minion | 12 ++++ 9 files changed, 153 insertions(+), 47 deletions(-) create mode 100644 salt/elastic-fleet-package-registry/config.sls create mode 100644 salt/elastic-fleet-package-registry/defaults.yaml create mode 100644 salt/elastic-fleet-package-registry/disabled.sls create mode 100644 salt/elastic-fleet-package-registry/enabled.sls create mode 100644 salt/elastic-fleet-package-registry/map.jinja create mode 100644 salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml create mode 100644 salt/elastic-fleet-package-registry/sostatus.sls diff --git a/salt/elastic-fleet-package-registry/config.sls b/salt/elastic-fleet-package-registry/config.sls new file mode 100644 index 000000000..aa2872069 --- /dev/null +++ b/salt/elastic-fleet-package-registry/config.sls @@ -0,0 +1,29 @@ +# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one +# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at +# https://securityonion.net/license; you may not use this file except in compliance with the +# Elastic License 2.0. + +{% from 'allowed_states.map.jinja' import allowed_states %} +{% if sls.split('.')[0] in allowed_states %} + +# Add Group +elasticsagentprgroup: + group.present: + - name: elastic-agent-pr + - gid: 948 + +# Add user +elastic-agent-pr: + user.present: + - uid: 948 + - gid: 948 + - home: /opt/so/conf/elastic-fleet-pr + - createhome: False + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elastic-fleet-package-registry/defaults.yaml b/salt/elastic-fleet-package-registry/defaults.yaml new file mode 100644 index 000000000..947ef103c --- /dev/null +++ b/salt/elastic-fleet-package-registry/defaults.yaml @@ -0,0 +1,2 @@ +elastic-fleet-package-registry: + enabled: False diff --git a/salt/elastic-fleet-package-registry/disabled.sls b/salt/elastic-fleet-package-registry/disabled.sls new file mode 100644 index 000000000..8487fc3d6 --- /dev/null +++ b/salt/elastic-fleet-package-registry/disabled.sls @@ -0,0 +1,27 @@ +# 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 %} + +include: + - elastic-fleet-package-registry.sostatus + +so-elastic-fleet-package-registry: + docker_container.absent: + - force: True + +so-elastic-fleet-package-registry_so-status.disabled: + file.comment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elastic-fleet-package-registry$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elastic-fleet-package-registry/enabled.sls b/salt/elastic-fleet-package-registry/enabled.sls new file mode 100644 index 000000000..5f663e78f --- /dev/null +++ b/salt/elastic-fleet-package-registry/enabled.sls @@ -0,0 +1,43 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} +{% from 'docker/docker.map.jinja' import DOCKER %} + +include: + - elastic-fleet-package-registry.config + - elastic-fleet-package-registry.sostatus + +so-elastic-fleet-package-registry: + docker_container.running: + - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-fleet-package-registry:{{ GLOBALS.so_version }} + - name: so-elastic-fleet-package-registry + - hostname: Fleet-package-reg-{{ GLOBALS.hostname }} + - detach: True + - user: 948 + - networks: + - sobridge: + - ipv4_address: {{ DOCKER.containers['so-elastic-fleet-package-registry'].ip }} + - extra_hosts: + - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} + - port_bindings: + {% for BINDING in DOCKER.containers['so-elastic-fleet-package-registry'].port_bindings %} + - {{ BINDING }} + {% endfor %} + +delete_so-elastic-fleet-package-registry_so-status.disabled: + file.uncomment: + - name: /opt/so/conf/so-status/so-status.conf + - regex: ^so-elastic-fleet-package-registry$ + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/elastic-fleet-package-registry/init.sls b/salt/elastic-fleet-package-registry/init.sls index b4cea6542..7a42c57be 100644 --- a/salt/elastic-fleet-package-registry/init.sls +++ b/salt/elastic-fleet-package-registry/init.sls @@ -1,52 +1,13 @@ # 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; 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 in allowed_states %} -{% from 'vars/globals.map.jinja' import GLOBALS %} -{% from 'docker/docker.map.jinja' import DOCKER %} +# 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. -# Add Group -elasticsagentprgroup: - group.present: - - name: elastic-agent-pr - - gid: 948 - - -# Add user -elastic-agent-pr: - user.present: - - uid: 948 - - gid: 948 - - home: /opt/so/conf/elastic-fleet-pr - - createhome: False - -so-elastic-fleet-package-registry: - docker_container.running: - - image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-fleet-package-registry:{{ GLOBALS.so_version }} - - name: so-elastic-fleet-package-registry - - hostname: Fleet-package-reg-{{ GLOBALS.hostname }} - - detach: True - - user: 948 - - networks: - - sobridge: - - ipv4_address: {{ DOCKER.containers['so-elastic-fleet-package-registry'].ip }} - - extra_hosts: - - {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }} - - port_bindings: - {% for BINDING in DOCKER.containers['so-elastic-fleet-package-registry'].port_bindings %} - - {{ BINDING }} - {% endfor %} - -append_so-elastic-fleet-package-registry_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-elastic-fleet-package-registry +{% from 'elastic-fleet-package-registry/map.jinja' import ELASTICFLEETPACKAGEREGISTRYMERGED %} +include: +{% if ELASTICFLEETPACKAGEREGISTRYMERGED.enabled %} + - elastic-fleet-package-registry.enabled {% else %} - -{{sls}}_state_not_allowed: - test.fail_without_changes: - - name: {{sls}}_state_not_allowed - + - elastic-fleet-package-registry.disabled {% endif %} diff --git a/salt/elastic-fleet-package-registry/map.jinja b/salt/elastic-fleet-package-registry/map.jinja new file mode 100644 index 000000000..00b421490 --- /dev/null +++ b/salt/elastic-fleet-package-registry/map.jinja @@ -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 'elastic-fleet-package-registry/defaults.yaml' as ELASTICFLEETPACKAGEREGISTRYDEFAULTS with context %} +{% set ELASTICFLEETPACKAGEREGISTRYMERGED = salt['pillar.get']('elastic-fleet-package-registry', ELASTICFLEETPACKAGEREGISTRYDEFAULTS.elastic-fleet-package-registry, merge=True) %} diff --git a/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml b/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml new file mode 100644 index 000000000..531789571 --- /dev/null +++ b/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml @@ -0,0 +1,4 @@ +elastic-fleet-package-registry: + enabled: + description: You can enable or disable Elastic Fleet Package Registry. + advanced: True diff --git a/salt/elastic-fleet-package-registry/sostatus.sls b/salt/elastic-fleet-package-registry/sostatus.sls new file mode 100644 index 000000000..191aa7e3d --- /dev/null +++ b/salt/elastic-fleet-package-registry/sostatus.sls @@ -0,0 +1,21 @@ +# 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 %} + +append_so-elastic-fleet-package-registry_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-elastic-fleet-package-registry + - unless: grep -q so-elastic-fleet-package-registry /opt/so/conf/so-status/so-status.conf + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + +{% endif %} diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 5bd205015..d2dae2d74 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -353,6 +353,13 @@ function add_idstools_to_minion() { " " >> $PILLARFILE } +function add_elastic-fleet-package-registry_to_minion() { + printf '%s\n'\ + "elastic-fleet-package-registry:"\ + " enabled: True"\ + " " >> $PILLARFILE +} + function create_fleet_policy() { JSON_STRING=$( jq -n \ @@ -412,6 +419,7 @@ function createEVAL() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion + add_elastic-fleet-package-registry_to_minion } function createSTANDALONE() { @@ -433,6 +441,7 @@ function createSTANDALONE() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion + add_elastic-fleet-package-registry_to_minion } function createMANAGER() { @@ -452,6 +461,7 @@ function createMANAGER() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion + add_elastic-fleet-package-registry_to_minion } function createMANAGERSEARCH() { @@ -471,6 +481,7 @@ function createMANAGERSEARCH() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion + add_elastic-fleet-package-registry_to_minion } function createIMPORT() { @@ -484,6 +495,7 @@ function createIMPORT() { add_registry_to_minion add_kratos_to_minion add_idstools_to_minion + add_elastic-fleet-package-registry_to_minion } function createFLEET() { From db47256cdd3c739daec5c805fe8d1368ec5ec9e0 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 11:23:27 -0400 Subject: [PATCH 61/68] rename --- salt/elastic-fleet-package-registry/defaults.yaml | 2 +- salt/elastic-fleet-package-registry/map.jinja | 4 ++-- .../soc_elastic-fleet-package-registry.yaml | 2 +- salt/manager/tools/sbin/so-minion | 14 +++++++------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/salt/elastic-fleet-package-registry/defaults.yaml b/salt/elastic-fleet-package-registry/defaults.yaml index 947ef103c..4f14e168b 100644 --- a/salt/elastic-fleet-package-registry/defaults.yaml +++ b/salt/elastic-fleet-package-registry/defaults.yaml @@ -1,2 +1,2 @@ -elastic-fleet-package-registry: +elastic_fleet_package_registry: enabled: False diff --git a/salt/elastic-fleet-package-registry/map.jinja b/salt/elastic-fleet-package-registry/map.jinja index 00b421490..54cdedd75 100644 --- a/salt/elastic-fleet-package-registry/map.jinja +++ b/salt/elastic-fleet-package-registry/map.jinja @@ -3,5 +3,5 @@ https://securityonion.net/license; you may not use this file except in compliance with the Elastic License 2.0. #} -{% import_yaml 'elastic-fleet-package-registry/defaults.yaml' as ELASTICFLEETPACKAGEREGISTRYDEFAULTS with context %} -{% set ELASTICFLEETPACKAGEREGISTRYMERGED = salt['pillar.get']('elastic-fleet-package-registry', ELASTICFLEETPACKAGEREGISTRYDEFAULTS.elastic-fleet-package-registry, merge=True) %} +{% import_yaml 'elastic-fleet-package-registry/defaults.yaml' as ELASTICFLEETPACKAGEREGISTRYDEFAULTS %} +{% set ELASTICFLEETPACKAGEREGISTRYMERGED = salt['pillar.get']('elastic_fleet_package_registry', ELASTICFLEETPACKAGEREGISTRYDEFAULTS.elastic_fleet_package_registry, merge=True) %} diff --git a/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml b/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml index 531789571..70886c447 100644 --- a/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml +++ b/salt/elastic-fleet-package-registry/soc_elastic-fleet-package-registry.yaml @@ -1,4 +1,4 @@ -elastic-fleet-package-registry: +elastic_fleet_package_registry: enabled: description: You can enable or disable Elastic Fleet Package Registry. advanced: True diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index d2dae2d74..69d77a9cf 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -353,9 +353,9 @@ function add_idstools_to_minion() { " " >> $PILLARFILE } -function add_elastic-fleet-package-registry_to_minion() { +function add_elastic_fleet_package_registry_to_minion() { printf '%s\n'\ - "elastic-fleet-package-registry:"\ + "elastic_fleet_package_registry:"\ " enabled: True"\ " " >> $PILLARFILE } @@ -419,7 +419,7 @@ function createEVAL() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion - add_elastic-fleet-package-registry_to_minion + add_elastic_fleet_package_registry_to_minion } function createSTANDALONE() { @@ -441,7 +441,7 @@ function createSTANDALONE() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion - add_elastic-fleet-package-registry_to_minion + add_elastic_fleet_package_registry_to_minion } function createMANAGER() { @@ -461,7 +461,7 @@ function createMANAGER() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion - add_elastic-fleet-package-registry_to_minion + add_elastic_fleet_package_registry_to_minion } function createMANAGERSEARCH() { @@ -481,7 +481,7 @@ function createMANAGERSEARCH() { add_mysql_to_minion add_kratos_to_minion add_idstools_to_minion - add_elastic-fleet-package-registry_to_minion + add_elastic_fleet_package_registry_to_minion } function createIMPORT() { @@ -495,7 +495,7 @@ function createIMPORT() { add_registry_to_minion add_kratos_to_minion add_idstools_to_minion - add_elastic-fleet-package-registry_to_minion + add_elastic_fleet_package_registry_to_minion } function createFLEET() { From f1c8467e9b1433f4120d3a0c9de6313fcde6ee53 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 13:13:38 -0400 Subject: [PATCH 62/68] create and assign kibana.soc and kibana.adv --- pillar/top.sls | 6 ++++++ setup/so-functions | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pillar/top.sls b/pillar/top.sls index ac46bfc12..7a36dcc53 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -101,6 +101,8 @@ base: - soc.adv_soc - soctopus.soc_soctopus - soctopus.adv_soctopus + - kibana.soc_kibana + - kibana.adv_kibana - strelka.soc_strelka - strelka.adv_strelka - curator.soc_curator @@ -155,6 +157,8 @@ base: - soc.adv_soc - soctopus.soc_soctopus - soctopus.adv_soctopus + - kibana.soc_kibana + - kibana.adv_kibana - strelka.soc_strelka - strelka.adv_strelka - curator.soc_curator @@ -248,6 +252,8 @@ base: - soc.adv_soc - soctopus.soc_soctopus - soctopus.adv_soctopus + - kibana.soc_kibana + - kibana.adv_kibana - curator.soc_curator - curator.adv_curator - backup.soc_backup diff --git a/setup/so-functions b/setup/so-functions index dff20b7b3..d14367361 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -898,7 +898,6 @@ create_manager_pillars() { manager_pillar create_global create_sensoroni_pillar - #create_strelka_pillar backup_pillar soctopus_pillar docker_pillar @@ -911,6 +910,7 @@ create_manager_pillars() { logrotate_pillar patch_pillar nginx_pillar + kibana_pillar } create_repo() { From 928b3b54711f2bd240bbeee2a37339b6a9a56ba8 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 13:40:52 -0400 Subject: [PATCH 63/68] create local kibana pillar dirs before touching pillar files --- setup/so-functions | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup/so-functions b/setup/so-functions index d14367361..beebc2b17 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1347,8 +1347,9 @@ idh_pillar() { } kibana_pillar() { - touch $adv_kibana_pillar_file - touch $kibana_pillar_file + logCmd "mkdir -p $local_salt_dir/pillar/kibana" + logCmd "touch $adv_kibana_pillar_file" + logCmd "touch $kibana_pillar_file" } logrotate_pillar() { From 6320528263c41892f1be3235eaab1e12a3617c7b Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 14:08:30 -0400 Subject: [PATCH 64/68] move so-catrust --- salt/elasticsearch/config.sls | 19 -------------- salt/ssl/init.sls | 25 +++++++++++++++++-- .../tools/sbin_jinja/so-catrust | 12 ++++----- 3 files changed, 29 insertions(+), 27 deletions(-) rename salt/{elasticsearch => ssl}/tools/sbin_jinja/so-catrust (70%) diff --git a/salt/elasticsearch/config.sls b/salt/elasticsearch/config.sls index dcd0283c0..68948e982 100644 --- a/salt/elasticsearch/config.sls +++ b/salt/elasticsearch/config.sls @@ -37,26 +37,7 @@ elasticsearch: - home: /opt/so/conf/elasticsearch - createhome: False -{% if GLOBALS.is_manager %} -# We have to add the Manager CA to the CA list -cascriptsync: - file.managed: - - name: /usr/sbin/so-catrust - - source: salt://elasticsearch/tools/sbin_jinja/so-catrust - - user: 939 - - group: 939 - - mode: 750 - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} -# Run the CA magic -cascriptfun: - cmd.run: - - name: /usr/sbin/so-catrust - - require: - - file: cascriptsync -{% endif %} elasticsearch_sbin: file.recurse: diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index ca23179b7..54f629182 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -35,18 +35,39 @@ include: {% set ca_server = global_ca_server[0] %} {% endif %} +{% if GLOBALS.is_manager %} +# We have to add the Manager CA to the CA list +cascriptsync: + file.managed: + - name: /usr/sbin/so-catrust + - source: salt://ssl/tools/sbin_jinja/so-catrust + - user: 939 + - group: 939 + - mode: 750 + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} + +# Run the CA magic +cascriptfun: + cmd.run: + - name: /usr/sbin/so-catrust + - require: + - file: cascriptsync +{% endif %} + {% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-searchnode'] %} cacertz: file.managed: - name: /opt/so/conf/ca/cacerts - - source: salt://common/cacerts + - source: salt://ssl/cacerts - user: 939 - group: 939 capemz: file.managed: - name: /opt/so/conf/ca/tls-ca-bundle.pem - - source: salt://common/tls-ca-bundle.pem + - source: salt://ssl/tls-ca-bundle.pem - user: 939 - group: 939 {% endif %} diff --git a/salt/elasticsearch/tools/sbin_jinja/so-catrust b/salt/ssl/tools/sbin_jinja/so-catrust similarity index 70% rename from salt/elasticsearch/tools/sbin_jinja/so-catrust rename to salt/ssl/tools/sbin_jinja/so-catrust index aec97deeb..49a3f97f1 100644 --- a/salt/elasticsearch/tools/sbin_jinja/so-catrust +++ b/salt/ssl/tools/sbin_jinja/so-catrust @@ -11,14 +11,14 @@ set -e # Check to see if we have extracted the ca cert. -if [ ! -f /opt/so/saltstack/local/salt/common/cacerts ]; then +if [ ! -f /opt/so/saltstack/local/salt/ssl/cacerts ]; then docker run -v /etc/pki/ca.crt:/etc/ssl/ca.crt --name so-elasticsearchca --user root --entrypoint jdk/bin/keytool {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ GLOBALS.so_version }} -keystore /usr/share/elasticsearch/jdk/lib/security/cacerts -alias SOSCA -import -file /etc/ssl/ca.crt -storepass changeit -noprompt - docker cp so-elasticsearchca:/usr/share/elasticsearch/jdk/lib/security/cacerts /opt/so/saltstack/local/salt/common/cacerts - docker cp so-elasticsearchca:/etc/ssl/certs/ca-certificates.crt /opt/so/saltstack/local/salt/common/tls-ca-bundle.pem + docker cp so-elasticsearchca:/usr/share/elasticsearch/jdk/lib/security/cacerts /opt/so/saltstack/local/salt/ssl/cacerts + docker cp so-elasticsearchca:/etc/ssl/certs/ca-certificates.crt /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem docker rm so-elasticsearchca - echo "" >> /opt/so/saltstack/local/salt/common/tls-ca-bundle.pem - echo "sosca" >> /opt/so/saltstack/local/salt/common/tls-ca-bundle.pem - cat /etc/pki/ca.crt >> /opt/so/saltstack/local/salt/common/tls-ca-bundle.pem + echo "" >> /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem + echo "sosca" >> /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem + cat /etc/pki/ca.crt >> /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem else exit 0 fi From c49b1341228df103946c0fbf2c322e81ffe3d66c Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 16:43:47 -0400 Subject: [PATCH 65/68] move so-catrust --- salt/elasticsearch/ca.sls | 33 +++++++++++++++++ salt/elasticsearch/config.sls | 12 +------ .../tools/sbin_jinja/so-catrust | 12 +++---- salt/logstash/enabled.sls | 1 + salt/ssl/init.sls | 35 ------------------- 5 files changed, 41 insertions(+), 52 deletions(-) create mode 100644 salt/elasticsearch/ca.sls rename salt/{ssl => elasticsearch}/tools/sbin_jinja/so-catrust (68%) diff --git a/salt/elasticsearch/ca.sls b/salt/elasticsearch/ca.sls new file mode 100644 index 000000000..fdd63338d --- /dev/null +++ b/salt/elasticsearch/ca.sls @@ -0,0 +1,33 @@ +# Move our new CA over so Elastic and Logstash can use SSL with the internal CA +catrustdir: + file.directory: + - name: /opt/so/conf/ca + - user: 939 + - group: 939 + - makedirs: True + +{% if GLOBALS.is_manager %} +# We have to add the Manager CA to the CA list +cascriptsync: + cmd.script: + - source: salt://elasticsearch/tools/sbin_jinja/so-catrust + - template: jinja + - defaults: + GLOBALS: {{ GLOBALS }} +{% endif %} + +{% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-searchnode'] %} +cacertz: + file.managed: + - name: /opt/so/conf/ca/cacerts + - source: salt://elasticsearch/cacerts + - user: 939 + - group: 939 + +capemz: + file.managed: + - name: /opt/so/conf/ca/tls-ca-bundle.pem + - source: salt://elasticsearch/tls-ca-bundle.pem + - user: 939 + - group: 939 +{% endif %} diff --git a/salt/elasticsearch/config.sls b/salt/elasticsearch/config.sls index 68948e982..23e11a710 100644 --- a/salt/elasticsearch/config.sls +++ b/salt/elasticsearch/config.sls @@ -8,6 +8,7 @@ include: - ssl + - elasticsearch.ca {% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'elasticsearch/config.map.jinja' import ELASTICSEARCHMERGED %} @@ -37,8 +38,6 @@ elasticsearch: - home: /opt/so/conf/elasticsearch - createhome: False - - elasticsearch_sbin: file.recurse: - name: /usr/sbin @@ -47,7 +46,6 @@ elasticsearch_sbin: - group: 939 - file_mode: 755 - exclude_pat: - - so-catrust - so-elasticsearch-pipelines # exclude this because we need to watch it for changes, we sync it in another state elasticsearch_sbin_jinja: @@ -80,14 +78,6 @@ so-elasticsearch-pipelines-script: - group: 939 - mode: 754 -# Move our new CA over so Elastic and Logstash can use SSL with the internal CA -catrustdir: - file.directory: - - name: /opt/so/conf/ca - - user: 939 - - group: 939 - - makedirs: True - esingestdir: file.directory: - name: /opt/so/conf/elasticsearch/ingest diff --git a/salt/ssl/tools/sbin_jinja/so-catrust b/salt/elasticsearch/tools/sbin_jinja/so-catrust similarity index 68% rename from salt/ssl/tools/sbin_jinja/so-catrust rename to salt/elasticsearch/tools/sbin_jinja/so-catrust index 49a3f97f1..fe4ff58bc 100644 --- a/salt/ssl/tools/sbin_jinja/so-catrust +++ b/salt/elasticsearch/tools/sbin_jinja/so-catrust @@ -11,14 +11,14 @@ set -e # Check to see if we have extracted the ca cert. -if [ ! -f /opt/so/saltstack/local/salt/ssl/cacerts ]; then +if [ ! -f /opt/so/saltstack/local/salt/elasticsearch/cacerts ]; then docker run -v /etc/pki/ca.crt:/etc/ssl/ca.crt --name so-elasticsearchca --user root --entrypoint jdk/bin/keytool {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ GLOBALS.so_version }} -keystore /usr/share/elasticsearch/jdk/lib/security/cacerts -alias SOSCA -import -file /etc/ssl/ca.crt -storepass changeit -noprompt - docker cp so-elasticsearchca:/usr/share/elasticsearch/jdk/lib/security/cacerts /opt/so/saltstack/local/salt/ssl/cacerts - docker cp so-elasticsearchca:/etc/ssl/certs/ca-certificates.crt /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem + docker cp so-elasticsearchca:/usr/share/elasticsearch/jdk/lib/security/cacerts /opt/so/saltstack/local/salt/elasticsearch/cacerts + docker cp so-elasticsearchca:/etc/ssl/certs/ca-certificates.crt /opt/so/saltstack/local/salt/elasticsearch/tls-ca-bundle.pem docker rm so-elasticsearchca - echo "" >> /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem - echo "sosca" >> /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem - cat /etc/pki/ca.crt >> /opt/so/saltstack/local/salt/ssl/tls-ca-bundle.pem + echo "" >> /opt/so/saltstack/local/salt/elasticsearch/tls-ca-bundle.pem + echo "sosca" >> /opt/so/saltstack/local/salt/elasticsearch/tls-ca-bundle.pem + cat /etc/pki/ca.crt >> /opt/so/saltstack/local/salt/elasticsearch/tls-ca-bundle.pem else exit 0 fi diff --git a/salt/logstash/enabled.sls b/salt/logstash/enabled.sls index 2f5a46323..65905cd6c 100644 --- a/salt/logstash/enabled.sls +++ b/salt/logstash/enabled.sls @@ -12,6 +12,7 @@ {% set lsheap = LOGSTASH_MERGED.settings.lsheap %} include: + - elasticsearch.ca - logstash.config - logstash.sostatus diff --git a/salt/ssl/init.sls b/salt/ssl/init.sls index 54f629182..e077d55d0 100644 --- a/salt/ssl/init.sls +++ b/salt/ssl/init.sls @@ -35,42 +35,7 @@ include: {% set ca_server = global_ca_server[0] %} {% endif %} -{% if GLOBALS.is_manager %} -# We have to add the Manager CA to the CA list -cascriptsync: - file.managed: - - name: /usr/sbin/so-catrust - - source: salt://ssl/tools/sbin_jinja/so-catrust - - user: 939 - - group: 939 - - mode: 750 - - template: jinja - - defaults: - GLOBALS: {{ GLOBALS }} -# Run the CA magic -cascriptfun: - cmd.run: - - name: /usr/sbin/so-catrust - - require: - - file: cascriptsync -{% endif %} - -{% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-searchnode'] %} -cacertz: - file.managed: - - name: /opt/so/conf/ca/cacerts - - source: salt://ssl/cacerts - - user: 939 - - group: 939 - -capemz: - file.managed: - - name: /opt/so/conf/ca/tls-ca-bundle.pem - - source: salt://ssl/tls-ca-bundle.pem - - user: 939 - - group: 939 -{% endif %} # Trust the CA trusttheca: From 2813d6767020e36cec2a4bfa6d36f10982b6a753 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 16:47:33 -0400 Subject: [PATCH 66/68] import GLOBALS --- salt/elasticsearch/ca.sls | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/salt/elasticsearch/ca.sls b/salt/elasticsearch/ca.sls index fdd63338d..7d7f1bdfb 100644 --- a/salt/elasticsearch/ca.sls +++ b/salt/elasticsearch/ca.sls @@ -1,3 +1,12 @@ +# 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 %} +{% from 'vars/globals.map.jinja' import GLOBALS %} + # Move our new CA over so Elastic and Logstash can use SSL with the internal CA catrustdir: file.directory: @@ -16,7 +25,7 @@ cascriptsync: GLOBALS: {{ GLOBALS }} {% endif %} -{% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-searchnode'] %} +{% if grains.role in ['so-manager', 'so-helix', 'so-managersearch', 'so-standalone', 'so-import', 'so-searchnode'] %} cacertz: file.managed: - name: /opt/so/conf/ca/cacerts @@ -30,4 +39,12 @@ capemz: - source: salt://elasticsearch/tls-ca-bundle.pem - user: 939 - group: 939 +{% endif %} + +{% else %} + +{{sls}}_state_not_allowed: + test.fail_without_changes: + - name: {{sls}}_state_not_allowed + {% endif %} From a0e08e4f41231ce021999f5697401920f93e38ca Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 15 May 2023 17:41:09 -0400 Subject: [PATCH 67/68] enable elasticfleet via pillar, fix sostatus for elasticfleet --- salt/elasticfleet/sostatus.sls | 2 +- salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup | 1 + salt/manager/tools/sbin/so-minion | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/salt/elasticfleet/sostatus.sls b/salt/elasticfleet/sostatus.sls index 964abe929..392733a4c 100644 --- a/salt/elasticfleet/sostatus.sls +++ b/salt/elasticfleet/sostatus.sls @@ -10,7 +10,7 @@ append_so-elastic-fleet_so-status.conf: file.append: - name: /opt/so/conf/so-status/so-status.conf - text: so-elastic-fleet - - unless: grep -q so-elastic-fleet /opt/so/conf/so-status/so-status.conf + - unless: grep -q ^so-elastic-fleet$ /opt/so/conf/so-status/so-status.conf {% else %} diff --git a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup index f6f053e2a..7c5db70f7 100755 --- a/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup +++ b/salt/elasticfleet/tools/sbin_jinja/so-elastic-fleet-setup @@ -81,6 +81,7 @@ GRIDNODESENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "loc pillar_file=/opt/so/saltstack/local/pillar/minions/{{ GLOBALS.minion_id }}.sls printf '%s\n'\ "elasticfleet:"\ + " enabled: True"\ " config:"\ " server:"\ " es_token: '$ESTOKEN'"\ diff --git a/salt/manager/tools/sbin/so-minion b/salt/manager/tools/sbin/so-minion index 69d77a9cf..3342f3c15 100755 --- a/salt/manager/tools/sbin/so-minion +++ b/salt/manager/tools/sbin/so-minion @@ -143,6 +143,7 @@ function add_fleet_to_minion() { # Write out settings to minion file printf '%s\n'\ "elasticfleet:"\ + " enabled: True"\ " config:"\ " server:"\ " es_token: '$ESTOKEN'"\ From 6325f6db16c4a5fca0b9e2559e1c5567b78deb05 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 16 May 2023 09:30:27 -0400 Subject: [PATCH 68/68] run elasticfleet.config so elasticfleet setup script gets put in place --- setup/so-setup | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/so-setup b/setup/so-setup index 6051ba742..853809e67 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -650,6 +650,7 @@ if ! [[ -f $install_opt_file ]]; then info "Restarting SOC to pick up initial user" logCmd "so-soc-restart" title "Setting up Elastic Fleet" + logCmd "salt-call state.apply elasticfleet.config" logCmd "so-elastic-fleet-setup" if [[ ! $is_import ]]; then title "Setting up Playbook"