rework of os patch scheduling, added the abilty to enable/disable and adjust splay - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84

This commit is contained in:
m0duspwnens
2019-11-07 09:49:36 -05:00
parent fa87308bac
commit 9914e55ec3
7 changed files with 188 additions and 74 deletions

View File

@@ -1,7 +1,4 @@
base: base:
'*':
- patch.os.{{ grains.id }}
'G@role:so-sensor': 'G@role:so-sensor':
- sensors.{{ grains.id }} - sensors.{{ grains.id }}
- static - static

View File

@@ -0,0 +1,76 @@
{% if salt['pillar.get']('patch:os:schedule_name') %}
{% set patch_os_pillar = salt['pillar.get']('patch:os') %}
{% set schedule_name = patch_os_pillar.schedule_name %}
{% set splay = patch_os_pillar.get('splay', 300) %}
{% if schedule_name != 'manual' and schedule_name != 'auto' %}
{% import_yaml "patch/os/schedules/"~schedule_name~".yml" as os_schedule %}
{% if patch_os_pillar.enabled %}
patch_os_schedule:
schedule.present:
- function: state.sls
- job_args:
- patch.os
- when:
{% for days in os_schedule.patch.os.schedule %}
{% for day, times in days.iteritems() %}
{% for time in times %}
- {{day}} {{time}}
{% endfor %}
{% endfor %}
{% endfor %}
- splay: {{splay}}
- return_job: True
{% else %}
disable_patch_os_schedule:
schedule.disabled:
- name: patch_os_schedule
{% endif %}
{% elif schedule_name == 'auto' %}
{% if patch_os_pillar.enabled %}
patch_os_schedule:
schedule.present:
- function: state.sls
- job_args:
- patch.os
- minutes: 1
- splay: {{splay}}
- return_job: True
{% else %}
disable_patch_os_schedule:
schedule.disabled:
- name: patch_os_schedule
{% endif %}
{% elif schedule_name == 'manual' %}
remove_patch_os_schedule:
schedule.absent:
- name: patch_os_schedule
{% endif %}
{% else %}
no_os_patch_schedule_name_set:
test.fail_without_changes:
- name: "Set a pillar value for patch:os:schedule_name in this minion's .sls file. If an OS patch schedule is not listed as enabled in show_schedule output below, then OS patches will need to be applied manually until this is corrected."
show_schedule:
module.run:
- name: schedule.is_enabled
- m_name: patch_os_schedule
{% endif %}

View File

@@ -0,0 +1,10 @@
patch:
os:
schedule:
- Tuesday:
- '15:00'
- Thursday:
- '03:00'
- Saturday:
- '01:00'
- '15:00'

View File

@@ -1,32 +0,0 @@
{% if salt['pillar.get']('patch:os:schedule') != 'manual' and salt['pillar.get']('patch:os:schedule') != 'auto' %}
patch_os_schedule:
schedule.present:
- function: state.sls
- job_args:
- patch.os
- when:
{% for days in pillar['patch']['os']['schedule'] %}
{% for day, times in days.iteritems() %}
{% for time in times %}
- {{day}} {{time}}
{% endfor %}
{% endfor %}
{% endfor %}
- splay:
start: 30
end: 120
{% elif salt['pillar.get']('patch:os:schedule') == 'auto' %}
patch_os_schedule:
schedule.present:
- function: state.sls
- job_args:
- patch.os
- minutes: 20
- splay:
start: 150
end: 300
{% endif %}

View File

@@ -6,7 +6,7 @@
{%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%}
base: base:
'*': '*':
- patch.schedule.os - patch.os.schedule
'G@role:so-sensor': 'G@role:so-sensor':
- ca - ca

View File

@@ -268,14 +268,14 @@ copy_master_config() {
} }
copy_minion_pillars() { copy_minion_tmp_files() {
if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then
echo "rsyncing TMP pillar files to pillar base" >> $SETUPLOG 2>&1 echo "rsyncing all files in $TMP to /opt/so/saltstack" >> $SETUPLOG 2>&1
rsync -a -v $TMP/pillar/ /opt/so/saltstack/pillar/ >> $SETUPLOG 2>&1 rsync -a -v $TMP/ /opt/so/saltstack/ >> $SETUPLOG 2>&1
else else
echo "scp TMP pillar files to pillar base on master" >> $SETUPLOG 2>&1 echo "scp all files in $TMP to master /opt/so/saltstack" >> $SETUPLOG 2>&1
scp -prv -i /root/.ssh/so.key $TMP/pillar socore@$MSRV:/opt/so/saltstack/pillar >> $SETUPLOG 2>&1 scp -prv -i /root/.ssh/so.key $TMP socore@$MSRV:/opt/so/saltstack >> $SETUPLOG 2>&1
fi fi
} }
@@ -626,38 +626,51 @@ node_pillar() {
} }
patch_pillar() { patch_pillar() {
OSPATCHPILLARDIR="$TMP/pillar/patch/os"
OSPATCHPILLAR="$OSPATCHPILLARDIR/$MINION_ID.sls"
if [ ! -d $OSPATCHPILLARDIR ] ; then case $INSTALLTYPE in
mkdir -p $OSPATCHPILLARDIR MASTERONLY | EVALMODE)
PATCHPILLARPATH=/opt/so/saltstack/pillar/masters
;;
SENSORONLY)
PATCHPILLARPATH=$SENSORPILLARPATH
;;
STORAGENODE | PARSINGNODE | HOTNODE | WARMNODE)
PATCHPILLARPATH=$NODEPILLARPATH
;;
esac
echo "" >> $PATCHPILLARPATH/$MINION_ID.sls
echo "patch:" >> $PATCHPILLARPATH/$MINION_ID.sls
echo " os:" >> $PATCHPILLARPATH/$MINION_ID.sls
echo " schedule_name: $PATCHSCHEDULENAME" >> $PATCHPILLARPATH/$MINION_ID.sls
echo " enabled: True" >> $PATCHPILLARPATH/$MINION_ID.sls
echo " splay: 300" >> $PATCHPILLARPATH/$MINION_ID.sls
}
patch_schedule_os_new() {
OSPATCHSCHEDULEDIR="$TMP/salt/patch/os/schedules"
OSPATCHSCHEDULE="$OSPATCHSCHEDULEDIR/$PATCHSCHEDULENAME.yml"
if [ ! -d $OSPATCHSCHEDULEDIR ] ; then
mkdir -p $OSPATCHSCHEDULEDIR
fi fi
touch $OSPATCHPILLAR
echo "patch:" > $OSPATCHPILLAR echo "patch:" > $OSPATCHSCHEDULE
case $PATCHSCHEDULE in echo " os:" >> $OSPATCHSCHEDULE
Scheduled) echo " schedule:" >> $OSPATCHSCHEDULE
echo " os:" >> $OSPATCHPILLAR
echo " schedule:" >> $OSPATCHPILLAR
for psd in "${PATCHSCHEDULEDAYS[@]}" for psd in "${PATCHSCHEDULEDAYS[@]}"
do do
psd=$(echo $psd | sed 's/"//g') psd=$(echo $psd | sed 's/"//g')
echo " - $psd:" >> $OSPATCHPILLAR echo " - $psd:" >> $OSPATCHSCHEDULE
for psh in "${PATCHSCHEDULEHOURS[@]}" for psh in "${PATCHSCHEDULEHOURS[@]}"
do do
psh=$(echo $psh | sed 's/"//g') psh=$(echo $psh | sed 's/"//g')
echo " - '$psh'" >> $OSPATCHPILLAR echo " - '$psh'" >> $OSPATCHSCHEDULE
done done
done done
;;
Automatic)
echo " os:" >> $OSPATCHPILLAR
echo " schedule: auto" >> $OSPATCHPILLAR
;;
Manual)
echo " os:" >> $OSPATCHPILLAR
echo " schedule: manual" >> $OSPATCHPILLAR
;;
esac
} }
@@ -1516,20 +1529,50 @@ whiptail_passwords_dont_match() {
} }
whiptail_patch_name_new_schedule() {
unset PATCHSCHEDULENAME
while [[ -z "$PATCHSCHEDULENAME" ]]; do
PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \
"What name do you want to give this OS patch schedule? This schedule needs to be named uniquely. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/<schedulename>.yml" 10 75 3>&1 1>&2 2>&3)
done
}
whiptail_patch_schedule() { whiptail_patch_schedule() {
# What kind of patch schedule are we doing? # What kind of patch schedule are we doing?
PATCHSCHEDULE=$(whiptail --title "Security Onion Setup" --radiolist \ PATCHSCHEDULE=$(whiptail --title "Security Onion Setup" --radiolist \
"Choose OS patch schedule. This will NOT update Security Onion related tools such as Zeek, Elasticsearch, Kibana, SaltStack, etc." 25 75 5 \ "Choose OS patch schedule. This will NOT update Security Onion related tools such as Zeek, Elasticsearch, Kibana, SaltStack, etc." 25 115 5 \
"Automatic" "Package updates will be installed automatically" ON \ "Automatic" "Package updates will be installed automatically" ON \
"Manual" "Package updates will need to be installed manually" OFF \ "Manual" "Package updates will need to be installed manually" OFF \
"Scheduled" "Select a schedule on the following screen" OFF 3>&1 1>&2 2>&3 ) "Import Schedule" "Enter the name of an existing schedule on the following screen and inherit it" OFF \
"New Schedule" "Configure and name a new schedule on the following screen" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$? local exitstatus=$?
whiptail_check_exitstatus $exitstatus whiptail_check_exitstatus $exitstatus
} }
whiptail_patch_schedule_import() {
unset PATCHSCHEDULENAME
# Ask to inherit from master
whiptail --title "Security Onion Setup" --yesno "Do you want to inherit the OS patch schedule from the master?" 8 78
local exitstatus=$?
if [ $exitstatus == 0 ]; then
PATCHSCHEDULENAME=default
else
while [[ -z "$PATCHSCHEDULENAME" ]]; do
PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \
"Enter the name of the OS patch schedule you want to inherit. If you leave this as default, it will use the same schedule as the master. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/<schedulename>.yml" 10 60 default 3>&1 1>&2 2>&3)
done
fi
}
whiptail_patch_schedule_select_days() { whiptail_patch_schedule_select_days() {
# Select the days to patch # Select the days to patch
PATCHSCHEDULEDAYS=($(whiptail --title "Security Onion Setup" --checklist \ PATCHSCHEDULEDAYS=($(whiptail --title "Security Onion Setup" --checklist \
@@ -1721,11 +1764,23 @@ if (whiptail_you_sure); then
# How do we want to handle OS patching? manual, auto or scheduled days and hours # How do we want to handle OS patching? manual, auto or scheduled days and hours
whiptail_patch_schedule whiptail_patch_schedule
if [[ $PATCHSCHEDULE == "Scheduled" ]] ; then case $PATCHSCHEDULE in
whiptail_patch_schedule_select_days 'New Schedule')
whiptail_patch_schedule_select_hours whiptail_patch_schedule_select_days
fi whiptail_patch_schedule_select_hours
patch_pillar whiptail_patch_name_new_schedule
patch_schedule_os_new
;;
'Import Schedule')
whiptail_patch_schedule_import
;;
Automatic)
PATCHSCHEDULENAME=auto
;;
Manual)
PATCHSCHEDULENAME=manual
;;
esac
#################### ####################
## Master ## ## Master ##
@@ -1821,9 +1876,11 @@ if (whiptail_you_sure); then
master_static >> $SETUPLOG 2>&1 master_static >> $SETUPLOG 2>&1
echo "** Generating the master pillar **" >> $SETUPLOG echo "** Generating the master pillar **" >> $SETUPLOG
master_pillar >> $SETUPLOG 2>&1 master_pillar >> $SETUPLOG 2>&1
echo "** Generating the patch pillar **" >> $SETUPLOG
patch_pillar >> $SETUPLOG 2>&1
echo -e "XXX\n30\nAccepting Salt Keys... \nXXX" echo -e "XXX\n30\nAccepting Salt Keys... \nXXX"
echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX"
copy_minion_pillars >> $SETUPLOG 2>&1 copy_minion_tmp_files >> $SETUPLOG 2>&1
# Do a checkin to push the key up # Do a checkin to push the key up
echo "** Pushing the key up to Master **" >> $SETUPLOG echo "** Pushing the key up to Master **" >> $SETUPLOG
salt_firstcheckin >> $SETUPLOG 2>&1 salt_firstcheckin >> $SETUPLOG 2>&1
@@ -1938,6 +1995,8 @@ if (whiptail_you_sure); then
network_setup >> $SETUPLOG 2>&1 network_setup >> $SETUPLOG 2>&1
echo -e "XXX\n4\nGenerating Sensor Pillar... \nXXX" echo -e "XXX\n4\nGenerating Sensor Pillar... \nXXX"
sensor_pillar >> $SETUPLOG 2>&1 sensor_pillar >> $SETUPLOG 2>&1
echo "** Generating the patch pillar **" >> $SETUPLOG
patch_pillar >> $SETUPLOG 2>&1
echo -e "XXX\n5\nInstalling Salt Components... \nXXX" echo -e "XXX\n5\nInstalling Salt Components... \nXXX"
saltify >> $SETUPLOG 2>&1 saltify >> $SETUPLOG 2>&1
echo -e "XXX\n20\nInstalling Docker... \nXXX" echo -e "XXX\n20\nInstalling Docker... \nXXX"
@@ -1945,7 +2004,7 @@ if (whiptail_you_sure); then
echo -e "XXX\n22\nConfiguring Salt Minion... \nXXX" echo -e "XXX\n22\nConfiguring Salt Minion... \nXXX"
configure_minion sensor >> $SETUPLOG 2>&1 configure_minion sensor >> $SETUPLOG 2>&1
echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX"
copy_minion_pillars >> $SETUPLOG 2>&1 copy_minion_tmp_files >> $SETUPLOG 2>&1
echo -e "XXX\n25\nSending Salt Key to Master... \nXXX" echo -e "XXX\n25\nSending Salt Key to Master... \nXXX"
salt_firstcheckin >> $SETUPLOG 2>&1 salt_firstcheckin >> $SETUPLOG 2>&1
echo -e "XXX\n26\nTelling the Master to Accept Key... \nXXX" echo -e "XXX\n26\nTelling the Master to Accept Key... \nXXX"
@@ -2049,6 +2108,8 @@ if (whiptail_you_sure); then
master_static >> $SETUPLOG 2>&1 master_static >> $SETUPLOG 2>&1
echo -e "XXX\n7\nCreating the master pillar... \nXXX" echo -e "XXX\n7\nCreating the master pillar... \nXXX"
master_pillar >> $SETUPLOG 2>&1 master_pillar >> $SETUPLOG 2>&1
echo "** Generating the patch pillar **" >> $SETUPLOG
patch_pillar >> $SETUPLOG 2>&1
echo -e "XXX\n7\nConfiguring minion... \nXXX" echo -e "XXX\n7\nConfiguring minion... \nXXX"
configure_minion eval >> $SETUPLOG 2>&1 configure_minion eval >> $SETUPLOG 2>&1
echo -e "XXX\n7\nSetting the node type to eval... \nXXX" echo -e "XXX\n7\nSetting the node type to eval... \nXXX"
@@ -2058,7 +2119,7 @@ if (whiptail_you_sure); then
echo -e "XXX\n8\nCreating firewall policies... \nXXX" echo -e "XXX\n8\nCreating firewall policies... \nXXX"
set_initial_firewall_policy >> $SETUPLOG 2>&1 set_initial_firewall_policy >> $SETUPLOG 2>&1
echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX"
copy_minion_pillars >> $SETUPLOG 2>&1 copy_minion_tmp_files >> $SETUPLOG 2>&1
echo -e "XXX\n10\nRegistering agent... \nXXX" echo -e "XXX\n10\nRegistering agent... \nXXX"
salt_firstcheckin >> $SETUPLOG 2>&1 salt_firstcheckin >> $SETUPLOG 2>&1
echo -e "XXX\n11\nAccepting Agent... \nXXX" echo -e "XXX\n11\nAccepting Agent... \nXXX"
@@ -2200,8 +2261,10 @@ if (whiptail_you_sure); then
configure_minion node >> $SETUPLOG 2>&1 configure_minion node >> $SETUPLOG 2>&1
set_node_type >> $SETUPLOG 2>&1 set_node_type >> $SETUPLOG 2>&1
node_pillar >> $SETUPLOG 2>&1 node_pillar >> $SETUPLOG 2>&1
echo "** Generating the patch pillar **" >> $SETUPLOG
patch_pillar >> $SETUPLOG 2>&1
echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX"
copy_minion_pillars >> $SETUPLOG 2>&1 copy_minion_tmp_files >> $SETUPLOG 2>&1
echo -e "XXX\n35\nSending and Accepting Salt Key... \nXXX" echo -e "XXX\n35\nSending and Accepting Salt Key... \nXXX"
salt_firstcheckin >> $SETUPLOG 2>&1 salt_firstcheckin >> $SETUPLOG 2>&1
# Accept the Salt Key # Accept the Salt Key