From 089d80427ac80bf21e5a309b7b16e200c2d2b2e7 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 25 Sep 2019 09:16:30 -0400 Subject: [PATCH 01/67] Fleet - New Docker env var for path prefix --- salt/fleet/init.sls | 1 + 1 file changed, 1 insertion(+) diff --git a/salt/fleet/init.sls b/salt/fleet/init.sls index 83c019880..8284dbe91 100644 --- a/salt/fleet/init.sls +++ b/salt/fleet/init.sls @@ -83,6 +83,7 @@ so-fleet: - KOLIDE_AUTH_JWT_KEY=thisisatest - KOLIDE_OSQUERY_STATUS_LOG_FILE=/var/log/osquery/status.log - KOLIDE_OSQUERY_RESULT_LOG_FILE=/var/log/osquery/result.log + - KOLIDE_SERVER_URL_PREFIX=/fleet - binds: - /etc/pki/fleet.key:/ssl/server.key:ro - /etc/pki/fleet.crt:/ssl/server.cert:ro From 94e15ed5029573e8593cda68a2db8999b622af28 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Sun, 27 Oct 2019 14:36:52 -0400 Subject: [PATCH 02/67] Tweaked for sigmac backend change --- salt/soctopus/files/templates/generic.template | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/salt/soctopus/files/templates/generic.template b/salt/soctopus/files/templates/generic.template index 992db3fa9..23b693258 100644 --- a/salt/soctopus/files/templates/generic.template +++ b/salt/soctopus/files/templates/generic.template @@ -3,20 +3,6 @@ {% set hivekey = salt['pillar.get']('static:hivekey', '') %} es_host: {{es}} es_port: 9200 -name: Alert-Name -type: frequency -index: "*:logstash-*" -num_events: 1 -timeframe: - minutes: 10 -buffer_time: - minutes: 10 -allow_buffer_time_overlap: true - -filter: -- query: - query_string: - query: 'select from test' alert: modules.so.thehive.TheHiveAlerter @@ -32,7 +18,7 @@ hive_alert_config: title: '{rule[name]}' type: 'external' source: 'SecurityOnion' - description: '`Data:` {match[message]}' + description: "`Play:` https://{{es}}/playbook/issues/6000 \n\n `Data:` {match[message]}" severity: 2 tags: ['elastalert', 'SecurityOnion'] tlp: 3 From f7df14b48f3f1945fe9540920080ee1fad4c6647 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 5 Nov 2019 08:58:51 -0500 Subject: [PATCH 03/67] add os patch scheduling options to the network install script - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- so-setup-network.sh | 107 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index 6e54b8ce4..23cde3a5b 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -619,6 +619,42 @@ node_pillar() { } +patch_pillar() { + OSPATCHPILLARDIR="$TMP/patch/os" + OSPATCHPILLAR="$OSPATCHPILLARDIR/$MINION_ID.sls" + + if [ ! -d $OSPATCHPILLARDIR ] ; then + mkdir -p $OSPATCHPILLARDIR + fi + touch $OSPATCHPILLAR + echo "patch:" > $OSPATCHPILLAR + case $PATCHSCHEDULE in + Scheduled) + echo " os:" >> $OSPATCHPILLAR + echo " schedule:" >> $OSPATCHPILLAR + for psd in "${PATCHSCHEDULEDAYS[@]}" + do + psd=$(echo $psd | sed 's/"//g') + echo " - $psd:" >> $OSPATCHPILLAR + for psh in "${PATCHSCHEDULEHOURS[@]}" + do + psh=$(echo $psh | sed 's/"//g') + echo " - $psh" >> $OSPATCHPILLAR + done + done + ;; + Automatic) + echo " os:" >> $OSPATCHPILLAR + echo " schedule: auto" >> $OSPATCHPILLAR + ;; + Manual) + echo " os:" >> $OSPATCHPILLAR + echo " schedule: manual" >> $OSPATCHPILLAR + ;; + esac + +} + process_components() { CLEAN=${COMPONENTS//\"} GRAFANA=0 @@ -1469,6 +1505,69 @@ whiptail_passwords_dont_match() { } +whiptail_patch_schedule() { + + # What kind of patch schedule are we doing? + 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 \ + "Automatic" "Package updates will be installed automatically" ON \ + "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 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_patch_schedule_select_days() { + # Select the days to patch + PATCHSCHEDULEDAYS=($(whiptail --title "Security Onion Setup" --checklist \ + "Which days do you want to apply OS patches?" 20 55 9 \ + "Monday" "" OFF \ + "Tuesday" "" ON \ + "Wednesday" "" OFF \ + "Thursday" "" OFF \ + "Friday" "" OFF \ + "Saturday" "" OFF \ + "Sunday" "" OFF 3>&1 1>&2 2>&3 )) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus +} + +whiptail_patch_schedule_select_hours() { + # Select the hours to patch + PATCHSCHEDULEHOURS=($(whiptail --title "Security Onion Setup" --checklist \ + "At which time, UTC, do you want to apply OS patches on the selected days?" 35 55 26 \ + "00:00" "" OFF \ + "01:00" "" OFF \ + "02:00" "" OFF \ + "03:00" "" OFF \ + "04:00" "" OFF \ + "05:00" "" OFF \ + "06:00" "" OFF \ + "07:00" "" OFF \ + "08:00" "" OFF \ + "09:00" "" OFF \ + "10:00" "" OFF \ + "11:00" "" OFF \ + "12:00" "" OFF \ + "13:00" "" OFF \ + "14:00" "" OFF \ + "15:00" "" ON \ + "16:00" "" OFF \ + "17:00" "" OFF \ + "18:00" "" OFF \ + "19:00" "" OFF \ + "20:00" "" OFF \ + "21:00" "" OFF \ + "22:00" "" OFF \ + "23:00" "" OFF 3>&1 1>&2 2>&3 )) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus +} + whiptail_rule_setup() { # Get pulled pork info @@ -1609,6 +1708,14 @@ if (whiptail_you_sure); then # What kind of install are we doing? whiptail_install_type + # How do we want to handle OS patching? manual, auto or scheduled days and hours + whiptail_patch_schedule + if [[ $PATCHSCHEDULE == "Scheduled" ]] ; then + whiptail_patch_schedule_select_days + whiptail_patch_schedule_select_hours + fi + patch_pillar + #################### ## Master ## #################### From 5e5d0d616cdd3e8e2ef07202a6d677fccfa6d85f Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 5 Nov 2019 14:22:37 -0500 Subject: [PATCH 04/67] copy_minion_pillar replaced with copy_minion_pillar to simplify pillar copying, os patch pillar written - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- so-setup-network.sh | 108 +++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 46 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 23cde3a5b..bed63a0c6 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -268,14 +268,15 @@ copy_master_config() { } -copy_minion_pillar() { +copy_minion_pillars() { - # Pass the type so it knows where to copy the pillar - local TYPE=$1 - - # Copy over the pillar - echo "Copying the pillar over" >> $SETUPLOG 2>&1 - scp -v -i /root/.ssh/so.key $TMP/$MINION_ID.sls socore@$MSRV:/opt/so/saltstack/pillar/$TYPE/$MINION_ID.sls + if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + echo "rsyncing TMP pillar files to pillar base" >> $SETUPLOG 2>&1 + rsync -a -v $TMP/pillar/ /opt/so/saltstack/pillar/ >> $SETUPLOG 2>&1 + else + echo "scp TMP pillar files to pillar base on master" >> $SETUPLOG 2>&1 + scp -prv -i /root/.ssh/so.key $TMP/pillar socore@$MSRV:/opt/so/saltstack/pillar >> $SETUPLOG 2>&1 + fi } @@ -599,28 +600,33 @@ minio_generate_keys() { node_pillar() { + NODEPILLARPATH=$TMP/pillar/nodes + if [ ! -d $NODEPILLARPATH ]; then + mkdir -p $NODEPILLARPATH + fi + # Create the node pillar - touch $TMP/$MINION_ID.sls - echo "node:" > $TMP/$MINION_ID.sls - echo " mainip: $MAINIP" >> $TMP/$MINION_ID.sls - echo " mainint: $MAININT" >> $TMP/$MINION_ID.sls - echo " esheap: $NODE_ES_HEAP_SIZE" >> $TMP/$MINION_ID.sls - echo " esclustername: {{ grains.host }}" >> $TMP/$MINION_ID.sls - echo " lsheap: $NODE_LS_HEAP_SIZE" >> $TMP/$MINION_ID.sls - echo " ls_pipeline_workers: $LSPIPELINEWORKERS" >> $TMP/$MINION_ID.sls - echo " ls_pipeline_batch_size: $LSPIPELINEBATCH" >> $TMP/$MINION_ID.sls - echo " ls_input_threads: $LSINPUTTHREADS" >> $TMP/$MINION_ID.sls - echo " ls_batch_count: $LSINPUTBATCHCOUNT" >> $TMP/$MINION_ID.sls - echo " es_shard_count: $SHARDCOUNT" >> $TMP/$MINION_ID.sls - echo " node_type: $NODETYPE" >> $TMP/$MINION_ID.sls - echo " es_port: $NODE_ES_PORT" >> $TMP/$MINION_ID.sls - echo " log_size_limit: $LOG_SIZE_LIMIT" >> $TMP/$MINION_ID.sls - echo " cur_close_days: $CURCLOSEDAYS" >> $TMP/$MINION_ID.sls + touch $NODEPILLARPATH/$MINION_ID.sls + echo "node:" > $NODEPILLARPATH/$MINION_ID.sls + echo " mainip: $MAINIP" >> $NODEPILLARPATH/$MINION_ID.sls + echo " mainint: $MAININT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " esheap: $NODE_ES_HEAP_SIZE" >> $NODEPILLARPATH/$MINION_ID.sls + echo " esclustername: {{ grains.host }}" >> $NODEPILLARPATH/$MINION_ID.sls + echo " lsheap: $NODE_LS_HEAP_SIZE" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_pipeline_workers: $LSPIPELINEWORKERS" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_pipeline_batch_size: $LSPIPELINEBATCH" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_input_threads: $LSINPUTTHREADS" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_batch_count: $LSINPUTBATCHCOUNT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " es_shard_count: $SHARDCOUNT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " node_type: $NODETYPE" >> $NODEPILLARPATH/$MINION_ID.sls + echo " es_port: $NODE_ES_PORT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " log_size_limit: $LOG_SIZE_LIMIT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " cur_close_days: $CURCLOSEDAYS" >> $NODEPILLARPATH/$MINION_ID.sls } patch_pillar() { - OSPATCHPILLARDIR="$TMP/patch/os" + OSPATCHPILLARDIR="$TMP/pillar/patch/os" OSPATCHPILLAR="$OSPATCHPILLARDIR/$MINION_ID.sls" if [ ! -d $OSPATCHPILLARDIR ] ; then @@ -962,37 +968,42 @@ salt_master_directories() { sensor_pillar() { + SENSORPILLARPATH=$TMP/pillar/sensors + if [ ! -d $SENSORPILLARPATH ]; then + mkdir -p $SENSORPILLARPATH + fi + # Create the sensor pillar - touch $TMP/$MINION_ID.sls - echo "sensor:" > $TMP/$MINION_ID.sls - echo " interface: bond0" >> $TMP/$MINION_ID.sls - echo " mainip: $MAINIP" >> $TMP/$MINION_ID.sls - echo " mainint: $MAININT" >> $TMP/$MINION_ID.sls + touch $SENSORPILLARPATH/$MINION_ID.sls + echo "sensor:" > $SENSORPILLARPATH/$MINION_ID.sls + echo " interface: bond0" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " mainip: $MAINIP" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " mainint: $MAININT" >> $SENSORPILLARPATH/$MINION_ID.sls if [ $NSMSETUP == 'ADVANCED' ]; then - echo " bro_pins:" >> $TMP/$MINION_ID.sls + echo " bro_pins:" >> $SENSORPILLARPATH/$MINION_ID.sls for PIN in $BROPINS; do PIN=$(echo $PIN | cut -d\" -f2) - echo " - $PIN" >> $TMP/$MINION_ID.sls + echo " - $PIN" >> $SENSORPILLARPATH/$MINION_ID.sls done - echo " suripins:" >> $TMP/$MINION_ID.sls + echo " suripins:" >> $SENSORPILLARPATH/$MINION_ID.sls for SPIN in $SURIPINS; do SPIN=$(echo $SPIN | cut -d\" -f2) - echo " - $SPIN" >> $TMP/$MINION_ID.sls + echo " - $SPIN" >> $SENSORPILLARPATH/$MINION_ID.sls done else - echo " bro_lbprocs: $BASICBRO" >> $TMP/$MINION_ID.sls - echo " suriprocs: $BASICSURI" >> $TMP/$MINION_ID.sls + echo " bro_lbprocs: $BASICBRO" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " suriprocs: $BASICSURI" >> $SENSORPILLARPATH/$MINION_ID.sls fi - echo " brobpf:" >> $TMP/$MINION_ID.sls - echo " pcapbpf:" >> $TMP/$MINION_ID.sls - echo " nidsbpf:" >> $TMP/$MINION_ID.sls - echo " master: $MSRV" >> $TMP/$MINION_ID.sls - echo " mtu: $MTU" >> $TMP/$MINION_ID.sls + echo " brobpf:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " pcapbpf:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " nidsbpf:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " master: $MSRV" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " mtu: $MTU" >> $SENSORPILLARPATH/$MINION_ID.sls if [ $HNSENSOR != 'inherit' ]; then - echo " hnsensor: $HNSENSOR" >> $TMP/$MINION_ID.sls + echo " hnsensor: $HNSENSOR" >> $SENSORPILLARPATH/$MINION_ID.sls fi - echo " access_key: $ACCESS_KEY" >> $TMP/$MINION_ID.sls - echo " access_secret: $ACCESS_SECRET" >> $TMP/$MINION_ID.sls + echo " access_key: $ACCESS_KEY" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " access_secret: $ACCESS_SECRET" >> $SENSORPILLARPATH/$MINION_ID.sls } @@ -1811,6 +1822,8 @@ if (whiptail_you_sure); then echo "** Generating the master pillar **" >> $SETUPLOG master_pillar >> $SETUPLOG 2>&1 echo -e "XXX\n30\nAccepting Salt Keys... \nXXX" + echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" + copy_minion_pillars >> $SETUPLOG 2>&1 # Do a checkin to push the key up echo "** Pushing the key up to Master **" >> $SETUPLOG salt_firstcheckin >> $SETUPLOG 2>&1 @@ -1931,8 +1944,8 @@ if (whiptail_you_sure); then docker_install >> $SETUPLOG 2>&1 echo -e "XXX\n22\nConfiguring Salt Minion... \nXXX" configure_minion sensor >> $SETUPLOG 2>&1 - echo -e "XXX\n24\nCopying Sensor Pillar to Master... \nXXX" - copy_minion_pillar sensors >> $SETUPLOG 2>&1 + echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" + copy_minion_pillars >> $SETUPLOG 2>&1 echo -e "XXX\n25\nSending Salt Key to Master... \nXXX" salt_firstcheckin >> $SETUPLOG 2>&1 echo -e "XXX\n26\nTelling the Master to Accept Key... \nXXX" @@ -2044,6 +2057,8 @@ if (whiptail_you_sure); then node_pillar >> $SETUPLOG 2>&1 echo -e "XXX\n8\nCreating firewall policies... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 + echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" + copy_minion_pillars >> $SETUPLOG 2>&1 echo -e "XXX\n10\nRegistering agent... \nXXX" salt_firstcheckin >> $SETUPLOG 2>&1 echo -e "XXX\n11\nAccepting Agent... \nXXX" @@ -2185,7 +2200,8 @@ if (whiptail_you_sure); then configure_minion node >> $SETUPLOG 2>&1 set_node_type >> $SETUPLOG 2>&1 node_pillar >> $SETUPLOG 2>&1 - copy_minion_pillar nodes >> $SETUPLOG 2>&1 + echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" + copy_minion_pillars >> $SETUPLOG 2>&1 echo -e "XXX\n35\nSending and Accepting Salt Key... \nXXX" salt_firstcheckin >> $SETUPLOG 2>&1 # Accept the Salt Key From f608cba4426fabd74675b88babc2d0b21dae7f18 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 5 Nov 2019 15:46:14 -0500 Subject: [PATCH 05/67] Sensoroni State - Fix log location --- salt/sensoroni/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/sensoroni/init.sls b/salt/sensoroni/init.sls index 245c34344..83e960716 100644 --- a/salt/sensoroni/init.sls +++ b/salt/sensoroni/init.sls @@ -41,7 +41,7 @@ so-sensoroni: - binds: - /nsm/sensoroni/jobs:/opt/sensoroni/jobs:rw - /opt/so/conf/sensoroni/sensoroni.json:/opt/sensoroni/sensoroni.json:ro - - /opt/so/log/sensoroni/:/opt/sensoroni/log/:rw + - /opt/so/log/sensoroni/:/opt/sensoroni/logs/:rw - port_bindings: - 0.0.0.0:9822:9822 - watch: From 21494ab1ffd32a801cd261be95fd5ec6c5cec0d0 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 5 Nov 2019 16:01:12 -0500 Subject: [PATCH 06/67] install package python-dateutil during setup to help with job scheduling - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- so-setup-network.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index bed63a0c6..38f5b7e44 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -833,7 +833,7 @@ EOF fi yum clean expire-cache - yum -y install salt-minion-2018.3.4 yum-utils device-mapper-persistent-data lvm2 openssl + yum -y install salt-minion-2018.3.4 yum-utils device-mapper-persistent-data lvm2 openssl python-dateutil yum -y update exclude=salt* systemctl enable salt-minion @@ -882,7 +882,7 @@ EOF # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 - apt-get -y install salt-minion=2018.3.4+ds-1 salt-common=2018.3.4+ds-1 python-m2crypto >> $SETUPLOG 2>&1 + apt-get -y install salt-minion=2018.3.4+ds-1 salt-common=2018.3.4+ds-1 python-m2cryptoi python-dateutil >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common else @@ -896,7 +896,7 @@ EOF echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 - apt-get -y install salt-minion=2018.3.4+ds-1 salt-common=2018.3.4+ds-1 python-m2crypto >> $SETUPLOG 2>&1 + apt-get -y install salt-minion=2018.3.4+ds-1 salt-common=2018.3.4+ds-1 python-m2crypto python-dateutil >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common fi From e6421f45fb3ae862a115ce419d3bdf512c3e902b Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 5 Nov 2019 17:22:27 -0500 Subject: [PATCH 07/67] add state to add os patch schedule and state to apply patches - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- pillar/top.sls | 3 +++ salt/patch/os.sls | 4 ++++ salt/patch/schedule/os.sls | 32 ++++++++++++++++++++++++++++++++ salt/top.sls | 3 +++ 4 files changed, 42 insertions(+) create mode 100644 salt/patch/os.sls create mode 100644 salt/patch/schedule/os.sls diff --git a/pillar/top.sls b/pillar/top.sls index 031352a11..13ea5e5a8 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -1,4 +1,7 @@ base: + '*': + - patch.os.{{ grains.id }} + 'G@role:so-sensor': - sensors.{{ grains.id }} - static diff --git a/salt/patch/os.sls b/salt/patch/os.sls new file mode 100644 index 000000000..d3ae6a1ff --- /dev/null +++ b/salt/patch/os.sls @@ -0,0 +1,4 @@ +patch_os: + pkg.uptodate: + - name: patch_os + - refresh: True diff --git a/salt/patch/schedule/os.sls b/salt/patch/schedule/os.sls new file mode 100644 index 000000000..6056f8ee3 --- /dev/null +++ b/salt/patch/schedule/os.sls @@ -0,0 +1,32 @@ +{% 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 day in pillar['patch']['os']['schedule'] %} + {% for day, time in day.iteritems() %} + {% for each_time in time %} + - {{day}} {{each_time}} + {% endfor %} + {% endfor %} + {% endfor %} + - splay: + start: 5 + end: 10 + +{% 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 %} diff --git a/salt/top.sls b/salt/top.sls index cf5d47699..08d82285c 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -5,6 +5,9 @@ {%- set THEHIVE = salt['pillar.get']('master:thehive', '0') -%} {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} base: + '*': + - patch.schedule.os + 'G@role:so-sensor': - ca - ssl From c96678f5a0b87530e12d23407b20c7f279fb4865 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 5 Nov 2019 17:34:36 -0500 Subject: [PATCH 08/67] clean up variable name - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- salt/patch/schedule/os.sls | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/salt/patch/schedule/os.sls b/salt/patch/schedule/os.sls index 6056f8ee3..ebb84ad28 100644 --- a/salt/patch/schedule/os.sls +++ b/salt/patch/schedule/os.sls @@ -6,10 +6,10 @@ patch_os_schedule: - job_args: - patch.os - when: - {% for day in pillar['patch']['os']['schedule'] %} - {% for day, time in day.iteritems() %} - {% for each_time in time %} - - {{day}} {{each_time}} + {% for days in pillar['patch']['os']['schedule'] %} + {% for day, times in days.iteritems() %} + {% for time in times %} + - {{day}} {{time}} {% endfor %} {% endfor %} {% endfor %} From 9c83cceba15dff532566cb485f2cbd569265438d Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 5 Nov 2019 18:02:17 -0500 Subject: [PATCH 09/67] put quotes around hours to interpret properly for 24h - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- so-setup-network.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 38f5b7e44..57280473a 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -645,7 +645,7 @@ patch_pillar() { for psh in "${PATCHSCHEDULEHOURS[@]}" do psh=$(echo $psh | sed 's/"//g') - echo " - $psh" >> $OSPATCHPILLAR + echo " - '$psh'" >> $OSPATCHPILLAR done done ;; From fa87308baca32d1a66e431209f679163543d3ce6 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Wed, 6 Nov 2019 07:47:00 -0500 Subject: [PATCH 10/67] change splay for scheduled pkg update - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- salt/patch/schedule/os.sls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/patch/schedule/os.sls b/salt/patch/schedule/os.sls index ebb84ad28..a041afeea 100644 --- a/salt/patch/schedule/os.sls +++ b/salt/patch/schedule/os.sls @@ -14,8 +14,8 @@ patch_os_schedule: {% endfor %} {% endfor %} - splay: - start: 5 - end: 10 + start: 30 + end: 120 {% elif salt['pillar.get']('patch:os:schedule') == 'auto' %} From f3c204c7905019d75b94f9ede7f54b527329d34e Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 6 Nov 2019 13:37:42 -0500 Subject: [PATCH 11/67] Disable Beats input - Update sensoroni version --- salt/logstash/conf/conf.enabled.txt.so-eval | 2 +- salt/pcap/init.sls | 4 ++-- salt/sensoroni/init.sls | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/salt/logstash/conf/conf.enabled.txt.so-eval b/salt/logstash/conf/conf.enabled.txt.so-eval index dfc3ea421..d125fc829 100644 --- a/salt/logstash/conf/conf.enabled.txt.so-eval +++ b/salt/logstash/conf/conf.enabled.txt.so-eval @@ -13,7 +13,7 @@ #/usr/share/logstash/pipeline.so/0002_input_windows_json.conf #/usr/share/logstash/pipeline.so/0003_input_syslog.conf #/usr/share/logstash/pipeline.so/0005_input_suricata.conf -/usr/share/logstash/pipeline.dynamic/0006_input_beats.conf +#/usr/share/logstash/pipeline.dynamic/0006_input_beats.conf /usr/share/logstash/pipeline.so/0007_input_import.conf /usr/share/logstash/pipeline.dynamic/0010_input_hhbeats.conf #/usr/share/logstash/pipeline.so/1000_preprocess_log_elapsed.conf diff --git a/salt/pcap/init.sls b/salt/pcap/init.sls index ed23cf308..a49dc00e3 100644 --- a/salt/pcap/init.sls +++ b/salt/pcap/init.sls @@ -96,13 +96,13 @@ stenolog: so-stenoimage: cmd.run: - - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-steno:HH1.1.1 + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-steno:HH1.1.3 so-steno: docker_container.running: - require: - so-stenoimage - - image: docker.io/soshybridhunter/so-steno:HH1.1.1 + - image: docker.io/soshybridhunter/so-steno:HH1.1.3 - network_mode: host - privileged: True - port_bindings: diff --git a/salt/sensoroni/init.sls b/salt/sensoroni/init.sls index 83e960716..19fcd8b4a 100644 --- a/salt/sensoroni/init.sls +++ b/salt/sensoroni/init.sls @@ -29,13 +29,13 @@ sensoronisync: so-sensoroniimage: cmd.run: - - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-sensoroni:HH1.1.1 + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-sensoroni:HH1.1.3 so-sensoroni: docker_container.running: - require: - so-sensoroniimage - - image: docker.io/soshybridhunter/so-sensoroni:HH1.1.1 + - image: docker.io/soshybridhunter/so-sensoroni:HH1.1.3 - hostname: sensoroni - name: so-sensoroni - binds: From e323a448270b062be73de18d4c26e36c6f182877 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Thu, 7 Nov 2019 14:37:18 +0000 Subject: [PATCH 12/67] change intial user role to superadmin --- salt/hive/thehive/scripts/cortex_init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/hive/thehive/scripts/cortex_init.sh b/salt/hive/thehive/scripts/cortex_init.sh index 5d4de730b..3596c98dd 100644 --- a/salt/hive/thehive/scripts/cortex_init.sh +++ b/salt/hive/thehive/scripts/cortex_init.sh @@ -16,7 +16,7 @@ cortex_init(){ curl -v -k -XPOST "https://$CORTEX_IP:/cortex/api/maintenance/migrate" # Create intial Cortex user - curl -v -k "https://$CORTEX_IP/cortex/api/user" -H "Content-Type: application/json" -d "{\"login\" : \"$CORTEX_USER\",\"name\" : \"$CORTEX_USER\",\"roles\" : [\"read\",\"analyze\",\"orgadmin\"],\"preferences\" : \"{}\",\"password\" : \"$CORTEX_PASSWORD\", \"key\": \"$CORTEX_KEY\"}" + curl -v -k "https://$CORTEX_IP/cortex/api/user" -H "Content-Type: application/json" -d "{\"login\" : \"$CORTEX_USER\",\"name\" : \"$CORTEX_USER\",\"roles\" : [\"superadmin\"],\"preferences\" : \"{}\",\"password\" : \"$CORTEX_PASSWORD\", \"key\": \"$CORTEX_KEY\"}" # Enable URLScan.io Analyzer curl -v -k -XPOST -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/organization/analyzer/Urlscan_io_Search_0_1_0" -d '{"name":"Urlscan_io_Search_0_1_0","configuration":{"auto_extract_artifacts":false,"check_tlp":true,"max_tlp":2}}' From 9914e55ec3248b7f367085bab97f2fe99c6d7947 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 09:49:36 -0500 Subject: [PATCH 13/67] rework of os patch scheduling, added the abilty to enable/disable and adjust splay - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- pillar/top.sls | 3 - salt/patch/{os.sls => os/init.sls} | 0 salt/patch/os/schedule.sls | 76 ++++++++++ salt/patch/os/schedules/example_schedule.yml | 10 ++ salt/patch/schedule/os.sls | 32 ----- salt/top.sls | 2 +- so-setup-network.sh | 139 ++++++++++++++----- 7 files changed, 188 insertions(+), 74 deletions(-) rename salt/patch/{os.sls => os/init.sls} (100%) create mode 100644 salt/patch/os/schedule.sls create mode 100644 salt/patch/os/schedules/example_schedule.yml delete mode 100644 salt/patch/schedule/os.sls diff --git a/pillar/top.sls b/pillar/top.sls index 13ea5e5a8..031352a11 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -1,7 +1,4 @@ base: - '*': - - patch.os.{{ grains.id }} - 'G@role:so-sensor': - sensors.{{ grains.id }} - static diff --git a/salt/patch/os.sls b/salt/patch/os/init.sls similarity index 100% rename from salt/patch/os.sls rename to salt/patch/os/init.sls diff --git a/salt/patch/os/schedule.sls b/salt/patch/os/schedule.sls new file mode 100644 index 000000000..9ea98ede7 --- /dev/null +++ b/salt/patch/os/schedule.sls @@ -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 %} diff --git a/salt/patch/os/schedules/example_schedule.yml b/salt/patch/os/schedules/example_schedule.yml new file mode 100644 index 000000000..b2748ab09 --- /dev/null +++ b/salt/patch/os/schedules/example_schedule.yml @@ -0,0 +1,10 @@ +patch: + os: + schedule: + - Tuesday: + - '15:00' + - Thursday: + - '03:00' + - Saturday: + - '01:00' + - '15:00' diff --git a/salt/patch/schedule/os.sls b/salt/patch/schedule/os.sls deleted file mode 100644 index a041afeea..000000000 --- a/salt/patch/schedule/os.sls +++ /dev/null @@ -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 %} diff --git a/salt/top.sls b/salt/top.sls index 08d82285c..f742a66cf 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -6,7 +6,7 @@ {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} base: '*': - - patch.schedule.os + - patch.os.schedule 'G@role:so-sensor': - ca diff --git a/so-setup-network.sh b/so-setup-network.sh index 57280473a..32217a865 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -268,14 +268,14 @@ copy_master_config() { } -copy_minion_pillars() { +copy_minion_tmp_files() { if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - echo "rsyncing TMP pillar files to pillar base" >> $SETUPLOG 2>&1 - rsync -a -v $TMP/pillar/ /opt/so/saltstack/pillar/ >> $SETUPLOG 2>&1 + echo "rsyncing all files in $TMP to /opt/so/saltstack" >> $SETUPLOG 2>&1 + rsync -a -v $TMP/ /opt/so/saltstack/ >> $SETUPLOG 2>&1 else - echo "scp TMP pillar files to pillar base on master" >> $SETUPLOG 2>&1 - scp -prv -i /root/.ssh/so.key $TMP/pillar socore@$MSRV:/opt/so/saltstack/pillar >> $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 socore@$MSRV:/opt/so/saltstack >> $SETUPLOG 2>&1 fi } @@ -626,38 +626,51 @@ node_pillar() { } patch_pillar() { - OSPATCHPILLARDIR="$TMP/pillar/patch/os" - OSPATCHPILLAR="$OSPATCHPILLARDIR/$MINION_ID.sls" - if [ ! -d $OSPATCHPILLARDIR ] ; then - mkdir -p $OSPATCHPILLARDIR + case $INSTALLTYPE in + 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 - touch $OSPATCHPILLAR - echo "patch:" > $OSPATCHPILLAR - case $PATCHSCHEDULE in - Scheduled) - echo " os:" >> $OSPATCHPILLAR - echo " schedule:" >> $OSPATCHPILLAR + + echo "patch:" > $OSPATCHSCHEDULE + echo " os:" >> $OSPATCHSCHEDULE + echo " schedule:" >> $OSPATCHSCHEDULE for psd in "${PATCHSCHEDULEDAYS[@]}" do psd=$(echo $psd | sed 's/"//g') - echo " - $psd:" >> $OSPATCHPILLAR + echo " - $psd:" >> $OSPATCHSCHEDULE for psh in "${PATCHSCHEDULEHOURS[@]}" do psh=$(echo $psh | sed 's/"//g') - echo " - '$psh'" >> $OSPATCHPILLAR + echo " - '$psh'" >> $OSPATCHSCHEDULE 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/.yml" 10 75 3>&1 1>&2 2>&3) + done + + +} + whiptail_patch_schedule() { # What kind of patch schedule are we doing? 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 \ "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=$? 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/.yml" 10 60 default 3>&1 1>&2 2>&3) + done + fi + +} + whiptail_patch_schedule_select_days() { # Select the days to patch 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 whiptail_patch_schedule - if [[ $PATCHSCHEDULE == "Scheduled" ]] ; then - whiptail_patch_schedule_select_days - whiptail_patch_schedule_select_hours - fi - patch_pillar + case $PATCHSCHEDULE in + 'New Schedule') + whiptail_patch_schedule_select_days + whiptail_patch_schedule_select_hours + whiptail_patch_name_new_schedule + patch_schedule_os_new + ;; + 'Import Schedule') + whiptail_patch_schedule_import + ;; + Automatic) + PATCHSCHEDULENAME=auto + ;; + Manual) + PATCHSCHEDULENAME=manual + ;; + esac #################### ## Master ## @@ -1821,9 +1876,11 @@ if (whiptail_you_sure); then master_static >> $SETUPLOG 2>&1 echo "** Generating the master pillar **" >> $SETUPLOG 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\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 echo "** Pushing the key up to Master **" >> $SETUPLOG salt_firstcheckin >> $SETUPLOG 2>&1 @@ -1938,6 +1995,8 @@ if (whiptail_you_sure); then network_setup >> $SETUPLOG 2>&1 echo -e "XXX\n4\nGenerating Sensor Pillar... \nXXX" sensor_pillar >> $SETUPLOG 2>&1 + echo "** Generating the patch pillar **" >> $SETUPLOG + patch_pillar >> $SETUPLOG 2>&1 echo -e "XXX\n5\nInstalling Salt Components... \nXXX" saltify >> $SETUPLOG 2>&1 echo -e "XXX\n20\nInstalling Docker... \nXXX" @@ -1945,7 +2004,7 @@ if (whiptail_you_sure); then echo -e "XXX\n22\nConfiguring Salt Minion... \nXXX" configure_minion sensor >> $SETUPLOG 2>&1 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" salt_firstcheckin >> $SETUPLOG 2>&1 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 echo -e "XXX\n7\nCreating the master pillar... \nXXX" master_pillar >> $SETUPLOG 2>&1 + echo "** Generating the patch pillar **" >> $SETUPLOG + patch_pillar >> $SETUPLOG 2>&1 echo -e "XXX\n7\nConfiguring minion... \nXXX" configure_minion eval >> $SETUPLOG 2>&1 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" set_initial_firewall_policy >> $SETUPLOG 2>&1 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" salt_firstcheckin >> $SETUPLOG 2>&1 echo -e "XXX\n11\nAccepting Agent... \nXXX" @@ -2200,8 +2261,10 @@ if (whiptail_you_sure); then configure_minion node >> $SETUPLOG 2>&1 set_node_type >> $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" - copy_minion_pillars >> $SETUPLOG 2>&1 + copy_minion_tmp_files >> $SETUPLOG 2>&1 echo -e "XXX\n35\nSending and Accepting Salt Key... \nXXX" salt_firstcheckin >> $SETUPLOG 2>&1 # Accept the Salt Key From 98cd96eeddd47f9bf68c9061dba4590c6339dbe0 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 10:18:40 -0500 Subject: [PATCH 14/67] change auto schedule to every 8 hours and update wording of whiptail auto patch selection - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- salt/patch/os/schedule.sls | 2 +- so-setup-network.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/patch/os/schedule.sls b/salt/patch/os/schedule.sls index 9ea98ede7..128862fa7 100644 --- a/salt/patch/os/schedule.sls +++ b/salt/patch/os/schedule.sls @@ -42,7 +42,7 @@ patch_os_schedule: - function: state.sls - job_args: - patch.os - - minutes: 1 + - hours: 8 - splay: {{splay}} - return_job: True diff --git a/so-setup-network.sh b/so-setup-network.sh index 32217a865..40ada00cc 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1545,7 +1545,7 @@ whiptail_patch_schedule() { # What kind of patch schedule are we doing? 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 115 5 \ - "Automatic" "Package updates will be installed automatically" ON \ + "Automatic" "Package updates will be installed automatically every 8 hours if available" ON \ "Manual" "Package updates will need to be installed manually" OFF \ "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 ) From 43915488e27689fb444dfd18d3758d45f126ced6 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 10:50:27 -0500 Subject: [PATCH 15/67] prevent hostname from being localhost in setup script - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/101 --- so-setup-network.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index 40ada00cc..c82a9f6f5 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1654,6 +1654,13 @@ whiptail_set_hostname() { HOSTNAME=$(whiptail --title "Security Onion Setup" --inputbox \ "Enter the Hostname you would like to set." 10 60 $HOSTNAME 3>&1 1>&2 2>&3) + while [[ "$HOSTNAME" == 'localhost' ]] ; do + whiptail --title "Security Onion Setup" --msgbox "Please choose a hostname that isn't localhost." 8 65 + HOSTNAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the Hostname you would like to set." 10 60 $HOSTNAME 3>&1 1>&2 2>&3) + done + + local exitstatus=$? whiptail_check_exitstatus $exitstatus From d849c33b9c37ce53ee306ba26a439c6aa18f33a6 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 10:57:35 -0500 Subject: [PATCH 16/67] ensure the os patch schedule name is set - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- so-setup-network.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index c82a9f6f5..f43bebd70 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1530,9 +1530,12 @@ whiptail_passwords_dont_match() { } whiptail_patch_name_new_schedule() { + + 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/.yml" 10 75 3>&1 1>&2 2>&3) - unset PATCHSCHEDULENAME while [[ -z "$PATCHSCHEDULENAME" ]]; do + whiptail --title "Security Onion Setup" --msgbox "Please enter a name for this OS patch schedule." 8 65 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/.yml" 10 75 3>&1 1>&2 2>&3) done From c640a0bf9bb55feea412f7c2b3d0cb11f0e397b4 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 11:22:42 -0500 Subject: [PATCH 17/67] ensure inherit patch schedule name isn't blank, allow cancel from inherit screen - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/84 --- so-setup-network.sh | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index f43bebd70..de7b6f137 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -1532,12 +1532,17 @@ whiptail_passwords_dont_match() { whiptail_patch_name_new_schedule() { 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/.yml" 10 75 3>&1 1>&2 2>&3) + "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/.yml" 10 105 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus while [[ -z "$PATCHSCHEDULENAME" ]]; do whiptail --title "Security Onion Setup" --msgbox "Please enter a name for this OS patch schedule." 8 65 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/.yml" 10 75 3>&1 1>&2 2>&3) + "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/.yml" 10 105 3>&1 1>&2 2>&3) + local exitstatus=$? + whiptail_check_exitstatus $exitstatus done @@ -1561,18 +1566,20 @@ whiptail_patch_schedule() { 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 + PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the name of the OS patch schedule you want to inherit. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/.yml" 10 60 3>&1 1>&2 2>&3) 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/.yml" 10 60 default 3>&1 1>&2 2>&3) - done - fi + whiptail_check_exitstatus $exitstatus + + while [[ -z "$PATCHSCHEDULENAME" ]]; do + whiptail --title "Security Onion Setup" --msgbox "Please enter a name for the OS patch schedule you want to inherit." 8 65 + PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the name of the OS patch schedule you want to inherit. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/.yml" 10 60 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + done } From 7d29787512c093e57259e5c38901487fad5f4c90 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 7 Nov 2019 11:44:08 -0500 Subject: [PATCH 18/67] Update nids2hive.yaml --- salt/elastalert/files/rules/so/nids2hive.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/salt/elastalert/files/rules/so/nids2hive.yaml b/salt/elastalert/files/rules/so/nids2hive.yaml index 92de99537..019a0844f 100644 --- a/salt/elastalert/files/rules/so/nids2hive.yaml +++ b/salt/elastalert/files/rules/so/nids2hive.yaml @@ -15,7 +15,7 @@ timeframe: buffer_time: minutes: 10 allow_buffer_time_overlap: true -query_key: alert +query_key: ["alert", "ips"] realert: days: 1 @@ -36,11 +36,11 @@ hive_proxies: hive_alert_config: title: '{match[alert]}' - type: 'external' + type: 'NIDS' source: 'SecurityOnion' description: "`NIDS Dashboard:` \n\n \n\n `IPs: `{match[source_ip]}:{match[source_port]} --> {match[destination_ip]}:{match[destination_port]} \n\n `Signature:` {match[rule_signature]}" severity: 2 - tags: ['elastalert', 'SecurityOnion', 'NIDS','{match[sid]}'] + tags: ['{match[sid]}','{match[source_ip]}','{match[destination_ip]}'] tlp: 3 status: 'New' follow: True From d99b865527850733320779c8cfd36036a5e31c97 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 7 Nov 2019 13:27:38 -0500 Subject: [PATCH 19/67] Do not disable a rule when an uncaught exception is thrown --- salt/elastalert/files/elastalert_config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/salt/elastalert/files/elastalert_config.yaml b/salt/elastalert/files/elastalert_config.yaml index 6a918093b..735ccb190 100644 --- a/salt/elastalert/files/elastalert_config.yaml +++ b/salt/elastalert/files/elastalert_config.yaml @@ -8,6 +8,11 @@ rules_folder: /etc/elastalert/rules/ # the rules directory - true or false scan_subdirectories: true +# Do not disable a rule when an uncaught exception is thrown - +# This setting should be tweaked once the following issue has been fixed +# https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/98 +disable_rules_on_error: false + # How often ElastAlert will query Elasticsearch # The unit can be anything from weeks to seconds run_every: From cf0164a55b761d25e11d4d8630a93a46259e9d8f Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 7 Nov 2019 15:40:54 -0500 Subject: [PATCH 20/67] SOCtopus - move logging outside container --- salt/soctopus/init.sls | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/salt/soctopus/init.sls b/salt/soctopus/init.sls index ebfbe3224..a5c72e362 100644 --- a/salt/soctopus/init.sls +++ b/salt/soctopus/init.sls @@ -12,6 +12,12 @@ soctopussync: - user: 939 - group: 939 - template: jinja + +soctopuslogdir: + file.directory: + - name: /opt/so/log/soctopus + - user: 939 + - group: 939 playbookrulesdir: file.directory: @@ -51,6 +57,7 @@ so-soctopus: - name: so-soctopus - 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/playbook/nav_layer_playbook.json:/etc/playbook/nav_layer_playbook.json:rw - port_bindings: From c0cb281d27d883e6b7bde89235d78293096b5d56 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 7 Nov 2019 15:41:40 -0500 Subject: [PATCH 21/67] Move logging outside container --- salt/soctopus/files/SOCtopus.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/soctopus/files/SOCtopus.conf b/salt/soctopus/files/SOCtopus.conf index f1d311602..dd32507ef 100644 --- a/salt/soctopus/files/SOCtopus.conf +++ b/salt/soctopus/files/SOCtopus.conf @@ -50,4 +50,4 @@ playbook_url = http://{{ip}}:3200/playbook playbook_key = a4a34538782804adfcb8dfae96262514ad70c37c [log] -logfile = /tmp/soctopus.log +logfile = /var/log/SOCtopus/soctopus.log From 0ff5541801ccd556e419ce64920e72a0d2851913 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 17:27:38 -0500 Subject: [PATCH 22/67] upgrade salt to 2019.2.2 - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- so-setup-network.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index de7b6f137..d3ae360f1 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -500,7 +500,7 @@ install_master() { wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH else - apt-get install -y salt-common=2018.3.4+ds-1 salt-master=2018.3.4+ds-1 salt-minion=2018.3.4+ds-1 python-m2crypto + apt-get install -y salt-common=2019.2.2+ds-1 salt-master=2019.2.2+ds-1 salt-minion=2019.2.2+ds-1 python-m2crypto apt-mark hold salt-common salt-master salt-minion apt-get install -y python-m2crypto fi @@ -697,8 +697,8 @@ saltify() { if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then yum -y install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm - cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2018-3.repo - sed -i 's/latest/2018.3/g' /etc/yum.repos.d/salt-2018-3.repo + cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo + sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo cat > /etc/yum.repos.d/wazuh.repo <<\EOF [wazuh_repo] gpgcheck=1 @@ -812,13 +812,13 @@ EOF echo "gpgkey=file:///etc/pki/rpm-gpg/saltstack-signing-key" >> /etc/yum.repos.d/salt-latest.repo # Proxy is hating on me.. Lets just set it manually - echo "[salt-2018.3]" > /etc/yum.repos.d/salt-2018-3.repo - echo "name=SaltStack Latest Release Channel for RHEL/Centos \$releasever" >> /etc/yum.repos.d/salt-2018-3.repo - echo "baseurl=https://repo.saltstack.com/yum/redhat/7/\$basearch/2018.3" >> /etc/yum.repos.d/salt-2018-3.repo - echo "failovermethod=priority" >> /etc/yum.repos.d/salt-2018-3.repo - echo "enabled=1" >> /etc/yum.repos.d/salt-2018-3.repo - echo "gpgcheck=1" >> /etc/yum.repos.d/salt-2018-3.repo - echo "gpgkey=file:///etc/pki/rpm-gpg/saltstack-signing-key" >> /etc/yum.repos.d/salt-2018-3.repo + echo "[salt-2019.2]" > /etc/yum.repos.d/salt-2019-2.repo + echo "name=SaltStack Latest Release Channel for RHEL/Centos \$releasever" >> /etc/yum.repos.d/salt-2019-2.repo + echo "baseurl=https://repo.saltstack.com/yum/redhat/7/\$basearch/2019.2" >> /etc/yum.repos.d/salt-2019-2.repo + echo "failovermethod=priority" >> /etc/yum.repos.d/salt-2019-2.repo + echo "enabled=1" >> /etc/yum.repos.d/salt-2019-2.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/salt-2019-2.repo + echo "gpgkey=file:///etc/pki/rpm-gpg/saltstack-signing-key" >> /etc/yum.repos.d/salt-2019-2.repo cat > /etc/yum.repos.d/wazuh.repo <<\EOF [wazuh_repo] @@ -831,8 +831,8 @@ protect=1 EOF else yum -y install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm - cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2018-3.repo - sed -i 's/latest/2018.3/g' /etc/yum.repos.d/salt-2018-3.repo + cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo + sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo cat > /etc/yum.repos.d/wazuh.repo <<\EOF [wazuh_repo] gpgcheck=1 @@ -846,16 +846,16 @@ EOF fi yum clean expire-cache - yum -y install salt-minion-2018.3.4 yum-utils device-mapper-persistent-data lvm2 openssl python-dateutil + yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl python-dateutil yum -y update exclude=salt* systemctl enable salt-minion # Nasty hack but required for now if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - yum -y install salt-master-2018.3.4 python-m2crypto salt-minion-2018.3.4 m2crypto + yum -y install salt-master-2019.2.2 python-m2crypto salt-minion-2019.2.2 m2crypto systemctl enable salt-master else - yum -y install salt-minion-2018.3.4 python-m2m2crypto m2crypto + yum -y install salt-minion-2019.2.2 python-m2m2crypto m2crypto fi echo "exclude=salt*" >> /etc/yum.conf @@ -874,9 +874,9 @@ EOF # Install the repo for salt wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add - - wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2018.3/SALTSTACK-GPG-KEY.pub | apt-key add - + wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2019.2/SALTSTACK-GPG-KEY.pub | apt-key add - echo "deb http://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest xenial main" > /etc/apt/sources.list.d/saltstack.list - echo "deb http://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2018.3 xenial main" > /etc/apt/sources.list.d/saltstack2018.list + echo "deb http://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2019.2 xenial main" > /etc/apt/sources.list.d/saltstack2019.list # Lets get the docker repo added curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - @@ -895,7 +895,7 @@ EOF # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 - apt-get -y install salt-minion=2018.3.4+ds-1 salt-common=2018.3.4+ds-1 python-m2cryptoi python-dateutil >> $SETUPLOG 2>&1 + apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 python-m2cryptoi python-dateutil >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common else @@ -909,7 +909,7 @@ EOF echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 - apt-get -y install salt-minion=2018.3.4+ds-1 salt-common=2018.3.4+ds-1 python-m2crypto python-dateutil >> $SETUPLOG 2>&1 + apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 python-m2crypto python-dateutil >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common fi From 939ab918b4778ebd3621c7a351e3760ffa0d69df Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 17:31:06 -0500 Subject: [PATCH 23/67] update states using module.run - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/106 --- salt/ca/init.sls | 8 ++++---- salt/patch/os/schedule.sls | 8 ++++---- salt/playbook/init.sls | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/salt/ca/init.sls b/salt/ca/init.sls index 27344fc7f..407516f6e 100644 --- a/salt/ca/init.sls +++ b/salt/ca/init.sls @@ -39,10 +39,10 @@ pki_private_key: - require: - file: /etc/pki -mine.send: +send_x509_pem_entries_to_mine: module.run: - - func: x509.get_pem_entries - - kwargs: - glob_path: /etc/pki/ca.crt + - mine.send: + - func: x509.get_pem_entries + - glob_path: /etc/pki/ca.crt - onchanges: - x509: /etc/pki/ca.crt diff --git a/salt/patch/os/schedule.sls b/salt/patch/os/schedule.sls index 128862fa7..62232b0d1 100644 --- a/salt/patch/os/schedule.sls +++ b/salt/patch/os/schedule.sls @@ -64,13 +64,13 @@ remove_patch_os_schedule: {% else %} -no_os_patch_schedule_name_set: +no_patch_os_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: +show_patch_os_schedule: module.run: - - name: schedule.is_enabled - - m_name: patch_os_schedule + - schedule.is_enabled: + - name: patch_os_schedule {% endif %} diff --git a/salt/playbook/init.sls b/salt/playbook/init.sls index ef66966f3..6a054195a 100644 --- a/salt/playbook/init.sls +++ b/salt/playbook/init.sls @@ -11,9 +11,9 @@ playbookdb: playbookwebhook: module.run: - - name: sqlite3.modify - - db: /opt/so/conf/playbook/redmine.db - - sql: "update webhooks set url = 'http://{{MASTERIP}}:7000/playbook/webhook' where project_id = 1" + - sqlite3.modify: + - db: /opt/so/conf/playbook/redmine.db + - sql: "update webhooks set url = 'http://{{MASTERIP}}:7000/playbook/webhook' where project_id = 1" navigatorconfig: file.managed: From f58031f4e3ed601a85282de6014013375cebc276 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Thu, 7 Nov 2019 17:35:19 -0500 Subject: [PATCH 24/67] enable the new module.run behavior on the minion config - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/106 --- so-setup-network.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index d3ae360f1..f7f6c7bd9 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -255,6 +255,9 @@ configure_minion() { fi + echo "use_superseded:" >> /etc/salt/minion + echo " - module.run" >> /etc/salt/minion + service salt-minion restart } From aac9ab8e83f4f54b89a9e3050eceb7e6e576d410 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 11 Nov 2019 08:49:59 -0500 Subject: [PATCH 25/67] install the py3 version of salt 2019.2.2 - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- so-setup-network.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index f7f6c7bd9..b7c858d32 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -699,7 +699,7 @@ saltify() { ADDUSER=adduser if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - yum -y install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm + yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo cat > /etc/yum.repos.d/wazuh.repo <<\EOF @@ -878,8 +878,8 @@ EOF # Install the repo for salt wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add - wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2019.2/SALTSTACK-GPG-KEY.pub | apt-key add - - echo "deb http://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest xenial main" > /etc/apt/sources.list.d/saltstack.list - echo "deb http://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2019.2 xenial main" > /etc/apt/sources.list.d/saltstack2019.list + echo "deb http://repo.saltstack.com/py3/ubuntu/$UVER/amd64/latest xenial main" > /etc/apt/sources.list.d/saltstack.list + echo "deb http://repo.saltstack.com/py3/ubuntu/$UVER/amd64/2019.2 xenial main" > /etc/apt/sources.list.d/saltstack2019.list # Lets get the docker repo added curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - From bd26db1f239eea0ad7f6980e32d1a01fe86aaea7 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 11 Nov 2019 10:50:35 -0500 Subject: [PATCH 26/67] install docker python3 library and set env var PYTHONPATH - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- so-setup-network.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index b7c858d32..8c9efa955 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -355,7 +355,9 @@ docker_install() { yum -y install yum-utils device-mapper-persistent-data lvm2 openssl yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum -y update - yum -y install docker-ce docker-python python-docker + yum -y install docker-ce + pip3 install docker + set_environment_var "PYTHONPATH=/usr/local/lib/python3.6/site-packages/" if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi @@ -1023,6 +1025,15 @@ sensor_pillar() { } +set_environment_var() { + + echo "Setting environment variable: $1" + + export "$1" + echo "$1" >> /etc/environment + +} + set_hostname() { hostnamectl set-hostname --static $HOSTNAME From 67108ccc77da9e710c42eccbd812473060274610 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 11 Nov 2019 11:09:32 -0500 Subject: [PATCH 27/67] iteritems deprecated for items in py3 - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- salt/common/init.sls | 8 ++++---- salt/patch/os/schedule.sls | 2 +- salt/utility/bin/crossthestreams.sh | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/salt/common/init.sls b/salt/common/init.sls index 1bba4c871..93940669c 100644 --- a/salt/common/init.sls +++ b/salt/common/init.sls @@ -316,7 +316,7 @@ grafanaconf: - source: salt://common/grafana/etc {% if salt['pillar.get']('mastertab', False) %} -{%- for SN, SNDATA in salt['pillar.get']('mastertab', {}).iteritems() %} +{%- for SN, SNDATA in salt['pillar.get']('mastertab', {}).items() %} dashboard-master: file.managed: - name: /opt/so/conf/grafana/grafana_dashboards/master/{{ SN }}-Master.json @@ -337,7 +337,7 @@ dashboard-master: {% endif %} {% if salt['pillar.get']('sensorstab', False) %} -{%- for SN, SNDATA in salt['pillar.get']('sensorstab', {}).iteritems() %} +{%- for SN, SNDATA in salt['pillar.get']('sensorstab', {}).items() %} dashboard-{{ SN }}: file.managed: - name: /opt/so/conf/grafana/grafana_dashboards/forward_nodes/{{ SN }}-Sensor.json @@ -358,7 +358,7 @@ dashboard-{{ SN }}: {% endif %} {% if salt['pillar.get']('nodestab', False) %} -{%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).iteritems() %} +{%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).items() %} dashboard-{{ SN }}: file.managed: - name: /opt/so/conf/grafana/grafana_dashboards/storage_nodes/{{ SN }}-Node.json @@ -379,7 +379,7 @@ dashboard-{{ SN }}: {% endif %} {% if salt['pillar.get']('evaltab', False) %} -{%- for SN, SNDATA in salt['pillar.get']('evaltab', {}).iteritems() %} +{%- for SN, SNDATA in salt['pillar.get']('evaltab', {}).items() %} dashboard-{{ SN }}: file.managed: - name: /opt/so/conf/grafana/grafana_dashboards/eval/{{ SN }}-Node.json diff --git a/salt/patch/os/schedule.sls b/salt/patch/os/schedule.sls index 62232b0d1..a91e61dfe 100644 --- a/salt/patch/os/schedule.sls +++ b/salt/patch/os/schedule.sls @@ -15,7 +15,7 @@ patch_os_schedule: - patch.os - when: {% for days in os_schedule.patch.os.schedule %} - {% for day, times in days.iteritems() %} + {% for day, times in days.items() %} {% for time in times %} - {{day}} {{time}} {% endfor %} diff --git a/salt/utility/bin/crossthestreams.sh b/salt/utility/bin/crossthestreams.sh index b9c8f6c1d..3cd8b005c 100644 --- a/salt/utility/bin/crossthestreams.sh +++ b/salt/utility/bin/crossthestreams.sh @@ -31,6 +31,6 @@ echo "Applying cross cluster search config..." # Add all the storage nodes to cross cluster searching. -{%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).iteritems() %} +{%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).items() %} curl -XPUT http://{{ ES }}:9200/_cluster/settings -H'Content-Type: application/json' -d '{"persistent": {"search": {"remote": {"{{ SN }}": {"skip_unavailable": "true", "seeds": ["{{ SNDATA.ip }}:9300"]}}}}}' {%- endfor %} From f1d7dff5657f05a185afa5b075974d81944ff361 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 11 Nov 2019 12:08:37 -0500 Subject: [PATCH 28/67] set PYTHONPATH env var differently - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 8c9efa955..54948c538 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -357,7 +357,7 @@ docker_install() { yum -y update yum -y install docker-ce pip3 install docker - set_environment_var "PYTHONPATH=/usr/local/lib/python3.6/site-packages/" + set_environment_var "PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.6/site-packages/" if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi @@ -1030,7 +1030,7 @@ set_environment_var() { echo "Setting environment variable: $1" export "$1" - echo "$1" >> /etc/environment + echo "export $1" >> /etc/profile.d/set_env_vars.sh } From 6a3eac3288b7722ea3573862b7fffb90a8dc02c8 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 12 Nov 2019 09:33:42 -0500 Subject: [PATCH 29/67] add mysql python library and dependencies for py3 salt centos7 - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- so-setup-network.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 54948c538..8b6451e59 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -357,7 +357,7 @@ docker_install() { yum -y update yum -y install docker-ce pip3 install docker - set_environment_var "PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.6/site-packages/" + set_environment_var "PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.6/site-packages/:/usr/local/lib64/python3.6/site-packages/" if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi @@ -984,6 +984,13 @@ salt_master_directories() { } +salt_install_mysql_deps() { + + yum -y install gcc mariadb-devel python3-devel + pip3 install mysqlclient + +} + sensor_pillar() { SENSORPILLARPATH=$TMP/pillar/sensors @@ -1888,6 +1895,8 @@ if (whiptail_you_sure); then # Install salt and dependencies { sleep 0.5 + echo -e "XXX\n1\nInstalling mysql dependencies for saltstack... \nXXX" + salt_install_mysql_deps >> $SETUPLOG 2>&1 echo -e "XXX\n0\nInstalling and configuring Salt... \nXXX" echo " ** Installing Salt and Dependencies **" >> $SETUPLOG saltify >> $SETUPLOG 2>&1 @@ -2122,6 +2131,8 @@ if (whiptail_you_sure); then sleep 0.5 echo -e "XXX\n0\nCreating Bond Interface... \nXXX" network_setup >> $SETUPLOG 2>&1 + echo -e "XXX\n1\nInstalling mysql dependencies for saltstack... \nXXX" + salt_install_mysql_deps >> $SETUPLOG 2>&1 echo -e "XXX\n1\nInstalling saltstack... \nXXX" saltify >> $SETUPLOG 2>&1 echo -e "XXX\n3\nInstalling docker... \nXXX" From dc54860e969d372efaef605eddc27a22f2b64edf Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 12 Nov 2019 11:10:07 -0500 Subject: [PATCH 30/67] add py3 python-dateutil for salt --- so-setup-network.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 8b6451e59..ee8f932bc 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -850,8 +850,9 @@ EOF fi fi + pip3 install python-dateutil yum clean expire-cache - yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl python-dateutil + yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl yum -y update exclude=salt* systemctl enable salt-minion From 3f02fed27717eb2954dcd705e40647018e9af772 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 12 Nov 2019 15:16:28 -0500 Subject: [PATCH 31/67] change PYTHONPATH assignment - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index ee8f932bc..4121b9ecf 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -357,7 +357,7 @@ docker_install() { yum -y update yum -y install docker-ce pip3 install docker - set_environment_var "PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.6/site-packages/:/usr/local/lib64/python3.6/site-packages/" + set_environment_var "PYTHONPATH=/usr/local/lib/python3.6/site-packages:/usr/local/lib64/python3.6/site-packages" if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi @@ -1038,7 +1038,7 @@ set_environment_var() { echo "Setting environment variable: $1" export "$1" - echo "export $1" >> /etc/profile.d/set_env_vars.sh + echo "$1" >> /etc/environment } From d809718d9e60dc5de4957cf017b2e66204b0efa1 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 12 Nov 2019 16:03:26 -0500 Subject: [PATCH 32/67] add --user to pip3 install --- so-setup-network.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 4121b9ecf..ca37e4da6 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -356,7 +356,7 @@ docker_install() { yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum -y update yum -y install docker-ce - pip3 install docker + pip3 install --user docker set_environment_var "PYTHONPATH=/usr/local/lib/python3.6/site-packages:/usr/local/lib64/python3.6/site-packages" if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry @@ -850,7 +850,7 @@ EOF fi fi - pip3 install python-dateutil + pip3 install --user python-dateutil yum clean expire-cache yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl yum -y update exclude=salt* @@ -988,7 +988,7 @@ salt_master_directories() { salt_install_mysql_deps() { yum -y install gcc mariadb-devel python3-devel - pip3 install mysqlclient + pip3 install --user mysqlclient } From 2e82d06f27add577be5c2bce50de309173158e95 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 12 Nov 2019 21:10:31 +0000 Subject: [PATCH 33/67] only configure Telegraf if Grafana enabled --- salt/common/init.sls | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/salt/common/init.sls b/salt/common/init.sls index 93940669c..505289bc0 100644 --- a/salt/common/init.sls +++ b/salt/common/init.sls @@ -141,6 +141,8 @@ so-core: - watch: - file: /opt/so/conf/nginx/nginx.conf +# If master or eval, install Grafana/Telegraf/Influx +{% if grains['role'] == 'so-master' or grains['role'] == 'so-eval' and GRAFANA == 1 %} # Add Telegraf to monitor all the things. tgraflogdir: file.directory: @@ -213,9 +215,6 @@ so-telegraf: - /opt/so/conf/telegraf/etc/telegraf.conf - /opt/so/conf/telegraf/scripts -# If its a master or eval lets install the back end for now -{% if grains['role'] == 'so-master' or grains['role'] == 'so-eval' and GRAFANA == 1 %} - # Influx DB influxconfdir: file.directory: From 5fc08a39b49b81c20c8f7a1601c5498090cf5115 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 12 Nov 2019 16:54:32 -0500 Subject: [PATCH 34/67] change target directory of pip3 installs --- so-setup-network.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index ca37e4da6..dfc3d1ee1 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -356,8 +356,7 @@ docker_install() { yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum -y update yum -y install docker-ce - pip3 install --user docker - set_environment_var "PYTHONPATH=/usr/local/lib/python3.6/site-packages:/usr/local/lib64/python3.6/site-packages" + pip3 install --user -t /usr/lib/python3.6/site-packages docker if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi @@ -850,7 +849,7 @@ EOF fi fi - pip3 install --user python-dateutil + pip3 install --user -t /usr/lib/python3.6/site-packages python-dateutil yum clean expire-cache yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl yum -y update exclude=salt* @@ -988,7 +987,7 @@ salt_master_directories() { salt_install_mysql_deps() { yum -y install gcc mariadb-devel python3-devel - pip3 install --user mysqlclient + pip3 install --user -t /usr/lib64/python3.6/site-packages mysqlclient } From e364638a62977aa8b3cbbd56312fa064c244dde8 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 12 Nov 2019 22:50:00 +0000 Subject: [PATCH 35/67] add Cyberchef --- salt/common/nginx/nginx.conf.so-eval | 12 ++++++++++++ salt/common/nginx/nginx.conf.so-master | 12 ++++++++++++ salt/firewall/init.sls | 12 ++++++++++++ salt/top.sls | 2 ++ 4 files changed, 38 insertions(+) diff --git a/salt/common/nginx/nginx.conf.so-eval b/salt/common/nginx/nginx.conf.so-eval index fe55dc274..a0b3a39de 100644 --- a/salt/common/nginx/nginx.conf.so-eval +++ b/salt/common/nginx/nginx.conf.so-eval @@ -188,6 +188,18 @@ http { proxy_set_header Proxy ""; } + + location /cyberchef/ { + proxy_pass http://{{ masterip }}:9080/; + proxy_read_timeout 90; + proxy_connect_timeout 90; + proxy_http_version 1.1; # this is essential for chunked responses to work + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Proxy ""; + + } location /soctopus/ { proxy_pass http://{{ masterip }}:7000/; diff --git a/salt/common/nginx/nginx.conf.so-master b/salt/common/nginx/nginx.conf.so-master index 964579a96..265413fa2 100644 --- a/salt/common/nginx/nginx.conf.so-master +++ b/salt/common/nginx/nginx.conf.so-master @@ -187,6 +187,18 @@ http { proxy_set_header Proxy ""; } + + location /cyberchef/ { + proxy_pass http://{{ masterip }}:9080/; + proxy_read_timeout 90; + proxy_connect_timeout 90; + proxy_http_version 1.1; # this is essential for chunked responses to work + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Proxy ""; + + } location /soctopus/ { proxy_pass http://{{ masterip }}:7000/; diff --git a/salt/firewall/init.sls b/salt/firewall/init.sls index c0c1e6d82..b0ff81b00 100644 --- a/salt/firewall/init.sls +++ b/salt/firewall/init.sls @@ -276,6 +276,18 @@ enable_master_cortex_9001_{{ip}}: - position: 1 - save: True +enable_master_cyberchef_9080_{{ip}}: + iptables.insert: + - table: filter + - chain: DOCKER-USER + - jump: ACCEPT + - proto: tcp + - source: {{ ip }} + - dport: 9080 + - position: 1 + - save: True + + {% endfor %} # Make it so all the minions can talk to salt and update etc. diff --git a/salt/top.sls b/salt/top.sls index f742a66cf..1d7d6ccf8 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -43,6 +43,7 @@ base: - suricata - bro - curator + - cyberchef - elastalert {%- if OSQUERY != 0 %} - fleet @@ -69,6 +70,7 @@ base: - ca - ssl - common + - cyberchef - sensoroni - firewall - master From 1feddb79227e9204dda4463241fed553b374d10c Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 12 Nov 2019 22:50:46 +0000 Subject: [PATCH 36/67] add Cyberchef dir --- salt/cyberchef/init.sls | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 salt/cyberchef/init.sls diff --git a/salt/cyberchef/init.sls b/salt/cyberchef/init.sls new file mode 100644 index 000000000..1f1d5c080 --- /dev/null +++ b/salt/cyberchef/init.sls @@ -0,0 +1,53 @@ +# Copyright 2014,2015,2016,2017,2018 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 . + +# Create the cyberchef group +cyberchefgroup: + group.present: + - name: cyberchef + - gid: 946 + +# Add the cyberchef user +cyberchef: + user.present: + - uid: 946 + - gid: 946 + - home: /opt/so/conf/cyberchef + +cyberchefconfdir: + file.directory: + - name: /opt/so/conf/cyberchef + - user: 946 + - group: 939 + - makedirs: True + +cybercheflog: + file.directory: + - name: /opt/so/log/cyberchef + - user: 946 + - group: 946 + - makedirs: True + +so-cyberchefimage: + cmd.run: + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-cyberchef:HH1.1.3 + +so-cyberchef: + docker_container.running: + - require: + - so-cyberchef + - image: docker.io/soshybridhunter/so-cyberchef:HH1.1.3 + - port_bindings: + - 0.0.0.0:9080:8080 From b15886b26a4a43108d94032184324d78a4912f84 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 12 Nov 2019 17:51:59 -0500 Subject: [PATCH 37/67] remove --user add trailing / for pip3 target install --- so-setup-network.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index dfc3d1ee1..bfdcad7a9 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -356,7 +356,7 @@ docker_install() { yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum -y update yum -y install docker-ce - pip3 install --user -t /usr/lib/python3.6/site-packages docker + pip3 install -t /usr/lib/python3.6/site-packages/ docker if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi @@ -849,7 +849,7 @@ EOF fi fi - pip3 install --user -t /usr/lib/python3.6/site-packages python-dateutil + pip3 install -t /usr/lib/python3.6/site-packages/ python-dateutil yum clean expire-cache yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl yum -y update exclude=salt* @@ -987,7 +987,7 @@ salt_master_directories() { salt_install_mysql_deps() { yum -y install gcc mariadb-devel python3-devel - pip3 install --user -t /usr/lib64/python3.6/site-packages mysqlclient + pip3 install -t /usr/lib64/python3.6/site-packages/ mysqlclient } From 55db27c8980e2141a1434762c2805978dc99593c Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Wed, 13 Nov 2019 02:21:36 +0000 Subject: [PATCH 38/67] fix require --- salt/cyberchef/init.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/cyberchef/init.sls b/salt/cyberchef/init.sls index 1f1d5c080..202b15037 100644 --- a/salt/cyberchef/init.sls +++ b/salt/cyberchef/init.sls @@ -47,7 +47,7 @@ so-cyberchefimage: so-cyberchef: docker_container.running: - require: - - so-cyberchef + - so-cyberchefimage - image: docker.io/soshybridhunter/so-cyberchef:HH1.1.3 - port_bindings: - 0.0.0.0:9080:8080 From 977f39cea7e59b34cb32549e3c48cb0f3736731f Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 13 Nov 2019 09:47:04 -0500 Subject: [PATCH 39/67] Update generic.template --- salt/soctopus/files/templates/generic.template | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/salt/soctopus/files/templates/generic.template b/salt/soctopus/files/templates/generic.template index 23b693258..e278afa2c 100644 --- a/salt/soctopus/files/templates/generic.template +++ b/salt/soctopus/files/templates/generic.template @@ -1,9 +1,6 @@ {% set es = salt['pillar.get']('static:masterip', '') %} {% set hivehost = salt['pillar.get']('static:masterip', '') %} {% set hivekey = salt['pillar.get']('static:hivekey', '') %} -es_host: {{es}} -es_port: 9200 - alert: modules.so.thehive.TheHiveAlerter hive_connection: @@ -16,11 +13,11 @@ hive_proxies: hive_alert_config: title: '{rule[name]}' - type: 'external' + type: 'playbook' source: 'SecurityOnion' - description: "`Play:` https://{{es}}/playbook/issues/6000 \n\n `Data:` {match[message]}" + description: "`Play:` https://{{es}}/playbook/issues/6000 \n\n `View Event:` \n\n `Raw Data:` {match[message]}" severity: 2 - tags: ['elastalert', 'SecurityOnion'] + tags: ['playbook'] tlp: 3 status: 'New' follow: True From 3fc43fa2da243f655d68b00c23ffaaad1532edc2 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 13 Nov 2019 09:52:07 -0500 Subject: [PATCH 40/67] Update osquery.template --- .../soctopus/files/templates/osquery.template | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/salt/soctopus/files/templates/osquery.template b/salt/soctopus/files/templates/osquery.template index 1e85a3182..096921618 100644 --- a/salt/soctopus/files/templates/osquery.template +++ b/salt/soctopus/files/templates/osquery.template @@ -1,23 +1,6 @@ {% set es = salt['pillar.get']('static:masterip', '') %} {% set hivehost = salt['pillar.get']('static:masterip', '') %} {% set hivekey = salt['pillar.get']('static:hivekey', '') %} -es_host: {{es}} -es_port: 9200 -name: Alert-Name -type: frequency -index: "*:logstash-*" -num_events: 1 -timeframe: - minutes: 10 -buffer_time: - minutes: 10 -allow_buffer_time_overlap: true - -filter: -- query: - query_string: - query: 'select from test' - alert: modules.so.thehive.TheHiveAlerter hive_connection: @@ -30,17 +13,18 @@ hive_proxies: hive_alert_config: title: '{rule[name]} -- {match[osquery][hostname]} -- {match[osquery][name]}' - type: 'external' + type: 'osquery' source: 'SecurityOnion' - description: '`Hostname:` __{match[osquery][hostname]}__ `Live Query:`__[Pivot Link](https://{{es}}/fleet/queries/new?host_uuids={match[osquery][LiveQuery]})__ `Pack:` __{match[osquery][name]}__ `Data:` {match[osquery][columns]}' + description: "`Play:` https://{{es}}/playbook/issues/6000 \n\n `View Event:` \n\n `Hostname:` __{match[osquery][hostname]}__ `Live Query:`__[Pivot Link](https://{{es}}/fleet/queries/new?host_uuids={match[osquery][LiveQuery]})__ `Pack:` __{match[osquery][name]}__ `Data:` {match[osquery][columns]}" severity: 2 - tags: ['elastalert', 'SecurityOnion'] + tags: ['playbook','osquery'] tlp: 3 status: 'New' follow: True caseTemplate: '5000' - -hive_observable_data_mapping: + + + hive_observable_data_mapping: - ip: '{match[osquery][EndpointIP1]}' - ip: '{match[osquery][EndpointIP2]}' - other: '{match[osquery][hostIdentifier]}' From 7259a5346b80cd481a44d822ee769afe6ffb3ea6 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 13 Nov 2019 13:49:34 -0500 Subject: [PATCH 41/67] Update osquery.template --- salt/soctopus/files/templates/osquery.template | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/salt/soctopus/files/templates/osquery.template b/salt/soctopus/files/templates/osquery.template index 096921618..5f1c6961a 100644 --- a/salt/soctopus/files/templates/osquery.template +++ b/salt/soctopus/files/templates/osquery.template @@ -11,6 +11,12 @@ hive_proxies: http: '' https: '' +hive_observable_data_mapping: + - ip: '{match[osquery][EndpointIP1]}' + - ip: '{match[osquery][EndpointIP2]}' + - other: '{match[osquery][hostIdentifier]}' + - other: '{match[osquery][hostname]}' + hive_alert_config: title: '{rule[name]} -- {match[osquery][hostname]} -- {match[osquery][name]}' type: 'osquery' @@ -23,9 +29,4 @@ hive_alert_config: follow: True caseTemplate: '5000' - - hive_observable_data_mapping: - - ip: '{match[osquery][EndpointIP1]}' - - ip: '{match[osquery][EndpointIP2]}' - - other: '{match[osquery][hostIdentifier]}' - - other: '{match[osquery][hostname]}' + From 0007af1e124ab038e653c1c592affcdadf809e65 Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Wed, 13 Nov 2019 14:27:24 -0500 Subject: [PATCH 42/67] Updated for bulk import --- salt/playbook/files/redmine.db | Bin 1454080 -> 2207744 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/salt/playbook/files/redmine.db b/salt/playbook/files/redmine.db index fdf24eae4bc011e63b0b5bcf33fb07ca0a5655e2..3477ef3c947f5107a7fd14571c53c7c36d4da742 100644 GIT binary patch literal 2207744 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

ZCp&+PgC0Cfp!9~}d%b{H5 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 Date: Wed, 13 Nov 2019 16:19:33 -0500 Subject: [PATCH 43/67] install py3 libraries for 2019.2.2 Salt on Ubuntu - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/105 --- install_scripts/disable-checksum-offload.sh | 2 +- so-setup-network.sh | 46 +++++++++++++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/install_scripts/disable-checksum-offload.sh b/install_scripts/disable-checksum-offload.sh index 9cc0b5d5b..32b8d46e6 100644 --- a/install_scripts/disable-checksum-offload.sh +++ b/install_scripts/disable-checksum-offload.sh @@ -6,4 +6,4 @@ if [ "$NM_DISPATCHER_ACTION" == "pre-up" ]; then ethtool -K $DEVICE_IFACE $i off; done fi -fi \ No newline at end of file +fi diff --git a/so-setup-network.sh b/so-setup-network.sh index bfdcad7a9..422ec8a99 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -356,10 +356,11 @@ docker_install() { yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum -y update yum -y install docker-ce - pip3 install -t /usr/lib/python3.6/site-packages/ docker if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi + echo "Using pip3 to install docker-py for salt" + pip3 install -t /usr/lib/python3.6/site-packages/ docker echo "Restarting Docker" >> $SETUPLOG 2>&1 systemctl restart docker systemctl enable docker @@ -382,6 +383,8 @@ docker_install() { echo "Restarting Docker" >> $SETUPLOG 2>&1 systemctl restart docker >> $SETUPLOG 2>&1 fi + echo "Using pip3 to install docker-py for salt" + pip3 install docker fi } @@ -483,6 +486,15 @@ install_cleanup() { } +install_pip3() { + + if [ $OS == 'ubuntu' ]; then + echo -e "XXX\n0\nInstalling pip3... \nXXX" + apt-get -y install python3-pip gcc python3-dev + fi + +} + install_prep() { # Create a tmp space that isn't in /tmp @@ -504,9 +516,13 @@ install_master() { wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH else - apt-get install -y salt-common=2019.2.2+ds-1 salt-master=2019.2.2+ds-1 salt-minion=2019.2.2+ds-1 python-m2crypto + apt-get install -y salt-common=2019.2.2+ds-1 salt-master=2019.2.2+ds-1 salt-minion=2019.2.2+ds-1 apt-mark hold salt-common salt-master salt-minion - apt-get install -y python-m2crypto + echo -e "XXX\n11\nInstalling libssl-dev for M2Crypto... \nXXX" + apt-get -y install libssl-dev + echo -e "XXX\n12\nUsing pip3 to install M2Crypto for Salt... \nXXX" + pip3 install M2Crypto + fi copy_master_config @@ -849,6 +865,7 @@ EOF fi fi + echo "Using pip3 to install python-dateutil for salt" pip3 install -t /usr/lib/python3.6/site-packages/ python-dateutil yum clean expire-cache yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl @@ -877,6 +894,8 @@ EOF # Nasty hack but required for now if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + echo "Using pip3 to install python-dateutil for salt" + pip3 install python-dateutil # Install the repo for salt wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add - wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2019.2/SALTSTACK-GPG-KEY.pub | apt-key add - @@ -900,7 +919,7 @@ EOF # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 - apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 python-m2cryptoi python-dateutil >> $SETUPLOG 2>&1 + apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common else @@ -914,7 +933,7 @@ EOF echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 - apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 python-m2crypto python-dateutil >> $SETUPLOG 2>&1 + apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common fi @@ -986,9 +1005,16 @@ salt_master_directories() { salt_install_mysql_deps() { - yum -y install gcc mariadb-devel python3-devel - pip3 install -t /usr/lib64/python3.6/site-packages/ mysqlclient - + if [ $OS == 'centos' ]; then + yum -y install gcc mariadb-devel python3-devel + echo "Using pip3 to install mysqlclient for salt" + pip3 install -t /usr/lib64/python3.6/site-packages/ mysqlclient + elif [ $OS == 'ubuntu' ]; then + apt-get -y install libmysqlclient-dev + echo "Using pip3 to install mysqlclient for salt" + pip3 install mysqlclient + fi + } sensor_pillar() { @@ -1895,9 +1921,10 @@ if (whiptail_you_sure); then # Install salt and dependencies { sleep 0.5 + install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n1\nInstalling mysql dependencies for saltstack... \nXXX" salt_install_mysql_deps >> $SETUPLOG 2>&1 - echo -e "XXX\n0\nInstalling and configuring Salt... \nXXX" + echo -e "XXX\n2\nInstalling and configuring Salt... \nXXX" echo " ** Installing Salt and Dependencies **" >> $SETUPLOG saltify >> $SETUPLOG 2>&1 echo -e "XXX\n5\nInstalling Docker... \nXXX" @@ -2131,6 +2158,7 @@ if (whiptail_you_sure); then sleep 0.5 echo -e "XXX\n0\nCreating Bond Interface... \nXXX" network_setup >> $SETUPLOG 2>&1 + install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n1\nInstalling mysql dependencies for saltstack... \nXXX" salt_install_mysql_deps >> $SETUPLOG 2>&1 echo -e "XXX\n1\nInstalling saltstack... \nXXX" From f8fed24aa5f7ef52cb30f04a41730788ef830218 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Thu, 14 Nov 2019 13:14:33 -0500 Subject: [PATCH 44/67] Version Updates --- salt/fleet/init.sls | 4 ++-- salt/playbook/init.sls | 4 ++-- salt/soctopus/init.sls | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/salt/fleet/init.sls b/salt/fleet/init.sls index af7951170..917ee541e 100644 --- a/salt/fleet/init.sls +++ b/salt/fleet/init.sls @@ -61,13 +61,13 @@ fleetdbpriv: so-fleetimage: cmd.run: - - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-fleet:HH1.1.0 + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-fleet:HH1.1.3 so-fleet: docker_container.running: - require: - so-fleetimage - - image: docker.io/soshybridhunter/so-fleet:HH1.1.0 + - image: docker.io/soshybridhunter/so-fleet:HH1.1.3 - hostname: so-fleet - port_bindings: - 0.0.0.0:8080:8080 diff --git a/salt/playbook/init.sls b/salt/playbook/init.sls index 6a054195a..bc22b60d4 100644 --- a/salt/playbook/init.sls +++ b/salt/playbook/init.sls @@ -26,13 +26,13 @@ navigatorconfig: so-playbookimage: cmd.run: - - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-playbook:HH1.1.1 + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-playbook:HH1.1.3 so-playbook: docker_container.running: - require: - so-playbookimage - - image: docker.io/soshybridhunter/so-playbook:HH1.1.1 + - image: docker.io/soshybridhunter/so-playbook:HH1.1.3 - hostname: playbook - name: so-playbook - binds: diff --git a/salt/soctopus/init.sls b/salt/soctopus/init.sls index a5c72e362..578789a76 100644 --- a/salt/soctopus/init.sls +++ b/salt/soctopus/init.sls @@ -12,7 +12,7 @@ soctopussync: - user: 939 - group: 939 - template: jinja - + soctopuslogdir: file.directory: - name: /opt/so/log/soctopus @@ -46,18 +46,18 @@ navigatordefaultlayer: so-soctopusimage: cmd.run: - - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-soctopus:HH1.1.1 + - name: docker pull --disable-content-trust=false docker.io/soshybridhunter/so-soctopus:HH1.1.3 so-soctopus: docker_container.running: - require: - so-soctopusimage - - image: docker.io/soshybridhunter/so-soctopus:HH1.1.1 + - image: docker.io/soshybridhunter/so-soctopus:HH1.1.3 - hostname: soctopus - name: so-soctopus - binds: - /opt/so/conf/soctopus/SOCtopus.conf:/SOCtopus/SOCtopus.conf:ro - - /opt/so/log/soctopus/:/var/log/SOCtopus/:rw + - /opt/so/log/soctopus/:/var/log/SOCtopus/:rw - /opt/so/rules/elastalert/playbook:/etc/playbook-rules:rw - /opt/so/conf/playbook/nav_layer_playbook.json:/etc/playbook/nav_layer_playbook.json:rw - port_bindings: From ff4077a46f3505a3cfd04ccbfc0ce45ecee41246 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 15 Nov 2019 13:58:32 -0500 Subject: [PATCH 45/67] update all nodes motd with nodes that need restarted from patch updates - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/112 --- salt/_modules/needs_restarting.py | 25 +++++++++++++++++++ .../package_update_reboot_required.jinja | 23 +++++++++++++++++ salt/motd/init.sls | 5 ++++ salt/patch/os/init.sls | 10 ++++++++ salt/top.sls | 1 + salt/yum/packages.sls | 3 +++ 6 files changed, 67 insertions(+) create mode 100644 salt/_modules/needs_restarting.py create mode 100644 salt/motd/files/package_update_reboot_required.jinja create mode 100644 salt/motd/init.sls create mode 100644 salt/yum/packages.sls diff --git a/salt/_modules/needs_restarting.py b/salt/_modules/needs_restarting.py new file mode 100644 index 000000000..51f80670a --- /dev/null +++ b/salt/_modules/needs_restarting.py @@ -0,0 +1,25 @@ +from os import path +import subprocess + +def check(): + + os = __grains__['os'] + cmd = 'needs-restarting -r > /dev/null 2>&1' + + if os == 'Ubuntu': + if path.exists('/var/run/reboot-required'): + retval = 'True' + else: + retval = 'False' + + elif os == 'CentOS': + try: + needs_restarting = subprocess.check_call(cmd.split(), shell=True) + except subprocess.CalledProcessError: + retval = 'True' + retval = 'False' + + else: + retval = 'Unsupported OS: %s' % os + + return retval diff --git a/salt/motd/files/package_update_reboot_required.jinja b/salt/motd/files/package_update_reboot_required.jinja new file mode 100644 index 000000000..3a1fd1e9e --- /dev/null +++ b/salt/motd/files/package_update_reboot_required.jinja @@ -0,0 +1,23 @@ +{% set needs_restarting_check = salt['mine.get']('*', 'needs_restarting.check', tgt_type='glob') -%} + +{%- if needs_restarting_check %} + {%- set minions_need_restarted = [] %} + + {%- for minion, need_restarted in needs_restarting_check | dictsort() %} + {%- if need_restarted == 'True' %} + {% do minions_need_restarted.append(minion) %} + {%- endif %} + {%- endfor -%} + + {%- if minions_need_restarted | length > 0 %} +***************************************************************************************** +* The following nodes in your Security Onion grid need restarted due to package updates * +***************************************************************************************** + + {% for minion in minions_need_restarted -%} + {{ minion }} + {% endfor -%} + + {%- endif -%} + +{%- endif -%} diff --git a/salt/motd/init.sls b/salt/motd/init.sls new file mode 100644 index 000000000..a314ddb80 --- /dev/null +++ b/salt/motd/init.sls @@ -0,0 +1,5 @@ +package_update_reboot_required_motd: + file.append: + - name: /etc/motd + - source: salt://motd/files/package_update_reboot_required.jinja + - template: jinja diff --git a/salt/patch/os/init.sls b/salt/patch/os/init.sls index d3ae6a1ff..97183199b 100644 --- a/salt/patch/os/init.sls +++ b/salt/patch/os/init.sls @@ -1,4 +1,14 @@ +{% if grains.os == "CentOS" %} +include: + - yum.packages +{% endif %} + patch_os: pkg.uptodate: - name: patch_os - refresh: True + +needs_restarting: + module.run: + - mine.send: + - func: needs_restarting.check diff --git a/salt/top.sls b/salt/top.sls index f742a66cf..711cf564c 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -7,6 +7,7 @@ base: '*': - patch.os.schedule + - motd 'G@role:so-sensor': - ca diff --git a/salt/yum/packages.sls b/salt/yum/packages.sls new file mode 100644 index 000000000..4c773d0e9 --- /dev/null +++ b/salt/yum/packages.sls @@ -0,0 +1,3 @@ +install_yum_utils: + pkg.installed: + - name: yum-utils From 8261b6fc6341893eef81e956efb236f0772d2ce4 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 15 Nov 2019 14:02:06 -0500 Subject: [PATCH 46/67] move cmd assignment - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/112 --- salt/_modules/needs_restarting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/_modules/needs_restarting.py b/salt/_modules/needs_restarting.py index 51f80670a..49f82bbf2 100644 --- a/salt/_modules/needs_restarting.py +++ b/salt/_modules/needs_restarting.py @@ -4,7 +4,6 @@ import subprocess def check(): os = __grains__['os'] - cmd = 'needs-restarting -r > /dev/null 2>&1' if os == 'Ubuntu': if path.exists('/var/run/reboot-required'): @@ -13,6 +12,7 @@ def check(): retval = 'False' elif os == 'CentOS': + cmd = 'needs-restarting -r > /dev/null 2>&1' try: needs_restarting = subprocess.check_call(cmd.split(), shell=True) except subprocess.CalledProcessError: From f9b1fc8b1fc22adaf2071684a9b8ae5285ae9a88 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 15 Nov 2019 15:48:21 -0500 Subject: [PATCH 47/67] bug fix for remote distribution so setup - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/114 --- so-setup-network.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 422ec8a99..db0a313b3 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -278,7 +278,7 @@ copy_minion_tmp_files() { rsync -a -v $TMP/ /opt/so/saltstack/ >> $SETUPLOG 2>&1 else echo "scp all files in $TMP to master /opt/so/saltstack" >> $SETUPLOG 2>&1 - scp -prv -i /root/.ssh/so.key $TMP socore@$MSRV:/opt/so/saltstack >> $SETUPLOG 2>&1 + scp -prv -i /root/.ssh/so.key "${TMP}/*" socore@$MSRV:/opt/so/saltstack >> $SETUPLOG 2>&1 fi } From f40f00255f1756663a5cbb5544129ed00baddabe Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 15 Nov 2019 16:02:21 -0500 Subject: [PATCH 48/67] adding install_pip3 for sensor and node types --- so-setup-network.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index db0a313b3..e1adb38c8 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -2056,6 +2056,7 @@ if (whiptail_you_sure); then copy_ssh_key { sleep 0.5 + install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 echo -e "XXX\n3\nCreating Bond Interface... \nXXX" @@ -2321,6 +2322,7 @@ if (whiptail_you_sure); then copy_ssh_key { sleep 0.5 + install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 echo -e "XXX\n5\nInstalling Salt Packages... \nXXX" From 95a3919df44ff528f01c8c80a7253121e695fae1 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 15 Nov 2019 16:08:50 -0500 Subject: [PATCH 49/67] make socore own /opt/so/saltstack recursively - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/113 --- salt/master/init.sls | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/salt/master/init.sls b/salt/master/init.sls index 1a7efe744..c6e11279d 100644 --- a/salt/master/init.sls +++ b/salt/master/init.sls @@ -17,6 +17,15 @@ {% if masterproxy == 1 %} +socore_own_saltstack: + file.directory: + - name: /opt/so/saltstack + - user: socore + - group: socore + - recurse: + - user + - group + # Create the directories for apt-cacher-ng aptcacherconfdir: file.directory: From 6bcadded1452a4d02bdf709718b17e4e17341fea Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 15 Nov 2019 18:16:27 -0500 Subject: [PATCH 50/67] change scp of pillar files, install pip3 for centos --- so-setup-network.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index e1adb38c8..a2871a9f5 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -278,7 +278,7 @@ copy_minion_tmp_files() { rsync -a -v $TMP/ /opt/so/saltstack/ >> $SETUPLOG 2>&1 else echo "scp all files in $TMP to master /opt/so/saltstack" >> $SETUPLOG 2>&1 - scp -prv -i /root/.ssh/so.key "${TMP}/*" socore@$MSRV:/opt/so/saltstack >> $SETUPLOG 2>&1 + scp -prv -i /root/.ssh/so.key $TMP/* socore@$MSRV:/opt/so/saltstack >> $SETUPLOG 2>&1 fi } @@ -488,9 +488,12 @@ install_cleanup() { install_pip3() { + echo "Installing pip3" + if [ $OS == 'ubuntu' ]; then - echo -e "XXX\n0\nInstalling pip3... \nXXX" apt-get -y install python3-pip gcc python3-dev + elif [ $OS == 'centos' ]; then + yum -y install python3-pip gcc python3-devel fi } @@ -716,7 +719,7 @@ saltify() { ADDUSER=adduser if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm + yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-2019.2-2.el7.noarch.rpm cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo cat > /etc/yum.repos.d/wazuh.repo <<\EOF @@ -1006,7 +1009,7 @@ salt_master_directories() { salt_install_mysql_deps() { if [ $OS == 'centos' ]; then - yum -y install gcc mariadb-devel python3-devel + yum -y install mariadb-devel echo "Using pip3 to install mysqlclient for salt" pip3 install -t /usr/lib64/python3.6/site-packages/ mysqlclient elif [ $OS == 'ubuntu' ]; then From 8da092e49752f7262ecf2fc0a3ea2753a7c1e77c Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 18 Nov 2019 09:40:08 -0500 Subject: [PATCH 51/67] fix repo for distributed salt install - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/116 --- so-setup-network.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index a2871a9f5..45ede5393 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -525,7 +525,7 @@ install_master() { apt-get -y install libssl-dev echo -e "XXX\n12\nUsing pip3 to install M2Crypto for Salt... \nXXX" pip3 install M2Crypto - + fi copy_master_config @@ -661,7 +661,7 @@ patch_pillar() { PATCHPILLARPATH=$NODEPILLARPATH ;; esac - + echo "" >> $PATCHPILLARPATH/$MINION_ID.sls echo "patch:" >> $PATCHPILLARPATH/$MINION_ID.sls @@ -719,7 +719,7 @@ saltify() { ADDUSER=adduser if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-2019.2-2.el7.noarch.rpm + yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo cat > /etc/yum.repos.d/wazuh.repo <<\EOF @@ -828,7 +828,7 @@ EOF # Proxy is hating on me.. Lets just set it manually echo "[salt-latest]" > /etc/yum.repos.d/salt-latest.repo echo "name=SaltStack Latest Release Channel for RHEL/Centos \$releasever" >> /etc/yum.repos.d/salt-latest.repo - echo "baseurl=https://repo.saltstack.com/yum/redhat/7/\$basearch/latest" >> /etc/yum.repos.d/salt-latest.repo + echo "baseurl=https://repo.saltstack.com/py3/redhat/7/\$basearch/latest" >> /etc/yum.repos.d/salt-latest.repo echo "failovermethod=priority" >> /etc/yum.repos.d/salt-latest.repo echo "enabled=1" >> /etc/yum.repos.d/salt-latest.repo echo "gpgcheck=1" >> /etc/yum.repos.d/salt-latest.repo @@ -837,7 +837,7 @@ EOF # Proxy is hating on me.. Lets just set it manually echo "[salt-2019.2]" > /etc/yum.repos.d/salt-2019-2.repo echo "name=SaltStack Latest Release Channel for RHEL/Centos \$releasever" >> /etc/yum.repos.d/salt-2019-2.repo - echo "baseurl=https://repo.saltstack.com/yum/redhat/7/\$basearch/2019.2" >> /etc/yum.repos.d/salt-2019-2.repo + echo "baseurl=https://repo.saltstack.com/py3/redhat/7/\$basearch/2019.2" >> /etc/yum.repos.d/salt-2019-2.repo echo "failovermethod=priority" >> /etc/yum.repos.d/salt-2019-2.repo echo "enabled=1" >> /etc/yum.repos.d/salt-2019-2.repo echo "gpgcheck=1" >> /etc/yum.repos.d/salt-2019-2.repo @@ -853,7 +853,7 @@ baseurl=https://packages.wazuh.com/3.x/yum/ protect=1 EOF else - yum -y install https://repo.saltstack.com/yum/redhat/salt-repo-latest-2.el7.noarch.rpm + yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo cat > /etc/yum.repos.d/wazuh.repo <<\EOF @@ -1017,7 +1017,7 @@ salt_install_mysql_deps() { echo "Using pip3 to install mysqlclient for salt" pip3 install mysqlclient fi - + } sensor_pillar() { @@ -1586,7 +1586,7 @@ whiptail_patch_name_new_schedule() { local exitstatus=$? whiptail_check_exitstatus $exitstatus - + while [[ -z "$PATCHSCHEDULENAME" ]]; do whiptail --title "Security Onion Setup" --msgbox "Please enter a name for this OS patch schedule." 8 65 PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \ @@ -1617,16 +1617,16 @@ whiptail_patch_schedule_import() { unset PATCHSCHEDULENAME PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \ - "Enter the name of the OS patch schedule you want to inherit. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/.yml" 10 60 3>&1 1>&2 2>&3) + "Enter the name of the OS patch schedule you want to inherit. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/.yml" 10 60 3>&1 1>&2 2>&3) local exitstatus=$? whiptail_check_exitstatus $exitstatus - + while [[ -z "$PATCHSCHEDULENAME" ]]; do whiptail --title "Security Onion Setup" --msgbox "Please enter a name for the OS patch schedule you want to inherit." 8 65 PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \ "Enter the name of the OS patch schedule you want to inherit. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/.yml" 10 60 3>&1 1>&2 2>&3) - + local exitstatus=$? whiptail_check_exitstatus $exitstatus done From 81e825b9545115ea30e3bee8f9816e14f23b8903 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 18 Nov 2019 11:12:05 -0500 Subject: [PATCH 52/67] move pip3 install after firewall setup --- so-setup-network.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 45ede5393..59e4437fc 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -2059,9 +2059,10 @@ if (whiptail_you_sure); then copy_ssh_key { sleep 0.5 - install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 + echo -e "XXX\n1\nInstalling pip3... \nXXX" + install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n3\nCreating Bond Interface... \nXXX" network_setup >> $SETUPLOG 2>&1 echo -e "XXX\n4\nGenerating Sensor Pillar... \nXXX" @@ -2325,9 +2326,10 @@ if (whiptail_you_sure); then copy_ssh_key { sleep 0.5 - install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 + echo -e "XXX\n1\nInstalling pip3... \nXXX" + install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n5\nInstalling Salt Packages... \nXXX" saltify >> $SETUPLOG 2>&1 echo -e "XXX\n20\nInstalling Docker... \nXXX" From f05fcc271f44d6072533ca3266fb89802cb6ebdb Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 18 Nov 2019 12:45:12 -0500 Subject: [PATCH 53/67] Trying using packages vs pip for centos --- so-setup-network.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 59e4437fc..8618553eb 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -359,8 +359,8 @@ docker_install() { if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi - echo "Using pip3 to install docker-py for salt" - pip3 install -t /usr/lib/python3.6/site-packages/ docker + #echo "Using pip3 to install docker-py for salt" + #pip3 install -t /usr/lib/python3.6/site-packages/ docker echo "Restarting Docker" >> $SETUPLOG 2>&1 systemctl restart docker systemctl enable docker @@ -493,7 +493,8 @@ install_pip3() { if [ $OS == 'ubuntu' ]; then apt-get -y install python3-pip gcc python3-dev elif [ $OS == 'centos' ]; then - yum -y install python3-pip gcc python3-devel + #yum -y install python3-pip gcc python3-devel + yum -y install epel-release python3 python36-dateutil python36-m2crypto python36-mysql python36-docker fi } @@ -868,8 +869,8 @@ EOF fi fi - echo "Using pip3 to install python-dateutil for salt" - pip3 install -t /usr/lib/python3.6/site-packages/ python-dateutil + #echo "Using pip3 to install python-dateutil for salt" + #pip3 install -t /usr/lib/python3.6/site-packages/ python-dateutil yum clean expire-cache yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl yum -y update exclude=salt* @@ -1010,8 +1011,8 @@ salt_install_mysql_deps() { if [ $OS == 'centos' ]; then yum -y install mariadb-devel - echo "Using pip3 to install mysqlclient for salt" - pip3 install -t /usr/lib64/python3.6/site-packages/ mysqlclient + #echo "Using pip3 to install mysqlclient for salt" + #pip3 install -t /usr/lib64/python3.6/site-packages/ mysqlclient elif [ $OS == 'ubuntu' ]; then apt-get -y install libmysqlclient-dev echo "Using pip3 to install mysqlclient for salt" From 05ef3d54e5ea23e435ae1ffdfe883914f1d16c8d Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 18 Nov 2019 13:39:06 -0500 Subject: [PATCH 54/67] Change install time for python36-docker --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 8618553eb..8b5e060ef 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -355,7 +355,7 @@ docker_install() { yum -y install yum-utils device-mapper-persistent-data lvm2 openssl yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum -y update - yum -y install docker-ce + yum -y install docker-ce python36-docker if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi @@ -494,7 +494,7 @@ install_pip3() { apt-get -y install python3-pip gcc python3-dev elif [ $OS == 'centos' ]; then #yum -y install python3-pip gcc python3-devel - yum -y install epel-release python3 python36-dateutil python36-m2crypto python36-mysql python36-docker + yum -y install epel-release python3 python36-dateutil python36-m2crypto python36-mysql fi } From 525b0e2a90f9891205759e3e10ca57c177d40f79 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 18 Nov 2019 14:16:13 -0500 Subject: [PATCH 55/67] Change install time for python36-docker --- so-setup-network.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 8b5e060ef..12029a4d3 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -494,7 +494,7 @@ install_pip3() { apt-get -y install python3-pip gcc python3-dev elif [ $OS == 'centos' ]; then #yum -y install python3-pip gcc python3-devel - yum -y install epel-release python3 python36-dateutil python36-m2crypto python36-mysql + yum -y install epel-release python3 fi } @@ -511,7 +511,7 @@ install_master() { # Install the salt master package if [ $OS == 'centos' ]; then - yum -y install wget salt-common salt-master >> $SETUPLOG 2>&1 + yum -y install wget salt-common salt-master python36-mysql python36-dateutil python36-m2crypto >> $SETUPLOG 2>&1 # Create a place for the keys for Ubuntu minions mkdir -p /opt/so/gpg From cc5565d5bc1fe95993076fe0a5736fba5e5e9359 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 18 Nov 2019 15:33:21 -0500 Subject: [PATCH 56/67] fix needs_restarting module --- salt/_modules/needs_restarting.py | 7 +++---- salt/motd/init.sls | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/salt/_modules/needs_restarting.py b/salt/_modules/needs_restarting.py index 49f82bbf2..5afb6f02a 100644 --- a/salt/_modules/needs_restarting.py +++ b/salt/_modules/needs_restarting.py @@ -4,20 +4,19 @@ import subprocess def check(): os = __grains__['os'] + retval = 'False' if os == 'Ubuntu': if path.exists('/var/run/reboot-required'): retval = 'True' - else: - retval = 'False' elif os == 'CentOS': cmd = 'needs-restarting -r > /dev/null 2>&1' + try: - needs_restarting = subprocess.check_call(cmd.split(), shell=True) + needs_restarting = subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError: retval = 'True' - retval = 'False' else: retval = 'Unsupported OS: %s' % os diff --git a/salt/motd/init.sls b/salt/motd/init.sls index a314ddb80..4dae979bf 100644 --- a/salt/motd/init.sls +++ b/salt/motd/init.sls @@ -1,5 +1,5 @@ package_update_reboot_required_motd: - file.append: + file.managed: - name: /etc/motd - source: salt://motd/files/package_update_reboot_required.jinja - template: jinja From 726251cd940b46d932f0e4e3b1939d70a375f82e Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 18 Nov 2019 16:02:48 -0500 Subject: [PATCH 57/67] changes to patch motd so nodes can be removed after they restarted - https://github.com/Security-Onion-Solutions/securityonion-saltstack/issues/112 --- salt/patch/needs_restarting.sls | 4 ++++ salt/patch/os/init.sls | 9 +++------ 2 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 salt/patch/needs_restarting.sls diff --git a/salt/patch/needs_restarting.sls b/salt/patch/needs_restarting.sls new file mode 100644 index 000000000..f7ba2626d --- /dev/null +++ b/salt/patch/needs_restarting.sls @@ -0,0 +1,4 @@ +needs_restarting: + module.run: + - mine.send: + - func: needs_restarting.check diff --git a/salt/patch/os/init.sls b/salt/patch/os/init.sls index 97183199b..a29bf8d12 100644 --- a/salt/patch/os/init.sls +++ b/salt/patch/os/init.sls @@ -1,5 +1,6 @@ -{% if grains.os == "CentOS" %} include: + - patch.needs_restarting +{% if grains.os == "CentOS" %} - yum.packages {% endif %} @@ -7,8 +8,4 @@ patch_os: pkg.uptodate: - name: patch_os - refresh: True - -needs_restarting: - module.run: - - mine.send: - - func: needs_restarting.check + - onchanges_in: needs_restarting From bec95f3aef89160d8c18b09d84966c4478bc8aa5 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 18 Nov 2019 16:25:06 -0500 Subject: [PATCH 58/67] apply patch.needs_restarting state to all nodes --- salt/top.sls | 1 + 1 file changed, 1 insertion(+) diff --git a/salt/top.sls b/salt/top.sls index 46745a38b..7f3d7fef4 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -6,6 +6,7 @@ {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} base: '*': + = patch.needs_restarting - patch.os.schedule - motd From 767115c218cb9c147a4d732d7168dc4979ac143e Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Mon, 18 Nov 2019 16:27:14 -0500 Subject: [PATCH 59/67] fix typo in salt top file --- salt/top.sls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/top.sls b/salt/top.sls index 7f3d7fef4..b1c64def4 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -6,7 +6,7 @@ {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} base: '*': - = patch.needs_restarting + - patch.needs_restarting - patch.os.schedule - motd From 09bf22c97a6e738672de2f7a2bbb277af700939c Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 19 Nov 2019 10:06:52 -0500 Subject: [PATCH 60/67] fix issues with updating motd if nodes needs restarted due to OS patch updates --- salt/patch/needs_restarting.sls | 1 + salt/patch/os/init.sls | 1 - salt/top.sls | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/patch/needs_restarting.sls b/salt/patch/needs_restarting.sls index f7ba2626d..f60909d22 100644 --- a/salt/patch/needs_restarting.sls +++ b/salt/patch/needs_restarting.sls @@ -2,3 +2,4 @@ needs_restarting: module.run: - mine.send: - func: needs_restarting.check + - order: last diff --git a/salt/patch/os/init.sls b/salt/patch/os/init.sls index a29bf8d12..7f2adc65b 100644 --- a/salt/patch/os/init.sls +++ b/salt/patch/os/init.sls @@ -8,4 +8,3 @@ patch_os: pkg.uptodate: - name: patch_os - refresh: True - - onchanges_in: needs_restarting diff --git a/salt/top.sls b/salt/top.sls index b1c64def4..a2662a89b 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -6,8 +6,8 @@ {%- set PLAYBOOK = salt['pillar.get']('master:playbook', '0') -%} base: '*': - - patch.needs_restarting - patch.os.schedule + - patch.needs_restarting - motd 'G@role:so-sensor': From 34460a6b07c0814ae623564a3ef7907b234c78ac Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 19 Nov 2019 16:25:10 +0000 Subject: [PATCH 61/67] add Cortex org user to setup --- so-setup-network.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/so-setup-network.sh b/so-setup-network.sh index 12029a4d3..5bf574429 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -436,6 +436,7 @@ generate_passwords(){ FLEETPASS=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) HIVEKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) CORTEXKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) + CORTEXORGUSERKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) SENSORONIKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) } @@ -604,6 +605,9 @@ master_static() { echo " cortexuser: cortexadmin" >> /opt/so/saltstack/pillar/static.sls echo " cortexpassword: cortexchangeme" >> /opt/so/saltstack/pillar/static.sls echo " cortexkey: $CORTEXKEY" >> /opt/so/saltstack/pillar/static.sls + echo " cortexorgname: SecurityOnion" >> /opt/so/saltstack/pillar/static.sls + echo " cortexorguser: soadmin" >> /opt/so/saltstack/pillar/static.sls + echo " cortexorguserkey: $CORTEXORGUSERKEY" >> /opt/so/saltstack/pillar/static.sls echo " fleetsetup: 0" >> /opt/so/saltstack/pillar/static.sls echo " sensoronikey: $SENSORONIKEY" >> /opt/so/saltstack/pillar/static.sls if [[ $MASTERUPDATES == 'MASTER' ]]; then From b7ad65a837bfaac5d31160f54c42b4bec9a33e87 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 19 Nov 2019 16:28:05 +0000 Subject: [PATCH 62/67] add Cortex org user --- salt/hive/thehive/scripts/cortex_init.sh | 26 +++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/salt/hive/thehive/scripts/cortex_init.sh b/salt/hive/thehive/scripts/cortex_init.sh index 3596c98dd..506b14be5 100644 --- a/salt/hive/thehive/scripts/cortex_init.sh +++ b/salt/hive/thehive/scripts/cortex_init.sh @@ -3,6 +3,9 @@ {%- set CORTEXUSER = salt['pillar.get']('static:cortexuser', '') %} {%- set CORTEXPASSWORD = salt['pillar.get']('static:cortexpassword', '') %} {%- set CORTEXKEY = salt['pillar.get']('static:cortexkey', '') %} +{%- set CORTEXORGNAME = salt['pillar.get']('static:cortexorgname', '') %} +{%- set CORTEXORGUSER = salt['pillar.get']('static:cortexorguser', '') %} +{%- set CORTEXORGUSERKEY = salt['pillar.get']('static:cortexorguserkey', '') %} cortex_init(){ sleep 60 @@ -10,17 +13,34 @@ cortex_init(){ CORTEX_USER="{{CORTEXUSER}}" CORTEX_PASSWORD="{{CORTEXPASSWORD}}" CORTEX_KEY="{{CORTEXKEY}}" + CORTEX_ORG_NAME="{{CORTEXORGNAME}}" + CORTEX_ORG_DESC="{{CORTEXORGNAME}} organization created by Security Onion setup" + CORTEX_ORG_USER="{{CORTEXORGUSER}}" + CORTEX_ORG_USER_KEY="{{CORTEXORGUSERKEY}}" SOCTOPUS_CONFIG="/opt/so/saltstack/salt/soctopus/files/SOCtopus.conf" + # Migrate DB curl -v -k -XPOST "https://$CORTEX_IP:/cortex/api/maintenance/migrate" - # Create intial Cortex user + # Create intial Cortex superadmin curl -v -k "https://$CORTEX_IP/cortex/api/user" -H "Content-Type: application/json" -d "{\"login\" : \"$CORTEX_USER\",\"name\" : \"$CORTEX_USER\",\"roles\" : [\"superadmin\"],\"preferences\" : \"{}\",\"password\" : \"$CORTEX_PASSWORD\", \"key\": \"$CORTEX_KEY\"}" - # Enable URLScan.io Analyzer - curl -v -k -XPOST -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/organization/analyzer/Urlscan_io_Search_0_1_0" -d '{"name":"Urlscan_io_Search_0_1_0","configuration":{"auto_extract_artifacts":false,"check_tlp":true,"max_tlp":2}}' + # Create user-supplied org + curl -k -XPOST -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/organization" -d "{ \"name\": \"$CORTEX_ORG_NAME\",\"description\": \"$CORTEX_ORG_DESC\",\"status\": \"Active\"}" + # Create user-supplied org user + curl -k -XPOST -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/user" -d "{\"name\": \"$CORTEX_ORG_USER\",\"roles\": [\"read\",\"analyze\",\"orgadmin\"],\"organization\": \"$CORTEX_ORG_NAME\",\"login\": \"$CORTEX_ORG_USER\",\"key\": \"$CORTEX_ORG_USER_KEY\" }" + + # Enable URLScan.io Analyzer + curl -v -k -XPOST -H "Authorization: Bearer $CORTEX_ORG_USER_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/organization/analyzer/Urlscan_io_Search_0_1_0" -d '{"name":"Urlscan_io_Search_0_1_0","configuration":{"auto_extract_artifacts":false,"check_tlp":true,"max_tlp":2}}' + + # Enable Cert PassiveDNS Analyzer + curl -v -k -XPOST -H "Authorization: Bearer $CORTEX_ORG_USER_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/organization/analyzer/CERTatPassiveDNS_2_0" -d '{"name":"CERTatPassiveDNS_2_0","configuration":{"auto_extract_artifacts":false,"check_tlp":true,"max_tlp":2, "limit": 100}}' + + # Revoke $CORTEX_USER key + curl -k -XDELETE -H "Authorization: Bearer $CORTEX_KEY" "https:///$CORTEX_IP/api/user/$CORTEX_USER/key" + # Update SOCtopus config with apikey value #sed -i "s/cortex_key = .*/cortex_key = $CORTEX_KEY/" $SOCTOPUS_CONFIG From 76cdc02305abb43c8709af760723a5a29cda1c95 Mon Sep 17 00:00:00 2001 From: Wes Lambert Date: Tue, 19 Nov 2019 16:28:42 +0000 Subject: [PATCH 63/67] user Cortex org user instead --- salt/hive/thehive/etc/application.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/hive/thehive/etc/application.conf b/salt/hive/thehive/etc/application.conf index 6cc72813e..3b6c89637 100644 --- a/salt/hive/thehive/etc/application.conf +++ b/salt/hive/thehive/etc/application.conf @@ -1,5 +1,5 @@ {%- set MASTERIP = salt['pillar.get']('static:masterip', '') %} -{%- set CORTEXKEY = salt['pillar.get']('static:cortexkey', '') %} +{%- set CORTEXKEY = salt['pillar.get']('static:cortexorguserkey', '') %} # Secret Key # The secret key is used to secure cryptographic functions. From cc98e45f736d574161aa6fc3383641955f48209e Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 19 Nov 2019 14:52:29 -0500 Subject: [PATCH 64/67] Move and simplify dependencies for Centos --- so-setup-network.sh | 85 +++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 54 deletions(-) diff --git a/so-setup-network.sh b/so-setup-network.sh index 12029a4d3..c68a39fca 100644 --- a/so-setup-network.sh +++ b/so-setup-network.sh @@ -55,10 +55,6 @@ add_master_hostfile() { MSRVIP=$(whiptail --title "Security Onion Setup" --inputbox \ "Enter your Master Server IP Address" 10 60 X.X.X.X 3>&1 1>&2 2>&3) - # Add the master to the host file if it doesn't resolve - #if ! grep -q $MSRVIP /etc/hosts; then - # echo "$MSRVIP $MSRV" >> /etc/hosts - #fi } add_socore_user_master() { @@ -77,21 +73,6 @@ add_socore_user_master() { } -#add_socore_user_master() { -# echo "Add socore on the master" >> $SETUPLOG 2>&1 -# if [ $OS == 'centos' ]; then -# local ADDUSER=adduser -# else -# local ADDUSER=useradd -# fi -# # Add user "socore" to the master. This will be for things like accepting keys. -# groupadd --gid 939 socore -# $ADDUSER --uid 939 --gid 939 --home-dir /opt/so socore -# # Prompt the user to set a password for the user -# passwd socore - -#} - add_socore_user_notmaster() { echo "Add socore user on non master" >> $SETUPLOG 2>&1 # Add socore user to the non master system. Probably not a bad idea to make system user @@ -359,8 +340,6 @@ docker_install() { if [ $INSTALLTYPE != 'EVALMODE' ]; then docker_registry fi - #echo "Using pip3 to install docker-py for salt" - #pip3 install -t /usr/lib/python3.6/site-packages/ docker echo "Restarting Docker" >> $SETUPLOG 2>&1 systemctl restart docker systemctl enable docker @@ -486,14 +465,13 @@ install_cleanup() { } -install_pip3() { +install_python3() { - echo "Installing pip3" + echo "Installing Python3" if [ $OS == 'ubuntu' ]; then apt-get -y install python3-pip gcc python3-dev elif [ $OS == 'centos' ]; then - #yum -y install python3-pip gcc python3-devel yum -y install epel-release python3 fi @@ -511,13 +489,13 @@ install_master() { # Install the salt master package if [ $OS == 'centos' ]; then - yum -y install wget salt-common salt-master python36-mysql python36-dateutil python36-m2crypto >> $SETUPLOG 2>&1 - + #yum -y install wget salt-common salt-master python36-mysql python36-dateutil python36-m2crypto >> $SETUPLOG 2>&1 + echo "" # Create a place for the keys for Ubuntu minions - mkdir -p /opt/so/gpg - wget --inet4-only -O /opt/so/gpg/SALTSTACK-GPG-KEY.pub https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub - wget --inet4-only -O /opt/so/gpg/docker.pub https://download.docker.com/linux/ubuntu/gpg - wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH + #mkdir -p /opt/so/gpg + #wget --inet4-only -O /opt/so/gpg/SALTSTACK-GPG-KEY.pub https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub + #wget --inet4-only -O /opt/so/gpg/docker.pub https://download.docker.com/linux/ubuntu/gpg + #wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH else apt-get install -y salt-common=2019.2.2+ds-1 salt-master=2019.2.2+ds-1 salt-minion=2019.2.2+ds-1 @@ -720,9 +698,14 @@ saltify() { ADDUSER=adduser if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm + yum -y install wget https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo + # Download Ubuntu Keys in case master updates = 1 + mkdir -p /opt/so/gpg + wget --inet4-only -O /opt/so/gpg/SALTSTACK-GPG-KEY.pub https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub + wget --inet4-only -O /opt/so/gpg/docker.pub https://download.docker.com/linux/ubuntu/gpg + wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH cat > /etc/yum.repos.d/wazuh.repo <<\EOF [wazuh_repo] gpgcheck=1 @@ -869,19 +852,16 @@ EOF fi fi - #echo "Using pip3 to install python-dateutil for salt" - #pip3 install -t /usr/lib/python3.6/site-packages/ python-dateutil yum clean expire-cache - yum -y install salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl + yum -y install epel-release salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl yum -y update exclude=salt* systemctl enable salt-minion - # Nasty hack but required for now if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - yum -y install salt-master-2019.2.2 python-m2crypto salt-minion-2019.2.2 m2crypto + yum -y install salt-master-2019.2.2 python3 python36-m2crypto salt-minion-2019.2.2 python36-dateutil python36-mysql python36-docker systemctl enable salt-master else - yum -y install salt-minion-2019.2.2 python-m2m2crypto m2crypto + yum -y install salt-minion-2019.2.2 python3 python36-m2crypto python36-dateutil python36-docker fi echo "exclude=salt*" >> /etc/yum.conf @@ -898,8 +878,8 @@ EOF # Nasty hack but required for now if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then - echo "Using pip3 to install python-dateutil for salt" - pip3 install python-dateutil + #echo "Using pip3 to install python-dateutil for salt" + #pip3 install python-dateutil # Install the repo for salt wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add - wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2019.2/SALTSTACK-GPG-KEY.pub | apt-key add - @@ -923,7 +903,8 @@ EOF # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 - apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 >> $SETUPLOG 2>&1 + # Need to add python packages here + apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 python3-dateutil >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common else @@ -937,6 +918,7 @@ EOF echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list # Initialize the new repos apt-get update >> $SETUPLOG 2>&1 + # Need to add python dateutil here apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 >> $SETUPLOG 2>&1 apt-mark hold salt-minion salt-common @@ -1011,12 +993,8 @@ salt_install_mysql_deps() { if [ $OS == 'centos' ]; then yum -y install mariadb-devel - #echo "Using pip3 to install mysqlclient for salt" - #pip3 install -t /usr/lib64/python3.6/site-packages/ mysqlclient elif [ $OS == 'ubuntu' ]; then - apt-get -y install libmysqlclient-dev - echo "Using pip3 to install mysqlclient for salt" - pip3 install mysqlclient + apt-get -y install libmysqlclient-dev python3-mysqldb fi } @@ -1925,11 +1903,10 @@ if (whiptail_you_sure); then # Install salt and dependencies { sleep 0.5 - install_pip3 >> $SETUPLOG 2>&1 - echo -e "XXX\n1\nInstalling mysql dependencies for saltstack... \nXXX" - salt_install_mysql_deps >> $SETUPLOG 2>&1 - echo -e "XXX\n2\nInstalling and configuring Salt... \nXXX" + #install_pip3 >> $SETUPLOG 2>&1 + echo -e "XXX\n1\nInstalling and configuring Salt... \nXXX" echo " ** Installing Salt and Dependencies **" >> $SETUPLOG + salt_install_mysql_deps >> $SETUPLOG 2>&1 saltify >> $SETUPLOG 2>&1 echo -e "XXX\n5\nInstalling Docker... \nXXX" docker_install >> $SETUPLOG 2>&1 @@ -2062,8 +2039,8 @@ if (whiptail_you_sure); then sleep 0.5 echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 - echo -e "XXX\n1\nInstalling pip3... \nXXX" - install_pip3 >> $SETUPLOG 2>&1 + #echo -e "XXX\n1\nInstalling pip3... \nXXX" + #install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n3\nCreating Bond Interface... \nXXX" network_setup >> $SETUPLOG 2>&1 echo -e "XXX\n4\nGenerating Sensor Pillar... \nXXX" @@ -2164,7 +2141,7 @@ if (whiptail_you_sure); then sleep 0.5 echo -e "XXX\n0\nCreating Bond Interface... \nXXX" network_setup >> $SETUPLOG 2>&1 - install_pip3 >> $SETUPLOG 2>&1 + #install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n1\nInstalling mysql dependencies for saltstack... \nXXX" salt_install_mysql_deps >> $SETUPLOG 2>&1 echo -e "XXX\n1\nInstalling saltstack... \nXXX" @@ -2329,8 +2306,8 @@ if (whiptail_you_sure); then sleep 0.5 echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" set_initial_firewall_policy >> $SETUPLOG 2>&1 - echo -e "XXX\n1\nInstalling pip3... \nXXX" - install_pip3 >> $SETUPLOG 2>&1 + #echo -e "XXX\n1\nInstalling pip3... \nXXX" + #install_pip3 >> $SETUPLOG 2>&1 echo -e "XXX\n5\nInstalling Salt Packages... \nXXX" saltify >> $SETUPLOG 2>&1 echo -e "XXX\n20\nInstalling Docker... \nXXX" From 7373473b3f2719ba5c7acfc051dbf32f4f06ab5b Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Tue, 19 Nov 2019 15:02:35 -0500 Subject: [PATCH 65/67] Fix dup events --- .../files/dynamic/0006_input_beats.conf | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/salt/logstash/files/dynamic/0006_input_beats.conf b/salt/logstash/files/dynamic/0006_input_beats.conf index 1a6b66bbe..a7140f859 100644 --- a/salt/logstash/files/dynamic/0006_input_beats.conf +++ b/salt/logstash/files/dynamic/0006_input_beats.conf @@ -9,23 +9,6 @@ input { } } filter { - if [type] == "ids" or [type] =~ "bro" { - mutate { - rename => { "host" => "beat_host" } - remove_tag => ["beat"] - add_field => { "sensor_name" => "%{[beat][name]}" } - add_field => { "syslog-host_from" => "%{[beat][name]}" } - remove_field => [ "beat", "prospector", "input", "offset" ] - } - } - if [type] =~ "ossec" { - mutate { - rename => { "host" => "beat_host" } - remove_tag => ["beat"] - add_field => { "syslog-host_from" => "%{[beat][name]}" } - remove_field => [ "beat", "prospector", "input", "offset" ] - } - } if [type] == "osquery" { mutate { rename => { "host" => "beat_host" } From 21a29d7274294d67a8c6e5a092a2771fdc49aec5 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 20 Nov 2019 10:36:32 -0500 Subject: [PATCH 66/67] Initial Setup overhaul testing --- .../registry/scripts/so-docker-download.sh | 48 + setup/functions.sh | 1125 +++++++++++++++++ setup/so-setup.sh | 627 +++++++++ setup/whiplash.sh | 611 +++++++++ 4 files changed, 2411 insertions(+) create mode 100644 salt/master/files/registry/scripts/so-docker-download.sh create mode 100644 setup/functions.sh create mode 100644 setup/so-setup.sh create mode 100644 setup/whiplash.sh diff --git a/salt/master/files/registry/scripts/so-docker-download.sh b/salt/master/files/registry/scripts/so-docker-download.sh new file mode 100644 index 000000000..33b5065ae --- /dev/null +++ b/salt/master/files/registry/scripts/so-docker-download.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +MASTER={{ MASTER }} +VERSION="HH1.1.3" +TRUSTED_CONTAINERS=( \ +"so-core:$VERSION" \ +"so-cyberchef:$VERSION" \ +"so-acng:$VERSION" \ +"so-sensoroni:$VERSION" \ +"so-fleet:$VERSION" \ +"so-soctopus:$VERSION" \ +"so-steno:$VERSION" \ +"so-playbook:$VERSION" \ +"so-thehive-cortex:$VERSION" \ +"so-thehive:$VERSION" \ +"so-thehive-es:$VERSION" \ +"so-wazuh:$VERSION" \ +"so-kibana:$VERSION" \ +"so-auth-ui:$VERSION" \ +"so-auth-api:$VERSION" \ +"so-elastalert:$VERSION" \ +"so-navigator:$VERSION" \ +"so-filebeat:$VERSION" \ +"so-suricata:$VERSION" \ +"so-logstash:$VERSION" \ +"so-bro:$VERSION" \ +"so-idstools:$VERSION" \ +"so-fleet-launcher:$VERSION" \ +"so-freqserver:$VERSION" \ +"so-influxdb:$VERSION" \ +"so-grafana:$VERSION" \ +"so-telegraf:$VERSION" \ +"so-redis:$VERSION" \ +"so-mysql:$VERSION" \ +"so-curtor:$VERSION" \ +"so-elasticsearch:$VERSION" \ +"so-domainstats:$VERSION" \ +"so-tcpreplay:$VERSION" \ +) + +for i in "${TRUSTED_CONTAINERS[@]}" +do + # Pull down the trusted docker image + docker pull --disable-content-trust=false docker.io/soshybridhunter/$i + # Tag it with the new registry destination + docker tag soshybridhunter/$i $MASTER:5000/soshybridhunter/$i + docker push $MASTER:5000/soshybridhunter/$i +done diff --git a/setup/functions.sh b/setup/functions.sh new file mode 100644 index 000000000..184750d61 --- /dev/null +++ b/setup/functions.sh @@ -0,0 +1,1125 @@ +# Functions + +accept_salt_key_local() { + echo "Accept the key locally on the master" >> $SETUPLOG 2>&1 + # Accept the key locally on the master + salt-key -ya $MINION_ID + +} + +accept_salt_key_remote() { + echo "Accept the key remotely on the master" >> $SETUPLOG 2>&1 + # Delete the key just in case. + ssh -i /root/.ssh/so.key socore@$MSRV sudo salt-key -d $MINION_ID -y + salt-call state.apply ca + ssh -i /root/.ssh/so.key socore@$MSRV sudo salt-key -a $MINION_ID -y + +} + +add_master_hostfile() { + echo "Checking if I can resolve master. If not add to hosts file" >> $SETUPLOG 2>&1 + # Pop up an input to get the IP address + MSRVIP=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter your Master Server IP Address" 10 60 X.X.X.X 3>&1 1>&2 2>&3) + +} + +add_socore_user_master() { + + echo "Add socore on the master" >>~/sosetup.log 2>&1 + # Add user "socore" to the master. This will be for things like accepting keys. + if [ $OS == 'centos' ]; then + local ADDUSER=adduser + else + local ADDUSER=useradd + fi + groupadd --gid 939 socore + $ADDUSER --uid 939 --gid 939 --home-dir /opt/so socore + # Set the password for socore that we got during setup + echo socore:$COREPASS1 | chpasswd --crypt-method=SHA512 + +} + +add_socore_user_notmaster() { + echo "Add socore user on non master" >> $SETUPLOG 2>&1 + # Add socore user to the non master system. Probably not a bad idea to make system user + groupadd --gid 939 socore + $ADDUSER --uid 939 --gid 939 --home-dir /opt/so --no-create-home socore + +} + +# Create an auth pillar so that passwords survive re-install +auth_pillar(){ + + if [ ! -f /opt/so/saltstack/pillar/auth.sls ]; then + echo "Creating Auth Pillar" >> $SETUPLOG 2>&1 + mkdir -p /opt/so/saltstack/pillar + echo "auth:" >> /opt/so/saltstack/pillar/auth.sls + echo " mysql: $MYSQLPASS" >> /opt/so/saltstack/pillar/auth.sls + echo " fleet: $FLEETPASS" >> /opt/so/saltstack/pillar/auth.sls + fi + +} + +# Enable Bro Logs +bro_logs_enabled() { + echo "Enabling Bro Logs" >> $SETUPLOG 2>&1 + + echo "brologs:" > pillar/brologs.sls + echo " enabled:" >> pillar/brologs.sls + + if [ $MASTERADV == 'ADVANCED' ]; then + for BLOG in ${BLOGS[@]}; do + echo " - $BLOG" | tr -d '"' >> pillar/brologs.sls + done + else + echo " - conn" >> pillar/brologs.sls + echo " - dce_rpc" >> pillar/brologs.sls + echo " - dhcp" >> pillar/brologs.sls + echo " - dhcpv6" >> pillar/brologs.sls + echo " - dnp3" >> pillar/brologs.sls + echo " - dns" >> pillar/brologs.sls + echo " - dpd" >> pillar/brologs.sls + echo " - files" >> pillar/brologs.sls + echo " - ftp" >> pillar/brologs.sls + echo " - http" >> pillar/brologs.sls + echo " - intel" >> pillar/brologs.sls + echo " - irc" >> pillar/brologs.sls + echo " - kerberos" >> pillar/brologs.sls + echo " - modbus" >> pillar/brologs.sls + echo " - mqtt" >> pillar/brologs.sls + echo " - notice" >> pillar/brologs.sls + echo " - ntlm" >> pillar/brologs.sls + echo " - openvpn" >> pillar/brologs.sls + echo " - pe" >> pillar/brologs.sls + echo " - radius" >> pillar/brologs.sls + echo " - rfb" >> pillar/brologs.sls + echo " - rdp" >> pillar/brologs.sls + echo " - signatures" >> pillar/brologs.sls + echo " - sip" >> pillar/brologs.sls + echo " - smb_files" >> pillar/brologs.sls + echo " - smb_mapping" >> pillar/brologs.sls + echo " - smtp" >> pillar/brologs.sls + echo " - snmp" >> pillar/brologs.sls + echo " - software" >> pillar/brologs.sls + echo " - ssh" >> pillar/brologs.sls + echo " - ssl" >> pillar/brologs.sls + echo " - syslog" >> pillar/brologs.sls + echo " - telnet" >> pillar/brologs.sls + echo " - tunnel" >> pillar/brologs.sls + echo " - weird" >> pillar/brologs.sls + echo " - mysql" >> pillar/brologs.sls + echo " - socks" >> pillar/brologs.sls + echo " - x509" >> pillar/brologs.sls + fi +} + +calculate_useable_cores() { + + # Calculate reasonable core usage + local CORES4BRO=$(( $CPUCORES/2 - 1 )) + LBPROCSROUND=$(printf "%.0f\n" $CORES4BRO) + # We don't want it to be 0 + if [ "$LBPROCSROUND" -lt 1 ]; then + LBPROCS=1 + else + LBPROCS=$LBPROCSROUND + fi + +} + +checkin_at_boot() { + echo "Enabling checkin at boot" >> $SETUPLOG 2>&1 + echo "startup_states: highstate" >> /etc/salt/minion +} + +check_hive_init_then_reboot() { + WAIT_STEP=0 + MAX_WAIT=100 + until [ -f /opt/so/state/thehive.txt ] ; do + WAIT_STEP=$(( ${WAIT_STEP} + 1 )) + echo "Waiting on the_hive to init...Attempt #$WAIT_STEP" + if [ ${WAIT_STEP} -gt ${MAX_WAIT} ]; then + echo "ERROR: We waited ${MAX_WAIT} seconds but the_hive is not working." + exit 5 + fi + sleep 1s; + done + docker stop so-thehive + docker rm so-thehive + shutdown -r now +} + +check_socore_pass() { + + if [ $COREPASS1 == $COREPASS2 ]; then + SCMATCH=yes + else + whiptail_passwords_dont_match + fi + +} + +chown_salt_master() { + + echo "Chown the salt dirs on the master for socore" >> $SETUPLOG 2>&1 + chown -R socore:socore /opt/so + +} + +clear_master() { + # Clear out the old master public key in case this is a re-install. + # This only happens if you re-install the master. + if [ -f /etc/salt/pki/minion/minion_master.pub ]; then + echo "Clearing old master key" >> $SETUPLOG 2>&1 + rm /etc/salt/pki/minion/minion_master.pub + service salt-minion restart + fi + +} + +configure_minion() { + + # You have to pass the TYPE to this function so it knows if its a master or not + local TYPE=$1 + echo "Configuring minion type as $TYPE" >> $SETUPLOG 2>&1 + touch /etc/salt/grains + echo "role: so-$TYPE" > /etc/salt/grains + if [ $TYPE == 'master' ] || [ $TYPE == 'eval' ]; then + echo "master: $HOSTNAME" > /etc/salt/minion + echo "id: $MINION_ID" >> /etc/salt/minion + echo "mysql.host: '$MAINIP'" >> /etc/salt/minion + echo "mysql.port: 3306" >> /etc/salt/minion + echo "mysql.user: 'root'" >> /etc/salt/minion + if [ ! -f /opt/so/saltstack/pillar/auth.sls ]; then + echo "mysql.pass: '$MYSQLPASS'" >> /etc/salt/minion + else + OLDPASS=$(cat /opt/so/saltstack/pillar/auth.sls | grep mysql | awk {'print $2'}) + echo "mysql.pass: '$OLDPASS'" >> /etc/salt/minion + fi + else + echo "master: $MSRV" > /etc/salt/minion + echo "id: $MINION_ID" >> /etc/salt/minion + + fi + + echo "use_superseded:" >> /etc/salt/minion + echo " - module.run" >> /etc/salt/minion + + service salt-minion restart + +} + +copy_master_config() { + + # Copy the master config template to the proper directory + cp files/master /etc/salt/master + # Restart the service so it picks up the changes -TODO Enable service on CentOS + service salt-master restart + +} + +copy_minion_tmp_files() { + + if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + echo "rsyncing all files in $TMP to /opt/so/saltstack" >> $SETUPLOG 2>&1 + rsync -a -v $TMP/ /opt/so/saltstack/ >> $SETUPLOG 2>&1 + else + echo "scp all files in $TMP to master /opt/so/saltstack" >> $SETUPLOG 2>&1 + scp -prv -i /root/.ssh/so.key $TMP/* socore@$MSRV:/opt/so/saltstack >> $SETUPLOG 2>&1 + fi + + } + +copy_ssh_key() { + + # Generate SSH key + mkdir -p /root/.ssh + cat /dev/zero | ssh-keygen -f /root/.ssh/so.key -t rsa -q -N "" + chown -R $SUDO_USER:$SUDO_USER /root/.ssh + #Copy the key over to the master + ssh-copy-id -f -i /root/.ssh/so.key socore@$MSRV + +} + +network_setup() { + echo "Setting up Bond" >> $SETUPLOG 2>&1 + + # Set the MTU + if [ "$NSMSETUP" != 'ADVANCED' ]; then + MTU=1500 + fi + + # Create the bond interface + nmcli con add ifname bond0 con-name "bond0" type bond mode 0 -- \ + ipv4.method disabled \ + ipv6.method link-local \ + ethernet.mtu $MTU \ + connection.autoconnect "yes" >> $SETUPLOG 2>&1 + + for BNIC in ${BNICS[@]}; do + # Strip the quotes from the NIC names + BONDNIC="$(echo -e "${BNIC}" | tr -d '"')" + # Turn off various offloading settings for the interface + for i in rx tx sg tso ufo gso gro lro; do + ethtool -K $BONDNIC $i off >> $SETUPLOG 2>&1 + done + # Create the slave interface and assign it to the bond + nmcli con add type ethernet ifname $BONDNIC con-name "bond0-slave-$BONDNIC" master bond0 -- \ + ethernet.mtu $MTU \ + connection.autoconnect "yes" >> $SETUPLOG 2>&1 + # Bring the slave interface up + nmcli con up bond0-slave-$BONDNIC >> $SETUPLOG 2>&1 + done + # Replace the variable string in the network script + sed -i "s/\$MAININT/${MAININT}/g" ./install_scripts/disable-checksum-offload.sh >> $SETUPLOG 2>&1 + # Copy the checksum offload script to prevent issues with packet capture + cp ./install_scripts/disable-checksum-offload.sh /etc/NetworkManager/dispatcher.d/disable-checksum-offload.sh >> $SETUPLOG 2>&1 +} + +detect_os() { + + # Detect Base OS + echo "Detecting Base OS" >> $SETUPLOG 2>&1 + if [ -f /etc/redhat-release ]; then + OS=centos + yum -y install bind-utils + elif [ -f /etc/os-release ]; then + OS=ubuntu + apt install -y network-manager + /bin/systemctl enable network-manager + /bin/systemctl start network-manager + else + echo "We were unable to determine if you are using a supported OS." >> $SETUPLOG 2>&1 + exit + fi + +} + +docker_install() { + + if [ $OS == 'centos' ]; then + yum clean expire-cache + yum -y install yum-utils device-mapper-persistent-data lvm2 openssl + yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo + yum -y update + yum -y install docker-ce python36-docker + if [ $INSTALLTYPE != 'EVALMODE' ]; then + docker_registry + fi + echo "Restarting Docker" >> $SETUPLOG 2>&1 + systemctl restart docker + systemctl enable docker + + else + if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + apt-get update >> $SETUPLOG 2>&1 + apt-get -y install docker-ce >> $SETUPLOG 2>&1 + if [ $INSTALLTYPE != 'EVALMODE' ]; then + docker_registry >> $SETUPLOG 2>&1 + fi + echo "Restarting Docker" >> $SETUPLOG 2>&1 + systemctl restart docker >> $SETUPLOG 2>&1 + else + apt-key add $TMP/gpg/docker.pub >> $SETUPLOG 2>&1 + add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" >> $SETUPLOG 2>&1 + apt-get update >> $SETUPLOG 2>&1 + apt-get -y install docker-ce >> $SETUPLOG 2>&1 + docker_registry >> $SETUPLOG 2>&1 + echo "Restarting Docker" >> $SETUPLOG 2>&1 + systemctl restart docker >> $SETUPLOG 2>&1 + fi + echo "Using pip3 to install docker-py for salt" + pip3 install docker + fi + +} + +docker_registry() { + + echo "Setting up Docker Registry" >> $SETUPLOG 2>&1 + mkdir -p /etc/docker >> $SETUPLOG 2>&1 + # Make the host use the master docker registry + echo "{" > /etc/docker/daemon.json + echo " \"registry-mirrors\": [\"https://$MSRV:5000\"]" >> /etc/docker/daemon.json + echo "}" >> /etc/docker/daemon.json + echo "Docker Registry Setup - Complete" >> $SETUPLOG 2>&1 + +} + +es_heapsize() { + + # Determine ES Heap Size + if [ $TOTAL_MEM -lt 8000 ] ; then + ES_HEAP_SIZE="600m" + elif [ $TOTAL_MEM -ge 100000 ]; then + # Set a max of 25GB for heap size + # https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html + ES_HEAP_SIZE="25000m" + else + # Set heap size to 25% of available memory + ES_HEAP_SIZE=$(($TOTAL_MEM / 4))"m" + fi + +} + +eval_mode_hostsfile() { + + echo "127.0.0.1 $HOSTNAME" >> /etc/hosts + +} + +filter_nics() { + + # Filter the NICs that we don't want to see in setup + FNICS=$(ip link | grep -vw $MNIC | awk -F: '$0 !~ "lo|vir|veth|br|docker|wl|^[^0-9]"{print $2 " \"" "Interface" "\"" " OFF"}') + +} + +generate_passwords(){ + # Generate Random Passwords for Things + MYSQLPASS=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) + FLEETPASS=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) + HIVEKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) + CORTEXKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) + SENSORONIKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1) +} + +get_filesystem_nsm(){ + FSNSM=$(df /nsm | awk '$3 ~ /[0-9]+/ { print $2 * 1000 }') +} + +get_log_size_limit() { + + DISK_DIR="/" + if [ -d /nsm ]; then + DISK_DIR="/nsm" + fi + DISK_SIZE_K=`df $DISK_DIR |grep -v "^Filesystem" | awk '{print $2}'` + PERCENTAGE=85 + DISK_SIZE=DISK_SIZE_K*1000 + PERCENTAGE_DISK_SPACE=`echo $(($DISK_SIZE*$PERCENTAGE/100))` + LOG_SIZE_LIMIT=$(($PERCENTAGE_DISK_SPACE/1000000000)) + +} + +get_filesystem_root(){ + FSROOT=$(df / | awk '$3 ~ /[0-9]+/ { print $2 * 1000 }') +} + +get_main_ip() { + + # Get the main IP address the box is using + MAINIP=$(ip route get 1 | awk '{print $NF;exit}') + MAININT=$(ip route get 1 | awk '{print $5;exit}') + +} + +got_root() { + + # Make sure you are root + if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run using sudo!" + exit 1 + fi + +} + +install_cleanup() { + + # Clean up after ourselves + rm -rf /root/installtmp + +} + +install_python3() { + + echo "Installing Python3" + + if [ $OS == 'ubuntu' ]; then + apt-get -y install python3-pip gcc python3-dev + elif [ $OS == 'centos' ]; then + yum -y install epel-release python3 + fi + +} + +install_prep() { + + # Create a tmp space that isn't in /tmp + mkdir /root/installtmp + TMP=/root/installtmp + +} + +install_master() { + + # Install the salt master package + if [ $OS == 'centos' ]; then + #yum -y install wget salt-common salt-master python36-mysql python36-dateutil python36-m2crypto >> $SETUPLOG 2>&1 + echo "" + # Create a place for the keys for Ubuntu minions + #mkdir -p /opt/so/gpg + #wget --inet4-only -O /opt/so/gpg/SALTSTACK-GPG-KEY.pub https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub + #wget --inet4-only -O /opt/so/gpg/docker.pub https://download.docker.com/linux/ubuntu/gpg + #wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH + + else + apt-get install -y salt-common=2019.2.2+ds-1 salt-master=2019.2.2+ds-1 salt-minion=2019.2.2+ds-1 + apt-mark hold salt-common salt-master salt-minion + echo -e "XXX\n11\nInstalling libssl-dev for M2Crypto... \nXXX" + apt-get -y install libssl-dev + echo -e "XXX\n12\nUsing pip3 to install M2Crypto for Salt... \nXXX" + pip3 install M2Crypto + + fi + + copy_master_config + +} + +ls_heapsize() { + + # Determine LS Heap Size + if [ $TOTAL_MEM -ge 32000 ] ; then + LS_HEAP_SIZE="1000m" + else + # If minimal RAM, then set minimal heap + LS_HEAP_SIZE="500m" + fi + +} + +master_pillar() { + + # Create the master pillar + touch /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo "master:" > /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " mainip: $MAINIP" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " mainint: $MAININT" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " esheap: $ES_HEAP_SIZE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " esclustername: {{ grains.host }}" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + if [ $INSTALLTYPE == 'EVALMODE' ]; then + echo " freq: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " domainstats: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " ls_pipeline_batch_size: 125" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " ls_input_threads: 1" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " ls_batch_count: 125" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " mtu: 1500" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + + else + echo " freq: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " domainstats: 0" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + fi + echo " lsheap: $LS_HEAP_SIZE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " lsaccessip: 127.0.0.1" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " elastalert: 1" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " ls_pipeline_workers: $CPUCORES" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " nids_rules: $RULESETUP" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " oinkcode: $OINKCODE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + #echo " access_key: $ACCESS_KEY" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + #echo " access_secret: $ACCESS_SECRET" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " es_port: $NODE_ES_PORT" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " log_size_limit: $LOG_SIZE_LIMIT" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " cur_close_days: $CURCLOSEDAYS" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + #echo " mysqlpass: $MYSQLPASS" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + #echo " fleetpass: $FLEETPASS" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " grafana: $GRAFANA" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " osquery: $OSQUERY" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " wazuh: $WAZUH" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " thehive: $THEHIVE" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + echo " playbook: $PLAYBOOK" >> /opt/so/saltstack/pillar/masters/$MINION_ID.sls + } + +master_static() { + + # Create a static file for global values + touch /opt/so/saltstack/pillar/static.sls + + echo "static:" > /opt/so/saltstack/pillar/static.sls + echo " hnmaster: $HNMASTER" >> /opt/so/saltstack/pillar/static.sls + echo " ntpserver: $NTPSERVER" >> /opt/so/saltstack/pillar/static.sls + echo " proxy: $PROXY" >> /opt/so/saltstack/pillar/static.sls + echo " broversion: $BROVERSION" >> /opt/so/saltstack/pillar/static.sls + echo " ids: $NIDS" >> /opt/so/saltstack/pillar/static.sls + echo " masterip: $MAINIP" >> /opt/so/saltstack/pillar/static.sls + echo " hiveuser: hiveadmin" >> /opt/so/saltstack/pillar/static.sls + echo " hivepassword: hivechangeme" >> /opt/so/saltstack/pillar/static.sls + echo " hivekey: $HIVEKEY" >> /opt/so/saltstack/pillar/static.sls + echo " cortexuser: cortexadmin" >> /opt/so/saltstack/pillar/static.sls + echo " cortexpassword: cortexchangeme" >> /opt/so/saltstack/pillar/static.sls + echo " cortexkey: $CORTEXKEY" >> /opt/so/saltstack/pillar/static.sls + echo " fleetsetup: 0" >> /opt/so/saltstack/pillar/static.sls + echo " sensoronikey: $SENSORONIKEY" >> /opt/so/saltstack/pillar/static.sls + if [[ $MASTERUPDATES == 'MASTER' ]]; then + echo " masterupdate: 1" >> /opt/so/saltstack/pillar/static.sls + else + echo " masterupdate: 0" >> /opt/so/saltstack/pillar/static.sls + fi +} + +minio_generate_keys() { + + local charSet="[:graph:]" + + ACCESS_KEY=$(cat /dev/urandom | tr -cd "$charSet" | tr -d \' | tr -d \" | head -c 20) + ACCESS_SECRET=$(cat /dev/urandom | tr -cd "$charSet" | tr -d \' | tr -d \" | head -c 40) + +} + +node_pillar() { + + NODEPILLARPATH=$TMP/pillar/nodes + if [ ! -d $NODEPILLARPATH ]; then + mkdir -p $NODEPILLARPATH + fi + + # Create the node pillar + touch $NODEPILLARPATH/$MINION_ID.sls + echo "node:" > $NODEPILLARPATH/$MINION_ID.sls + echo " mainip: $MAINIP" >> $NODEPILLARPATH/$MINION_ID.sls + echo " mainint: $MAININT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " esheap: $NODE_ES_HEAP_SIZE" >> $NODEPILLARPATH/$MINION_ID.sls + echo " esclustername: {{ grains.host }}" >> $NODEPILLARPATH/$MINION_ID.sls + echo " lsheap: $NODE_LS_HEAP_SIZE" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_pipeline_workers: $LSPIPELINEWORKERS" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_pipeline_batch_size: $LSPIPELINEBATCH" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_input_threads: $LSINPUTTHREADS" >> $NODEPILLARPATH/$MINION_ID.sls + echo " ls_batch_count: $LSINPUTBATCHCOUNT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " es_shard_count: $SHARDCOUNT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " node_type: $NODETYPE" >> $NODEPILLARPATH/$MINION_ID.sls + echo " es_port: $NODE_ES_PORT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " log_size_limit: $LOG_SIZE_LIMIT" >> $NODEPILLARPATH/$MINION_ID.sls + echo " cur_close_days: $CURCLOSEDAYS" >> $NODEPILLARPATH/$MINION_ID.sls + +} + +patch_pillar() { + + case $INSTALLTYPE in + 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 + + echo "patch:" > $OSPATCHSCHEDULE + echo " os:" >> $OSPATCHSCHEDULE + echo " schedule:" >> $OSPATCHSCHEDULE + for psd in "${PATCHSCHEDULEDAYS[@]}" + do + psd=$(echo $psd | sed 's/"//g') + echo " - $psd:" >> $OSPATCHSCHEDULE + for psh in "${PATCHSCHEDULEHOURS[@]}" + do + psh=$(echo $psh | sed 's/"//g') + echo " - '$psh'" >> $OSPATCHSCHEDULE + done + done + +} + +process_components() { + CLEAN=${COMPONENTS//\"} + GRAFANA=0 + OSQUERY=0 + WAZUH=0 + THEHIVE=0 + PLAYBOOK=0 + + IFS=$' ' + for item in $(echo "$CLEAN"); do + let $item=1 + done + unset IFS +} + +saltify() { + + # Install updates and Salt + if [ $OS == 'centos' ]; then + ADDUSER=adduser + + if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + yum -y install wget https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm + cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo + sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo + # Download Ubuntu Keys in case master updates = 1 + mkdir -p /opt/so/gpg + wget --inet4-only -O /opt/so/gpg/SALTSTACK-GPG-KEY.pub https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub + wget --inet4-only -O /opt/so/gpg/docker.pub https://download.docker.com/linux/ubuntu/gpg + wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH + cat > /etc/yum.repos.d/wazuh.repo <<\EOF +[wazuh_repo] +gpgcheck=1 +gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH +enabled=1 +name=Wazuh repository +baseurl=https://packages.wazuh.com/3.x/yum/ +protect=1 +EOF + + else + + if [ $MASTERUPDATES == 'MASTER' ]; then + + # Create the GPG Public Key for the Salt Repo + echo "-----BEGIN PGP PUBLIC KEY BLOCK-----" > /etc/pki/rpm-gpg/saltstack-signing-key + echo "Version: GnuPG v2.0.22 (GNU/Linux)" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "mQENBFOpvpgBCADkP656H41i8fpplEEB8IeLhugyC2rTEwwSclb8tQNYtUiGdna9" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "m38kb0OS2DDrEdtdQb2hWCnswxaAkUunb2qq18vd3dBvlnI+C4/xu5ksZZkRj+fW" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "tArNR18V+2jkwcG26m8AxIrT+m4M6/bgnSfHTBtT5adNfVcTHqiT1JtCbQcXmwVw" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "WbqS6v/LhcsBE//SHne4uBCK/GHxZHhQ5jz5h+3vWeV4gvxS3Xu6v1IlIpLDwUts" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "kT1DumfynYnnZmWTGc6SYyIFXTPJLtnoWDb9OBdWgZxXfHEcBsKGha+bXO+m2tHA" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "gNneN9i5f8oNxo5njrL8jkCckOpNpng18BKXABEBAAG0MlNhbHRTdGFjayBQYWNr" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "YWdpbmcgVGVhbSA8cGFja2FnaW5nQHNhbHRzdGFjay5jb20+iQE4BBMBAgAiBQJT" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "qb6YAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAOCKFJ3le/vhkqB/0Q" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "WzELZf4d87WApzolLG+zpsJKtt/ueXL1W1KA7JILhXB1uyvVORt8uA9FjmE083o1" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "yE66wCya7V8hjNn2lkLXboOUd1UTErlRg1GYbIt++VPscTxHxwpjDGxDB1/fiX2o" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "nK5SEpuj4IeIPJVE/uLNAwZyfX8DArLVJ5h8lknwiHlQLGlnOu9ulEAejwAKt9CU" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "4oYTszYM4xrbtjB/fR+mPnYh2fBoQO4d/NQiejIEyd9IEEMd/03AJQBuMux62tjA" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "/NwvQ9eqNgLw9NisFNHRWtP4jhAOsshv1WW+zPzu3ozoO+lLHixUIz7fqRk38q8Q" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "9oNR31KvrkSNrFbA3D89uQENBFOpvpgBCADJ79iH10AfAfpTBEQwa6vzUI3Eltqb" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "9aZ0xbZV8V/8pnuU7rqM7Z+nJgldibFk4gFG2bHCG1C5aEH/FmcOMvTKDhJSFQUx" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "uhgxttMArXm2c22OSy1hpsnVG68G32Nag/QFEJ++3hNnbyGZpHnPiYgej3FrerQJ" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "zv456wIsxRDMvJ1NZQB3twoCqwapC6FJE2hukSdWB5yCYpWlZJXBKzlYz/gwD/Fr" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "GL578WrLhKw3UvnJmlpqQaDKwmV2s7MsoZogC6wkHE92kGPG2GmoRD3ALjmCvN1E" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "PsIsQGnwpcXsRpYVCoW7e2nW4wUf7IkFZ94yOCmUq6WreWI4NggRcFC5ABEBAAGJ" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "AR8EGAECAAkFAlOpvpgCGwwACgkQDgihSd5Xv74/NggA08kEdBkiWWwJZUZEy7cK" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "WWcgjnRuOHd4rPeT+vQbOWGu6x4bxuVf9aTiYkf7ZjVF2lPn97EXOEGFWPZeZbH4" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "vdRFH9jMtP+rrLt6+3c9j0M8SIJYwBL1+CNpEC/BuHj/Ra/cmnG5ZNhYebm76h5f" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "T9iPW9fFww36FzFka4VPlvA4oB7ebBtquFg3sdQNU/MmTVV4jPFWXxh4oRDDR+8N" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "1bcPnbB11b5ary99F/mqr7RgQ+YFF0uKRE3SKa7a+6cIuHEZ7Za+zhPaQlzAOZlx" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "fuBmScum8uQTrEF5+Um5zkwC7EXTdH1co/+/V/fpOtxIg4XO4kcugZefVm5ERfVS" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "MA==" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "=dtMN" >> /etc/pki/rpm-gpg/saltstack-signing-key + echo "-----END PGP PUBLIC KEY BLOCK-----" >> /etc/pki/rpm-gpg/saltstack-signing-key + + # Add the Wazuh Key + cat > /etc/pki/rpm-gpg/GPG-KEY-WAZUH <<\EOF +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQINBFeeyYwBEACyf4VwV8c2++J5BmCl6ofLCtSIW3UoVrF4F+P19k/0ngnSfjWb +8pSWB11HjZ3Mr4YQeiD7yY06UZkrCXk+KXDlUjMK3VOY7oNPkqzNaP6+8bDwj4UA +hADMkaXBvWooGizhCoBtDb1bSbHKcAnQ3PTdiuaqF5bcyKk8hv939CHulL2xH+BP +mmTBi+PM83pwvR+VRTOT7QSzf29lW1jD79v4rtXHJs4KCz/amT/nUm/tBpv3q0sT +9M9rH7MTQPdqvzMl122JcZST75GzFJFl0XdSHd5PAh2mV8qYak5NYNnwA41UQVIa ++xqhSu44liSeZWUfRdhrQ/Nb01KV8lLAs11Sz787xkdF4ad25V/Rtg/s4UXt35K3 +klGOBwDnzPgHK/OK2PescI5Ve1z4x1C2bkGze+gk/3IcfGJwKZDfKzTtqkZ0MgpN +7RGghjkH4wpFmuswFFZRyV+s7jXYpxAesElDSmPJ0O07O4lQXQMROE+a2OCcm0eF +3+Cr6qxGtOp1oYMOVH0vOLYTpwOkAM12/qm7/fYuVPBQtVpTojjV5GDl2uGq7p0o +h9hyWnLeNRbAha0px6rXcF9wLwU5n7mH75mq5clps3sP1q1/VtP/Fr84Lm7OGke4 +9eD+tPNCdRx78RNWzhkdQxHk/b22LCn1v6p1Q0qBco9vw6eawEkz1qwAjQARAQAB +tDFXYXp1aC5jb20gKFdhenVoIFNpZ25pbmcgS2V5KSA8c3VwcG9ydEB3YXp1aC5j +b20+iQI9BBMBCAAnBQJXnsmMAhsDBQkFo5qABQsJCAcDBRUKCQgLBRYCAwEAAh4B +AheAAAoJEJaz7l8pERFFHEsQAIaslejcW2NgjgOZuvn1Bht4JFMbCIPOekg4Z5yF +binRz0wmA7JNaawDHTBYa6L+A2Xneu/LmuRjFRMesqopUukVeGQgHBXbGMzY46eI +rqq/xgvgWzHSbWweiOX0nn+exbEAM5IyW+efkWNz0e8xM1LcxdYZxkVOqFqkp3Wv +J9QUKw6z9ifUOx++G8UO307O3hT2f+x4MUoGZeOF4q1fNy/VyBS2lMg2HF7GWy2y +kjbSe0p2VOFGEZLuu2f5tpPNth9UJiTliZKmgSk/zbKYmSjiVY2eDqNJ4qjuqes0 +vhpUaBjA+DgkEWUrUVXG5yfQDzTiYIF84LknjSJBYSLZ4ABsMjNO+GApiFPcih+B +Xc9Kx7E9RNsNTDqvx40y+xmxDOzVIssXeKqwO8r5IdG3K7dkt2Vkc/7oHOpcKwE5 +8uASMPiqqMo+t1RVa6Spckp3Zz8REILbotnnVwDIwo2HmgASirMGUcttEJzubaIa +Mv43GKs8RUH9s5NenC02lfZG7D8WQCz5ZH7yEWrt5bCaQRNDXjhsYE17SZ/ToHi3 +OpWu050ECWOHdxlXNG3dOWIdFDdBJM7UfUNSSOe2Y5RLsWfwvMFGbfpdlgJcMSDV +X+ienkrtXhBteTu0dwPu6HZTFOjSftvtAo0VIqGQrKMvKelkkdNGdDFLQw2mUDcw +EQj6uQINBFeeyYwBEADD1Y3zW5OrnYZ6ghTd5PXDAMB8Z1ienmnb2IUzLM+i0yE2 +TpKSP/XYCTBhFa390rYgFO2lbLDVsiz7Txd94nHrdWXGEQfwrbxsvdlLLWk7iN8l +Fb4B60OfRi3yoR96a/kIPNa0x26+n79LtDuWZ/DTq5JSHztdd9F1sr3h8i5zYmtv +luj99ZorpwYejbBVUm0+gP0ioaXM37uO56UFVQk3po9GaS+GtLnlgoE5volgNYyO +rkeIua4uZVsifREkHCKoLJip6P7S3kTyfrpiSLhouEZ7kV1lbMbFgvHXyjm+/AIx +HIBy+H+e+HNt5gZzTKUJsuBjx44+4jYsOR67EjOdtPOpgiuJXhedzShEO6rbu/O4 +wM1rX45ZXDYa2FGblHCQ/VaS0ttFtztk91xwlWvjTR8vGvp5tIfCi+1GixPRQpbN +Y/oq8Kv4A7vB3JlJscJCljvRgaX0gTBzlaF6Gq0FdcWEl5F1zvsWCSc/Fv5WrUPY +5mG0m69YUTeVO6cZS1aiu9Qh3QAT/7NbUuGXIaAxKnu+kkjLSz+nTTlOyvbG7BVF +a6sDmv48Wqicebkc/rCtO4g8lO7KoA2xC/K/6PAxDrLkVyw8WPsAendmezNfHU+V +32pvWoQoQqu8ysoaEYc/j9fN4H3mEBCN3QUJYCugmHP0pu7VtpWwwMUqcGeUVwAR +AQABiQIlBBgBCAAPBQJXnsmMAhsMBQkFo5qAAAoJEJaz7l8pERFFz8IP/jfBxJSB +iOw+uML+C4aeYxuHSdxmSsrJclYjkw7Asha/fm4Kkve00YAW8TGxwH2kgS72ooNJ +1Q7hUxNbVyrJjQDSMkRKwghmrPnUM3UyHmE0dq+G2NhaPdFo8rKifLOPgwaWAfSV +wgMTK86o0kqRbGpXgVIG5eRwv2FcxM3xGfy7sub07J2VEz7Ba6rYQ3NTbPK42AtV ++wRJDXcgS7y6ios4XQtSbIB5f6GI56zVlwfRd3hovV9ZAIJQ6DKM31wD6Kt/pRun +DjwMZu0/82JMoqmxX/00sNdDT1S13guCfl1WhBu7y1ja9MUX5OpUzyEKg5sxme+L +iY2Rhs6CjmbTm8ER4Uj8ydKyVTy8zbumbB6T8IwCAbEMtPxm6pKh/tgLpoJ+Bj0y +AsGjmhV7R6PKZSDXg7/qQI98iC6DtWc9ibC/QuHLcvm3hz40mBgXAemPJygpxGst +mVtU7O3oHw9cIUpkbMuVqSxgPFmSSq5vEYkka1CYeg8bOz6aCTuO5J0GDlLrpjtx +6lyImbZAF/8zKnW19aq5lshT2qJlTQlZRwwDZX5rONhA6T8IEUnUyD4rAIQFwfJ+ +gsXa4ojD/tA9NLdiNeyEcNfyX3FZwXWCtVLXflzdRN293FKamcdnMjVRjkCnp7iu +7eO7nMgcRoWddeU+2aJFqCoQtKCp/5EKhFey +=UIVm +-----END PGP PUBLIC KEY BLOCK----- +EOF + + # Proxy is hating on me.. Lets just set it manually + echo "[salt-latest]" > /etc/yum.repos.d/salt-latest.repo + echo "name=SaltStack Latest Release Channel for RHEL/Centos \$releasever" >> /etc/yum.repos.d/salt-latest.repo + echo "baseurl=https://repo.saltstack.com/py3/redhat/7/\$basearch/latest" >> /etc/yum.repos.d/salt-latest.repo + echo "failovermethod=priority" >> /etc/yum.repos.d/salt-latest.repo + echo "enabled=1" >> /etc/yum.repos.d/salt-latest.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/salt-latest.repo + echo "gpgkey=file:///etc/pki/rpm-gpg/saltstack-signing-key" >> /etc/yum.repos.d/salt-latest.repo + + # Proxy is hating on me.. Lets just set it manually + echo "[salt-2019.2]" > /etc/yum.repos.d/salt-2019-2.repo + echo "name=SaltStack Latest Release Channel for RHEL/Centos \$releasever" >> /etc/yum.repos.d/salt-2019-2.repo + echo "baseurl=https://repo.saltstack.com/py3/redhat/7/\$basearch/2019.2" >> /etc/yum.repos.d/salt-2019-2.repo + echo "failovermethod=priority" >> /etc/yum.repos.d/salt-2019-2.repo + echo "enabled=1" >> /etc/yum.repos.d/salt-2019-2.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/salt-2019-2.repo + echo "gpgkey=file:///etc/pki/rpm-gpg/saltstack-signing-key" >> /etc/yum.repos.d/salt-2019-2.repo + + cat > /etc/yum.repos.d/wazuh.repo <<\EOF +[wazuh_repo] +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/GPG-KEY-WAZUH +enabled=1 +name=Wazuh repository +baseurl=https://packages.wazuh.com/3.x/yum/ +protect=1 +EOF + else + yum -y install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm + cp /etc/yum.repos.d/salt-latest.repo /etc/yum.repos.d/salt-2019-2.repo + sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-2019-2.repo +cat > /etc/yum.repos.d/wazuh.repo <<\EOF +[wazuh_repo] +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/GPG-KEY-WAZUH +enabled=1 +name=Wazuh repository +baseurl=https://packages.wazuh.com/3.x/yum/ +protect=1 +EOF + fi + fi + + yum clean expire-cache + yum -y install epel-release salt-minion-2019.2.2 yum-utils device-mapper-persistent-data lvm2 openssl + yum -y update exclude=salt* + systemctl enable salt-minion + + if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + yum -y install salt-master-2019.2.2 python3 python36-m2crypto salt-minion-2019.2.2 python36-dateutil python36-mysql python36-docker + systemctl enable salt-master + else + yum -y install salt-minion-2019.2.2 python3 python36-m2crypto python36-dateutil python36-docker + fi + echo "exclude=salt*" >> /etc/yum.conf + + else + ADDUSER=useradd + 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 + apt-get -y install ca-certificates curl software-properties-common apt-transport-https openssl >> $SETUPLOG 2>&1 + + # Grab the version from the os-release file + UVER=$(grep VERSION_ID /etc/os-release | awk -F '[ "]' '{print $2}') + + # Nasty hack but required for now + if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + + #echo "Using pip3 to install python-dateutil for salt" + #pip3 install python-dateutil + # Install the repo for salt + wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add - + wget --inet4-only -O - https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/2019.2/SALTSTACK-GPG-KEY.pub | apt-key add - + echo "deb http://repo.saltstack.com/py3/ubuntu/$UVER/amd64/latest xenial main" > /etc/apt/sources.list.d/saltstack.list + echo "deb http://repo.saltstack.com/py3/ubuntu/$UVER/amd64/2019.2 xenial main" > /etc/apt/sources.list.d/saltstack2019.list + + # Lets get the docker repo added + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + + # Create a place for the keys + mkdir -p /opt/so/gpg + wget --inet4-only -O /opt/so/gpg/SALTSTACK-GPG-KEY.pub https://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest/SALTSTACK-GPG-KEY.pub + wget --inet4-only -O /opt/so/gpg/docker.pub https://download.docker.com/linux/ubuntu/gpg + wget --inet4-only -O /opt/so/gpg/GPG-KEY-WAZUH https://packages.wazuh.com/key/GPG-KEY-WAZUH + + # Get key and install wazuh + curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | apt-key add - + # Add repo + echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list + + # Initialize the new repos + apt-get update >> $SETUPLOG 2>&1 + # Need to add python packages here + apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 python3-dateutil >> $SETUPLOG 2>&1 + apt-mark hold salt-minion salt-common + + else + + # Copy down the gpg keys and install them from the master + mkdir $TMP/gpg + scp socore@$MSRV:/opt/so/gpg/* $TMP/gpg + apt-key add $TMP/gpg/SALTSTACK-GPG-KEY.pub + apt-key add $TMP/gpg/GPG-KEY-WAZUH + echo "deb http://repo.saltstack.com/apt/ubuntu/$UVER/amd64/latest xenial main" > /etc/apt/sources.list.d/saltstack.list + echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list + # Initialize the new repos + apt-get update >> $SETUPLOG 2>&1 + # Need to add python dateutil here + apt-get -y install salt-minion=2019.2.2+ds-1 salt-common=2019.2.2+ds-1 >> $SETUPLOG 2>&1 + apt-mark hold salt-minion salt-common + + fi + + fi + +} + +salt_checkin() { + # Master State to Fix Mine Usage + if [ $INSTALLTYPE == 'MASTERONLY' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + echo "Building Certificate Authority" + salt-call state.apply ca >> $SETUPLOG 2>&1 + echo " *** Restarting Salt to fix any SSL errors. ***" + service salt-master restart >> $SETUPLOG 2>&1 + sleep 5 + service salt-minion restart >> $SETUPLOG 2>&1 + sleep 15 + echo " Applyng a mine hack " + sudo salt '*' mine.send x509.get_pem_entries glob_path=/etc/pki/ca.crt >> $SETUPLOG 2>&1 + echo " Applying SSL state " + salt-call state.apply ssl >> $SETUPLOG 2>&1 + echo "Still Working... Hang in there" + #salt-call state.highstate + + else + + # Run Checkin + salt-call state.apply ca >> $SETUPLOG 2>&1 + salt-call state.apply ssl >> $SETUPLOG 2>&1 + #salt-call state.highstate >> $SETUPLOG 2>&1 + + fi + +} + +salt_checkin_message() { + + # Warn the user that this might take a while + echo "####################################################" + echo "## ##" + echo "## Applying and Installing everything ##" + echo "## (This will take a while) ##" + echo "## ##" + echo "####################################################" + +} + +salt_firstcheckin() { + + #First Checkin + salt-call state.highstate >> $SETUPLOG 2>&1 + +} + +salt_master_directories() { + + # Create salt paster directories + mkdir -p /opt/so/saltstack/salt + mkdir -p /opt/so/saltstack/pillar + + # Copy over the salt code and templates + cp -R pillar/* /opt/so/saltstack/pillar/ + chmod +x /opt/so/saltstack/pillar/firewall/addfirewall.sh + chmod +x /opt/so/saltstack/pillar/data/addtotab.sh + cp -R salt/* /opt/so/saltstack/salt/ + +} + +salt_install_mysql_deps() { + + if [ $OS == 'centos' ]; then + yum -y install mariadb-devel + elif [ $OS == 'ubuntu' ]; then + apt-get -y install libmysqlclient-dev python3-mysqldb + fi + +} + +sensor_pillar() { + + SENSORPILLARPATH=$TMP/pillar/sensors + if [ ! -d $SENSORPILLARPATH ]; then + mkdir -p $SENSORPILLARPATH + fi + + # Create the sensor pillar + touch $SENSORPILLARPATH/$MINION_ID.sls + echo "sensor:" > $SENSORPILLARPATH/$MINION_ID.sls + echo " interface: bond0" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " mainip: $MAINIP" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " mainint: $MAININT" >> $SENSORPILLARPATH/$MINION_ID.sls + if [ $NSMSETUP == 'ADVANCED' ]; then + echo " bro_pins:" >> $SENSORPILLARPATH/$MINION_ID.sls + for PIN in $BROPINS; do + PIN=$(echo $PIN | cut -d\" -f2) + echo " - $PIN" >> $SENSORPILLARPATH/$MINION_ID.sls + done + echo " suripins:" >> $SENSORPILLARPATH/$MINION_ID.sls + for SPIN in $SURIPINS; do + SPIN=$(echo $SPIN | cut -d\" -f2) + echo " - $SPIN" >> $SENSORPILLARPATH/$MINION_ID.sls + done + else + echo " bro_lbprocs: $BASICBRO" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " suriprocs: $BASICSURI" >> $SENSORPILLARPATH/$MINION_ID.sls + fi + echo " brobpf:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " pcapbpf:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " nidsbpf:" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " master: $MSRV" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " mtu: $MTU" >> $SENSORPILLARPATH/$MINION_ID.sls + if [ $HNSENSOR != 'inherit' ]; then + echo " hnsensor: $HNSENSOR" >> $SENSORPILLARPATH/$MINION_ID.sls + fi + echo " access_key: $ACCESS_KEY" >> $SENSORPILLARPATH/$MINION_ID.sls + echo " access_secret: $ACCESS_SECRET" >> $SENSORPILLARPATH/$MINION_ID.sls + +} + +set_environment_var() { + + echo "Setting environment variable: $1" + + export "$1" + echo "$1" >> /etc/environment + +} + +set_hostname() { + + hostnamectl set-hostname --static $HOSTNAME + echo "127.0.0.1 $HOSTNAME $HOSTNAME.localdomain localhost localhost.localdomain localhost4 localhost4.localdomain" > /etc/hosts + echo "::1 localhost localhost.localdomain localhost6 localhost6.localdomain6" >> /etc/hosts + echo $HOSTNAME > /etc/hostname + if [ $INSTALLTYPE != 'MASTERONLY' ] || [ $INSTALLTYPE != 'EVALMODE' ]; then + if [[ $TESTHOST = *"not found"* ]] || [[ $TESTHOST = *"connection timed out"* ]]; then + if ! grep -q $MSRVIP /etc/hosts; then + echo "$MSRVIP $MSRV" >> /etc/hosts + fi + fi + fi + +} + +set_initial_firewall_policy() { + + get_main_ip + if [ $INSTALLTYPE == 'MASTERONLY' ]; then + printf " - $MAINIP\n" >> /opt/so/saltstack/pillar/firewall/minions.sls + printf " - $MAINIP\n" >> /opt/so/saltstack/pillar/firewall/masterfw.sls + /opt/so/saltstack/pillar/data/addtotab.sh mastertab $MINION_ID $MAINIP $CPUCORES $RANDOMUID $MAININT $FSROOT $FSNSM + fi + + if [ $INSTALLTYPE == 'EVALMODE' ]; then + printf " - $MAINIP\n" >> /opt/so/saltstack/pillar/firewall/minions.sls + printf " - $MAINIP\n" >> /opt/so/saltstack/pillar/firewall/masterfw.sls + printf " - $MAINIP\n" >> /opt/so/saltstack/pillar/firewall/forward_nodes.sls + printf " - $MAINIP\n" >> /opt/so/saltstack/pillar/firewall/storage_nodes.sls + /opt/so/saltstack/pillar/data/addtotab.sh evaltab $MINION_ID $MAINIP $CPUCORES $RANDOMUID $MAININT $FSROOT $FSNSM bond0 + fi + + if [ $INSTALLTYPE == 'SENSORONLY' ]; then + ssh -i /root/.ssh/so.key socore@$MSRV sudo /opt/so/saltstack/pillar/firewall/addfirewall.sh minions $MAINIP + ssh -i /root/.ssh/so.key socore@$MSRV sudo /opt/so/saltstack/pillar/firewall/addfirewall.sh forward_nodes $MAINIP + ssh -i /root/.ssh/so.key socore@$MSRV sudo /opt/so/saltstack/pillar/data/addtotab.sh sensorstab $MINION_ID $MAINIP $CPUCORES $RANDOMUID $MAININT $FSROOT $FSNSM bond0 + fi + + if [ $INSTALLTYPE == 'STORAGENODE' ]; then + ssh -i /root/.ssh/so.key socore@$MSRV sudo /opt/so/saltstack/pillar/firewall/addfirewall.sh minions $MAINIP + ssh -i /root/.ssh/so.key socore@$MSRV sudo /opt/so/saltstack/pillar/firewall/addfirewall.sh storage_nodes $MAINIP + ssh -i /root/.ssh/so.key socore@$MSRV sudo /opt/so/saltstack/pillar/data/addtotab.sh nodestab $MINION_ID $MAINIP $CPUCORES $RANDOMUID $MAININT $FSROOT $FSNSM + fi + + if [ $INSTALLTYPE == 'PARSINGNODE' ]; then + echo "blah" + fi + + if [ $INSTALLTYPE == 'HOTNODE' ]; then + echo "blah" + fi + + if [ $INSTALLTYPE == 'WARMNODE' ]; then + echo "blah" + fi + +} + +set_node_type() { + + # Determine the node type based on whiplash choice + if [ $INSTALLTYPE == 'STORAGENODE' ] || [ $INSTALLTYPE == 'EVALMODE' ]; then + NODETYPE='storage' + fi + if [ $INSTALLTYPE == 'PARSINGNODE' ]; then + NODETYPE='parser' + fi + if [ $INSTALLTYPE == 'HOTNODE' ]; then + NODETYPE='hot' + fi + if [ $INSTALLTYPE == 'WARMNODE' ]; then + NODETYPE='warm' + fi + +} + +set_updates() { + echo "MASTERUPDATES is $MASTERUPDATES" + if [ $MASTERUPDATES == 'MASTER' ]; then + if [ $OS == 'centos' ]; then + if ! grep -q $MSRV /etc/yum.conf; then + echo "proxy=http://$MSRV:3142" >> /etc/yum.conf + fi + + else + + # Set it up so the updates roll through the master + echo "Acquire::http::Proxy \"http://$MSRV:3142\";" > /etc/apt/apt.conf.d/00Proxy + echo "Acquire::https::Proxy \"http://$MSRV:3142\";" >> /etc/apt/apt.conf.d/00Proxy + + fi + fi +} + +update_sudoers() { + + if ! grep -qE '^socore\ ALL=\(ALL\)\ NOPASSWD:(\/usr\/bin\/salt\-key|\/opt\/so\/saltstack)' /etc/sudoers; then + # Update Sudoers so that socore can accept keys without a password + echo "socore ALL=(ALL) NOPASSWD:/usr/bin/salt-key" | sudo tee -a /etc/sudoers + echo "socore ALL=(ALL) NOPASSWD:/opt/so/saltstack/pillar/firewall/addfirewall.sh" | sudo tee -a /etc/sudoers + echo "socore ALL=(ALL) NOPASSWD:/opt/so/saltstack/pillar/data/addtotab.sh" | sudo tee -a /etc/sudoers + else + echo "User socore already granted sudo privileges" + fi + +} diff --git a/setup/so-setup.sh b/setup/so-setup.sh new file mode 100644 index 000000000..837cf6d6e --- /dev/null +++ b/setup/so-setup.sh @@ -0,0 +1,627 @@ +#!/bin/bash + +# Copyright 2014,2015,2016,2017,2018,2019 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 . + +# Source the other pieces of the setup +source functions.sh +source whiplash.sh + +# Global Variables +HOSTNAME=$(cat /etc/hostname) +MINION_ID=$(echo $HOSTNAME | awk -F. {'print $1'}) +TOTAL_MEM=`grep MemTotal /proc/meminfo | awk '{print $2}' | sed -r 's/.{3}$//'` +NICS=$(ip link | awk -F: '$0 !~ "lo|vir|veth|br|docker|wl|^[^0-9]"{print $2 " \"" "Interface" "\"" " OFF"}') +CPUCORES=$(cat /proc/cpuinfo | grep processor | wc -l) +LISTCORES=$(cat /proc/cpuinfo | grep processor | awk '{print $3 " \"" "core" "\""}') +RANDOMUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1) +NODE_ES_PORT="9200" +SETUPLOG="/root/sosetup.log" +# End Global Variables + +# Reset the Install Log +date -u >$SETUPLOG 2>&1 + +# Check for prerequisites +got_root +detect_os + +if [ $OS == ubuntu ]; then + # Override the Ubuntu whiptail color pallete + update-alternatives --set newt-palette /etc/newt/palette.original +fi + +# Question Time +if (whiptail_you_sure); then + + # Create a temp dir to get started + install_prep + + # Determine if this is a network install or ISO install + + # Let folks know they need their management interface already set up. + whiptail_network_notice + + # Set the hostname to reduce errors + whiptail_set_hostname + + # Go ahead and gen the keys so we can use them for any sensor type - Disabled for now + #minio_generate_keys + + # What kind of install are we doing? + whiptail_install_type + + # How do we want to handle OS patching? manual, auto or scheduled days and hours + whiptail_patch_schedule + case $PATCHSCHEDULE in + 'New Schedule') + whiptail_patch_schedule_select_days + whiptail_patch_schedule_select_hours + whiptail_patch_name_new_schedule + patch_schedule_os_new + ;; + 'Import Schedule') + whiptail_patch_schedule_import + ;; + Automatic) + PATCHSCHEDULENAME=auto + ;; + Manual) + PATCHSCHEDULENAME=manual + ;; + esac + + #################### + ## Master ## + #################### + + if [ $INSTALLTYPE == 'MASTERONLY' ]; then + + # Would you like to do an advanced install? + whiptail_master_adv + + # Pick the Management NIC + whiptail_management_nic + + # Choose Zeek or Community NSM + whiptail_bro_version + + # Select Snort or Suricata + whiptail_nids + + # Snag the HOME_NET + whiptail_homenet_master + + # Pick your Ruleset + whiptail_rule_setup + + # Get the code if it isn't ET Open + if [ $RULESETUP != 'ETOPEN' ]; then + # Get the code + whiptail_oinkcode + fi + + # Find out how to handle updates + whiptail_master_updates + whiptail_enable_components + process_components + + # Do Advacned Setup if they chose it + if [ $MASTERADV == 'ADVANCED' ]; then + # Ask which bro logs to enable - Need to add Suricata check + if [ $BROVERSION != 'SURICATA' ]; then + whiptail_master_adv_service_brologs + fi + fi + + whiptail_create_socore_user + SCMATCH=no + while [ $SCMATCH != yes ]; do + whiptail_create_socore_user_password1 + whiptail_create_socore_user_password2 + check_socore_pass + done + + # Last Chance to back out + whiptail_make_changes + set_hostname + generate_passwords + auth_pillar + clear_master + mkdir -p /nsm + get_filesystem_root + get_filesystem_nsm + # Enable Bro Logs + bro_logs_enabled + + # Figure out the main IP address + get_main_ip + + # Add the user so we can sit back and relax + #echo "" + #echo "**** Please set a password for socore. You will use this password when setting up other Nodes/Sensors" + #echo "" + add_socore_user_master + + # Install salt and dependencies + { + sleep 0.5 + #install_pip3 >> $SETUPLOG 2>&1 + echo -e "XXX\n1\nInstalling and configuring Salt... \nXXX" + echo " ** Installing Salt and Dependencies **" >> $SETUPLOG + salt_install_mysql_deps >> $SETUPLOG 2>&1 + saltify >> $SETUPLOG 2>&1 + echo -e "XXX\n5\nInstalling Docker... \nXXX" + docker_install >> $SETUPLOG 2>&1 + echo -e "XXX\n10\nConfiguring Salt Master... \nXXX" + echo " ** Configuring Minion **" >> $SETUPLOG + configure_minion master >> $SETUPLOG 2>&1 + echo " ** Installing Salt Master **" >> $SETUPLOG + install_master >> $SETUPLOG 2>&1 + salt_master_directories >> $SETUPLOG 2>&1 + update_sudoers >> $SETUPLOG 2>&1 + chown_salt_master >> $SETUPLOG 2>&1 + es_heapsize >> $SETUPLOG 2>&1 + ls_heapsize >> $SETUPLOG 2>&1 + echo -e "XXX\n25\nConfiguring Default Pillars... \nXXX" + master_static >> $SETUPLOG 2>&1 + echo "** Generating the master pillar **" >> $SETUPLOG + 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\n24\nCopying Minion Pillars to Master... \nXXX" + copy_minion_tmp_files >> $SETUPLOG 2>&1 + # Do a checkin to push the key up + echo "** Pushing the key up to Master **" >> $SETUPLOG + salt_firstcheckin >> $SETUPLOG 2>&1 + # Accept the Master Key + echo "** Accepting the key on the master **" >> $SETUPLOG + accept_salt_key_local >> $SETUPLOG 2>&1 + echo -e "XXX\n35\nConfiguring Firewall... \nXXX" + # Open the firewall + echo "** Setting the initial firewall policy **" >> $SETUPLOG + set_initial_firewall_policy >> $SETUPLOG 2>&1 + # Do the big checkin but first let them know it will take a bit. + echo -e "XXX\n40\nGenerating CA... \nXXX" + salt_checkin >> $SETUPLOG 2>&1 + salt-call state.apply ca >> $SETUPLOG 2>&1 + salt-call state.apply ssl >> $SETUPLOG 2>&1 + echo -e "XXX\n43\nInstalling Common Components... \nXXX" + salt-call state.apply common >> $SETUPLOG 2>&1 + echo -e "XXX\n45\nApplying firewall rules... \nXXX" + salt-call state.apply firewall >> $SETUPLOG 2>&1 + salt-call state.apply master >> $SETUPLOG 2>&1 + salt-call state.apply idstools >> $SETUPLOG 2>&1 + echo -e "XXX\n40\nInstalling Redis... \nXXX" + salt-call state.apply redis >> $SETUPLOG 2>&1 + if [[ $OSQUERY == '1' ]]; then + echo -e "XXX\n41\nInstalling MySQL... \nXXX" + salt-call state.apply mysql >> $SETUPLOG 2>&1 + fi + echo -e "XXX\n45\nInstalling Elastic Components... \nXXX" + salt-call state.apply elasticsearch >> $SETUPLOG 2>&1 + salt-call state.apply logstash >> $SETUPLOG 2>&1 + salt-call state.apply kibana >> $SETUPLOG 2>&1 + salt-call state.apply elastalert >> $SETUPLOG 2>&1 + if [[ $WAZUH == '1' ]]; then + echo -e "XXX\n68\nInstalling Wazuh... \nXXX" + salt-call state.apply wazuh >> $SETUPLOG 2>&1 + fi + echo -e "XXX\n75\nInstalling Filebeat... \nXXX" + salt-call state.apply filebeat >> $SETUPLOG 2>&1 + salt-call state.apply utility >> $SETUPLOG 2>&1 + salt-call state.apply schedule >> $SETUPLOG 2>&1 + if [[ $OSQUERY == '1' ]]; then + echo -e "XXX\n79\nInstalling Fleet... \nXXX" + salt-call state.apply fleet >> $SETUPLOG 2>&1 + salt-call state.apply launcher >> $SETUPLOG 2>&1 + fi + echo -e "XXX\n85\nConfiguring SOctopus... \nXXX" + salt-call state.apply soctopus >> $SETUPLOG 2>&1 + if [[ $THEHIVE == '1' ]]; then + echo -e "XXX\n87\nInstalling TheHive... \nXXX" + salt-call state.apply hive >> $SETUPLOG 2>&1 + fi + if [[ $PLAYBOOK == '1' ]]; then + echo -e "XXX\n89\nInstalling Playbook... \nXXX" + salt-call state.apply playbook >> $SETUPLOG 2>&1 + fi + echo -e "XXX\n75\nEnabling Checking at Boot... \nXXX" + checkin_at_boot >> $SETUPLOG 2>&1 + echo -e "XXX\n95\nVerifying Install... \nXXX" + salt-call state.highstate >> $SETUPLOG 2>&1 + + } |whiptail --title "Hybrid Hunter Install" --gauge "Please wait while installing" 6 60 0 + GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') + if [[ $GOODSETUP == '0' ]]; then + whiptail_setup_complete + if [[ $THEHIVE == '1' ]]; then + check_hive_init_then_reboot + else + shutdown -r now + fi + else + whiptail_setup_failed + shutdown -r now + fi + + fi + + #################### + ## Sensor ## + #################### + + if [ $INSTALLTYPE == 'SENSORONLY' ]; then + whiptail_management_nic + filter_nics + whiptail_bond_nics + whiptail_management_server + whiptail_master_updates + set_updates + whiptail_homenet_sensor + whiptail_sensor_config + # Calculate lbprocs so we can call it in the prompts + calculate_useable_cores + if [ $NSMSETUP == 'ADVANCED' ]; then + whiptail_bro_pins + whiptail_suricata_pins + whiptail_bond_nics_mtu + else + whiptail_basic_bro + whiptail_basic_suri + fi + whiptail_make_changes + set_hostname + clear_master + mkdir -p /nsm + get_filesystem_root + get_filesystem_nsm + copy_ssh_key + { + sleep 0.5 + echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" + set_initial_firewall_policy >> $SETUPLOG 2>&1 + #echo -e "XXX\n1\nInstalling pip3... \nXXX" + #install_pip3 >> $SETUPLOG 2>&1 + echo -e "XXX\n3\nCreating Bond Interface... \nXXX" + network_setup >> $SETUPLOG 2>&1 + echo -e "XXX\n4\nGenerating Sensor Pillar... \nXXX" + sensor_pillar >> $SETUPLOG 2>&1 + echo "** Generating the patch pillar **" >> $SETUPLOG + patch_pillar >> $SETUPLOG 2>&1 + echo -e "XXX\n5\nInstalling Salt Components... \nXXX" + saltify >> $SETUPLOG 2>&1 + echo -e "XXX\n20\nInstalling Docker... \nXXX" + docker_install >> $SETUPLOG 2>&1 + echo -e "XXX\n22\nConfiguring Salt Minion... \nXXX" + configure_minion sensor >> $SETUPLOG 2>&1 + echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" + copy_minion_tmp_files >> $SETUPLOG 2>&1 + echo -e "XXX\n25\nSending Salt Key to Master... \nXXX" + salt_firstcheckin >> $SETUPLOG 2>&1 + echo -e "XXX\n26\nTelling the Master to Accept Key... \nXXX" + # Accept the Salt Key + accept_salt_key_remote >> $SETUPLOG 2>&1 + echo -e "XXX\n27\nApplying SSL Certificates... \nXXX" + salt-call state.apply ca >> $SETUPLOG 2>&1 + salt-call state.apply ssl >> $SETUPLOG 2>&1 + echo -e "XXX\n35\nInstalling Core Components... \nXXX" + salt-call state.apply common >> $SETUPLOG 2>&1 + salt-call state.apply firewall >> $SETUPLOG 2>&1 + echo -e "XXX\n50\nInstalling PCAP... \nXXX" + salt-call state.apply pcap >> $SETUPLOG 2>&1 + echo -e "XXX\n60\nInstalling IDS components... \nXXX" + salt-call state.apply suricata >> $SETUPLOG 2>&1 + echo -e "XXX\n80\nVerifying Install... \nXXX" + salt-call state.highstate >> $SETUPLOG 2>&1 + checkin_at_boot >> $SETUPLOG 2>&1 + } |whiptail --title "Hybrid Hunter Install" --gauge "Please wait while installing" 6 60 0 + GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') + if [[ $GOODSETUP == '0' ]]; then + whiptail_setup_complete + shutdown -r now + else + whiptail_setup_failed + shutdown -r now + fi + fi + + ####################### + ## Eval Mode ## + ####################### + + if [ $INSTALLTYPE == 'EVALMODE' ]; then + # Select the management NIC + whiptail_management_nic + + # Filter out the management NIC + filter_nics + + # Select which NICs are in the bond + whiptail_bond_nics + + # Snag the HOME_NET + whiptail_homenet_master + whiptail_eval_adv_warning + whiptail_enable_components + + # Set a bunch of stuff since this is eval + es_heapsize + ls_heapsize + NODE_ES_HEAP_SIZE="600m" + NODE_LS_HEAP_SIZE="500m" + LSPIPELINEWORKERS=1 + LSPIPELINEBATCH=125 + LSINPUTTHREADS=1 + LSINPUTBATCHCOUNT=125 + RULESETUP=ETOPEN + NSMSETUP=BASIC + NIDS=Suricata + BROVERSION=ZEEK + CURCLOSEDAYS=30 + process_components + whiptail_create_socore_user + SCMATCH=no + while [ $SCMATCH != yes ]; do + whiptail_create_socore_user_password1 + whiptail_create_socore_user_password2 + check_socore_pass + done + whiptail_make_changes + set_hostname + generate_passwords + auth_pillar + clear_master + mkdir -p /nsm + get_filesystem_root + get_filesystem_nsm + get_log_size_limit + get_main_ip + # Add the user so we can sit back and relax + add_socore_user_master + { + sleep 0.5 + echo -e "XXX\n0\nCreating Bond Interface... \nXXX" + network_setup >> $SETUPLOG 2>&1 + #install_pip3 >> $SETUPLOG 2>&1 + echo -e "XXX\n1\nInstalling mysql dependencies for saltstack... \nXXX" + salt_install_mysql_deps >> $SETUPLOG 2>&1 + echo -e "XXX\n1\nInstalling saltstack... \nXXX" + saltify >> $SETUPLOG 2>&1 + echo -e "XXX\n3\nInstalling docker... \nXXX" + docker_install >> $SETUPLOG 2>&1 + echo -e "XXX\n5\nInstalling master code... \nXXX" + install_master >> $SETUPLOG 2>&1 + echo -e "XXX\n6\nCopying salt code... \nXXX" + salt_master_directories >> $SETUPLOG 2>&1 + echo -e "XXX\n6\nupdating suduers... \nXXX" + update_sudoers >> $SETUPLOG 2>&1 + echo -e "XXX\n7\nFixing some permissions... \nXXX" + chown_salt_master >> $SETUPLOG 2>&1 + echo -e "XXX\n7\nCreating the static pillar... \nXXX" + # Set the static values + master_static >> $SETUPLOG 2>&1 + echo -e "XXX\n7\nCreating the master pillar... \nXXX" + master_pillar >> $SETUPLOG 2>&1 + echo "** Generating the patch pillar **" >> $SETUPLOG + patch_pillar >> $SETUPLOG 2>&1 + echo -e "XXX\n7\nConfiguring minion... \nXXX" + configure_minion eval >> $SETUPLOG 2>&1 + echo -e "XXX\n7\nSetting the node type to eval... \nXXX" + set_node_type >> $SETUPLOG 2>&1 + echo -e "XXX\n7\nStorage node pillar... \nXXX" + node_pillar >> $SETUPLOG 2>&1 + echo -e "XXX\n8\nCreating firewall policies... \nXXX" + set_initial_firewall_policy >> $SETUPLOG 2>&1 + echo -e "XXX\n24\nCopying Minion Pillars to Master... \nXXX" + copy_minion_tmp_files >> $SETUPLOG 2>&1 + echo -e "XXX\n10\nRegistering agent... \nXXX" + salt_firstcheckin >> $SETUPLOG 2>&1 + echo -e "XXX\n11\nAccepting Agent... \nXXX" + accept_salt_key_local >> $SETUPLOG 2>&1 + echo -e "XXX\n12\nRunning the SSL states... \nXXX" + salt_checkin >> $SETUPLOG 2>&1 + salt-call state.apply ca >> $SETUPLOG 2>&1 + salt-call state.apply ssl >> $SETUPLOG 2>&1 + echo -e "XXX\n15\nInstalling core components... \nXXX" + salt-call state.apply common >> $SETUPLOG 2>&1 + echo -e "XXX\n18\nInitializing firewall rules... \nXXX" + salt-call state.apply firewall >> $SETUPLOG 2>&1 + echo -e "XXX\n25\nInstalling master components... \nXXX" + salt-call state.apply master >> $SETUPLOG 2>&1 + salt-call state.apply idstools >> $SETUPLOG 2>&1 + if [[ $OSQUERY == '1' ]]; then + salt-call state.apply mysql >> $SETUPLOG 2>&1 + fi + echo -e "XXX\n35\nInstalling ElasticSearch... \nXXX" + salt-call state.apply elasticsearch >> $SETUPLOG 2>&1 + echo -e "XXX\n40\nInstalling Logstash... \nXXX" + salt-call state.apply logstash >> $SETUPLOG 2>&1 + echo -e "XXX\n45\nInstalling Kibana... \nXXX" + salt-call state.apply kibana >> $SETUPLOG 2>&1 + echo -e "XXX\n50\nInstalling pcap... \nXXX" + salt-call state.apply pcap >> $SETUPLOG 2>&1 + echo -e "XXX\n52\nInstalling Suricata... \nXXX" + salt-call state.apply suricata >> $SETUPLOG 2>&1 + echo -e "XXX\n54\nInstalling Zeek... \nXXX" + salt-call state.apply bro >> $SETUPLOG 2>&1 + echo -e "XXX\n56\nInstalling curator... \nXXX" + salt-call state.apply curator >> $SETUPLOG 2>&1 + echo -e "XXX\n58\nInstalling elastalert... \nXXX" + salt-call state.apply elastalert >> $SETUPLOG 2>&1 + if [[ $OSQUERY == '1' ]]; then + echo -e "XXX\n60\nInstalling fleet... \nXXX" + salt-call state.apply fleet >> $SETUPLOG 2>&1 + salt-call state.apply redis >> $SETUPLOG 2>&1 + fi + if [[ $WAZUH == '1' ]]; then + echo -e "XXX\n65\nInstalling Wazuh components... \nXXX" + salt-call state.apply wazuh >> $SETUPLOG 2>&1 + fi + echo -e "XXX\n85\nInstalling filebeat... \nXXX" + salt-call state.apply filebeat >> $SETUPLOG 2>&1 + salt-call state.apply utility >> $SETUPLOG 2>&1 + echo -e "XXX\n95\nInstalling misc components... \nXXX" + salt-call state.apply schedule >> $SETUPLOG 2>&1 + salt-call state.apply soctopus >> $SETUPLOG 2>&1 + if [[ $THEHIVE == '1' ]]; then + echo -e "XXX\n96\nInstalling The Hive... \nXXX" + salt-call state.apply hive >> $SETUPLOG 2>&1 + fi + if [[ $PLAYBOOK == '1' ]]; then + echo -e "XXX\n97\nInstalling Playbook... \nXXX" + salt-call state.apply playbook >> $SETUPLOG 2>&1 + fi + echo -e "XXX\n98\nSetting checkin to run on boot... \nXXX" + checkin_at_boot >> $SETUPLOG 2>&1 + echo -e "XXX\n99\nVerifying Setup... \nXXX" + salt-call state.highstate >> $SETUPLOG 2>&1 + + } |whiptail --title "Hybrid Hunter Install" --gauge "Please wait while installing" 6 60 0 + GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') + if [ $OS == 'centos' ]; then + if [[ $GOODSETUP == '1' ]]; then + whiptail_setup_complete + if [[ $THEHIVE == '1' ]]; then + check_hive_init_then_reboot + else + shutdown -r now + fi + else + whiptail_setup_failed + shutdown -r now + fi + else + if [[ $GOODSETUP == '0' ]]; then + whiptail_setup_complete + if [[ $THEHIVE == '1' ]]; then + check_hive_init_then_reboot + else + shutdown -r now + fi + else + whiptail_setup_failed + shutdown -r now + fi + fi + fi + + ################### + ## Nodes ## + ################### + + if [ $INSTALLTYPE == 'STORAGENODE' ] || [ $INSTALLTYPE == 'PARSINGNODE' ] || [ $INSTALLTYPE == 'HOTNODE' ] || [ $INSTALLTYPE == 'WARMNODE' ]; then + whiptail_management_nic + whiptail_management_server + whiptail_master_updates + set_updates + get_log_size_limit + CURCLOSEDAYS=30 + es_heapsize + ls_heapsize + whiptail_node_advanced + if [ $NODESETUP == 'NODEADVANCED' ]; then + whiptail_node_es_heap + whiptail_node_ls_heap + whiptail_node_ls_pipeline_worker + whiptail_node_ls_pipline_batchsize + whiptail_node_ls_input_threads + whiptail_node_ls_input_batch_count + whiptail_cur_close_days + whiptail_log_size_limit + else + NODE_ES_HEAP_SIZE=$ES_HEAP_SIZE + NODE_LS_HEAP_SIZE=$LS_HEAP_SIZE + LSPIPELINEWORKERS=$CPUCORES + LSPIPELINEBATCH=125 + LSINPUTTHREADS=1 + LSINPUTBATCHCOUNT=125 + fi + whiptail_make_changes + set_hostname + clear_master + mkdir -p /nsm + get_filesystem_root + get_filesystem_nsm + copy_ssh_key + { + sleep 0.5 + echo -e "XXX\n0\nSetting Initial Firewall Policy... \nXXX" + set_initial_firewall_policy >> $SETUPLOG 2>&1 + #echo -e "XXX\n1\nInstalling pip3... \nXXX" + #install_pip3 >> $SETUPLOG 2>&1 + echo -e "XXX\n5\nInstalling Salt Packages... \nXXX" + saltify >> $SETUPLOG 2>&1 + echo -e "XXX\n20\nInstalling Docker... \nXXX" + docker_install >> $SETUPLOG 2>&1 + echo -e "XXX\n30\nInitializing Minion... \nXXX" + configure_minion node >> $SETUPLOG 2>&1 + set_node_type >> $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" + copy_minion_tmp_files >> $SETUPLOG 2>&1 + echo -e "XXX\n35\nSending and Accepting Salt Key... \nXXX" + salt_firstcheckin >> $SETUPLOG 2>&1 + # Accept the Salt Key + accept_salt_key_remote >> $SETUPLOG 2>&1 + echo -e "XXX\n40\nApplying SSL Certificates... \nXXX" + salt-call state.apply ca >> $SETUPLOG 2>&1 + salt-call state.apply ssl >> $SETUPLOG 2>&1 + echo -e "XXX\n50\nConfiguring Firewall... \nXXX" + salt-call state.apply common >> $SETUPLOG 2>&1 + salt-call state.apply firewall >> $SETUPLOG 2>&1 + echo -e "XXX\n70\nInstalling Elastic Components... \nXXX" + salt-call state.apply logstash >> $SETUPLOG 2>&1 + salt-call state.apply elasticsearch >> $SETUPLOG 2>&1 + salt-call state.apply curator >> $SETUPLOG 2>&1 + salt-call state.apply filebeat >> $SETUPLOG 2>&1 + echo -e "XXX\n90\nVerifying Install... \nXXX" + salt-call state.highstate >> $SETUPLOG 2>&1 + checkin_at_boot >> $SETUPLOG 2>&1 + + } |whiptail --title "Hybrid Hunter Install" --gauge "Please wait while installing" 6 60 0 + GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}') + if [[ $GOODSETUP == '0' ]]; then + whiptail_setup_complete + shutdown -r now + else + whiptail_setup_failed + shutdown -r now + fi + + #set_initial_firewall_policy + #saltify + #docker_install + #configure_minion node + #set_node_type + #node_pillar + #copy_minion_pillar nodes + #salt_checkin + # Accept the Salt Key + #accept_salt_key_remote + # Do the big checkin but first let them know it will take a bit. + #salt_checkin_message + #salt_checkin + #checkin_at_boot + + #whiptail_setup_complete + fi + +else + exit +fi diff --git a/setup/whiplash.sh b/setup/whiplash.sh new file mode 100644 index 000000000..1806588ae --- /dev/null +++ b/setup/whiplash.sh @@ -0,0 +1,611 @@ +########################################### +## ## +## Whiptail Menu Section ## +## ## +########################################### + +whiptail_basic_bro() { + + BASICBRO=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the number of bro processes:" 10 60 $LBPROCS 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_basic_suri() { + + BASICSURI=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the number of Suricata Processes:" 10 60 $LBPROCS 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_bro_pins() { + + BROPINS=$(whiptail --noitem --title "Pin Bro CPUS" --checklist "Please Select $LBPROCS cores to pin Bro to:" 20 78 12 ${LISTCORES[@]} 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + + +} + +whiptail_bro_version() { + + BROVERSION=$(whiptail --title "Security Onion Setup" --radiolist "What tool would you like to use to generate meta data?" 20 78 4 "ZEEK" "Install Zeek (aka Bro)" ON \ + "COMMUNITY" "Install Community NSM" OFF "SURICATA" "SUPER EXPERIMENTAL" OFF 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_bond_nics() { + + BNICS=$(whiptail --title "NIC Setup" --checklist "Please add NICs to the Monitor Interface" 20 78 12 ${FNICS[@]} 3>&1 1>&2 2>&3 ) + + while [ -z "$BNICS" ] + do + BNICS=$(whiptail --title "NIC Setup" --checklist "Please add NICs to the Monitor Interface" 20 78 12 ${FNICS[@]} 3>&1 1>&2 2>&3 ) + done + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_bond_nics_mtu() { + + # Set the MTU on the monitor interface + MTU=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the MTU for the monitor NICs" 10 60 1500 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_cancel() { + + whiptail --title "Security Onion Setup" --msgbox "Cancelling Setup. No changes have been made." 8 78 + install_cleanup + exit + +} + +whiptail_check_exitstatus() { + + if [ $1 == '1' ]; then + echo "They hit cancel" + whiptail_cancel + fi + +} + +whiptail_create_socore_user() { + + whiptail --title "Security Onion Setup" --msgbox "Set a password for the socore user. This account is used for adding sensors remotely." 8 78 + +} + +whiptail_create_socore_user_password1() { + + COREPASS1=$(whiptail --title "Security Onion Install" --passwordbox \ + "Enter a password for user socore" 10 60 3>&1 1>&2 2>&3) + +} + +whiptail_create_socore_user_password2() { + + COREPASS2=$(whiptail --title "Security Onion Install" --passwordbox \ + "Re-enter a password for user socore" 10 60 3>&1 1>&2 2>&3) + +} + +whiptail_cur_close_days() { + + CURCLOSEDAYS=$(whiptail --title "Security Onion Setup" --inputbox \ + "Please specify the threshold (in days) at which Elasticsearch indices will be closed" 10 60 $CURCLOSEDAYS 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} +whiptail_enable_components() { + COMPONENTS=$(whiptail --title "Security Onion Setup" --checklist \ + "Select Components to install" 20 78 8 \ + "GRAFANA" "Enable Grafana for system monitoring" ON \ + "OSQUERY" "Enable Fleet with osquery" ON \ + "WAZUH" "Enable Wazuh" ON \ + "THEHIVE" "Enable TheHive" ON \ + "PLAYBOOK" "Enable Playbook" ON 3>&1 1>&2 2>&3 ) +} + +whiptail_eval_adv() { + EVALADVANCED=$(whiptail --title "Security Onion Setup" --radiolist \ + "Choose your eval install:" 20 78 4 \ + "BASIC" "Install basic components for evaluation" ON \ + "ADVANCED" "Choose additional components to be installed" OFF 3>&1 1>&2 2>&3 ) +} + +whiptail_eval_adv_warning() { + whiptail --title "Security Onion Setup" --msgbox "Please keep in mind the more services that you enable the more RAM that is required." 8 78 +} + +whiptail_homenet_master() { + + # Ask for the HOME_NET on the master + HNMASTER=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter your HOME_NET separated by ," 10 60 10.0.0.0/8,192.168.0.0/16,172.16.0.0/12 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_homenet_sensor() { + + # Ask to inherit from master + whiptail --title "Security Onion Setup" --yesno "Do you want to inherit the HOME_NET from the Master?" 8 78 + + local exitstatus=$? + if [ $exitstatus == 0 ]; then + HNSENSOR=inherit + else + HNSENSOR=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter your HOME_NET separated by ," 10 60 10.0.0.0/8,192.168.0.0/16,172.16.0.0/12 3>&1 1>&2 2>&3) + fi + +} + +whiptail_install_type() { + + # What kind of install are we doing? + INSTALLTYPE=$(whiptail --title "Security Onion Setup" --radiolist \ + "Choose Install Type:" 20 78 14 \ + "SENSORONLY" "Create a forward only sensor" ON \ + "STORAGENODE" "Add a Storage Hot Node with parsing" OFF \ + "MASTERONLY" "Start a new grid" OFF \ + "PARSINGNODE" "TODO Add a dedicated Parsing Node" OFF \ + "HOTNODE" "TODO Add a Hot Node (Storage Node without Parsing)" OFF \ + "WARMNODE" "TODO Add a Warm Node to an existing Hot or Storage node" OFF \ + "EVALMODE" "Evaluate all the things" OFF \ + "WAZUH" "TODO Stand Alone Wazuh Node" OFF \ + "STRELKA" "TODO Stand Alone Strelka Node" OFF \ + "FLEET" "TODO Stand Alone Fleet OSQuery Node" OFF 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_log_size_limit() { + + LOG_SIZE_LIMIT=$(whiptail --title "Security Onion Setup" --inputbox \ + "Please specify the amount of disk space (in GB) you would like to allocate for Elasticsearch data storage. \ + By default, this is set to 85% of the disk space allotted for /nsm." 10 60 $LOG_SIZE_LIMIT 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + + +whiptail_management_nic() { + + MNIC=$(whiptail --title "NIC Setup" --radiolist "Please select your management NIC" 20 78 12 ${NICS[@]} 3>&1 1>&2 2>&3 ) + + while [ -z "$MNIC" ] + do + MNIC=$(whiptail --title "NIC Setup" --radiolist "Please select your management NIC" 20 78 12 ${NICS[@]} 3>&1 1>&2 2>&3 ) + done + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_nids() { + + NIDS=$(whiptail --title "Security Onion Setup" --radiolist \ + "Choose which IDS to run:" 20 78 4 \ + "Suricata" "Suricata 4.X" ON \ + "Snort" "Snort 3.0 Beta" OFF 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_oinkcode() { + + OINKCODE=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter your oinkcode" 10 60 XXXXXXX 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_make_changes() { + + whiptail --title "Security Onion Setup" --yesno "We are going to set this machine up as a $INSTALLTYPE. Please hit YES to make changes or NO to cancel." 8 78 + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_management_server() { + + MSRV=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter your Master Server HOSTNAME. It is CASE SENSITIVE!" 10 60 XXXX 3>&1 1>&2 2>&3) + + # See if it resolves. Otherwise prompt to add to host file + TESTHOST=$(host $MSRV) + + if [[ $TESTHOST = *"not found"* ]] || [[ $TESTHOST = *"connection timed out"* ]]; then + add_master_hostfile + fi + + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +# Ask if you want to do advanced setup of the Master +whiptail_master_adv() { + MASTERADV=$(whiptail --title "Security Onion Setup" --radiolist \ + "Choose what type of master install:" 20 78 4 \ + "BASIC" "Install master with recommended settings" ON \ + "ADVANCED" "Do additional configuration to the master" OFF 3>&1 1>&2 2>&3 ) +} + +# Ask which additional components to install +whiptail_master_adv_service_brologs() { + + BLOGS=$(whiptail --title "Security Onion Setup" --checklist "Please Select Logs to Send:" 24 78 12 \ + "conn" "Connection Logging" ON \ + "dce_rpc" "RPC Logs" ON \ + "dhcp" "DHCP Logs" ON \ + "dhcpv6" "DHCP IPv6 Logs" ON \ + "dnp3" "DNP3 Logs" ON \ + "dns" "DNS Logs" ON \ + "dpd" "DPD Logs" ON \ + "files" "Files Logs" ON \ + "ftp" "FTP Logs" ON \ + "http" "HTTP Logs" ON \ + "intel" "Intel Hits Logs" ON \ + "irc" "IRC Chat Logs" ON \ + "kerberos" "Kerberos Logs" ON \ + "modbus" "MODBUS Logs" ON \ + "mqtt" "MQTT Logs" ON \ + "notice" "Zeek Notice Logs" ON \ + "ntlm" "NTLM Logs" ON \ + "openvpn" "OPENVPN Logs" ON \ + "pe" "PE Logs" ON \ + "radius" "Radius Logs" ON \ + "rfb" "RFB Logs" ON \ + "rdp" "RDP Logs" ON \ + "signatures" "Signatures Logs" ON \ + "sip" "SIP Logs" ON \ + "smb_files" "SMB Files Logs" ON \ + "smb_mapping" "SMB Mapping Logs" ON \ + "smtp" "SMTP Logs" ON \ + "snmp" "SNMP Logs" ON \ + "software" "Software Logs" ON \ + "ssh" "SSH Logs" ON \ + "ssl" "SSL Logs" ON \ + "syslog" "Syslog Logs" ON \ + "telnet" "Telnet Logs" ON \ + "tunnel" "Tunnel Logs" ON \ + "weird" "Zeek Weird Logs" ON \ + "mysql" "MySQL Logs" ON \ + "socks" "SOCKS Logs" ON \ + "x509" "x.509 Logs" ON 3>&1 1>&2 2>&3 ) +} + +whiptail_network_notice() { + + whiptail --title "Security Onion Setup" --yesno "Since this is a network install we assume the management interface, DNS, Hostname, etc are already set up. Hit YES to continue." 8 78 + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_advanced() { + + NODESETUP=$(whiptail --title "Security Onion Setup" --radiolist \ + "What type of config would you like to use?:" 20 78 4 \ + "NODEBASIC" "Install Storage Node with recommended settings" ON \ + "NODEADVANCED" "Advanced Node Setup" OFF 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_es_heap() { + + es_heapsize + NODE_ES_HEAP_SIZE=$(whiptail --title "Security Onion Setup" --inputbox \ + "\nEnter ES Heap Size: \n \n(Recommended value is pre-populated)" 10 60 $ES_HEAP_SIZE 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_ls_heap() { + + ls_heapsize + NODE_LS_HEAP_SIZE=$(whiptail --title "Security Onion Setup" --inputbox \ + "\nEnter LogStash Heap Size: \n \n(Recommended value is pre-populated)" 10 60 $LS_HEAP_SIZE 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_ls_pipeline_worker() { + + LSPIPELINEWORKERS=$(whiptail --title "Security Onion Setup" --inputbox \ + "\nEnter LogStash Pipeline Workers: \n \n(Recommended value is pre-populated)" 10 60 $CPUCORES 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_ls_pipline_batchsize() { + + LSPIPELINEBATCH=$(whiptail --title "Security Onion Setup" --inputbox \ + "\nEnter LogStash Pipeline Batch Size: \n \n(Default value is pre-populated)" 10 60 125 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_ls_input_threads() { + + LSINPUTTHREADS=$(whiptail --title "Security Onion Setup" --inputbox \ + "\nEnter LogStash Input Threads: \n \n(Default value is pre-populated)" 10 60 1 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_ls_input_batch_count() { + + LSINPUTBATCHCOUNT=$(whiptail --title "Security Onion Setup" --inputbox \ + "\nEnter LogStash Input Batch Count: \n \n(Default value is pre-populated)" 10 60 125 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_passwords_dont_match() { + + whiptail --title "Security Onion Setup" --msgbox "Passwords don't match. Please re-enter." 8 78 + +} + +whiptail_patch_name_new_schedule() { + + 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/.yml" 10 105 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + + while [[ -z "$PATCHSCHEDULENAME" ]]; do + whiptail --title "Security Onion Setup" --msgbox "Please enter a name for this OS patch schedule." 8 65 + 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/.yml" 10 105 3>&1 1>&2 2>&3) + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + done + + +} + +whiptail_patch_schedule() { + + # What kind of patch schedule are we doing? + 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 115 5 \ + "Automatic" "Package updates will be installed automatically every 8 hours if available" ON \ + "Manual" "Package updates will need to be installed manually" OFF \ + "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=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_patch_schedule_import() { + + unset PATCHSCHEDULENAME + PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the name of the OS patch schedule you want to inherit. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/.yml" 10 60 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + + while [[ -z "$PATCHSCHEDULENAME" ]]; do + whiptail --title "Security Onion Setup" --msgbox "Please enter a name for the OS patch schedule you want to inherit." 8 65 + PATCHSCHEDULENAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the name of the OS patch schedule you want to inherit. Available schedules can be found on the master under /opt/so/salt/patch/os/schedules/.yml" 10 60 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + done + +} + +whiptail_patch_schedule_select_days() { + # Select the days to patch + PATCHSCHEDULEDAYS=($(whiptail --title "Security Onion Setup" --checklist \ + "Which days do you want to apply OS patches?" 20 55 9 \ + "Monday" "" OFF \ + "Tuesday" "" ON \ + "Wednesday" "" OFF \ + "Thursday" "" OFF \ + "Friday" "" OFF \ + "Saturday" "" OFF \ + "Sunday" "" OFF 3>&1 1>&2 2>&3 )) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus +} + +whiptail_patch_schedule_select_hours() { + # Select the hours to patch + PATCHSCHEDULEHOURS=($(whiptail --title "Security Onion Setup" --checklist \ + "At which time, UTC, do you want to apply OS patches on the selected days?" 35 55 26 \ + "00:00" "" OFF \ + "01:00" "" OFF \ + "02:00" "" OFF \ + "03:00" "" OFF \ + "04:00" "" OFF \ + "05:00" "" OFF \ + "06:00" "" OFF \ + "07:00" "" OFF \ + "08:00" "" OFF \ + "09:00" "" OFF \ + "10:00" "" OFF \ + "11:00" "" OFF \ + "12:00" "" OFF \ + "13:00" "" OFF \ + "14:00" "" OFF \ + "15:00" "" ON \ + "16:00" "" OFF \ + "17:00" "" OFF \ + "18:00" "" OFF \ + "19:00" "" OFF \ + "20:00" "" OFF \ + "21:00" "" OFF \ + "22:00" "" OFF \ + "23:00" "" OFF 3>&1 1>&2 2>&3 )) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus +} + +whiptail_rule_setup() { + + # Get pulled pork info + RULESETUP=$(whiptail --title "Security Onion Setup" --radiolist \ + "What IDS rules to use?:" 20 140 4 \ + "ETOPEN" "Emerging Threats Open - no oinkcode required" ON \ + "ETPRO" "Emerging Threats PRO - requires ETPRO oinkcode" OFF \ + "TALOSET" "Snort Subscriber (Talos) ruleset and Emerging Threats NoGPL ruleset - requires Snort Subscriber oinkcode" OFF \ + "TALOS" "Snort Subscriber (Talos) ruleset only and set a Snort Subscriber policy - requires Snort Subscriber oinkcode" OFF 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_sensor_config() { + + NSMSETUP=$(whiptail --title "Security Onion Setup" --radiolist \ + "What type of configuration would you like to use?:" 20 78 4 \ + "BASIC" "Install NSM components with recommended settings" ON \ + "ADVANCED" "Configure each component individually" OFF 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_set_hostname() { + + HOSTNAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the Hostname you would like to set." 10 60 $HOSTNAME 3>&1 1>&2 2>&3) + + while [[ "$HOSTNAME" == 'localhost' ]] ; do + whiptail --title "Security Onion Setup" --msgbox "Please choose a hostname that isn't localhost." 8 65 + HOSTNAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the Hostname you would like to set." 10 60 $HOSTNAME 3>&1 1>&2 2>&3) + done + + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_setup_complete() { + + whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE. Press Enter to reboot." 8 78 + install_cleanup + +} + +whiptail_setup_failed() { + + whiptail --title "Security Onion Setup" --msgbox "Install had a problem. Please see $SETUPLOG for details. Press Enter to reboot." 8 78 + install_cleanup + +} + +whiptail_shard_count() { + + SHARDCOUNT=$(whiptail --title "Security Onion Setup" --inputbox \ + "\nEnter ES Shard Count: \n \n(Default value is pre-populated)" 10 60 125 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_suricata_pins() { + + FILTEREDCORES=$(echo ${LISTCORES[@]} ${BROPINS[@]} | tr -d '"' | tr ' ' '\n' | sort | uniq -u | awk '{print $1 " \"" "core" "\""}') + SURIPINS=$(whiptail --noitem --title "Pin Suricata CPUS" --checklist "Please Select $LBPROCS cores to pin Suricata to:" 20 78 12 ${FILTEREDCORES[@]} 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_master_updates() { + + MASTERUPDATES=$(whiptail --title "Security Onion Setup" --radiolist \ + "How would you like to download updates for your grid?:" 20 78 4 \ + "MASTER" "Have the master node act as a proxy for OS/Docker updates." ON \ + "OPEN" "Have each node connect to the Internet for updates" OFF 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_node_updates() { + + NODEUPDATES=$(whiptail --title "Security Onion Setup" --radiolist \ + "How would you like to download updates for this node?:" 20 78 4 \ + "MASTER" "Download OS/Docker updates from the Master." ON \ + "OPEN" "Download updates directly from the Internet" OFF 3>&1 1>&2 2>&3 ) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +} + +whiptail_you_sure() { + + whiptail --title "Security Onion Setup" --yesno "Are you sure you want to install Security Onion over the internet?" 8 78 + +} From d16f5c53984d143e57e5bb68ee12c33e3cc9802a Mon Sep 17 00:00:00 2001 From: Josh Brower Date: Thu, 21 Nov 2019 16:10:22 -0500 Subject: [PATCH 67/67] redmine db updated for new custom field - Case Analyzers --- salt/playbook/files/redmine.db | Bin 2207744 -> 2207744 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/salt/playbook/files/redmine.db b/salt/playbook/files/redmine.db index 3477ef3c947f5107a7fd14571c53c7c36d4da742..7d84b5856cd5da11e7431b3bebcefaa6443b4fa1 100644 GIT binary patch delta 66951 zcmc${cYG7a_6I7h%C4luQ_Uk6c~5dG*Mxo7RHIDMu|lrgqEx+RdArPHC7rcMcJ6<{FPZCMS%&SIebNC}Z846|0(CoW|`B%0}yXt#YNgb^1f{{haah0r>%= z=^FWKWBK3ZJB)9yl`k>s56BlAIoHdV84IqJFEx(3K|aNpeWTpo`k$NR>1Jccb@E=L z<|g^lJNI%P%ZH}C3vCBR@^{Oh%S+@Xt=`+sgXIgC+;$>wE3uf(CDsccxNW{Ua+i4f zyHdJb|0N%qYl!}f3rLCnivVPh{_|EK#rn^6K>Yg8M?-u4sQ)|yNSFTeFd&`!&!i38 z^`Dx6wCO)B0&+#LqZ!DHddFfQFX$anAkXR@#Xz3c+ex^m^!AlNp48iq0`i1j++G3nalM^n_%Xc= zifwvCZ<`O~VZCkAosYT>*aGrz@{gnzzn1wgX9MT;^8FjkPgn*^gIk~8U_Q}pm47$C z-8$@4^A|Pdj#lwe^OJJmQ_-4l=BS*_(5{6*&-XY4)N8=uxgLi?%3~XmT2&s}`o2m!^B_3SHx>YMVu=Rb^Yvm$@O>FHrH&| zVCRp{7n}#2Tb)NcOB|h!=Nwl$HaliG1_|xLGs5MvRW{i^UdxW;Y3h>CnR|iAM zXe?AYD(iJgpI(DwqM_<&I39}xjVqYcz&%)0VC9Hx6pQCK91wWmVSe zqW-)Fs*{mWG!`+6m7cN%$3&9V@nj?(i&a)+qnOuE6yP4v^o$CN5TQ)>cgXsR7b+ld~xGNaL;b9#3R8-u(CKC_1ONR4nuV&Ly>6Zpsd$qe_lh?@h~V>(wL(imRhJf5RXUV;mV?H z6w&^o2v$cUQOI$nFY7hjpH~o-SRfHe7%v~5TA&)_H3`yIkd0z=KT(8})rmkd5sz2q zXT6T<-)krsiUfnkycAcM?rx-TqB<6ggk#CdylfQZ{Y4S4js^muWV~`f*6XnTyb@6X z<%(D4X1xw&y{5Z$IY`t#3>iy=Ds!@a2eW=zuTf~AWGtGj^k%)5^zStk41k7Lda_;z z^>|G)y$R$XQXLCNqsdUEob_AO;ApqKt2!X^1S+6*8>fKET$Apql1@Q=Y<+EO0J+U6%2%$uE z1o9e-RNAwCg&x0$H3Ibh$#6W7j8xjPUitpLMqr=_CM&I3uePk$DZQ#T6oWcQCL*y) zOV+O?>$kVpD0HxaL@aLHl;%d%!!!~G+5(gOru+{%CC``3q@Sf1r32CyX@=x?A96qG zzQn!OJ;^;l{7QUK+$+|L2~l)??7G`^hHI%S;Ica3b>8ee&3TNo!tuM~RmZiC7RPKy zsn97r3&ZRNVX9C7qh}7!2`ga+d%*a94>!~ijMj$&wV^txmBY}ZPG#G2BkH(EF2&{$Pv!S*=7&o2+m>W+vG&a`8>l>;nd6U`ebJCIkcBi$(*hYHN)-1VUFAuB(kjLxut{Hw1lhZLl^RtQwYy zWf;cN5Kcf+3GnwC3Dyv5tdG@28XAm02n;rc5~~t*u{xvjEQlo#Nv>)LtO^FI24`X! zjIjh78{?7sM6A}(!JngcRYR~5`p=|s3xNUXngWsfx<=#QB$i}tZLG0Au_{_MC=<&d zjHR(L5o-trRz;2A*$}KT7=+x_g+j(M0-^fq0>MD6!8j9OZbJ}6ClN~|stPl)6w+9P zNFd%2s!P@zAD_*YIfCJEG8~H5)fw({NY3K%P$XOzj2TIQxpnbGIMfi1HdN(hBFQsu zJCpMX4Xc7N@LOx_BcZ~v+F)I%F#Mw(NW55{ z+VHBnRmn!kam~39tgbFz9||`{qQ*J`qmALns(3gYHvR@MHyTa^g0)bnDt9IpcP5tL zs$jf6P#ZSdNU%ixs=9DvFjQ*{IuBr|HWaK&Bv&PknE-R+@g$6rkyve&BNK}QV@W`> z#zIh7<7yJDF;rh$n+U9`H(nyJp*|9?4J8wG#xLh_WjXZ?4Ute|BvfU~L}J58LUnbk zBG5(=W5M|lDp(&#GzKCKA!9p%_4TU)!BusQwZ=cs=SJ?|%hjiaQUBAwYyJ*;#=x-c;bLnp!UUTSg z96!DEHx7^<`Wpv8nf}HRPNKhY2y@flI7W%|Hx5Fs6DYu8#z}wUFyf%Uahwq7ZyX4C z`a9Fn)8E*W+vsoXs;%_5#rW(h?zFVa`#=4g{@*6=E&YEh{r;=D5v{je&DA?#`Dy(e zB;*atp094@;D17`tzX@08-0iQ>DGdk_8a$F-9z0&Tc18;UnYWg?oIG+HMfrV(|!qe z#5z{uul)b$Sj~TC9{siaf&7B}lzhK@i+r_wv3#byP2MOsz}CYYxkir4mGU6jE8C=B zr0=DJ(pyF%z>g08Ab%>qBflm;BHtz7AYUe*FYlDM%WLEn@*;Vhtc0<^!HHudkFnKnEo!Mzf0)vV)}a!{q3i}i|B73{ar|Z7tnw6smnn6Zyt47 zIe>y(3UcUgFa7PIzh(McqQBkrw@81x=x--<;#3ANf!*&{9Zk6W9w${LDyifAkO{RfX^C&a+3d~Me zNo)Oi{0&!If0DaoBlxuYOIX1FB;|f&x0tyiZ34`H-XTA|sUiC(3H52w^FRH&=KnDH z{WSt~$u&Zw6NJw~6^?8Da;~u5n-*>V)4yx}50l?tD=cfhsa7}vYT^D582$NcCVK)q^~$2f0)ayi^Zlst0bW z2QI1y0@VYa>VeHlw83H_|8g8irPT@lm^`LdeuMDaXv=%1Ji~TC7|Gu#eZVe%*bS`y%&N_p$D{yFmO!d{2Bpyj5mD}T{zrY8_|oOVQ06~s`_O2?5g$0#+|f^BiU(4Jd)i$D?gG? z*x6mQ;r+33=WJNt?Cfq?S)c55_paH{KKb37XG8j9x7d@Jq4KQ``M z$&?N9&u*zh;@Rygsqf&~Eh=|^Y}}R-`(|giqFh<_;hR6o#7wG#w{dU-|XzJk+pAjcBja~vV&ox;cQap5wHRsO`a>cW}>V~*^o6ROK>JeN;FJhz29e`eZ{X z1HoV@7FpUi8$u^Qv0^9oVrM(*P<134iG*S&^x|haYSO?Xg2}O?Y zj}7Mpfn?~oBiW>*hO-*j3xP9+V~^w$HuMZfG?Yk07WK(a zlR+jJ4J9KB`{a}38rVDz#TN9-4#J^AV1D0h=x?HtU_3IfKXy6_IS+^D_Qwyzldw@V zr*C!~j!B^660`ebN1$es!CC#WVNW^@`*uh7&4=^4a0GU!X7bF{3|rI0DmeCR7fp36y)=@`bx(7$Nv3R0Cb}Rth zOeo$TI}%MK0V$xe?6!=wjBolvs!h|JNv#X%lJ zuqE8bESqGVoa%!vMEjm(0~v| z8Q9Qhp;)NzNj9*22P)teTXCX=lw+p#dSA7v~k70bLqFeS5_^37&6JhB!WZU1(a#Rlqa6R9)q z!dm^^XI=yJw(*pMr!&^VZB6Uzo40ND>uuwVZ@+Q*%e{KrSn31MW~}+En@(E2r&Mnn z!;^&03(^B^tMQsoOtyaTnro>=Zc9>@-jrc2IOxeU&QrV|W8GV>qX)b7wgin44{xl} z2)!*p9nhr6V$|e|1B<%zc)DG0i_sYOY|q4~FYw-C9CC<0W7pfRJ(rO{2y_&%7-$ul+#@!Ez$(h)Xk-?4gI7&D7URaVY8@padXQH6S2h8uzSA<{H2T1Ina$CgYTbRDvKpk=1f#IR*-v}N4g2dK{5OuIq&c8tl< z+b~o4SR+Np1YzL_6;Q)u)mozSdfPm#?ldOmF+4Zql<)t}wJ-v{=Q6(S5;)9Z9fVyj zy=^uPepbdh!>Ebp+-kh{rAw;nk%2K)OP6liy1stxS{PIsTEO0R?$pwTQySK9Sy5lR zrMB8|f93MI>l-$2XqrKuULZd)gO<=SkP+h$?r>M}JEEYHa`-uT*eVrkpaY)*W$ z^tPGkHJg#S-?%1?Y@0!Sq0HD1lbK4rZ8~Khg>l=B!QZ<4!{u+F71%#e=%bjVY(!|L z8ZXJBKj+LXdfOD5>V;^UXlpI}*7c>8*uD-l{`--+pw)iJ^`~4v)NC@zU(3(QcgTjk zN?st36~~Ew(dByI5p;MRCc8s;LioEdS}5i_?Fr!r+t0R}xi#FeT#PH`tmaqD51apC z-f2DwqWQt}6#W08=_S*Hrkmhz_Rmew?B$$!nGw90^I7CoHe=%jUY~g^ILEzpVBU(g z6Q_lB8chSm=Qv_KAnc7YGt#o>97;ng%6?EM_1_giT^V-| zv3M8h>!ixVMSSxqb*q~50U@F#NAl!6wl$>8jR;k#ER0kdNx14 zX1%QrGmrM94r78#tRLOBiu%Hi$>Cj8yRKE!0En>T~iPs92Oy{(pdn35^+YcA10 z9SVCA8#(C{S1=9&5%1;H0sBOucb~XxxZbv`bs{HT&yn6}DfNrJ5l?%g+1(8Yai7S< z&6BuKVB+SFh+Ea$me8V}-9U5Ax2_PyAGlcC@iZ6;nw5(aDnYQ+g{rS+wryuHiz|R>nB_zH;s!rzcc?~{@8q>d57s@NjGma zuQXd+PdMLj-sQTMbD|1cb%D6I!5dUN;L64AmglD+k?xuOb(Ni?Cqo=*#CX<7P zf+pFoo2j?Ej9We8 z%)y0vyOXl8OBE06Qitm84&yhEI5Y$?6tXdtfCJAsxIh%z?bHFq%w_2LVy>qh42570 zbLI-#`mVgzGe(F_Tp~wrw^Gk208T0Z35e6e#OVY9Xy>Q{3V^fNSjUNF>4AE?nL48Y zIQ`vf4FZs+925X2BLJsTcg&o#x17QhY&+#+&*P*$&#u*aTMC62ZJ?cbnpW4mw)GvK z_zvf3(@=*qMerDHH{}!>-xi4@$v~^p=rT=323m!65Ox;nZ7nqXZnXY!8g$0>mpiB2 zaFvMv5?w_mxW8dCLA?$z^CrIyKL?3?Ya^g$hi zZ2(k0W>6$`90)^|78w7i62sB`ojF3hpR?^y z^>(RsceSXQBalbQbb-m)<$TNer1N5DqjM%$LZ0NPwvV@uv=`YvGF@<$iQKg?ooCt( ze@%cu4~`yY`;a&u_UEh_dV2+}mW#1pm*`x{cy)*9YJI;{{KYD_m($GQ1VZu{59Ej= zpu*dSQ)jGjiKxIZ)8rqdS*84>{c!p^NpfCqN|TNi~)0)PGeSu_@UH3 zl*Wz|I*F)fu5omwSTLl02%D@=pRKopNhGwwP6t&1i8EgFiWeJ&RpN+|?WNQ+s-AS1 z>OmuyP-Z5#Flj6mi%HuTGtO?>_Ql;sdr<5_O!{u3m3|{R2Ie+r+4c4!nv)B0j_+<= z;e`sF;kK?a6`8KEIBT4Poeswjj!PUbId<62wXJg;Z++7mvK?s8i0)^)B|Y%#}LTeV}O<3q=X(58!X^jf`rJeC)2=sm`x0r4HV9oI6uPo$OL zL1Dk|PtS42jUn-RsXa+^jUA$gR40hHrCPQ2@z z*Ec}+aUliS9}ainX%!uj*9=Z)UG`;17Rl5vfuHc3H}>+n2J&W zeG9H9v2T%R{~d$A1y^6#T}#ErSzfX1cqj(DN|Q>Qi+d#uZ8nN&Gs)jA(9mWhCv#C8DI>aEDn&`agv7G zor`MRZL$kBhEq0_m0Y66%Z$JYqJI?BJgyh9<~`V}@7k`nFQsKVdkrm9Zr+xrEo+V2 zR)~46S4|e*=7vC=?A$Gf46ZnL!>Y-F!F7&UHXYhx3C%9*PmaIaau{O3SsUgmrwAGc zCv4a_IZWdmYdm|DNVYcGajJ#_n}aiYi0Bxa*>hYpvpKjRzG0g994EIgqAVRJXgNlD zrZ_XyzK~`qlQ7XGoW*4vgwsX69oN`rU^ko7J)Dkcef?;$(k!*lqfuZNlS3y|gWK8V zaE=cKpE;N~4n8@Yan&4gOmL9iKAQ#}h1oq~Y7U*jEb0N9Gsn1Nwm4X7#}zHQc}WxJ z56W6$LkVUwMe>pso?(obCi-)C&C=VaV_V|V*PGXRV4C<4cdXm`vdL%mo2;M8C(E;~ z*SZ(EC%c2&2ge*ilY)PAABmjWUIGLwS{d~^Oxpltgo9dF*lk0=JU+k&1=mk znkSos=2Ei^J6(TLRsIu%^hC~lyRr9G&*Xjc9Ts`C)$l&*EV9BRQ8Oyi;w-LRHMXY3 zQBpfjVz5L5snAZU&03*D32@Ge-RQvH-O#Rt-hK)#*IBi+9tWa~F5e?oxBj+6Y~jev z7*|TzN(1OXFijq9vO;~eF!eRi4{d_0A#9TYeYMF}rcLr_ZfAEJ$wP#=SVj@bBMpEn zWXyhE@9gic*V{MI?4O&Y+0Sd8y;)phiMHeF81-=g>LbLCOJt0F08utv6r-{YFy2}s zmZ#g-(;T9v4e)pCKPc8(%0a~%z$g|jkTH(~dgl?;?PMAb)olQ(+eEz`*UINK(~J+m zY3$lsn3aO`s^juqDZj+kSn#lv-Q|Fj0U)4*$qRkBK_1S1Vs5ALT>P!bLMaM&n zW3A@XT7_!CC1xf=q~c6W#pMe-VW3Q-qzp3TQ^l#q$~V2u#>cxw-8g2mSYp&K@=oB| zPc>GbDpusSAaBj(P)eN7vlR>zsg5F=*kWwbV&ktJVp+~ERquf7NRZXc zZb|_ToUl5&o3rUAy**`Id#ZREPYh`PYx&0D4~QfAx1?vK2c%DoG4tI+`6u12?i<~& z8NXjGR#k~yYbH*W0e=To1yX@{8fR+ik{uDW3)};ZpI5rw{AqBtywP#4A=bJF8`sTu`wZ=X7%@8LyZy!s2Sm}hrq*3; z%q0Gct`>`p?F-yaW6ITHzQhHH-r*nfzwW9zaIe`oXQ|tnE>sS%x9P9y0R_sHEP#bb z_F8^{aybhwW5J~?xP%1;3-)I~8fMT1%Ec_}A{Jc8f(ux%j|F>Ka6SvpW5KyBIER2V zJ~WW8oZZ99SI%O=nJhSi1-n_Wiv_2%U?&T9us|2n-IbcJoW`=!EI5?~+gXrefyM&0 z2Mkmc7PK%Rt!!hEa!L=#Q?{~T3kx>0U{enmploEp1{O54V0{*(w>At=)@Bg_YglkH z3z}H4ngu7ZppgX)EU0He9R)aq3{Y0FtXdYV>;bvT3KlG90o)GCsz1?1J<#?8L91D(R!D1F1!-7RDSjd6}ESS%N^gI^LWx*U4%x1x?9^h4uX2DDr z%wWOv9^g@?b%S(+M>(n+0hr2yDJ-aA!6X(;WWfX$jAy|(7K}xZCePV;lrbzT$$|t6 z;w*@H1XwVF1ywAlWI+WB%2_a+>1HHl z7|SYS!B7?qVZmS)l(L|t2e_4D77XeEX}99no{1-UH9 z$pA9`h>DkGc~~H`Kw^QL1tJSvEO4^G(F0tHKtN{vaVb2@va`U}1DuM51sn^^EU+@5 zLcQ@FferV8Q1s_>2XgvfvXI9P9x?%f~GEhyomcgq9Ck z)(1U+Z+V{u|6##}slbRz(dv)~~XJjj9v zSnw|v+|PphSkTIXdlAs_$J%la%etEdcd_737TnPTEG@UQ;5HWA%7R;Z0JnwIk8$%= zVwnvN&rLrWw)yVqA{@uI37-k?2!9IC8<)>_ms{@VKQ^A84-1awTDN3$!K%acuI&Ze z9ky$2hV5a)x4=Efc%;^C&pTkf(7M}ti&e3%wXU!(v>s(mSVtHVEI;@imaUf6mh+7b z3*7mIFLIA?cXHQpmvCou8@YP!IPO&LXl^_gF!ru=pJB|N@19C77t%jH`K?qJvS0xV z=J$XKbuJ6$uz;DwRH*Y<&e1HG$*4tzI)i0RXF<;_rlCSTisejY!4wuuWErl znx4qAm?=%U%1mj>)p0%E%GI$f7}EoWs|gmwS-?zUhO5bLPP$>Z%FJShtKn`Ia6&8y zvLL{M(JZKD!6+7tWI<*|L)BuqTE(&|Sy0gfhN-W$SuiloB4$ccrZQ8SGBua=mcs&X4;ZR?SRk`N zVu8B{q=%@?EM|!6>|qU29V`%8z_Y;40vijgEU>VE%K$Ph8={(7mWct%Uo2pzG((g> zSkCV(_^k&FR(@r{FD&?(fXuXPu<}z6t5jj8G^GkNr72aIDNU);!G>vPK^qGWvET<5 z{Fj-Ql`7w}tnXOB%x_ASZ&=RPEMTTLrOKBq=ZhXtqI}MPwDK8)luudkNe?JiK4!s3 zEMR6d#mYgJ^F9my!-Ds+0H$Td%D=OSfOlE&4hxw1O|invZ;F*SS#NK!;B^+f#)4NV zz-iea<&_@RAmwEiyu^YRdw^eI<~M%jIhMoBX#C1EEa!O^JjIMZ0rip|RzNjau%87N z_khvrMJ%|G1sAYjUk|8O_p%^;K8wy{!MQ9rhXrS|;4BuL$$~Rju!jY^yFt34THV!+ z0G!T(oh;bF0-Xh?^?*?-)1!`3Ph~mVS&%|N$Dfg^*25a9sw_}g(87XKSg@4^TUfA} z1)Er~5kPkQ8L4hyS9ZR}xHsSPZsXF(kc zRkHD7Jk!8~A|*=Kf`I^gjWlj{f9qo)0?D_mc@-gQ0W zy4Q6bM6=Pf5|=+F)4rK5ONXf*POn0o>mp;{`TR(*O6x$gH?#~Wq-X6l-4EBnAs5<8 z;USj~j`D)>IGm`l)%COq}>6&uBOh~#QbN01(d;gO%u-yJU;`JrJE9{Ks0 zBfn~6?0tA*iiSmaw&%kG@#%WUNP3KR4i2k6!~3phOsjB*$XPrcBk(l!BzpAb^B6ze z0jH^R?iR=8HiFCzuC-&uhS#w8Qj?=@SsKgws6VbOMT=@nH!!#Jdz; z1jm}Gq}5nVDtLl%qRs0C^O25YXaTW?i>Z-MNyj3l(8a#VdIuU4ZOepT_g+q7S_j$_ zp_mj?yE>@R`7|WfXt8}x)4HZLwOiEEnd?W*X;|01NddV>t0I*9K~(OGyPtD}3TF+B z29XM%W4!#1#~+5s$1sumy;C9bEt{H}HTwOk!w^4fwd5x%ix+ZGW&Op*(g&%5cE@y@4^&ydzdMJZvS{OoD(h!db}9{l zqUi4}ie9|~tva!V{8W+87^HVhroyl{6D(t(o&T=KZS{22P~Ofs)}P1N@Q^sg*!I5X zqEH7Ke4^U=i5{bcXU0L;Ia}{Q8^Jw}OzmgQvqu^OKlFShb&RLkMM?9cIavp5@#**J zQ}vFqGz&YFOe8Zu^4xcW`BAZS3CMJz*<+G_kUx}9cmC@9)cJ(-Cg(oqQs*pZl;6qM z@eBE(yvhElUAJ$rPqS{euCgw$S|P|!rf1+*S&KG9Sv z0#!mKbM=ljG~}L)6S1ql$@ud%Pa|trz2$Y!Kco({PQpqnJ-h>KV$<<0 z*E=!>Nux6PDV>!w%sBfEPxagmG)KZ-u(WqCh^9%Xv!(Wh4eM*+ibv`E=4}m|7Oier zyB2h|fhL72R6P*k8|e|Mh(3WPUwP=SgW z1v=4adeh^t%+)*4t`jXNi!)bT&VZM)X9lq$LMzWqhKUT|wVaHD;FiBMRhs^8vOFk1Bi|-p32(2>lP9<%?g4I#_@;O> zJf3`lI8!Wf-T~hwINy1k;NpMe-{v3YujQNh<@^lToSi8DVD(tuvRr7%x7fLlLCpU$ z{nzw&?wD@7ZulU{G5c!#7VdGgQG2zw$U6hR6oL6gYt1s_@;^M|L!D@Vgn282%y#B8 zl2s<`oTYaTM1e)~$}$|H!5BT)EOp}52kbJ+h+5|k2ZLgWWdIwCuSM_7#l+EmtBf zGeZF#N(3}t%)Tt_*E=O+^sgR&&aQgB6J7)+)<9^GIJEVugPwnLu}(BBL#Z2*mAX!} zrows|0#etB7FQ^BLyC>_KlhNyR;Pnz2nBD5zxxg20eUA-IVgBTdIYc2ZX|#75M$p? zw6wxLdI;^KPoJ)LT4^rNNK>&If|IQ+pL;k??zGS-PehK#kiPJgL#NY;w|+8tC2hzW zV+|2@H0hlt8tE>)3^#p08= zXT1E4XV@_XdPj=-Lxad6-Z{0K)@zHH9~V*%*kNV)1Zwj_B7!A8&9sMV;e2#9#q=F zd97#P$kA6XPj zA$Kb`*Zit^gXs%;D>`Hx_)COmC9PtzgL8I+^NcFT&#iGMf#Wz>_3ZHq6gSajHy0$5UdN2ekdoGNj3Xc%aP%;oMLYIpd(YIPq@H~MZF)} zBX9M=LmkmUT(h5~Ivs0x+GpbM!&1d3Uiu23dHjW2UPM!6LSSmKXL;EBj7NU!lS=cz`Qj$fXLX;2Q6LE=ET5h+p;znInT{ zIL2jPh|>=XfRD=b6@YRK_m?8Pme#FR*=J_@3II(GPo)gxmgn^@Qug(kzCuOe0}-)s z9#=QOnD^CTX=UG}IWkn1Gk{y3+dHl7Q#E~tf*11w(Ohmrj&a}%csrx|Yq5eUT=p58 zBZFo+Ioxt@uLQeax9KZXJP-(m<6dr~$9VNe+R;?@q}ToK%@HBHIUa7gd}Mm~9L^D; z=#!4{7*|5(Hb_`NkPnyf;Wy%-!&1ffa*hb!^O6p?+)Y#M>DjuU(djExI2KO^6K-y` zNc1jgfVSruM|~@nj_ekk?q_z644-{~$JqC+7-3S(zP!^{2vGk}Fzn(Qog~F5rr7+Q zSj?0&`!vsy;j{_%w|uzeLhm+-!xL`g9iP5J!NW-K@hX8^ z&i4+Lecq?9Q1B%t_{Id!t+yNBeJ@U8a+rPf=g3f5j-6X>qiOYwz3|u%J_giRsCWQg zij3Mg-D))+`mcB_lUVkRpd*82IaY4Dg(k){HhEQ*JRQ_msAMb-)nrWkL0olxsk`(T za=#=W9`X_25+4;0h-ZlF#iUpv=D2+#`a`g)@wf0gsA+=*M0nT@~U-BZ_6W6sw(gJ9m*If9MM zw^r}0qPfs8KeP9R-&i*gvuRy&6oipA^C*#nCnyjp!8PKbxKZg@54Qp@a4+>ykENEum(gy80X zCvFupu4GZ%$!<-Sk>v?)P2y~}tk`((S6rTy&`jcNw#?uC#T8hd;7t{ryq5J$UOWB9 zFP*qN!AljmJSoGy;Ng0wk5=C~*%ceP3~JC-@$CmaPjkkynWA_9A&<3bn0b7!M_=Hx zdt{IN64w&f2J!Un0`f_vWd|0TgX&9q- z;@0U&7|3q49n2ZE7$RqPPb&w31MZ%pELRdSz^zkU98~sR9PASGPQ00U7B15(^IAQ> z=BQ+Qq!Tw!Q4%W1#$yN`n&@QrOe=^a%%M$=l2BoM@A8(XJ7+UuP~or3ewGKs0QW6X z3@R8gz@1CXW<~F8=IWiek%^lo6`4(wJtn;q?_!>dFHu$C4x<52K!jVL7QJIExw=j7 zoQ6%L(aNjv7$bi2Y$HOAd!1NU6{I7;P0oyiuvG8F=Z5r34B5Szohx_Z&Zd4`hC`ni z*lY7HF72$LWzR(78>e^TZsr>F$r+Q}-qGGFy%YB|ar?N!YuxmcXOMTS-Z_B=Z$jU8 zqxnZqHPL?D&_wMo$6c}RYK5G$dzkiZEW`8q+5uQP7^n_u~frJv*T7aHv4en(ob@R6~p#KjA{7c{_g$>8a`qKMDIYZ zGi=Ndy~XLy5cP=-Iy}>$PWwLd$(H@_%nE$`;Td?T;x_R{(c?Nr-T~kKn(MyBohwxH zm+^vqtL;Cw8P!;R-`n=sE9}p~zU=M7(ZXYnRZfd@xvSE3wm3|D$-Pn% zq?2XC@|N`@+vN^P*y4OE?L5x$kW&?lU8l=?rT3(z?g!k1g>n2p`GNMGwy$l+TA#26 zELT{bvDR9Dvt4YD+0Ww3_=kmZ;Y!B_$CJ*r&c9rL6T{+v-0R(sOD*zsmiw)z+pdAH zcpmS(-#ONCHGHvvb3Gw%ksg*Nxvz5Dgi`)o`>*zsY%kfySZ}bV2Uu2s((O{ny-)l}$l=rW@9ax#kJv_9|7NvYzOlxwui4hv-n8f1@8;+7UkPVAhC1dr z{_A|yHNbVNI3q3I=bq*6kao+@T4&qx?NfyhTqiiMbq;r&Bkpm1FSpApq<=~y+-Hf0 zU_Y?M{<(dj?LONu>jjp-ET3ApTc3wp%zxTN`z`!*{-ChK;de}PeChngHNka*SmPGm zQ{CT5Psxv2n{AuyZWLFA@KQGtb@j4*N>m)3&hn zfYoie);huZuC2zV*nRc~_{IDW!V2LR$1#pBr|v3p-6PHuA8{{q|0YvLMr48Gs`x%7klFY9XCjrOY?ys*ysvU9%UUROZO zcWsx?gs;6WcHiyx2~qyJ;B;(JI_Aa{whC+Zxt2@hNH>p zgy-jec3mKj6yJ281aFb$NIy!KN$ElEcibuWc<~b{&Huqa#h=WF?C;pGvQM?!Y&Y6A z+48L)Sx>jlwzOI9hmF^lt<8`jhmC`?;md7@;O&-6?E82#KY~y47x8cKFA6sc*EtgK zyxHrH7o3xwo1O2w?5<|lYS;6k1HO%SjeE4a!u_iIIroRsbm=QuOUri&&$^C+{a&wQ zo4CpKE__?)Xz3zppnI!yPzw~P~s!oVqJ&h1q-9-qm zo=ym-?x4I>9U)$IKSk=rgz%}82;ouU)IP)qhjR)IN$*=M&;dQMvG_0fHoTG$DdoO^B?HB7|2*q9gsnQJPb$2=uCz zgxJ*z>L+y}As+Q0A(HwrA#&;>L_ZNCs6SFiwTlp5?IeU#+X?ZiZG_m>Lxe~vDuF_Z zN}xwAq>gF12gxEDI>zwjBL0;uG>ZrU* zy=X@h!f7)oPn%91(=AlGWo;H^wovKzwmeIay@hI=N1IEKq|G5j&}IwQb?3>eEu%iQ zrNXnl8(nUBk??qJB_W))+)>rri>GD&{e&sC+((Ge(n^TjaxWo#%RLlnwS;gjv{Uf5 z+)0qVR!4}St#WKL9=pU{oR%~NU0Mi{wQYp(+9`x^+7?2*+GaxR+9t;f zN90SPvMebc;zdwoLS%(XFRxJP^=K+_Nzi_r25A#%&lgzzmtIX8DV1=rF=V`-t9 zZg1%zh)Zh+sH=7rA$ILb=lR_s>`Do7l(lOJ;kCaz-#;?>uL)0Tp)xJBP??rns7&)M zpA(*-T}uep@+l$SmQM(=w;Xh~k%ZDzD?Qrv#8uL+gX6obs(LlrzIN?y*HOLG6|{em z0J28KgV(5da2k~huR`_HqdkamKHys2JGiIi70PRQIZde0@{;R7Z$F$u<=LyuCSL3c zDu701)~iviuxrn|p6|}Dq)~MeG^$RrMw8&Rmq~D5ndf@9+owl+U36f2nHx96k4G6# zh@^}oL{P>OA}eDE;o%XeG2P)gh4unoB}RC5B}xdV(VF#Yw9mI|AB*+f0VIt!jG)nm zku};dy!II#KV@aUxT)K#NBc^=rgvRU;aLuky1SlFQRU@QRBOE{kwj`wx!lhk5u0)o zON*lXN$SJh<@G7+Tuq(9p;8RqP zxKvU~cl)%b;!@AxC8Vh2$*FPD!6Qn&NZEnO>zMp$m^@V+UZL|UDMhA2Q0x>TUPU9s zuBg(FN5qzzC~GG238Cf2?fGt7T3Jo}O3F!u2udR%veG~Zuhh#|cITK=RuM<9LVJ6= zvXUS!HBY{|+lxIlNB-c*6c-bpQtB8&gw!HJ2Y(j40HPq);!g1qagR99@;+Hmz{=Kc`O8{q9RdsJ0kDLgZ9Ro7GGM)X0G5zX zz?$YBSe||l3setTc)%)n47^&k%yz78o^6J0kL@&ArjW(R#kMzLP5YDW5UiR%fu$_i zHp22G2CJa;_LJ=CefG2LJMAg^1NOUNE%uK6Ram79bmdY8i==_D!kf!)gw;% zGOh|%xW~X6cN#3vcR5aVT9s!AI5$tVh9;_$K)S@jmf1afWg7WOxBkkGz0ujLks zw$MJgFg1$menDy^am`PSAjFrVgF#-)zcC;k0}E2c6e%`zq=P|T%QuKVAfzyrPe?&( zAR+mwJVJaaiI6;{2np@C3sM52>2%SVr_eqpPYI$c?Me$%96<#sGa>mY6Cpm0PKxrB zrRbA(1O-|LqMbEA^vdQ>Z?I3bZ@WaXymiNNC&VskHJ6H9DddXmmu&*Zx7g__V9h zC+(8+)MW$}XqOR^&Qs~=lc%1EerUg+r*0;wP`e1dUPws3b^#$i?QBBwRGLJddL??< zg^sjJ@>Hxml@=*ay_fI`wNugOc0%$snvgH8ZN-4Jf$~&Zdj(oEb<_%w&|y7KqXLnq zQV}TB=x9@*(a|Pfqeb&+D=@$)By{*K(3T)N9?3i;laZup?GdZ7d-^4Yg6b9ev(_UaHdw-$3#- zl7|Q>(kcll)TlZXXypXuYr_fgX(fc@X=~@5LBRf z3CY(yRR4UMgL+L3LNWmTSP)G@5=K%*NRdXBvQYhePeA{F(oB|~1L`j_AG05Yjo7OI~URG@xFNWKa>N+P8t%vW-$W6K}tg{on`vY0w5 z6OqtbD^jUa7OJnH&zC7rr7G%EX*K67q|wq`zH&19p=y|~JVCuGw;_XzQ+v_Yp3p*->S%#_0GZ1P z@u`;}It$4bLJHIi2+2#WKu6k9qe(G-o<)vtnz7$Qwo7#(BXnc7o8ed^*7dld*&rj{da61U`rBZ}= zQ!08n1$k7*3sY393sO{{^3$nx$XrW^FV#qhH&stak*Xn~I#;Apoh?$6=r|O~5F{cc z3YEGdrL|tD(q=DIk0xFU)d&)*TURwS_@;wq-(88972r5u%$qG~|2?gp&RPzf|D#Hcp0`!yV zE5;%UBN>Lok3>RZr$qS~NgI++k^BeAOGutXaxaowkq{+Ia|Mcl5an6fhG;XAHAt2r zITi`k-~we5q7afQB$z{mHhO`AIc%YAU(oU$_0sYo654U33tC=Bh*@lT5D{i^%VPu; zrj}60)bWJmr%=jL^I=O`yf5;+ zt=ZNLv6{>;nqMR|`-fmy`;}PXAhyXkcc^zrXkZ}*0i zwq`iAMT=)Vv>izfZ4>0s7VVqy&~_v_v_+Foo@Bf< z)a!?@e|6$z5G-I-vGK_FIq)#&(R$}HY65V!jiyzF4|C@KnzI{>-0{K&7N80XumX}} z@0nE57f(C!W(rnv6;?7Fd9R}R%GiJS1C8)4x>#K#0riJBNzm4zim`QAVSGQ(TU^tL zmq@Tat7v^fx+gNltRfYM*F~`0Rn$5OFN*A*XS`DAy~|j6Fh^qV@|=1w=L7OdB=Q-D z89BScdgo?Z__L0~Ho}V~Q1~3IY~zO#uQz9>sCVKmq}`5;KYFJMjP~UK^WmK-OUEo- zdfd#pQ|BGGXz9|;%H}N%>%yU>OSi3RSO>UnQ(g1=&BlbkJY~ib&f82(b58P`_M6;q z!l~&s?k(=5yFk2Fyija%-sZg0d9JfXaPnRJTX0$GX8reuqxg_T>e{b5~ z{f7Hsvxj-n9S~f#`oi=U+@QS+{+chLlFxkGXR98}GH{+&-df zAgx`ry9#(0^?bi)q~3*>OJ>p12keH>nL`x5Yk*;1;vG^P42R*9$kDnwx89Y@w9#m= zw&=<+US0&YR%cf0UHCrn1#@ULqwnp^x!MZK--VY(uobI86}!+FA0@Tg&ax*Db!(D(byhVbtRox?7T`ptY@!sNLU3h&2tDqY1dNk=> z4q7v3;edS0`;~dIV~Q!ybc4we64u+3j=>I(?KRW;!f(QV z;L~FNG~FOvB0nHsC!gu|N=qjTnK-mZwX=m;*@l2?ZVp<~?E-)6Pyc1hNKL2Jlevos$IrVziAgnFC zYZUMprS9Bgb50NFU1&dd23BLhcP83vCNgk^}y3-2uTxOF|Uf03*1iGzv6W z3iLKu^6Fh^S%~r(paKnd)Vus_!bCvPh%l2Act5*~y>J%r$?MGf?y5O(uGt&YyGGH# zE2t!e?1tIvtpro6u94IkO|63TR?w_KydhMVtS2e5_MJhZ`&CTFgS|7pN7cJ3Y15qF zK+_2tD>}S`jN3-TcLStK?*kT2e$Du}ge#qvqj#a@Ck`+HVsS^V`gWn=XOC+j40f7b zXz$6m#>3F*j|LGMAvhfcrk~&qXTvw&y**BzXM0GvUARVgUf2&?rzxRXSOs6$oFR-A zs)fPA0DB>Y zd!l8or3PMWi&)AnK8xF8;yR28%VsfVHO3g*7%;XG z7%)p%!xFG0;xq&Tgd`*+)JKv@$T~Aw$&f_Z6T)Pl0Lf&T?95DNvJLYjHmlw)I zcOA{H3GJj{ z2L&nxmr-yj1=}eIQxGDcEfgdu)JnlN3bs;k2?bjy*i6AD3N|LeP0N&t}LmN7g z2G&!sE(v_WGZcJ6!N(MQM8Ss?d_ckb9N-(=7kn=nU9eKLcwbkyh_0<6ueBqOBB3FLE8%y{h5LjNl+Mko`T~PJV(K^ zN#G7XL&4J&Jkf7 zK-XhrnT>L;vU{c4Udm^mSC#RI!pQ!?a-$BmrM2URBAh6@HG>pxAwr{rJDZJ>WsRSr z9XAr;Oy2GEbk2lfCXXA1a3=32GkM%9gfn?}_X#n~eWbbOc z6OC2cM|~s9^5vUFjW|uz83xI7)OOras^a|G-DS-$%xy2APt6Fc?PK^u)kMzOLzi0N z%V;Cy#?b@RcHCNuWJvDw$dJI$Fo{124Go33qqD{3brt)4e)!sQJKacDs972&ve%!K zohxDTkDJ62nd5u33erq33Qpll$#PQXwmdC?J<0Tl>CTiB`aY&>V8TD&G+y@!O!bFZ zuh2aUGi;sdw6)ywmE}Im4&bZ08E%Y9|I+^9v|IZHnpLdH70uWvSDz-=MMMHV)8$|~ z4R8_c!J_ygU|0K2(SE^w$OwS6kTd$UzsB4>v}l z;&{6&4rnOuZA1wd#qu>f~E>w)UA=Efze>KAA611iOAa z-7)FmcKvqTTZz*2pfo}8apNQ^zQ@^BF`)RkF%lKuLlnP?rN1U;SGVJiNK|l7!mi(r z8y``M9!-k4<1ul}RN5d4byAh$2Vxx{v+bC|9MoG+n>Os@9iX-74GJ+P5tg`B2!cq_BRi)-ItZOgo{_TX+&zT*#bnft1gg zfmmYKJC;I6{)$zbS8iF7zjXcDF5~J~?^p&>-abKX$2B(m6r{ha z+cC0|N96$n+c(kFGpf{f{N|;K)#H~~#B^wm=_gfy>y{@5|1C@RGrWKx~6P-UhD#i!V~aUA>UK{ytdH4}|3nI=NMC zZ$`acnoxYM25T0|!&v?%*;NM$HAI*r*tXlU(r->5m-a~7Th951z=HEuF(xu`wD3ASYFj0%{LxyG zBwFwQ+eJ~a+XWmd-FR)fVk)J;Oir|rV?CR|UL0z~goK+-1_zi5fW%^lNcS90ds$dW*fqMLlorjF~6}O1mdm zm|yJIxVd_}%TowcR=!f{;t8yvPW z6s`~&98fnEjh9s8ICk6PN_~>R1a5=6_j-G&iOv{S8l!AA9(TSU^rEP+w}jkKTwn26 zXrRQDld}xLqkE=-9?9<9xgUmdq zf3oHg>ALbgUcbMfm%MhyuvT7^X(jk`^{xIk+Pne5Id6iQZAoL^J`RnW6=@KB5?kOE_RCRph5 zc?x?bsAWZ~5%(A=oUf6KRV51tanR!x6!uifu9$o&Fq)^8YSA)}na85XFJ7zmIGTQ??iJn6$fFn*i&a= zu2?Ywq_z49xgZ z$WA^k4;^ZIt%sLc6kSs=v&As#jq2EKXTT+7Pf(4bN6NLhkY9{0A+J3ykBl7OBu~%- zcS;m}Q*f~BhaoV06dMG94k?K-x;EHt<0ZnuuAgmuQXW>)j=m^3*!4TR2I4T-4fCsU zu_TON+u8{%Zb!GQm+$^r_M?( zFux4$l2;kOGoCS?GF~J;ATAT9hzQ?S%S~*~u7J-YB|QVRQ*9Z;={BrvB>|acvpLz&J341$2&)>|Cx@ zA9*>`;n&N}Y7{B5)WXDNi&rXjF#n699}8C9I8B+69xHLew5z`w9f-=D!z$AhKL4ZM zc#+>k$4jCV&1LUO%JAGMda)#K&se5L(Wgg6znyW+u6HcRiy~JRYVx@AG`UQTqRYz` z%&3uFlj-o3L&h?QRL5$Hiw-*|&9U93xo3+Sy?|%@+D87Qv8c|~I)}eYGQ;%XXcFzu zAB;L(qD|}k;E)zYM>;G>3Fvebz2{J;OS0Juo8-ZhKn?ovyHO2FoLyQ9wXX0ORO^yX zwT1_wgAG1t9Q%ESV@N}qu}!eSEZ?}!q604WH;tvh#lG46fcbZ(-%>JDQjHykD4i)-}VlJ2+^SNLq*je6( z@(MQcIJ9wS2L)`aqzuX~0J7Nv&$6Y<^cK=`4z-P>h+NsSnyd z6DLeN7pYOSdtQNGl9i(dE+&eLTe_f z)cEcywRf8uMc%xF=zBLFRmyfkzEBhH34M8*VTIrnPwC93%}34uW4^+?7Iqm9GrR%& z9KW{i((lkW=*}AU>aLfvV4LYw@s#ypLmn(-|EPaof0tpK;YsTn!wT@Q``}pFkt;;G zLXB4O!m0+I_lfMGzslp49UIjs+WvN-5=}&*o_b4u!WON-JF*gYfIKsp{T?Ngz5ce` zM_H*x(P*Zky?mm?+TN8L?1RQBWJjxXbQusn`oT6t!3$!&CN^JwB)W@ zms>Vvjsdh8S=~A_a{P0!YedoBh;3q`vw2C2YdQF97ekvs3n#XTiJff%1Yg6R%~PCh zebs0+&qgBqT}p?D``vw{!g!DFD;Ddne8!V{ddt)k^T(EzoV&v@{? zRr*QMaqMtE#hK|)qqyQRfR|%Jf|(5X?Qa3CyHV0!g~%I+ufkIPD(u@;iMyw((b-(b z_P4R0^OVxat*2#CH!;mvAf!p33n{-(sZ7~!{I}6!IBU2irLSR&^tthEjbvyFu*YasGJ&Kn4@jT~~xbd*x>h)XK zRjN@m(5q&Q;#xg`RsUTcq79tT?2Em_r1N@*foc@(zh1o2$ePc}ee@|qh0V~#ZI}jC zwv3A!t89{e9()^RJrJ>PTEAuE(w0q7WoU>)flt!(68+^9CrlvDM)u@ztw&wHyvVc6 z?`wu@=nBK6jFdIPP)KeNj8&rx*iXY1=g^d^d+HT+lrMAIiUt08jced>$kBLL6C zQIwOl4thPQjLF^G&%T9f6gR2dfYmj*Z{*Bi$83Z4mS4;7#6~?yYt)*VHoAtNP1Kdv z-q6O2?QK#vJ9kFbzDf{9BQLhMNw5bZQIpWT(5{O;+9cAWtzZp4#W@OkwBUG&XKfGI9=NuwzfK$lwf7@z zsu!;j4N!q)ee^#FP01Fh{W45ve;+HBD_6`>WBAR4YfxNMBjD2eqRwHnJuqI4;sU|i zM6L7p^~VlJt|PjI$Z|@C?ExVdK9~WbkLif$r-10)THVGZdO3(bhI0!P{giBG8{*JJ zAH&H7ihhc-OFKaHIHN$(Pa&e;&YpECnvpz;GmE~MS3Y9CGDnSuxY!SkIpkI*vICip z)JQ{L$9Mx9Gt%L(MT4l;qZ0+J8R@9W2Tf_E+0~l)HhRLed%haQPbFNH!^RdV53~0_ zv!oAM2JYjl)-`J%XIQjh{l?8Dg@yj&+_I`Exh(RRk`_w2;%7E$HH(*E&$B>vMdsL5pOj;U%4XB3x* z*mEmU0A|)MD_7c+D#!C&&SZx&LM~Qg*}SYcNht>o=%_VMD?}DMQl<>bXmKxJ27Am} zT2`qsKUNFAW-4%k5O63nIUZ%Sm!g~#S_Ch1in^gbbs-H?vCc=LESB96Z$Db zl)YQj*f5^?gN=#OYvj(6;X36OJv)}EIMQQ7`E8*@G+&qdB2yVMHHI@0%s@F`#gE}^ z1zS-$zQLe{;@k`yNV&61aL_n0A#1awwuK|@sN0oyDYsdyi8k#{xLl(drn@j7u~{G zXdXo{o{r(P1C?ziSGF{_zsS?bpzSTfr{4_o5PEE6^f@4hXnr`sN_Qb zREwpTc_Aw8tTfL$mQ@c?%y}_%<-n3xYPE&4sKg1=P7phe*>@MQGdsYFb7nUzmKM}l zjVwJ&F|vh2l^4@vRYXXY+&f}mjLy0$Gj@n-44qMS;{3aktsAC9^I|jkt+=VT^88J` z@K&hcu?sNc?7(nkM0zhW$?lQ~6rh~nf(4kV)g_Q_ZC0F)-GkKFG%kq!UjDq9eIp+a zRQl+&fd~k%i0Cq{CJ-IeX~#*6OLf@Ta?1c*wM;Gk}WolX9R5w z6?S&~n!bbEcwxpsX>js}f~nA|x`aro!jvY?hq1yi(b#HSVEf#563pp)Y#S}L7Pn=f zI4t$gsdt%wHh*P)F2$WPFvV`X8W!z87M~IC7Wa$uEp|~Bz81bVykyWEP3RxEY2Tn1 z=W&%Dm;q_@qp|oK6nzn!cAGLN-3u#BOPhUOx5Z)?j(~RGtn68+##ZryUyJgp(kxRY zk%?~Q0=*QQ%T7J0WDkj<-)Uc0z3|sBe*1)&-YW1x^6zqdG^l#Juv8AOcOq|-A!o(52DZDG`yV?{cKJ86m^l9%@VR{*Ho^J{h z=lS!~Y5VUI;h6z=k*2WR!BFma`C3KLiQrZDlO zZweDn`o=Kvq;CupPx{6%@uY7I6HoevFmax52&40S8!u5qxXXKfOG`tTc-%LHiSv9z zm^jZjgx4mE*AQMq!Dhr@hl2P-*(fX?k^^THEo)OZTUQ81Q*5(915~2$V!6Ra3%#A6bzuiNkM-K`e`7s zS*kYNmqzuWz(IjRflPs&0viSC6r@pLC7Y#c!3Vx;F7Ycr+;3o?HLqSI;fcH;zDBg)Q5ThWP1hYfn_|mB*vqL{p z@B;w-al2Lf6}Ob zQ1EvO&LqLC&?gjpOu1y&lH@X;CTw3qu^Nz zo}u7r3ZA0iNdTSipNh~EH0p5*9-|;a!J`yBLczmHFe7w~fZlvHa1^+_ErDL6pEHA%2Ad^H7EX&~`> zS{U9>qps8n+E4eMVEc@JsQd=oV)#&bvE{VosO47621|{_llo5T3#lVa3r&@#u_=dj zXLauZt@UlX1G-CKdFL+SdSR!qQE29jItD%@k#+&KA3rNA19wdNuoax^kU6 zww+8!tF>u1uCCxTyV|sKx*EfkmEG7qS2LJq-^+e|!!EPH3}qReZ@)Q1IcSdIQp=7U zHtQ8I`oZogGdobBY{-q##g^)f1~r!0$AU|^)hu_WGJ8U7E6-5k+yNt|z2b4<5SCDEPqNFWx3LFv;LI+LF1dcm~Ne} zR{Bl9S9(pa=sI+t>t577qPtW3hiaw$g0|f(*$dP-+J$l9whoQ)Z5J!DGFy$KJy^xn z%sRdVe*sHVl@a<2)c7Fw@fXSkusbJ?R^9o023f~`*`N&5-6+ffRhJKf!+gzgTF3K+ zdaZP+?34GEK?91Gdzbi^7x|XE)Hu4ep=#8!D;r_q;PMG-ybo`Id)9I>)p9Sch<%ds zp$LRnvTWV4QjOz!)vhx3`g_V0w)ic1J*!=$JYdZ+*~M>xBT2j;+xwQ1-4;iOxB-~Mgc}LS z5?9?4=|DFTmr1*-HCcZn9X|9;4jzkrQ*DBlElyY1YJo{Ip2n|ANJG*-c+UovDfxME zT!zFxp!U2zV6+;?6}DNJLnAx$oi%r;ZBNho!c|Vpat*ZnxQXR_0M))Ttj1G#MO?9p zKcpt|OPTVm2-}O}bUCjY+IZZ+vxpU0oz2>&D1)`diEW_Sn>7~zD<~I?GJ4GmzwKX-gjx$*3@|Fcjl+f2jSxbrJQ4*-Sb`A7{h+}5`Z7Nn29M! zW}Fk|1jyN8PV(yv|4t)J%?xWquToa{YAtYvuhN2?@Lny*4)4K}S7(wB12E9>U>oP^&Dr)YBF=J~9iFD4>@a6t&JJ_d>#Ho&JKRgZwzt*-s~V}-pvl)i6=P~ zb9S&5(NYX%VNirYE(WPQXl>_Y#@Vf(Abc5vKVfha2B>qb>k&0zFa?8r3@*Sx;=wkq z9@*R8LG+v!WQ8j+@L|Ankrmc*(I#buARBN^i02|J#H%YS#H%YS#G6A_i0gV*h%0hd zh}TwDh}TwDhzma}#FaEF#D$*~zR%@=9<9 zKSRhHmoxYVBHqTF!6y;ji@_Zj9K_&i3@*iB8wM*eSb{+<23!N3!EuPVB07UZdHZt) zQIjH!` zFqn)%AqJx{$ikpM1}PYbJlOUv2A^Q?0S0el@B#+UV(=gjHuJjA3`6o_4ZK0hwX>OF zHwI1&bUX<0UN1AmADS8BPs-3QToa@F_@bb~tJ;$x-xk+JtGef8crF6HAmbDlQNEP_SJIJ%qT z0A!vvews$cPxIL7zd43^;<%uXgVA}w7wmC?`nuD?(yvYGsH7V=jF1{fUn+G)B8xwL?AS0WjvFm-m&82kR|{oA7n_B6y^*CnrVQ668$MS4jWVdR zOKOm5bc4Z6&(#LH=!}DPI=6eB?%Jfraks^lI9;0?$rRogTZ zcM+k~X_Z<)Dzz?~J#d*a7`~z%M^`4S*E(m{WDn|fG*iFSCK-9`@Ry2nT$!(R;LaLGf$5#f1Zwa_5U5d5%t%nk$Z zfMf3nHI4)p*P#blW8cW(t=60L!=Mm2_SR-Nf6jXeCEa-qQ%U(HK{6ZQr>TXbBxP@52- zLo;eZgQm}`NYyo%c0&U~w~PG_mM=PvamwpR$BW8L$sAw7HC^4#PU;*3*z#ADl{s87D*-qJx*f!hd+Z3Caev9=Y>jI$aX)?AOKQulC z`vmqG=fXGE@w3qa(Or^gD z2_AIuO8%S~{5kWv2VHiTJfSe?eukx+uk~w-S(?G&oRDT7EhzdG63juFZI9^((<`RM z<_RW2|D)|=+w1xjspHHSn`=@Br>2_Uw&mF(w)N)Swty`FDkj+SU`9GZukkr`h`hiF zKBp!-YujcGD!WtEI2uZ?Y~vYg>e}2^9tqS~QzTn_J4y=8kWFYWLp$djYoXGj#?fM` zqUtqC?7&>>d~jHd2YG?9CY#u-I;+zbN2}-}Ov}iQY_*OUZrwi}n)Vd9xYlSflFJGs?5 zcuGIDBZZ&N!F)PfmM(P_xq;lKkJ^DY64d*qPQBl|TJ4ayoDNP;$dUWWLiz5}>unLC z3EFtQ)|j`k_xd;n)pkA6_HA!|XlZH(8oaRpO`5j1@hl}yn4osg-_CpY0mXi8HGIu4 z{b!qItI5|H8U;h6VU1yjVY=>h-BF!ge@^XOAt%(d)C5+y4s`OyE~QE9QhWv1x2heuWBiXxxd0YMI;xd5 zslAOFVI1hnPcxkrtR`?>Jp*4|oNc?zwlw`j`k&JGn2(sRF<)xhYn}-NXh7L-`ptCK zbQbc`Xo4-k9r)RZ#1`NH)3yNXZO;hJ2g{Bu1o3vHvx2`l290-lm$?g?-374ovjg4l zQEmYcWCt4k5+_W1m#Q6TsXSQ3a~{yTjR&;74;eY@R&8F@yt!pr$>xn)TKJxa^L9f- z?pvi;CEB^Xyjsakqt~orzpYmC*paG?}x(s)2J*#6I~@OY$!aF@7? z@?o9B?dy4KS4@)>XzZ4t+m{cdDn&i$fB5rYPmrs~)hMlok;2o;_|CLkC0;ksl>p^W zPcoIRmT`(X8+KFz3<1xT~QtbCGkk;0-tZ$%j>%X?z7`#EP?AvFQF1f;` zu6%!Sk*61aj;@$`DKNi#(!kgP$rksLG;q%Niv2GCd?`4OeG^eCNiki(qT&WxkDeLs zjF~3|=5|l30QjlgKpWKCU4`Ib?)T1>w$^E^IGGxml9}EAtTKe83Oq5M;@F?poK3!BKaH-o>=mq|j z^Yz_T(iKxJ1!nW4lO!)5;8gJf-%ro7YIgy#Nm1c!NlmL_3xBXKB8dTk3y8HB9vXNc z##BjxSv)bwR<7GsQUDq81HDjjaW8Z$+FhW}p5j?jx0eFE4+dV4rvIm4(y!4OChDIw z@L!!fR()iZY4_1S zyN~vL^k~17%M2FyblPxcE$Ck>iT&8(g8sKl;%KIK^`9q+Ls^rn|2j$diT%aZf0$^F z{OIbR3S)sGhYI@-mBe~Bys-auZK4AnaUmRTI7Yy67!LRrh&T(5DmcD?V-6g!^dioM z!vzP7N5x0s7zxK1I0nN3n>WP?aA@2lKSK!OhP{4*m8+UKEZ-oDE z_p67cY&NdKX0x}#|J^$V#(B`x1&80&v}#T7^i~`F=VhYnzi!S^Zf{+)vU&CT`S<*| zMk!KVV6kg|68m4;pKbQ)qJ0|oXZhXRxgy8CwjMiOR}K;8YxJ+pyWL)+?VNwdLP7i3 zCV-Ef58pAOA>*}bJ8`ewgNgXoj}ZV`yy+3&`IsL6ge z5JYwMyPhC=WwPHvjOK%P2rc_<5ePNgxegxhm2Br+5HDss4*~H)wzCq%bJ+c68o z)7h$yILN269n~P7%yu|HJf3Y|2I8@7`w@3P;knW^MEg_wg`{G;ChVFDme>1Vu-5*x zW3cjN+jDE}3zZ!+-ED*a;oq^}ztQd)ZGW##e!~8Y7JOHBmf5+<>(}ee6U|NF@8yCb zY}^KlmkNq<{l5Em*~^0VU+(j9HxDTeMXE#b;gR6*P^vB*Nd&`D>+K=j3sj#R9*Yc* zBfLP7h@ocqx>kpFVl#57lKeV5?` zPi%NFUYCp}5~-MV9M(qaLdj$}9fk=f zM9AuOLLqLUXk8MXCLXQrlk+hlA6m375=?|6soLH-+qisak-9`Q41d;@xzOPGLnJk! zsHCiyb6R-*P`EB04u#+ud*#9zkq;+a7fgksv7l9RVlJ=1N2o3u35VkeYg$fA!U@(z zqp?sbUK_}TlgPz2n5s+0V~KF0wjyVXAzLIEOC}Pv{+unGw&O|L#Ng+nsYo&uwcg2agP{kp4I+(E|BRx&W2+PP*tDCpleAe{ zKlOL@RrM-WS0}5L%J<5%%0Ya=JGgkf>5%%!Hfq$-h$)ByQc)LC6vdr;|!jyFVO$#BD zYqTyU7!5TwX z6puDHSc?ck8Z?C(np=|A>3}7vXriSl)|`wD@^^*exBfXDo+p`zGzOcSBGztjCN`xS zQVmJyeLQD!eWh4KG8B$13&pMEnGi-K(G+P|wyYsCsApFgJy}dznwnxQ;YhH>+79ld zR5;!gjm4I=SdS2lwj^4D(QtB^^$iIHlDVNV9*Q*$D((uUn1vFGH;2Ma4e$V?&jN4D zQjz9(h@{G~1mmGZBiyAiWnBnZ5=kx#H$^`bvbuPW*{9tmU^5p+8IEvd(i8? z^tyyz_ommy^tzf}d+Bu*y)L5H0eY>`Yd^hK>9vnuEA+Z2y_V^94|?rcK%tm|n_d^u zYl&W~^jf6X9(pa%Yd5{->9t6&UG$o#*G_uvw7$54+n71L@BV~} zjl%!@v$kKwRa#eE#i{?V|HHT4b`{qok<4%8ij)g&GW0uL|Lk{?Y<`ebM_s?@k4Hk zq4x$JOXeRJatBOFRN?<0Rh{s$eb`>@bL~CtW$i)j9_g!fAC=3g=YyZ{W(4N&E*KX6U($3emLQi^})(q3m>Dm}ArqybF zv@*>LQ;{FluhkFLcdQG8!eGZ+N~Z0(pzx=>W2W5p>Ii|i3(knkVYl$%rJG{frRp>CMw!KL%y+-E+qs68S zcL}9b(_t%V@yxZeiGs4wy$T1CwWOTv!UBxllnjYl#T!QKj8-SSApSxYinkMxX@bC zAWkFy;oEL$5Esx#TxBm-F14wolIQ-hwqv(bJ-zE8H`)aex+LKP|*QT8MknLfnHE;$m8ei)bNMX(9H|LhPo6SnO7a zIZ}w7ZW75NTbr;}{BxM&W?K)-b)`5&7^~4gvV7v!tg&~9%SG)2n@Aj6ci$l%&TF69 z>fAFeVV_u^nJM-@@K3n@fBiX5|G)o{XcYdnjSAYY<($s3wvi-V59Ne^$Qs5+4yU-( zwt=Wl;DjgIKn~)pD}EAXYtQ4NAfq*mVb-UQizP&pTfeBwYjSHBLzxDxSPaQ)a_ba> z^P1cm#h|<Ogs3lUoz; zAq`s(D9dYds{lRon%vyK6lvIuzeiq^o9CD0HM!Y+abA;~(|eJI&E$)Srl*vfziSM0 zvv!qXZmzE6kj>I%hPk=9Cx>iC?q-;qhf6smv+sCHWSEjfq{y6iNk_MdgOtXB$0?FW2t%)1g#|Tx@b6& zhy)ksHIcetGz!a|i}D&MOt4%Mj4#Y>Va4fL^X+ptBC>EQ~G^}a`6Y*&LsJtc# z3q!$FGC2=vU^)i>j?8Nkbuf*DWw*IV69z}|*b#XRELX-ti9~WvUIRrZ9*>1$vymo} ziozPjtegg_XdKE;C@~Xh!ekXFc{tJpBf(%iG9#~v*Toa5R3tVXX@b#sJd~Q2*Ti5s zDG^R4ry>n3gvKJ_DS1s4)_Y(fC^{KwlEDb9Lmh@RknX8aXcE#u3}H2DVqOD9Bp!~& zLlclD9#6&M;qgclhQ*~wY#h?SgTp%C*t`bHRtO40bPUo!gk#CzXru|nNUn}TnjkDP z#v>#18d4IHp&qLYY(kR}<4Bw*{hq6RU$+ej*vocR8SeM-Rs$ z`7Q@Eum&7TB=cQPFba$8L0Is}cR8SmL|_#yR-3)XKR|g5&-w=eg&TuSBJDZ+T5*|64h(~BoLogPG zmCyw3W(Wpj5h(VwkLf8Tpap<@kJAo@AS~*@3MuVf2*T=DC?29+OHT=!3#ezQAnjKO z#-ot7VcMw>grzsA8?;9u7=#7PV2XApJte5xkba3M?Mo;I;h7S&Bk3tYZ=Hfw*-%$6 z0^Jof7QuK|FA}W_M^o@NqN^8y{E8=_1?uWWpcjX?5s6S&FA}MPwN}W`u3jVz#Sh+Z zM7w&CFjyh6<6XT-7?KXwj^nf!@d>FovOY_wl4bc6 z?LT^okf-rb7*=JW2Pv~Y>ZOQnpZ+U;w##v^9B+GWm-LZ`bRflB?)^w=yZ0ma+(!H7 zZAI16TN+XO>}uODhkITfeZYM8a?iV=5#nZB5Bp+Hx>6aY^bo%k$4Hxmucf1eM_p}F zKdFZ+VLw;gCEh7sD2=o)mR9BeMoH`J)5zFPwf7b`J30%)LbwWL+vo7MGP`{)UBYlw zS>Ju+>07*|I@>;7Ao{aI%wTyRkW+0Zzu{TrC~BWZP1zO9RAkk>nt+ zupGnPMM}YK+(N~60!+WA+B|~$YxldhsqUNHXSzqYhe&q_enH}Y+lHf*-2b+Nv+YOG+fJr&bz0eZYELD<*a`mH$n@f#;%#ww`Al>1yv5Y1tE)uq z_Uv<(WQA;d1IyzKvldyef9M@xE&kLqo21=R^lUDY{!6ezJgq3(UQhjR^LB-v{YSah z+S^lgTT72A_B&TK9Nlc~`r1=!?fcr}w-yhS%dGkV@=unh-ILMU7qgo;=AuRl->vPQ zh1Kng@QwUav+WC+Q=!Z0fDX^-A?*vOE0$p{$go0w)n?o0Q{x2YfwzXWdjd7^2=h?L z&Hxm{BdKCAbqCE!ho_`R`&@dro%5Npv~@-6vDT1wPj%ZRyFE`i@89Qf79HKoemTeW z(O%T<(kyM6Hcg%`50wL+J)S2$S9*qe0`4EAkW?*c;?u5Ev`*JD*A!RK`KR+sZaC+# z|6qUGez`qtKh!?h?zh`*`)r@sUV}gKuQA)vb!A^;JDOx$(0=hfbzWSRE3e4#5B!+O?CY zmbGhw^@&{`5N+Q;b*yp@=1_k+s7i4=2S|r=hZDLmy7VapS66TEL+D2@|kM;IvOTxHz8W2=-#S%WilE-FqH0#}d0OwQ@(Bu0dMvs*PfGVn>s1X>^0X7O?Z?n~oY72!teZ`pe`iKYnP8YqQgn=*N5r6hp%d0S3SRB)!OD`p}Nz> ztMY6|C3V9ZGkL$p3?l4D5%!P@Ty9M%mIF{CI?AYtl?XR25z`X6cVytRC-UhgK1->B z<%s*h968m@cJ!c6uyqNIt-CEg9jY~)ldJl5DAdl1f<%kLY0I-6GAp-Zaw$rNM9|h<%V`}R zme^gfvQ~fS^;?hnzD8SfeF@wk74m-pAY&vq|ykCl#-mP!No5MRw} zuD5KP9V;CR97)Fj#|w@&XAj4zc^&{d_#Cq-)hF zX!G*@bsO~8Z`#$45DlD-A|QGfsa4kY<5f=|xNi{O*Por1?HESyyGiQ0@3va`$srwe z)EO(_%6guI~&=`WsU1rw617uIQFzuwxeI$3l;K%oO6D*qpu}+ z<%Rt^`cTJRtp!Qw-dG`?azeJFrfqYTe4>4vQ@54dZg)vvxMS{0`0VX`x6^fwq)Q8& zZ#&1iRyfkGNsbxz^IWi=Zo6G}Iv;ml;oRaH>UrJspsUVxlI$)rdeQ<81Sc1&TZ z7@?`C!Ne>spJ)vZ$qTiPNz}A?Av2MTz1`aNy?mr~QCPlS?U+a-II7D^JEx@)*{yYq zr~Xc1?U!a9ACVu{I@l0)Dsv69t+3oH=<4U{*L^JC!A9yVT{V=h)2-uTa-g3#+cAya zn$=;A)?vuqF;vNNSEX%KCjYu0(sMFOPmLrno0PB=*F@J*xp966n@g}9*8(^UHhAyy z;&+{Vz(^fpHV(&Zpm+6})y>l61DtJ%WjjXFG&-B5t=e`)OuosnXypM8A(Ep}tkr<@ zTW;hJZR{v&Vr{H?U>ges_)uzR&8AXyL5)m$*N#J|mOY#j$oD%%*^UIYl+YYf%8p%Q zy5|<&RzWoxLG7%XD70}V-=RW1NKpgJF9qdSlImFm6%s+KeUL1Zx5p>6LHRT6MG(tb z)DerNW_@yqJW%VHN)zXtCAp#njj>fdU6I=EjLDY6Dtbirx)s+Gwkmrso9kxFJz5^n zPv_RVp5c~p5zcGhXJ25SZ0}`%%l?%8F8E+!3*4*OeuVu9QtU@M?LXU|AXi(8pb=(c zBvy(`3PY@#4mLJod0pbqLf)=o<(j2XiM3&geCnLaYzG?-4W*GS={Cx$%66=zk2s7u z;HS+QGiOfq^yXD-)*W9xUSG8qitaJg1uMG6wCE0LfKR39cPvl{*zk!(r8scfN!gC0 zX;jWwNy98|yM3&@k0Ytsf>P6KJw8G1R|Pr8Cax^!G}gdD&N-nBEw=_wlmnz(u(1^@ z7v4brvl+NM8(p!xdn+Kn*|?qMw-@F2GJ12C-`)cYB&1&hwX<65rL}f51iw_Ud0?7w zriVU@mvu@vOq5@Qu6GH2%q*KCc&*H2d2+a;o(9tuA5xJQV}*FCob6ad{hiLb1~2P% zNAFRcZEsGIYoVW6NPVzOhdbuS)g5fI*A=!Odd&GO2CT;fr*^rArA?9tgdpSD^mr(X zcejj(Y-Q6xmaSgvu4!_O+QDXmOjks+dOA+*x#(Gn$ViHk%q~tOG$n_z^0L`p(?4ezMn7mjYGXTo;vPD<5d#K*IKA1Cbh6? zQi7_9VI4D84h(<_p;H&ELX@xyF)G{9O5=6r8Wtq04?Nm{kmj?3r-6Pv6qckrqquI&3aY^G-HqXK7wa(|qg7Y^Ovc zwQ~|HUM$VGba=0W^(!&k$p-PKutuP?$h!O_Ibz-Rg?Cb4DAEGGB}?~GNcT=WoQLnT z;d8)qgdwi%A+V{#Ix#Ij8tM!nFJ;6_1y+cQvYqgyCnQpqRi84FQzI?MU2+N6S#E7P zQ6AW%(}%tIv$kw!nYA$^Z*)%1cJ{QYXUS8!&QfdDEO{u`*~7YYmfX84{|P1Bk8*0E#M ze%7PM$l8gY`Gsw>ZS4yF&! zCQRk~O_&ndPB!;xV19VZK3g7SJ$bQOGPaY=eOT~5Qho-|a9BU(>();tvz_oUHWcY? zEHGbb+Y=k)n>m<%b@oHKSVr~ull^K?uWi>^v`xywe4z^uXkkJ+AdqC<5QdVw01vyX@4nvSa^!2Ys=O7!{7`&Nd{Vquyg|HJJWJdt zt`}Rx`OqYc62oFY(IPjNqAJaQ@BRBK-em55Y`CGpf5R0I7FxuYJ?tw z!2iMT;dk?I@y|ieaw~rYe=dI-pXOKc^?YU)Kb}wUgZN6mhvmUlhNdr^#v%? zufuRHhHEffh2csHtfeW_ufV3uFQVf@1xERAl7%s$MVYoncW^$=jrk`Ih_0-S9 zuoJ_%7k`NsTek4I3*96=2AVICxDFw z=%HsYoQ&Zl3>ykiqMwN21PsSxFd1aXCejk!z$P6-D~9zL)?qjf!&(e$Fs#O~3Lw+9 zkF`WU7MoTUpjbZ!!wL+`F&te0uik>88AB6>MwG%{eHk`2U|5P_35I$Mi!m(1un@z7 z0%W}U`~rFPqcF@XK#_hVhPfDyz%Zu(nm!xDEDSTdAOqR2=`*ltI)-T&rec_aVKRop zFigTQ5yJ!m8McjC)5l}eI1FP8pz32VjK(ku!^i?C`k@#O!7xJ3-};>pf83#7|I0_)@90ofE8-mt<3m~-qorg@b(E3-N0RF-72ZrA< z{D$FI48LIb8N*K)eq=!VAEEUJZ2BI1T_WB3Ha#~Doj#qbe^4>5dz;Xeg%w!V+yJq+(+c&7jvN9$V! za1D7+&gvNznf|T3^Jb7ce}J;W-S?VtB@S!McFgMYF7{K?Co8*$rAfveu&p}2LhDHp_Ff?FTieU)`H1-%|ps~jw zV^Nng(!CEd(BNZ`fd(IgjQKdYqY6-K9Eo8rhIts~V3>`84mY~G_gW)2-hlYj8i!+d zGcZiYFb%_03{xh@|=xvk~Ouda_3@{SOO@wB9cMQK__!Yx10J-kHm;N(0p^->0{YPy10RtL{^wRfX%U%rMVc3J= z+YF}80#xZ87}_y>g8_|7D)p}lmP-8#44-58vH+P%9gRdP_1y(irTz(qk1_lg!$%m< zK%`Rt09*c3fUt3E7m)rZWZY6Pg^Zgq+=SuA0tAg4FkFw}Itgc^7Cc3M#txPJ{erque-FdE7~UyBKz|#>McGo z+j$s!-F-BD(O6Mrop}?yV4rlIJiK_*oNVU=YTd%#^H$Kepl!>pmn-aQ=Xe^OQOqCv zkcVt6DqfQ99LvIFpIudO){?8`Ss8fY$vzWgFFY&ud*RtD+sQt+V;iF?`0>-GRZm;f z&{S=#XsD*&Z3!R4t5vqGioN>`1mF!O`(Usue((kp_S(XGOZFLKFBZ2zf}C!YA;%lR zi%a(XB75UpfnHp)y-4gOYQ;fbTuz~n%U)bo&=;2w9lZIdg1kp&A7--nRfwV&-p;Zw zzy@1yx5+(y;Dmjq*yY48&a=V)`jB_?y~cxU_N5<-hX255h{t#PO0jb!jTZ~fAMjji zZEsV{iZ{Emorls~IO9Z`3jVfBZ-nny?A1HQ1mJ76&cmsWi1G&e6LR$&?P^;;n`zg^s1Kv+-8 z=x}fsa!LC`_64wA%Cwmzb^186w*J<}HR|jjIqWhuJP12hb9+W%gJEiDC^WRYr9W5S z&+4^C4esxY?khd0FSg^9tM6-lTB7Xli|suwt*Ei?ELILd&zjr&+TB;qQp455 zHrNC2#rDS@%vTbsSTt45HTAN_^nhnQzeEY_cSE+3_F!JSw%Bs@u&owu80*Te2sw?D z?YBLcFF3jqc6(QGYbwiac4?ATQ>K(!HKodc++C@Ewn6s*|Hx9w)x&mO^q64F?c+U| zuShHjnHu1lD%fNGP+E9Q>Xq&J?d~@>hUY>hGPj%hV7@|dE?_EH%&qm35;@s=GN6=OS5KAw z*3@#vjcyHr&^_4Q1IbyuTs?gFzkibEwrU^D7wmP91rtTwahg@sqSBV87Tqwnt-HI| zoJHg6VUzcPH)OlN59SL_A4mk_Dz{d#0%cI$-}Ea3_q!q6DSj}oU3CNF*m?tZi8xP^!>fa~s;b`_EYtE4*kLTZI5 z30DbY_}BQ=uJ7Q3rM}K*oKqYfjs@HwbV%`xy~*~uZ4(JL#MQ$gC@9n5Xkw_9^mLR1 z;szEt5DCsZi3X=~nJL!gtD!WnIY#wZm#!)9eXu?rLSm0W168KX>xV z!F<7i6NyB4GPmw9Ys25g<8#>uaf9}Pp3c(USI%-6R}TlZ9C$Bwg3CdDB_ePt#UyU& zL~G_h#o!`0;(~jzQ(g|{tLyw1u6_c&SEAr6cM{COd_~}pp=5jlmsQ65p@e4b)?JNi zPixq}#p80N2A(lOP6vULW4ecsvsk^FR5({UAJa%3J6YynJ`!-mOEff&OOGX$Vm_<( zYnI|sA~^(`o+!4(2NkC+5VHqqvhtk|%7oo~(ju-(#5?Lum@9sn8R04(6X( ztW1lVZ-5~eawq5<)CY{0lHn2Dafh;=>BnVizGtFd*-<;)y@udGYI+C{R}ZJ|?Ei?l z<9H6{3(ir2*832yWjJfQ=_6j=q*kJYg@az`;XU2`=PbjydN{{tzf8;@@N+OnYI*r`O_edR1s&Ww;um`BQ4e{1nP zwa39)#bE9Fyn{=RajA|32r@B;!N z*y6yo2Cd8rbt1|?GMptRCw2Fgvjn+%I7Df`VhRVwN9pNG2lGYFD+eHEWd$kP%W#35wl z?YG9QR3rO&W#>9|_nJTPiK~Yrp7u}C+}TeD^93y`oV7KW+c1dDfPXwzg(Hyiam^hP z)!l2(G6=>BwIqd(W3BN6tJPxb*6)?-gBGOR5mN^Xuj}wBt{zUC+W!G^$50*27o6%3 zKUFZ0tA`V*z!!A)xkZNDQB?=?6^$q1NU;IjwMtRO?YzOh$Z>&9GU1DaS#p_Yx%+!} zz4Ws3u`*SDK>I;EN_|%I2*>eX@^KiNR5{Oe@{T8*6P)kEx77RiqXoNgmgp3>OG#b<3)LCwV{qvFcE>x?Y2pv!61ktpaR2K*R{D?ftukMJPT8TgsF}Ca zl#t~RG7=Z$opOET%6N@;o2?EGn`MmZgzdhUm=8r z$HXb(f2E71zuf1*0o^aj8|7D(qm@74gZ~e-RgTM?LFowiG(J-YpXX0-zve!~?S=3C z2g>Kej;WY>weW#3gMW%Iajk^YS=Kl{cl_(T&sFBSh9AaXC=3?b#8yd=cDnn!AM`YM zo|cbSN??D$kLod+Q+vp9fwMtcCcZ8nDs!GW?vLD)rTdi^mAHHjoMk*ty;Jx`Sj6w* zYh1^>q>S?<$M=rAoeAeluDe{H@z)C};aTAq@f2yT+u^>zQ|oy{9wNW3tXA#nX!TRA z6?W=XNYllK!~t-q%t-h1?x_1(JWM!K=SZ!4Q*6tC@oeQLs#ZK`kxyrM~ z{hPa4dQDXRZ}xsv1X}Z7-3J8RPi41M6p^L#}D}MPi zd5e6w_9SfG7@+P|&r|0LuLzgGb~cT_m*2oIAZj_#J``q)~x41hzr+QBE z+$R^wE9EBG#F6<&*`#cMO_!DGBK0iw7p+>mRlCmfi8M;Q)n+3n7^~@(M2P8Qh~U%5 zQ!*|kLNhKQLNG2Sf-^28!fRMW@WusHnLd$-B4aBNs&P6IqOpYt&DfkFQZPy%jZ=u=jVuvb`eY)6^hrb%8J80wrm1($xR2V5dx_wTyNU1`cM-uGcM?&QrlF|m zjg*X5B2;5Np8+Wv>j-MbaYP8lS|UW_ej+$yH4$E86%o8~tn(52^G<|{j0cENjW*|= zyizotCrZtDjtIecmI%&xnh3A)6cN1fr0cLQ5AasL$XH6Wsk(g z1tK_O0TEtfJ`uce6jQ#>l;D*x)YQ{7o z1Y;@_9}vMAlZo&ehY`UWlZa4_{}Le@9}%G$AG+SQysH&o#`xIvYyK{xv5%Se5+NAh z5y2VX@~*rS-ss?`=Bdbt6DO(>BSJKyL}*5Y2*C(5+xJ9pMvw@vF^mY_sNVJPmvLzE{zK6 z((qH4Mmcq9_=w=m9z<|PPa?cVDODO&DVWp=XZ93E!zn(wf7UA(DkZCnOcu7u!Zumh zX1Q=4x;=}i!6Is~h#D-ShJ)R{mfhaYZcmee*Z(CXm_w<}94x$IJ$a#0l_@eqM5CHC zDMgberDoQNp29u#AE^`l2O>nBroE=qY!!5xt(rNG*aUMd5u7<%tj>Gq&5=Y|ls;B$ z$t#Ome<4aW)A}=!V(U*tXsz^4@a-#An&XM!TIrpv!Ubg<#By#EEK75UspY zGiiMg%z4ziIaj`^FbGx3yDoN7f5{$ta!Y+TpD$tQZSDt9yl{|jC9q3#-i3&XlSi3 z6Ct*~M1Z3Q%wwnbbkZDG8vw1weYpCL|)%(XL|#33;cSPRoN=r)7=TyUN;5_vv{jyt%`D zOP)lNc0ihW0lBYWo=-%PzQp}R-bs;p5$}MuS2ZtmcNDZbZF^LmwmqUw+a67)ZI7Ub zJWAdrr_&1K)$3R~bycq$Jr#K;ym`GRktfl-mAKT*TUeZK_MBwPklzVpaqCNjs`nv6 z)O!=5=`}hrG?jNX%Wp%>ci}yKFoG`Up{Qk{7e2PPrUhu z;_n`{J;a}Ceyiwtmqq&NRH<(vLew{pAyU(6?GW@+2?^#uL~uH-PF|f>Ctlx3lxo^e zgqWsfMl=6au3(*5nj?B%znOYXdzIVr_vF(W{9sw3oUNw;>Fa1fIvww5I&Crpoi-Ul zx`c+J(>BJd)252oS5kjz+Ovu2QbJm~hgwM z_E$oBAiZI_znbapZwR~ZU?RlyAR@f_x9VAiz|yIVy0@E0ownYpPKPL>PFrtHr>(c3 z|A*c15Gr(9dc69(gm|5nOffx*kd~%Bn2;W!6?eNsn&zIG9!;AuPT!-Ut}i`PJEfZs z{RI-Jsy|PJsMFS4(`oB1=+6)(m!3_9PAj5Uf07Wd(~2mjk0hj}=Mo{LkI-^GA2ee^ zdO7u&ZqZPmmu}LY>=uhOZQ0fIJjk*_xwxBnSM|Gy5cNBW(DXZq5cJzArB@Ka>9iU1 z>bJNZFWL5TuMgoqYI9dBzx0BM{JHjpFp+mW=(rmuC$GU)<$oQ&!SstvQhGQQm{m`6 zu5m7h$;(CZtIqqJw>xieega#d|AdL!9ynR63g+CyVN$=+)dVx-jW9dB3nsI#l8KG$ zSD5OT@G|e>NAPi&%8`lACYTmo!C%PlfJyLEeCA93WBxrs6GWJv_JtYHTww;Bgm{e5 z2(zg3gf`gRO=ip=2!9K|2z$i=VzoF!ld;Dm=*sn{vee~ zDok-FN~2(9VXd@6I!!uRx>5d6ejKKB7fU-G*E%kPN#PG#CrtJKtG&C^cW2L_^r*B@ z8Uza&my1V<#V~=}ER2So~hh`B~v=AtNk;sc}zOsn`W;2iy3gVbghy>mS#L zFeyAAmH-ZS4RJ}%ubfZA8pcU5DNI0%`?=!@_+`Df<-4r2muf@8(jD;Yc>!3h*bYkr zPT?^jErek>Fp2M7;%ml48zVviPUor6p6OS-)0~6;GQJ$VagfBgwh_W;t@%Yn+QYYym zD$GBblQ>ht=>y=@n;y?CM#7{(7x||4qx|lhk9b;+hXLJzhOUqQNGtv4lbMq?^U)n`PSsKbE z1Y`b9M5*p$q6ZN^lX@uCX|r3Z(=b3V9Jk~pm|@azeuRuq|L6+yo*qoNt<22c@uN_6BAz( z;WMwHWY8i|YKY86N)i6$b- zO%D-1(@jK~DP@TCn{)_RYMw=?)Z9$n7=JOM{dlQ)HKU7(C^vp#PJSk$%%FwMZ|q@C zo?)VmIiV%6)clkw>ENlXV5^)jF(v`EEZ{+_@(Kg%sWlPa)VYepYbrOf5t=1$34u=G$zIp;WKVy zw3LbYOiAllS?h0v%342X;x*=E6%pkIO)j5t6}1^x65%&4(oW$%=^E}bVP(#DzIFrr zU;<~2K3Z{R%G0M2r@r*5)MI)R5vA!f^BD`r@fqZF$*=Ri~Pp>89ORpiKLNB4B z^&ckMnRuHBzd?ic8`P!WSjd#LsQWWUh#@UkeuJZ=(>(C&?=yOu37Rr~{X#}GqJDif zqXkS%U?Ru_ExCT3r_}mA6CW}0JQ3wa<}4=DOf)euhl$}#bmbu}0_FOzRH@SvRIamf zrQgq#H1W&zGZ~poG%_)Ri4+q9nb2r;C~y6PV(XVo>>|Qv>|}z5<}*%aL<991D;UwR zea37?E|*!g9+AX>a@)G^yN&sjEN(dm`r6a}<_l#8jZ>LHBU5J3SduCrr@h zxlF&8(G^T=V}e$PGQEKjt;}V5!Y%o1ufVqA{8r`~YuZNHYfY_Ihr7s5<}a*As*0-XmX+s3Ws~~>c!_ekdx!OLjar^LRr*kR zO?pzgSGob_1ZPR>r50(vG!5nq8>KM(5{fU^R1|hSOf=CRpou2h12oY@dw?dIXb;dt z6YT+-Xy*3-!Iq*4CfWov!9<&YCYWdw&;;}NLKMcEXb;eM6YT*SZ?e5Y^h@>eCfWlu z-b8zV#+z&p5ZfRz-b9;##+zsp(0CJV0vd0^CZOCNpz$W!12o=5dw|B9Xb;eM6YT*S zZ=yXw<4xEDl;6@i&P1Dl#+faJ8;vuYF*Frmtho$B1BONnOEA=9$SlUR2*W}Q3oy*b za1@4l7>>j+7sC;G$TW{N=j5q*j5!;_EDSR-9A1FY=5!3xFwDR(1;b7>8jjhA|jMV;BXH+tNDP99b}pGDl!I6vH7Hh8JL@nZ%I5kirnd5JgpV zq#41cFoqC@AckQW>M#t&Fa*Qk0%S&-g9Dc z3&<|FL(N{;RE41uLjXes20w;!3_c8H7<=tX-8z*5E%a!AZ7f6;cpCoVfeEEN#l16 zzhU?z2YvMBr149R2>guUC-?>S);9QPc&&pRFzC)CjUTc72Mph1*oR>+hVL-!!SF4H zP7EDgK#FU^XfK!&#y1$g#_&}E;>MR4zQFJ~hR-m3ieWc_uHqUuKEbAsG5i<9M;JcD z@BxPZV0a(Hdl=qD#WiNUQ!vF0wCy!!yoD`q79eW8fngVh*D<_`;S~fK18sYa8ZRM} z@gjy7Fg%apISkKYcm~7M7@o=j440zDlR46xBgPXL9>?$)hDR_wjNu^+4`O%#LmLG) zT#6X?W7B;Y?!|BqhPyG`h2hQugpE5e+)jRU?N7%ToA#sjmG&RadcH;rkW+vPL+6M! zuv)v!wLx4XZna*j)+(*Tv#`pZ7FG(USx;1}y`)R{v*Apjqxr1muhD8OsYb1H&4$nK zmRPHSh2@SJjxmmfq?V7P$B4Q!_36_Kv8YdP!LSv>X&6q$unEH{7_t~PV#ss>spa+Q zldz?GcKEqVzfptr*r~Sc73ThE*7j#el}k zi_*uSTD~Z~0=rv|;b;sk7@9FO6<}ey5yLVJ4G1#nr3G4$UV@<>!(t4JFf7Ed0KnpHilUkW)@(6`fv<0FifYwYWe*1w1VlV^i&K}FdT+q z5{AhbCSVwkVH}3BXi{`kdJHy=#xM%QNDLz|9E#x(48t*`3NSC7Nn%Q1h+~Kq;K+0Y zLl{F8LlDC-40Uv1qMHca)8{V=!moro60cs#88T%2Zj<1#TdL8iZE!ob{LxBIcc?E znv+&A$QV2Yn4NZGkT8fCcnq!rWM-$G1)809VBj#=G1w58|6=$D!`~SG!tiGokp5@3 z`A5Mt%lsX~Zy0{X@Jj(^nm=Rs3B!*VzQ?eSKv(}W)7*o8o4;TjBA7vM1S zDhyX*xPk%ge-1M*!=_6yT!P_Z3>RUz5QBx`0u1M4I1eD#{~TuS#HMpG>?pt_b32A} zFr1CytO86l&%|&BhHW!2ZN+dphAkL2V>k`Nsn@Sn*4|K5T~q{zsgAL=OFL~lRq4~o+m1kb3lSCRtwdC&=}WXgn!ci{O0Q>5)-floL{z1h zFmV_Y5hm!Hm#Q><^HOF0M3p9e^HOEfH!oEtec@DP(lZ&Z#o{FrqJxsto$ZsLG%(*s2Wrg00GUoH{YCV`4iKCo*v~6Gt*Jf(aI;kzs-A z^sQZ$PTxOO>GZ`@mHr@gs$a{*IZT|uL<ShAIijFCW@(O{hJB;4z8;8Ekc!P z`kJpYeK@0JhDjQm$~28krAeQ#(xj28G-+fi&4;Km{re@7HZ)4~!+*ArVH zJ%fo!OeB~HGtrxgN+uL0L=YJ+VE#tY{E>;znfREA*O+*b30fcm=Dmz)xd@n7FrvjH zVA9u<0h1QJfJxs{225I50w#U07%*v>37GWtVkThHvJ)^_gv|jgG!|i#mZX5mB5cqC z6);$Q4O*@O1}!B4gQj}GpoJx1JVrw?ZfD|VCRlt8niTBU4@k)F!L6ecD!5oMwm6K*QZpPAUr#LKk)RhaiPyo!l!Or)7; zWMT#rDJJ?dp;2M{!30g&3gZn%PcU%<6W24bg9+MfR2YzIQ2#27c}zQ!iGED5TNvyX zIxTY*`d8GZf5`-Gdn@#Z8PNu+Lcfj?ZJ;W2S`RApCZ?Rt#0c_kx_W){I%CCs?&4px zEzrr4j&6HcvEO4;Y>k{}wCfZ(>-o?>5+iVL69l3Mx>FqnuKI5XD&u+bN=X+N3X*iYM+>SP&v$&m?o%sW2v+Zm?=aPHQIct&~euS0#n3z7`iWRZV<`T}fX^WLf zVt?Um`A*W8ZV>J{ds8iO==i;DN2~p3$If3*vF>R*^+9g)6WaAp6cx==9KXVE#r3i| z-qsRYfAueAu;N!FxkmU`=zt%9x?8vqz8;+}B%G%?o1I5E`#CvBn`5qHyu)uFV~3;W zY;VGEw5qnhZQt5HgukwT9?M%TC7kxjw&~UHPSaquPmo2DVq> zAVK)$=}!DZu)X~C*-rL5u-T#XwSF(o`txgf=0Z4Gko^!WJ6W*TfhP;H-~D7K3s!o^ zuUNIBb=`_J>#OG++pwx(-HP?_^q#I1fO81hPsTFWy{w|I#p5N0wqt=ih3N-b*ZxYgxX>r$!8|L5}iX|-B^uFQtCXzRlN+c%zsls=|lDuY_ww$ShXP zWT8lWfqgyaf*g;DRG8zhxgqJ%4vhbnWXVVJC0V4VYvzC$#Awj{lLyhcTBX zGBKNF+GB~%!1 zS7vb$%^0E`VDLI!%~?!DucfbEglx2X;h@YNh{hef$gGsmf^QsOvjo{^^?7GA>8gv4 zi965glg?(k^;+O+T@{&-tof`y3vK2wzs_F8A4Gx59H|{r$XU!yi^=OVhm+TDAZNG8 z2(AUZsh}(&J$GouM~?fY<5`e(c&s!@FbB-zP5(4KX*y;~QDf>W^1tNI<#*&8Y^!ba zY?E!tkah3{>qFL`n3ov;Y5ZT~@1;qSMf_U)RQ$ELT`YscXI~aV!hOQ+@cUIlDGq;` zj){L{V(?#LjD4MT?X!?@0dLb`Owl@l+Rw{rq4^i&4hh&2*5?`>kD9ZqBhb+m^ai>C z5c*t}!w`reH;|EjF- zAF{Q{K0`%VpGPy7Nq2Fni-gDXa!}^^RW9?GQxj!AH-j#iFSF$E;T--jihZuzJJ=i$ zdrYZ`VxKzT3cB$YgfmJmG4HoHT)5oUuCI@V<`qH@CvBS~r zsDp@v%l^LoCF??~*P3PYnm;!G(fkN(q^dUO7~*ElaJ%pgL+C>;)~W`5tMXA-Ey#4( zO=yN3uq%}oTNeJ%KiQS(H2J*jqc2>Pr#YvQFeZmx$NQ8=zipL^)$ml_XgrKLPos@1 z<#errgfT5_FFtCf=`C`R7XUPwKaH%KFp^bENq8Po9J!xAtTX8saoM9yC*irg07PBB zM30@9Jx0KB4gL8FImhi^Q?kYb$6<966A1^gEYxOsPWoD#yv+w>4(Q07$GC@?by271 zLFVHyCe=-3KF(ug;+c;%ZGeOmnRHQ8=V1#Ew8~4?hxNI1^U^?9I0p3v)Pb3Av5pCD zxPZqf$Zpr(O(a~!OF6Wdw`*buR9?3P>C3}-7&A(I9y8$JyiyXz zGo4Z5^D<~ti_FrOho|voBG2>OLs}6e9+NAh#OLWGzKs55m7I|s#(c_XW#^^#^>p`c z?K>cla0zeLjhkp=wOkbf@Rb|Z$)-kOobZ`onrJd%_F2bX_gK4X3kHq&hqJ~J-_iPB8(n4T2Yn(j9(55-~VyNElC@-iGX?cYh_9jt}Em z-3df6T+Y|AFCUV4i@6~vIFpUY;kEo8lCpsIB`FhkhS6$9Iu^LgbU^6Ql~e#Dau|(f zBy53>uxK@-d=`w9Pf(?uydYGi1!z}+3Dm)QX%G+9((nEW^j>07CP=fxtM$)1`#1FW zK%daG#!eQnPPXftX4z9q!e~+NN8%Lx-%9E}C5)CfVz~fi^3);4njO|#+y!YHNf-@o zvXE20K%%c&l+NOG5=KjV3SQP0cl7mc&Z^n4bzq>Uqr0ac22ixPaR4na)2OTzFrY8x z%}1c;vjMNv58OdV3%Qe@LF>=s(6)p>j10;jR#w0dJkA~Yk+0)N;>>i!$&c`3p^nD+ zoFDsqB;3SNcX%njrW@L5#RVA;6AR5eFGKeq`bO4{S367##G3^;aQtz@A;SVgF)Wyasln&NZePzL2Jfzkt_%E#4qrBle2R#M$5+ zq>B#WTj5(K0rMq8J^K!imr2B^V{=g&B(#qhcq0=D?TdgDb;>o63_OCSF?z5?mw2#? zNf`ZVg7hvN8Xt1#tCdP}Rv0~KL|0+jwItlnDvmvb`Kbc4HF?DH@Ui~cZHIGO3jUV7I*Ww&z*iJ(P4 zpBGd_pDk9hp^S(?ua=dZ3|~pNucNcGgN;XM$72~&SQ*#T$7RKxw*LwezK*y5#u>bn zDg2!Ip7JdET(OcB+F7Ug40(XTYk7YXG+`Ko!|_OX2fvCKETsKG1zak$;}L*`?xBtV z0MTYg02b;1xQ(ve$e)64`S7_n&6COA8noq@=>Im_UTSdm_K ze8@?c%~Yy_g5V+%O~>UTGMg-Xer{L|C6L-EQp}fj2tZD z90akn=-5yMY>1#Aj9`SF>Zb*^;1GVMlE`TOENV^<{csK_`A7<#E-5*Mfetu<(bwq> zLJ8<;Uv@})6Sl6XOUUpy^7Af8~qyupU4Y`i`qxwex?2DY+`SL|`pV+Kb7eRh>n z<0FxDeU}&$-1-ZagV&HqA%FcC+7ZQ}H?C3oj9~vo(4I!1dbw9w&|TJ1)=?Vtmq0-U zx`Mo*S|aF$;`r{R&o5Pyosmhr>?24(Z%XL-CdF=;28cr!6!nUSBhC+3^LUxMtAPLj z9vwf_HXb@{1!$WHx_yXEk9!CsfKBxAP}_KhwM`_O{%wqsF(HDU9%9wQv3dY-l*t=< z6XFO&kNNz`ZOTT&W4kn?r`~OtD?qS!QBtls0_QVyg2|>DgW&pqptjq8uzz8H#s09J z+B@wH_7s@7{hjSzn>T3>goH=Ii$g!=i{^_=6TD~??+`Y!zxpN9MaIbI#bh#zL@<-g z?&~-w{Z5*`S?QwFu2Pm3N6>^v==&KX(P~dzV1eOCfcN15nyfy0tXX-A)=zQR=rwQK z3+N3?KpotMyys}r8D94ouIw>1?tv*ycyIPd&tcXv?V_#Y$i6lG}tkp-K zZ&7O12s$T7I-f=hmn)OBViG}*ZYh>(rq5lWu=FPpbm|aR#TY{>DJ}7Jd3w5G#EPJE zhZPhvSWTg?1QoYqUp|S<;vGC(OBc*l9t~~YrkoSi2xiYA^O0t(^%?Z&c4cN}q)yj* ze_Az()ba}hi6=LGu8pEAcPLrRGN|FVaNPD^GH!zqp_hV!?Kd;Ung?TJq?*5jX!QYx zy>MC}Mk45^AYOeOulrY! zNEs)^jp)(=&zQo${)}DY#{!3(%ap(I>_Z@erToc+nd0Mt)baGxLI@beP#P^!1j%%qmb@(mC0igj2|1*jSfSj3cw=rw(?5_BI&xI`(g?PH1dVURmY?az(jZ_96EPvS{26q| zCWVEyBIxlUy!`GVX##kmn}_i7>)?e6ny_L1kqraT&Eq{m(D^y&4oxGGdfwVwaOm?V zZ2!VKr82Z)ld{gp!lRujkXXz1yzK$oVcTX~hi$ga1t+q64o9r~hk3ub-Sm~|Bhvw+ z6Har98h#-(i)-bNM87yrvWAGR!<_Ed83Gl zv!|4Pc(*d0!D*9@7o`kN8}%0~yEl`_2L9$gBxflz#U7&X-=jRCMiQoddZJ7oUT20F zefC~uD$JQh(9B0zm8M-mBI~ggXiS$%H2ZOY;MiX(wMt|iuec&n)|J0h(#A*7wnreB znrB|!)3tR=N9X#Utls{t8Fh;RUcGedQh--ia80+jqi0PiRCwX5lBI|9@^-49qY(p}Mpr?*wQZNxlIb2R6t9a9HL#rc*3XEB-p*xQ%Ul@1F!crkw zSYm<#VQ)-h% zmPypazJ-G$GI_y;gMzAq7<*Dj)N%`4;6CC)5xZKRW?3K@;i`VJrd$Eqqho~qE*shJ zn}J(6;c=&(^Svx3wDDzSXVOILl_S~&PwJ;l${@=Pi3+sv8fC1{dZn90(Q3wu%AGAR zmkObStbq+%H+S_604s5>Bmv?KD&B`W0i7;nWvP1zMkyq+h4(mt?V*_u&^hSAq0T8~ zI;XgVDSr|{2Mx7IsZNVP^f*-%v1z3`8d$au^lj)@n-pn2@|W>| z;;1zx!S0~Hrvs)qqBz-gSftNh1*7|~A64EEEl~r1XF6TKT^T!ON&mVH+xiV&%ek~wYS|=$?rs1to9Xi*aIT>Xr`Qm5vQ|#IQBb6N3^04Yh0ou&CQV2>VVJLe zsJ?Ek5X821eU^V4wMI?$I4bCA=ljz|yN_N3$5>4U#LAFfO=5=iDXF;HWLJ~#a zW*%?*G!`7lQKHE@idAr1Xa=!s&JgV@Q z5g6rQ6TQrV5tVf^ygmd8JxCPIaq|Ka#p%+!RH|)KszTddRt_c6=YOgs?~LjvhAKeIMbSCM0xEPU z;~-<^i6#vQ()ZGT$<^{yIm2<>a;>EcPHUTN(USg}^rAtL9+mEq2Be_)y?CuOS1Oez zN~0x{7#80XpAi3p{X!v$A6nrNOAO+lMS7-O&S0E=NBo*G^*kUrI!VWm>6{;xJ&?wr zw98xS1toz_4Qh_*tm){_VAH3MYY3&L|Siq8^eLL*}CG>H<|zVuo@tD84L)#QVhi1{u41 zCW+Q24gXs*h&+P$whQktg|c@CZ+$h7%FwoR$_=jTNOUqPn|1tNr9{Vlt!!`xNE995 zm3WzceNM@@_mXHLEoUvg>t3(`PJN}!P2IbmM9X<0hfw)dVN%Cq=ajV2_VY@$1l~ln zjME<(TZw`NjKx_96yi$iyP!+}gD;9UJMy*CJp@7ED^5Tmt15L;h%O!?v2r95H4;Tn zF9kb;2H#c^MR)Jk6?j<}>{vQ;J)X;gizOUCB6)o?qgE zWiN2Ph*Ra@+5`>30^>`WY$3<@$}Z6c5;BETrHa~5Fls{FJwK|S?y6*SVOGxLG7`lI z1ez3;X6pUBQV7Oc6x}zhw>oVeiB=;=lX$h&61_uKr!RrZ&~>ZA%Ubh>zN{rZ>$ePa zUD2C0sk&>`jHc#QTQ~RQ=aMKobY=LYdFlMQSu?MKbyr!7w{{M6ZSLK;rFTO==!@y} z&`F5M2D^L8x_Z|1fPWiBhYuT5#dJgkwcoF#FM&Rc5q~Q1kixxi4B~sRqUK)5AxE>L z(wb`d8Z4lYWtXKBj&+=u#8M$#VOnZ3h(8tgi9O;AJTU&H@Z})b*|+gs%v-tq4Qot zcUshZDM5scAtFGl(c!`xXE44r(Wa2%PTrqGq6>K4N6@aAkrMigsE#r)WsK8mD6`c} zW=mm)CW=lM%4~H8z3#lirXr*0bD_{yyN56VLR-&Ch(cSf6WY1d`76bp4dRK>9~94O zE}r|q#+c39b$C8~?j#JN6|#Dzq(*1)!qB6vcG6ABYTlL5uBp(+nL1WgGgj55CkB_HeLaeq7D}IxzzCtglp-qpI34ke12c2r(;cLhduie zvm7Xk<||URj#1X@1rnkmiX^Oa54{c~+(JKki;ZUk^j~k`c!oiL9M9^8$Fr3rioyS5 zs0`~6=QS>MtZ`WqPW`f@MPNlSLJtf^84CEI(Cfu(B%s`&x}#W(+5*jYx06cS(h#IG>lcB zwM21-X$HOcrZRT&lK%C*>w4C2hicIWMReDtk?|yYCCAQg6!to*q^T#SMtgbd^06aY z@3!9c>(}-4Y~0qdrR$10B#JZ6M8x}MT6ED>PMzb_|$%Era zw3|2JD2i=uN~pr6%G|<1R})!Z!&uK&^h7&(1&E}Y40=&iS?D8*?k6Im#yup^fQVK6 z1r(~9L7|e>%|g0B1jxVhh5f%F{(jirXIE`M*gD~q+ntvFq|?T1IHLDe^-=X6^`Idv zo)uqJw~0R&*NKgyEPMyAz9Bp-JS5x!iaPmi^-t>W)O*!?6MFY6VFts0wziGLQh4{s zDo(38G<%-9J~M_kKC)p>+H?{_10Rtyhwf@neUoEo0Anm_&Ly#^DI|u*@ccxnA2g_J z<}U_wUtfVzhXk_4B|ZM0fSbe=`s78$ox0~*62tXu2YUHSv(ffARj-Z@ot~|}D1xgH zbLfaWD}#Pt0XvfpO2^zT94A&e(rz=5f2-n2Ww?k=| zH7E@L6ASJ5OmR18B!+PYRBf}kYGb~Y16H*tw<^0K4^*3DEF@_9yZz7hQ}!M99=LG? zA~Gk1w;_A@8exf0C-|5g{EmshskGa+lUNS#&HXqrHFs!+`Pc^6l+Y_Ft`ZxJp|Nbv zDirrQOxz)xFNxtS4T}4m4En}wl{qxAO#U$Tc#eAr@6f??`q8&A0L0w%U*9V3{A3bC z&toj-&74H!X>TQorSVoB?86%fYCc!`Ouagq$;3P2T%gBTUKP?~PGX5kY>W<9a~P)e zp4%MD?kh+P7fB(+H0sQy;jstWR3%3Jb-mfta>&$2*$ zP`yPZ>MFHSZDczXaxGd1iJ^&1e7v>wbjNz|$iJ@0=D^jSQRfDE8U45lX8JhOV z6q`aPu5>vh8Xv8g*$x3yV&>s?uN@xzzy{Md;3|@oPw9u5QZ}FhO?d=xeHt7z)A5EfrfDpRp^uHyT7QYOs*NK;YXEQb zi&5a_jubeR4AwSY$JV)!Z-*YcIjN8-)(P~be=0e>UA_)T{JW;J6F80@Nup&80(yU> z9*n45!6`%xrfTD9Q@gDJ*xJz6swm=L# zm;Ex?nPe1a3V!yN#|VWjW`8Yk7L!;7Z{<=>um*a4tvb=*70TG{fYU=_=)EjX+~ypJ z)~FgR36G(>f^BX{TR>vdQ5~v@hn=-*T}BLD6P&AU&@TuFLX^`7ENad;pU2m;CfHq4 zdJixVSHiu}!wZ=g`lwF*Kr9wMGAc`O24pnvBUO{40ImI4WOTTldRk*f-%klthh zEln26#KY1~X^pf*s*`+@@7Rp7u6tlSuH!}h3CH6Gv_F5{q~0ec7l36J!_|`s%dCN} zUZhgjiB1wjul3PDf@dJ{Pg7W6n-&tA)r)o(=j8CoWDLjY%ml+3NcBE&gXO-s=B$&& zOn=$N7d&^YV>040}m1{_05HX;M6 z-_bISY7AY~J*dYTY5#lLUkhXCpdvLJ88!9pX`^LtfW*)}J-C8arm7E8=U=oWI_Z7w zlgrJQ)DN^nYOERM4<~@21#JJu-~`h+`q*|QGb@IUYogY)86>udcX%u3f1^Y%p3?j< zbsa;`6*XexB^q%OiQ$Z4Exu!>(93Z=&N?H8zAF|#AB>Y2x~+)(`6G4Z!7LKP72Zd^ zys-J9qo=eK+88P%-QxN<^=1FqWSwTGjDG(o5mdR)38{`R&KRGJw??HCWf7=e&CR*>bR$5-N ztW7%0M$|tfC0*0b(x0xx^rs(vJDheqP!73aOG^Bufstuxb$8mO_LZ09JLUKM#U&*^ z&xp*W{7$Jq0QXi(TifW#E@k#$a#*rzGef*<#(DWm5anODcqWrA1{vPZ=cF z9hr=nl~>~PdxA@)oh>Xy{KDZ>+wc~w&u2fEy)}4;R(V^V}q0Zn)%0K~wcbcX4#Ur~1S&jo&8G_hTjTJM@l=E?6Qqm_^tdEDDyCmH93w5ftV1 z`{2L%(zXUxHBX{Fnm+TLtEf}|zQ-R7dPiyi$gCa&Y_U5H5?{tpjkK4zB-jnvcxbRgkw_E(3o_1Es5ch zgWGZ7X+p0AHWyezKYLLdXHsK*TtA|9*W{#?FKH~u9>ahSYVjsEH0dKfO_u%O$Y7-B zNHSNQP0UkxI`rSCwRw^n>&0Q{y2LF$49$F9yCO5DUu)0=Yo}ssdHn;4Cr`hw`L&58 zhG8G{b(%DK*i&kx4eL|9bpY!uqC6b!wcSW4C6l7 zl?7}-!jKORNDD>|NQWno7~dNp-d4dIwE$Mnyr`v`>KKE@3hlyB2(!XI4puI`2WPS0 zYg-BI%CY{Z^SQjBENBTu+fHD#6~?9q>7`LjicV845~irU|wt7!uyS*-XgcRv!fHXtOPqp zk+_+@F;5*W#ZC0{d1^*>9AhSE(Jo3@w1-S2jtkn4?V#&tgY^lU$gH8pvyM`uGmaq? zf{i0eZli(n^GED;jPr@x)6)=|U5j$|cu378Z`g!ogY+yNYw_C^l$eDEnGU&rEYTVHn(6On>?Hzy>t=H7RMa?S0#6^Mlf}w%^-sw_RuJk`CME%LBH!Z5pKOHrw+Z zf3dH1Y!>cj#|a249B(`R;LuJw4m-B9UqG)Q*kH*3nAWwfJpmHW=Uv;sg44PMBMSc- ztthk~JbNSG})pE8>{8OPCzlvXd^I| zxIqvxB7_`nW`Y>>gT$rlSlR3zA_qtuMum`-&4a9TlXx0`0|C}N5@5+B4&k6Om?B2e zY)*(KG-xz`4;$3X}NRmE*r8)4+Xf^!9t}r2a*eG2{EWAnHy@5otH80V-N;8vCNW3;?wyPC}qpIOiXHmnc|*-E$}o(ToO;G0ZnnbAEjg|UtluL z@9prf>GXHP7S}jNGY|($N8;d65sBjx@LT5db}mf`WogPUjN>hTyeuLUFVVGpsoT1N zuD(N_1yPu|kKaJ$*pfl}F7W+jag3MX7}nw*V!B4+Mf?RMcME!E2K|zuI0kS~L|eFr z=m#!>EMoiyWwAvki&J@t*v%H`W@caCl%>7>Qx@|jKl|!QdpI)Q*o4u_gupNvq~1W%6Ry3}NW794eGsEF%Z380V|3b9OI4=Z zb+J&oJXNWpqo35A^qy4ZG+PH-Iag)ot>SGGaVc3rAV+zYh0v5>LLE;#3Nd&lC zS%ABxJg$$pv@(Y2BQC9$gIh@)qY=k&R9rqZxxiW%nzCCdG%kkGK_8r0#>Rhk*h?IP z69`Cl)#HPc1mYN*&|PImz{GLp9mQc;2A!wz$^1BmD^MJkxrbyFK#hS41obiV03CDLJQ;IQk5I94Bo!{EvA{$;yhO?|{>XJS2`z1Uf=(bm#L*o)qt*M`Bt|MgT0HKv|H5>Eq};V4W)%6g%k2 zFEn@Z;gux5nv3}DC`l_)Lj7+m3rw)JF0PM3w$k@*=BusZ`VeHRTaWjZI=#{g(`<2l zOtMwS{1yDcgy@cx1Aqj^Dv?vI2#FFBhd8Aj7= zHuEN;ytTQ97!4%f$nT)MwdqKXt~Qdq?MFzCD=`wn!ATA$6vXxJa~o4UR}Rt!&S`Fg zk;3?gkeKCs;{gj&K~^8yx0W@?k!$v?ti%50n;z$$k#~MI>o^2EF@f?w_1X($S#Z zJ@kS`&KdX}>`OcE%cZM!&!Jv(K|(puwAcoz!=`nTZqPRJ3aH1md``y$#HZ>vFMddw_Fwa-wiJJ zE_NPX)BaPV_Mb|5?9}L_T_#wWC_Y9Vp43H>@K3thlX{ONT%bm8YKtWNjkbAH`z0|z zPkU1*ivG|)ys0)(623U@OU;vn^K_Cg^_HFde4uk6mXI9>&XE)N_Rp{3dp>*`;aU{F z7sL18;qx(k{ue%