From a2c444e03b9f12bfe9aba22186a49afe7bb62bb1 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 8 May 2023 13:43:08 -0400 Subject: [PATCH] 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 %}