[feature] Final changes for so-status re: predefined container list

This commit is contained in:
William Wernert
2020-02-06 15:23:03 -05:00
parent d2dd0f09e9
commit 7c00e7c286
11 changed files with 388 additions and 32 deletions

215
pillar/docker/config.sls Normal file
View File

@@ -0,0 +1,215 @@
{%- set OSQUERY = salt['pillar.get']('master:osquery', '0') -%}
{%- set WAZUH = salt['pillar.get']('master:wazuh', '0') -%}
{%- set THEHIVE = salt['pillar.get']('master:thehive', '0') -%}
{%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%}
{%- set FREQSERVER = salt['pillar.get']('master:freq', '0') -%}
{%- set DOMAINSTATS = salt['pillar.get']('master:domainstats', '0') -%}
{%- set BROVER = salt['pillar.get']('static:broversion', 'COMMUNITY') -%}
eval:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-dockerregistry
- so-sensoroni
- so-idstools
- so-auth-api
- so-auth-ui
{%- if OSQUERY != 0 %}
- so-mysql
- so-fleet
- so-redis
{%- endif %}
- so-elasticsearch
- so-logstash
- so-kibana
- so-steno
- so-suricata
- so-zeek
- so-curator
- so-elasalert
{%- if WAZUH != 0 %}
- so-wazuh
{%- endif %}
- so-soctopus
{%- if THEHIVE != 0 %}
- so-thehive
- so-thehive-es
- so-cortex
{%- endif %}
{%- if PLAYBOOK != 0 %}
- so-playbook
- so-navigator
{%- endif %}
{%- if FREQSERVER != 0 %}
- so-freqserver
{%- endif %}
{%- if DOMAINSTATS != 0 %}
- so-domainstats
{%- endif %}
heavy_node:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-redis
- so-logstash
- so-elasticsearch
- so-curator
- so-steno
- so-suricata
- so-wazuh
- so-filebeat
{%- if BROVER != 'SURICATA' %}
- so-zeek
{%- endif %}
helix:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-idstools
- so-steno
- so-zeek
- so-zeek
- so-redis
- so-logstash
- so-filebeat
hot_node:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-logstash
- so-elasticsearch
- so-curator
master_search:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-sensoroni
- so-acng
- so-idstools
- so-redis
- so-auth-api
- so-auth-ui
- so-logstash
- so-elasticsearch
- so-curator
- so-kibana
- so-elasalert
- so-filebeat
- so-soctopus
{%- if OSQUERY != 0 %}
- so-mysql
- so-fleet
- so-redis
{%- endif %}
{%- if WAZUH != 0 %}
- so-wazuh
{%- endif %}
- so-soctopus
{%- if THEHIVE != 0 %}
- so-thehive
- so-thehive-es
- so-cortex
{%- endif %}
{%- if PLAYBOOK != 0 %}
- so-playbook
- so-navigator
{%- endif %}
{%- if FREQSERVER != 0 %}
- so-freqserver
{%- endif %}
{%- if DOMAINSTATS != 0 %}
- so-domainstats
{%- endif %}
master:
containers:
- so-dockerregistry
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-sensoroni
- so-acng
- so-idstools
- so-redis
- so-auth-api
- so-auth-ui
- so-elasticsearch
- so-logstash
- so-kibana
- so-elasalert
- so-filebeat
{%- if OSQUERY != 0 %}
- so-mysql
- so-fleet
- so-redis
{%- endif %}
{%- if WAZUH != 0 %}
- so-wazuh
{%- endif %}
- so-soctopus
{%- if THEHIVE != 0 %}
- so-thehive
- so-thehive-es
- so-cortex
{%- endif %}
{%- if PLAYBOOK != 0 %}
- so-playbook
- so-navigator
{%- endif %}
{%- if FREQSERVER != 0 %}
- so-freqserver
{%- endif %}
{%- if DOMAINSTATS != 0 %}
- so-domainstats
{%- endif %}
parser_node:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-logstash
search_node:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-logstash
- so-elasticsearch
- so-curator
- so-filebeat
{%- if WAZUH != 0 %}
- so-wazuh
{%- endif %}
sensor:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-steno
- so-suricata
{%- if BROVER != 'SURICATA' %}
- so-zeek
{%- endif %}
- so-wazuh
- so-filebeat
warm_node:
containers:
- so-core
- so-telegraf
- so-influxdb
- so-grafana
- so-elasticsearch

View File

@@ -1,6 +1,7 @@
base: base:
'*': '*':
- patch.needs_restarting - patch.needs_restarting
- docker.config
'G@role:so-mastersearch or G@role:so-heavynode': 'G@role:so-mastersearch or G@role:so-heavynode':
- match: compound - match: compound

View File

@@ -0,0 +1,21 @@
#!/bin/bash
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. /usr/sbin/so-common
/usr/sbin/so-restart auth $1

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. /usr/sbin/so-common
/usr/sbin/so-start auth $1

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. /usr/sbin/so-common
/usr/sbin/so-stop auth $1

View File

@@ -32,5 +32,6 @@ fi
case $1 in case $1 in
"cortex") docker stop so-thehive-cortex so-thehive && docker rm so-thehive-cortex so-thehive && salt-call state.apply hive queue=True;; "cortex") docker stop so-thehive-cortex so-thehive && docker rm so-thehive-cortex so-thehive && salt-call state.apply hive queue=True;;
"steno") docker stop so-steno && docker rm so-steno && salt-call state.apply pcap queue=True;; "steno") docker stop so-steno && docker rm so-steno && salt-call state.apply pcap queue=True;;
"auth") docker stop so-auth-api; docker stop so-auth-ui; salt-cal state.apply auth queue=True;;
*) docker stop so-$1 ; docker rm so-$1 ; salt-call state.apply $1 queue=True;; *) docker stop so-$1 ; docker rm so-$1 ; salt-call state.apply $1 queue=True;;
esac esac

View File

@@ -32,5 +32,16 @@ fi
case $1 in case $1 in
"all") salt-call state.highstate queue=True;; "all") salt-call state.highstate queue=True;;
"steno") if docker ps | grep -q so-$1; then printf "\n$1 is already running!\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply pcap queue=True; fi ;; "steno") if docker ps | grep -q so-$1; then printf "\n$1 is already running!\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply pcap queue=True; fi ;;
"auth")
if docker ps | grep -q so-auth-api; then
if docker ps | grep -q so-auth-ui; then
printf "\n$1 is already running!\n\n"
else
docker rm so-auth-api >/dev/null 2>&1; docker rm so-auth-ui >/dev/null 2>&1; salt-call state.apply $1 queue=True
fi
else
docker rm so-auth-api >/dev/null 2>&1; docker rm so-auth-ui >/dev/null 2>&1; salt-call state.apply $1 queue=True
fi
;;
*) if docker ps | grep -q so-$1; then printf "\n$1 is already running\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply $1 queue=True; fi ;; *) if docker ps | grep -q so-$1; then printf "\n$1 is already running\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply $1 queue=True; fi ;;
esac esac

View File

@@ -15,7 +15,32 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# {% raw %} {%- set pillar_suffix = ':containers' -%}
{%- if (salt['grains.get']('role') == 'so-mastersearch') -%}
{%- set pillar_val = 'master_search' -%}
{%- elif (salt['grains.get']('role') == 'so-master') -%}
{%- set pillar_val = 'master' -%}
{%- elif (salt['grains.get']('role') == 'so-heavynode') -%}
{%- set pillar_val = 'heavy_node' -%}
{%- elif (salt['grains.get']('role') == 'so-sensor') -%}
{%- set pillar_val = 'sensor' -%}
{%- elif (salt['grains.get']('role') == 'so-eval') -%}
{%- set pillar_val = 'eval' -%}
{%- elif (salt['grains.get']('role') == 'so-helix') -%}
{%- set pillar_val = 'helix' -%}
{%- elif (salt['grains.get']('role') == 'so-node') -%}
{%- if (salt['pillar.get']('node:node_type') == 'parser') -%}
{%- set pillar_val = 'parser_node' -%}
{%- elif (salt['pillar.get']('node:node_type') == 'hot') -%}
{%- set pillar_val = 'hot_node' -%}
{%- elif (salt['pillar.get']('node:node_type') == 'warm') -%}
{%- set pillar_val = 'warm_node' -%}
{%- elif (salt['pillar.get']('node:node_type') == 'search') -%}
{%- set pillar_val = 'search_node' -%}
{%- endif -%}
{%- endif -%}
{%- set pillar_name = pillar_val ~ pillar_suffix -%}
{%- set container_list = salt['pillar.get'](pillar_name) %}
if ! [ $(id -u)=0 ]; then if ! [ $(id -u)=0 ]; then
echo "This command must be run as root" echo "This command must be run as root"
@@ -26,13 +51,56 @@ fi
ERROR_STRING="ERROR" ERROR_STRING="ERROR"
SUCCESS_STRING="OK" SUCCESS_STRING="OK"
PENDING_STRING="PENDING" PENDING_STRING="PENDING"
MISSING_STRING='MISSING'
declare -a BAD_STATUSES=("removing", "paused", "exited", "dead") declare -a BAD_STATUSES=("removing", "paused", "exited", "dead")
declare -a PENDING_STATUSES=("paused", "created", "restarting") declare -a PENDING_STATUSES=("paused", "created", "restarting")
declare -a GOOD_STATUSES=("running") declare -a GOOD_STATUSES=("running")
declare -a temp_container_name_list=()
declare -a temp_container_state_list=()
declare -a container_name_list=() declare -a container_name_list=()
declare -a container_state_list=() declare -a container_state_list=()
declare -a expected_container_list=()
# {% raw %}
compare_lists() {
local found=0
create_expected_container_list
if [[ ${#expected_container_list[@]} = 0 ]]; then
container_name_list=$temp_container_name_list
container_state_list=$temp_container_state_list
return 1
fi
for intended_item in ${expected_container_list[@]}; do
found = 0
for i in ${!temp_container_name_list[@]}; do
[[ ${temp_container_name_list[$i]} = $intended_item ]] \
&& found = 1 \
&& container_name_list+=("${temp_container_name_list[$i]}") \
&& container_state_list+=("${temp_container_state_list[$i]}") \
&& break
done
if [[ $found = 0 ]]; then
container_name_list+=("$intended_item")
container_state_list+=("missing")
fi
done
}
# {% endraw %}
create_expected_container_list() {
{% for item in container_list%}
expected_container_list+=("{{ item }}")
{% endfor %}
}
populate_container_lists() { populate_container_lists() {
systemctl is-active --quiet docker systemctl is-active --quiet docker
@@ -50,51 +118,51 @@ populate_container_lists() {
for line in ${docker_raw_list[@]}; do for line in ${docker_raw_list[@]}; do
container_name="$( echo $line | sed -e 's/Name:\(.*\),State:\(.*\)/\1/' )" # Get value in the first search group (container names) container_name="$( echo $line | sed -e 's/Name:\(.*\),State:\(.*\)/\1/' )" # Get value in the first search group (container names)
container_state="$( echo $line | sed -e 's/Name:\(.*\),State:\(.*\)/\2/' )" # Get value in the second search group (container states) container_state="$( echo $line | sed -e 's/Name:\(.*\),State:\(.*\)/\2/' )" # Get value in the second search group (container states)
container_name_list+=( "${container_name}" )
container_state_list+=( "${container_state}" ) temp_container_name_list+=( "${container_name}" )
temp_container_state_list+=( "${container_state}" )
done done
compare_lists
} }
parse_status() { parse_status() {
local container_state=${1} local container_state=${1}
local found=0
[[ $container_state = "missing" ]] && printf $MISSING_STRING && return 1
for state in "${GOOD_STATUSES[@]}"; do for state in "${GOOD_STATUSES[@]}"; do
[[ $container_state = $state ]] && printf $SUCCESS_STRING && return 0 [[ $container_state = $state ]] && printf $SUCCESS_STRING && return 0
done done
if [[ $found = 0 ]]; then for state in "${PENDING_STATUSES[@]}"; do
for state in "${PENDING_STATUSES[@]}"; do [[ $container_state = $state ]] && printf $PENDING_STRING && return 0
[[ $container_state = $state ]] && printf $PENDING_STRING && return 0 done
done
fi
# This is technically not needed since the default is error state # This is technically not needed since the default is error state
if [[ $found = 0 ]]; then for state in "${BAD_STATUSES[@]}"; do
for state in "${BAD_STATUSES[@]}"; do [[ $container_state = $state ]] && printf $ERROR_STRING && return 1
[[ $container_state = $state ]] && printf $ERROR_STRING && return 1 done
done
fi
printf $ERROR_STRING && return 1 printf $ERROR_STRING && return 1
} }
columns=$(tput cols) # {% raw %}
print_line() { print_line() {
local service_name=${1} local service_name=${1}
local service_state=$( parse_status ${2} ) local service_state=$( parse_status ${2} )
local PADDING_CONSTANT=14 local columns=$(tput cols)
local state_color="\e[0m" local state_color="\e[0m"
if [[ $service_state = $ERROR_STRING ]]; then local PADDING_CONSTANT=14
if [[ $service_state = $ERROR_STRING ]] || [[ $service_state = $MISSING_STRING ]]; then
state_color="\e[1;31m" state_color="\e[1;31m"
elif [[ $service_state = $SUCCESS_STRING ]]; then elif [[ $service_state = $SUCCESS_STRING ]]; then
state_color="\e[1;32m" state_color="\e[1;32m"
elif [[ $service_state = $PENDING_STRING ]]; then elif [[ $service_state = $PENDING_STRING ]]; then
state_color="\e[1;33m" state_color="\e[1;33m"
else
state_color="\e[0m"
fi fi
printf " $service_name " printf " $service_name "
@@ -121,13 +189,9 @@ main() {
populate_container_lists populate_container_lists
printf "\n" printf "\n"
printf "${focus_color}%b\e[0m" "Checking container statuses\n\n" printf "${focus_color}%b\e[0m" "Checking container statuses\n\n"
local num_containers=${#docker_raw_list[@]} local num_containers=${#docker_raw_list[@]}
local container_name=""
local container_state=""
for i in $(seq 0 $(($num_containers - 1 ))); do for i in $(seq 0 $(($num_containers - 1 ))); do
print_line ${container_name_list[$i]} ${container_state_list[$i]} print_line ${container_name_list[$i]} ${container_state_list[$i]}
@@ -136,6 +200,8 @@ main() {
printf "\n" printf "\n"
} }
# {% endraw %}
main main
# {% endraw %}

View File

@@ -23,5 +23,8 @@ echo $banner
printf "Stopping $1...\n" printf "Stopping $1...\n"
echo $banner echo $banner
docker stop so-$1 ; docker rm so-$1 case $1 in
"auth") docker stop so-auth-api; docker rm so-auth-api; docker stop so-auth-ui; docker rm so-auth-ui ;;
*) docker stop so-$1 ; docker rm so-$1 ;;
esac

View File

@@ -1,7 +1,6 @@
{%- set BROVER = salt['pillar.get']('static:broversion', 'COMMUNITY') -%} {%- set BROVER = salt['pillar.get']('static:broversion', 'COMMUNITY') -%}
{%- set OSQUERY = salt['pillar.get']('master:osquery', '0') -%} {%- set OSQUERY = salt['pillar.get']('master:osquery', '0') -%}
{%- set WAZUH = salt['pillar.get']('master:wazuh', '0') -%} {%- set WAZUH = salt['pillar.get']('master:wazuh', '0') -%}
{%- set GRAFANA = salt['pillar.get']('master:grafana', '0') -%}
{%- set THEHIVE = salt['pillar.get']('master:thehive', '0') -%} {%- set THEHIVE = salt['pillar.get']('master:thehive', '0') -%}
{%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%}
{%- set FREQSERVER = salt['pillar.get']('master:freq', '0') -%} {%- set FREQSERVER = salt['pillar.get']('master:freq', '0') -%}
@@ -100,6 +99,7 @@ base:
- master - master
- idstools - idstools
- redis - redis
- auth
{%- if OSQUERY != 0 %} {%- if OSQUERY != 0 %}
- mysql - mysql
{%- endif %} {%- endif %}
@@ -188,6 +188,7 @@ base:
- firewall - firewall
- sensor - sensor
- master - master
- auth
{%- if OSQUERY != 0 %} {%- if OSQUERY != 0 %}
- launcher - launcher
{%- endif %} {%- endif %}
@@ -204,6 +205,7 @@ base:
- master - master
- idstools - idstools
- redis - redis
- auth
{%- if OSQUERY != 0 %} {%- if OSQUERY != 0 %}
- mysql - mysql
{%- endif %} {%- endif %}
@@ -257,9 +259,5 @@ base:
{%- if BROVER != 'SURICATA' %} {%- if BROVER != 'SURICATA' %}
- zeek - zeek
{%- endif %} {%- endif %}
- wazuh
- filebeat - filebeat
{%- if OSQUERY != 0 %}
- launcher
{%- endif %}
- schedule - schedule

View File

@@ -1036,7 +1036,7 @@ EOF
fi fi
yum clean expire-cache yum clean expire-cache
yum -y install epel-release salt-minion-2019.2.3 yum-utils device-mapper-persistent-data lvm2 openssl yum -y install epel-release salt-minion-2019.2.3 yum-utils device-mapper-persistent-data lvm2 openssl jq
yum -y update exclude=salt* yum -y update exclude=salt*
systemctl enable salt-minion systemctl enable salt-minion
@@ -1054,7 +1054,7 @@ EOF
DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade
# Add the pre-requisites for installing docker-ce # Add the pre-requisites for installing docker-ce
apt-get -y install ca-certificates curl software-properties-common apt-transport-https openssl >> $SETUPLOG 2>&1 apt-get -y install ca-certificates curl software-properties-common apt-transport-https openssl jq >> $SETUPLOG 2>&1
# Grab the version from the os-release file # Grab the version from the os-release file
UVER=$(grep VERSION_ID /etc/os-release | awk -F '[ "]' '{print $2}') UVER=$(grep VERSION_ID /etc/os-release | awk -F '[ "]' '{print $2}')