enabled/disable elastalert via web ui

This commit is contained in:
m0duspwnens
2023-05-08 15:56:26 -04:00
parent 9aaa33c224
commit 9049f9cf03
16 changed files with 284 additions and 177 deletions

View File

@@ -3,7 +3,6 @@
# https://securityonion.net/license; you may not use this file except in compliance with the # https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0. # Elastic License 2.0.
{% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %}
{% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %}
{% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %}
{% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %}
@@ -243,7 +242,7 @@
{% do allowed_states.append('curator') %} {% do allowed_states.append('curator') %}
{% endif %} {% 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') %} {% do allowed_states.append('elastalert') %}
{% endif %} {% endif %}

103
salt/elastalert/config.sls Normal file
View File

@@ -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 %}

View File

@@ -1,4 +1,5 @@
elastalert: elastalert:
enabled: False
config: config:
rules_folder: /opt/elastalert/rules/ rules_folder: /opt/elastalert/rules/
scan_subdirectories: true scan_subdirectories: true

View File

@@ -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 %}

View File

@@ -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) %}

View File

@@ -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 %}

View File

@@ -1,141 +1,13 @@
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # 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 # or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# this file except in compliance with the Elastic License 2.0. # https://securityonion.net/license; you may not use this file except in compliance with the
{% from 'allowed_states.map.jinja' import allowed_states %} # Elastic License 2.0.
{% if sls in allowed_states %}
{% from 'vars/globals.map.jinja' import GLOBALS %} {% from 'elastalert/map.jinja' import ELASTALERTMERGED %}
{% 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
include:
{% if ELASTALERTMERGED.enabled %}
- elastalert.enabled
{% else %} {% else %}
- elastalert.disabled
{{sls}}_state_not_allowed:
test.fail_without_changes:
- name: {{sls}}_state_not_allowed
{% endif %} {% endif %}

15
salt/elastalert/map.jinja Normal file
View File

@@ -0,0 +1,15 @@
{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
https://securityonion.net/license; you may not use this file except in compliance with the
Elastic License 2.0. #}
{% from '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) %}

View File

@@ -1,4 +1,7 @@
elastalert: elastalert:
enabled:
description: You can enable or disable Elastalert.
helpLink: elastalert.html
config: config:
disable_rules_on_error: disable_rules_on_error:
description: Disable rules on failure. description: Disable rules on failure.

View File

@@ -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 %}

View File

@@ -227,6 +227,14 @@ function add_playbook_to_minion() {
" " >> $PILLARFILE " " >> $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() { function create_fleet_policy() {
JSON_STRING=$( jq -n \ JSON_STRING=$( jq -n \
@@ -274,6 +282,29 @@ function createEVAL() {
add_elastic_to_minion add_elastic_to_minion
add_logstash_to_minion add_logstash_to_minion
add_sensor_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() { function createFLEET() {
@@ -300,18 +331,6 @@ function createHEAVYNODE() {
add_sensor_to_minion 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() { function createSENSOR() {
add_sensor_to_minion add_sensor_to_minion
} }
@@ -323,12 +342,6 @@ function createSEARCHNODE() {
apply_ES_state apply_ES_state
} }
function createSTANDALONE() {
add_elastic_to_minion
add_logstash_to_minion
add_sensor_to_minion
add_playbook_to_minion
}
function testConnection() { function testConnection() {
retry 15 3 "salt '$MINION_ID' test.ping" True retry 15 3 "salt '$MINION_ID' test.ping" True

View File

@@ -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 %} {% import_yaml 'pcap/defaults.yaml' as PCAPDEFAULTS %}
{% set PCAPMERGED = salt['pillar.get']('pcap', PCAPDEFAULTS.pcap, merge=True) %} {% set PCAPMERGED = salt['pillar.get']('pcap', PCAPDEFAULTS.pcap, merge=True) %}

View File

@@ -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 %} {% from 'allowed_states.map.jinja' import allowed_states %}
{% if sls.split('.')[0] in allowed_states %} {% if sls.split('.')[0] in allowed_states %}

View File

@@ -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 'vars/globals.map.jinja' import GLOBALS %}
{% from 'pcap/config.map.jinja' import PCAPMERGED %} {% from 'pcap/config.map.jinja' import PCAPMERGED %}

View File

@@ -3,7 +3,6 @@
# https://securityonion.net/license; you may not use this file except in compliance with the # https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0. # Elastic License 2.0.
{% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %}
{% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %} {% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %}
{% set KIBANA = salt['pillar.get']('kibana:enabled', True) %} {% set KIBANA = salt['pillar.get']('kibana:enabled', True) %}
{% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %} {% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %}
@@ -89,9 +88,7 @@ base:
- strelka - strelka
{%- endif %} {%- endif %}
- curator - curator
{%- if ELASTALERT %}
- elastalert - elastalert
{%- endif %}
- utility - utility
- soctopus - soctopus
- playbook - playbook
@@ -133,9 +130,7 @@ base:
- kibana.so_savedobjects_defaults - kibana.so_savedobjects_defaults
{%- endif %} {%- endif %}
- curator - curator
{%- if ELASTALERT %}
- elastalert - elastalert
{%- endif %}
- utility - utility
- soctopus - soctopus
- playbook - playbook
@@ -181,9 +176,7 @@ base:
- strelka - strelka
{%- endif %} {%- endif %}
- curator - curator
{%- if ELASTALERT %}
- elastalert - elastalert
{%- endif %}
- utility - utility
- soctopus - soctopus
- playbook - playbook
@@ -238,9 +231,7 @@ base:
- elastic-fleet-package-registry - elastic-fleet-package-registry
- kibana.so_savedobjects_defaults - kibana.so_savedobjects_defaults
{%- endif %} {%- endif %}
{%- if ELASTALERT %}
- elastalert - elastalert
{%- endif %}
- utility - utility
- soctopus - soctopus
- playbook - playbook