#!/bin/bash # Copyright 2014-2020 Security Onion Solutions, LLC # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Make sure you are root before doing anything uid="$(id -u)" if [ "$uid" -ne 0 ]; then echo "This script must be run using sudo!" exit 1 fi # Save the original argument array since we modify it original_args=("$@") cd "$(dirname "$0")" || exit 255 echo "Getting started..." # Source the generic function libraries that are also used by the product after # setup. These functions are intended to be reusable outside of the setup process. source ../salt/common/tools/sbin/so-common source ../salt/common/tools/sbin/so-image-common # Setup bash functionality is divided into functions and user-facing prompts. # Do not attempt to re-use any of this functionality outside of setup. Instead, # if needed, migrated generic functions into so-common. source ./so-functions source ./so-whiptail # Finally, source the default variable definitions, which require availability of # functions sourced above. source ./so-variables # Parse command line arguments setup_type=$1 automation=$2 WHATWOULDYOUSAYYAHDOHERE=setup while [[ $# -gt 0 ]]; do arg="$1" shift case "$arg" in "--turbo="* ) export TURBO="http://${arg#*=}";; "--proxy="* ) export {http,https,ftp,rsync,all}_proxy="${arg#*=}";; "--allow-role="* ) export ALLOW_ROLE="${arg#*=}";; "--allow-cidr="* ) export ALLOW_CIDR="${arg#*=}";; "--skip-reboot" ) export SKIP_REBOOT=1;; * ) if [[ "$arg" == "--"* ]]; then echo "Invalid option" fi esac done if [[ "$setup_type" == 'iso' ]]; then is_iso=true fi if ! [ -f $install_opt_file ] && [ -d /root/manager_setup/securityonion ] && [[ $(pwd) != /root/manager_setup/securityonion/setup ]]; then exec bash /root/manager_setup/securityonion/setup/so-setup "${original_args[@]}" fi if [[ -f /root/accept_changes ]]; then is_reinstall=true # Move last setup log to backup mv "$setup_log" "$setup_log.bak" [ -f "$error_log" ] && mv "$error_log" "$error_log.bak" fi parse_install_username if ! [ -f $install_opt_file ]; then # Begin Installation pre-processing title "Initializing Setup" info "Installing as the $INSTALLUSERNAME user" analyze_system fi # Set up handler for setup to exit early (use `kill -SIGUSR1 "$setup_proc"; exit 1` in child scripts) trap 'catch $LINENO' SIGUSR1 setup_proc="$$" catch() { info "Fatal error occurred at $1 in so-setup, failing setup." grep --color=never "ERROR" "$setup_log" > "$error_log" whiptail_setup_failed exit 1 } automated=no progress() { local title='Security Onion Setup' local msg=${1:-'Please wait while installing...'} if [ $automated == no ]; then whiptail --title "$title" --gauge "$msg" 6 70 0 # append to text else cat >> $setup_log 2>&1 fi } detect_os if [[ -f automation/$automation && $(basename $automation) == $automation ]]; then echo "Preselecting variable values based on automated setup: $automation" >> $setup_log 2>&1 source automation/$automation automated=yes attempt=1 attempts=60 ip a | grep "$MNIC:" | grep "state UP" >> $setup_log 2>&1 while [ $? -ne 0 ]; do ip a >> $setup_log 2>&1 if [ $attempt -gt $attempts ]; then echo "Network unavailable - setup cannot continue" >> $setup_log 2>&1 exit 1 fi echo "Waiting for network to come up (attempt $attempt of $attempts)" >> $setup_log 2>&1 attempt=$((attempt + 1)) sleep 10; ip a | grep "$MNIC:" | grep "state UP" >> $setup_log 2>&1 done echo "Network is up on $MNIC" >> $setup_log 2>&1 if [[ ! $is_iso ]]; then echo "Installing sshpass for automated testing." >> $setup_log 2>&1 if [ "$OS" == ubuntu ]; then retry 50 10 "apt-get -y install sshpass" >> $setup_log 2>&1 || exit 1 else yum -y install sshpass >> $setup_log 2>&1 fi fi fi case "$setup_type" in iso | network) # Accepted values echo "Beginning Security Onion $setup_type install" >> $setup_log 2>&1 ;; *) echo "Invalid install type, must be 'iso' or 'network'" | tee -a $setup_log exit 1 ;; esac #set ssh commands that will be used based on if this is an automated test install or not set_ssh_cmds $automated # Allow execution of SO tools during setup local_sbin="$(pwd)/../salt/common/tools/sbin" export PATH=$PATH:$local_sbin set_palette >> $setup_log 2>&1 # Kernel messages can overwrite whiptail screen #812 # https://github.com/Security-Onion-Solutions/securityonion/issues/812 dmesg -D # Kernel consoleblank is causing whiptail progress screen to appear to hang #1084 # https://github.com/Security-Onion-Solutions/securityonion/issues/1084 if [ "$automated" == no ]; then TTY=$(tty) echo "Setup is running on TTY $TTY" >> $setup_log 2>&1 if echo $TTY | grep -q "/dev/tty"; then CONSOLEBLANK=$(cat /sys/module/kernel/parameters/consoleblank) echo "Kernel consoleblank value before: $CONSOLEBLANK" >> $setup_log 2>&1 if [ $CONSOLEBLANK -gt 0 ]; then echo "Running 'setterm -blank 0' for TTY $TTY" >> $setup_log 2>&1 TERM=linux setterm -blank 0 >$TTY <$TTY CONSOLEBLANK=$(cat /sys/module/kernel/parameters/consoleblank) echo "Kernel consoleblank value after: $CONSOLEBLANK" >> $setup_log 2>&1 fi fi fi if ! [[ -f $install_opt_file ]]; then if (whiptail_you_sure); then true else echo "User cancelled setup." | tee -a "$setup_log" whiptail_cancel fi if [[ $setup_type == 'iso' ]] && [ "$automated" == no ]; then whiptail_first_menu_iso if [[ $option == "CONFIGURENETWORK" ]]; then collect_hostname network_init_whiptail whiptail_network_init_notice network_init printf '%s\n' \ "MNIC=$MNIC" \ "HOSTNAME=$HOSTNAME" > "$net_init_file" set_main_ip >> $setup_log 2>&1 compare_main_nic_ip whiptail_net_setup_complete else true fi fi whiptail_install_type else source $install_opt_file fi if [ "$install_type" = 'EVAL' ]; then is_node=true is_manager=true is_sensor=true is_eval=true STRELKARULES=1 elif [ "$install_type" = 'STANDALONE' ]; then is_manager=true is_distmanager=true is_node=true is_sensor=true elif [ "$install_type" = 'MANAGERSEARCH' ]; then is_manager=true is_distmanager=true is_node=true elif [ "$install_type" = 'MANAGER' ]; then is_manager=true is_distmanager=true elif [ "$install_type" = 'SENSOR' ]; then is_sensor=true is_minion=true elif [[ "$install_type" =~ ^('SEARCHNODE'|'HOTNODE'|'WARMNODE')$ ]]; then is_node=true is_minion=true elif [ "$install_type" = 'HEAVYNODE' ]; then is_node=true is_minion=true is_sensor=true elif [ "$install_type" = 'FLEET' ]; then is_minion=true is_fleet_standalone=true OSQUERY=1 elif [ "$install_type" = 'HELIXSENSOR' ]; then is_helix=true elif [ "$install_type" = 'IMPORT' ]; then is_import=true elif [ "$install_type" = 'ANALYST' ]; then is_analyst=true fi if [[ $is_manager || $is_import ]]; then check_elastic_license fi if ! [[ -f $install_opt_file ]]; then # Check if this is an airgap install if [[ ( $is_manager || $is_import || $is_minion ) && $is_iso ]]; then whiptail_airgap if [[ "$INTERWEBS" == 'AIRGAP' ]]; then is_airgap=true fi fi if [[ $is_manager && $is_sensor ]]; then check_requirements "standalone" elif [[ $is_fleet_standalone ]]; then check_requirements "dist" "fleet" elif [[ $is_sensor && ! $is_eval ]]; then check_requirements "dist" "sensor" elif [[ $is_distmanager || $is_minion ]] && [[ ! $is_import ]]; then check_requirements "dist" elif [[ $is_import ]]; then check_requirements "import" fi [[ -f $net_init_file ]] && whiptail_net_reinit && reinit_networking=true if [[ $reinit_networking ]] || ! [[ -f $net_init_file ]]; then collect_hostname fi whiptail_node_description if [[ $reinit_networking ]] || ! [[ -f $net_init_file ]]; then network_init_whiptail else source "$net_init_file" fi if [[ $reinit_networking ]] || ! [[ -f $net_init_file ]]; then whiptail_network_init_notice network_init fi set_main_ip >> $setup_log 2>&1 compare_main_nic_ip if [[ $is_minion ]]; then collect_mngr_hostname add_mngr_ip_to_hosts fi reset_proxy if [[ -z $is_airgap ]]; then collect_net_method [[ -n "$so_proxy" ]] && set_proxy >> $setup_log 2>&1 fi if [[ $is_minion ]]; then whiptail_ssh_key_copy_notice copy_ssh_key >> $setup_log 2>&1 fi if [[ $is_minion ]] && ! (compare_versions); then info "Installer version mismatch, downloading correct version from manager" printf '%s\n' \ "install_type=$install_type" \ "MNIC=$MNIC" \ "HOSTNAME=$HOSTNAME" \ "MSRV=$MSRV" \ "MSRVIP=$MSRVIP" \ "is_airgap=$is_airgap" \ "NODE_DESCRIPTION=\"$NODE_DESCRIPTION\"" > "$install_opt_file" [[ -n $so_proxy ]] && echo "so_proxy=$so_proxy" >> "$install_opt_file" download_repo_tarball exec bash /root/manager_setup/securityonion/setup/so-setup "${original_args[@]}" fi if [[ $is_analyst ]]; then cd .. || exit 255 exec bash so-analyst-install fi else rm -rf $install_opt_file >> "$setup_log" 2>&1 fi percentage=0 { installer_progress_loop & # Run progress bar to 98 in ~8 minutes while waiting for package installs progress_bg_proc=$! installer_prereq_packages install_success=$? kill -9 "$progress_bg_proc" wait "$progress_bg_proc" &> /dev/null # Kill just sends signal, redirect output of wait to catch stdout if [[ $install_success -gt 0 ]]; then echo "Could not install packages required for setup, exiting now." >> "$setup_log" 2>&1 kill -SIGUSR1 "$setup_proc"; exit 1 fi } | progress '...' detect_cloud short_name=$(echo "$HOSTNAME" | awk -F. '{print $1}') MINION_ID=$(echo "${short_name}_${install_type}" | tr '[:upper:]' '[:lower:]') export MINION_ID echo "MINION_ID = $MINION_ID" >> $setup_log 2>&1 minion_type=$(get_minion_type) # Set any variables needed set_default_log_size >> $setup_log 2>&1 if [[ $is_helix ]]; then RULESETUP=${RULESETUP:-ETOPEN} NSMSETUP=${NSMSETUP:-BASIC} HNSENSOR=${HNSENSOR:-inherit} MANAGERUPDATES=${MANAGERUPDATES:-0} fi if [[ $is_helix || ( $is_manager && $is_node ) ]]; then RULESETUP=${RULESETUP:-ETOPEN} NSMSETUP=${NSMSETUP:-BASIC} fi if [[ $is_manager && $is_node ]]; then LSPIPELINEWORKERS=${LSPIPELINEWORKERS:-1} LSPIPELINEBATCH=${LSPIPELINEBATCH:-125} LSINPUTTHREADS=${LSINPUTTHREADS:-1} LSPIPELINEWORKERS=${LSPIPELINEBATCH:-125} NIDS=${NIDS:-Suricata} ZEEKVERSION=${ZEEKVERSION:-ZEEK} fi if [[ $is_node ]]; then CURCLOSEDAYS=${CURCLOSEDAYS:-30} fi if [[ $is_import ]]; then PATCHSCHEDULENAME=${PATCHSCHEDULENAME:-auto} MTU=${MTU:-1500} RULESETUP=${RULESETUP:-ETOPEN} NSMSETUP=${NSMSETUP:-BASIC} HNSENSOR=${HNSENSOR:-inherit} MANAGERUPDATES=${MANAGERUPDATES:-0} MANAGERADV=${MANAGERADV:-BASIC} INTERFACE=${INTERFACE:-bond0} ZEEKVERSION=${ZEEKVERSION:-ZEEK} NIDS=${NIDS:-Suricata} RULESETUP=${RULESETUP:-ETOPEN} GRAFANA=${GRAFANA:-0} OSQUERY=${OSQUERY:-0} WAZUH=${WAZUH:-0} THEHIVE=${THEHIVE:-0} PLAYBOOK=${PLAYBOOK:-0} fi if [[ $is_airgap ]]; then PATCHSCHEDULENAME=${PATCHSCHEDULENAME:-manual} [[ ! $is_minion ]] && MANAGERUPDATES=${MANAGERUPDATES:-0} || MANAGERUPDATES=${MANAGERUPDATES:-1} fi # Start user prompts if [[ $is_helix ]]; then collect_helix_key fi if [[ $is_helix || $is_sensor ]]; then set_network_dev_status_list whiptail_sensor_nics fi if [[ $is_helix || $is_sensor || $is_import ]]; then calculate_useable_cores fi if [[ ! $is_airgap && ! $is_import ]]; then collect_patch_schedule fi if [[ $is_helix || $is_manager || $is_import ]]; then collect_homenet_mngr fi if [[ $is_helix || $is_manager || $is_node || $is_import ]]; then set_base_heapsizes fi if [[ $is_manager && ! $is_eval ]]; then whiptail_manager_adv if [ "$MANAGERADV" = 'ADVANCED' ]; then if [ "$install_type" = 'MANAGER' ] || [ "$install_type" = 'MANAGERSEARCH' ]; then collect_es_cluster_name fi fi whiptail_metadata_tool [[ $MANAGERADV == "ADVANCED" ]] && [[ $ZEEKVERSION == "ZEEK" ]] && whiptail_manager_adv_service_zeeklogs # Don't run this function for now since Snort is not yet supported # whiptail_nids NIDS=Suricata whiptail_rule_setup if [ "$RULESETUP" != 'ETOPEN' ]; then collect_oinkcode fi fi if [[ $is_manager ]]; then whiptail_components_adv_warning whiptail_enable_components if [[ "$STRELKA" = 1 ]]; then info "Enabling Strelka rules" STRELKARULES=1 else info "Disabling Strelka rules: STRELKA='$STRELKA'" fi collect_dockernet fi if [[ $is_manager || $is_import ]]; then collect_webuser_inputs get_redirect fi if [[ $is_distmanager ]]; then collect_soremote_inputs fi if [[ $is_sensor && ! $is_eval ]]; then [[ $is_manager ]] || collect_homenet_snsr whiptail_sensor_config if [ $NSMSETUP == 'ADVANCED' ]; then if [[ $is_manager ]]; then [[ $ZEEKVERSION == "ZEEK" ]] && whiptail_zeek_pins else whiptail_zeek_pins fi whiptail_suricata_pins collect_mtu else if [[ $is_node && $is_sensor && ! $is_eval ]]; then PROCS=$(( lb_procs / 2 )) if [ "$PROCS" -lt 1 ]; then PROCS=1; else PROCS=$PROCS; fi else PROCS=$lb_procs fi if [[ $is_manager ]]; then [[ $ZEEKVERSION == "ZEEK" ]] && collect_zeek else collect_zeek fi collect_suri fi fi [[ $is_iso ]] && collect_ntp_servers if [[ $is_node && ! $is_eval ]]; then whiptail_node_advanced if [ "$NODESETUP" == 'NODEADVANCED' ]; then collect_node_es_heap collect_node_ls_heap collect_node_ls_pipeline_worker_count collect_node_ls_pipeline_batch_size collect_node_ls_input collect_cur_close_days collect_es_space_limit else NODE_ES_HEAP_SIZE=$ES_HEAP_SIZE NODE_LS_HEAP_SIZE=$LS_HEAP_SIZE LSPIPELINEWORKERS=$num_cpu_cores LSPIPELINEBATCH=125 LSINPUTTHREADS=1 fi fi if [ "$install_type" == 'FLEET' ]; then collect_fleetuser_inputs collect_fleet_custom_hostname_inputs else FLEETNODEUSER=$WEBUSER FLEETNODEPASSWD1=$WEBPASSWD1 fi if [[ $is_manager || $is_import ]]; then collect_so_allow; fi # This block sets REDIRECTIT which is used by a function outside the below subshell set_redirect >> $setup_log 2>&1 if [[ $is_minion ]] && ! check_manager_state; then echo "Manager was not in a good state" >> "$setup_log" 2>&1 whiptail_manager_error fi whiptail_end_settings # From here on changes will be made. echo "1" > /root/accept_changes # Begin install { # Set initial percentage to 0 export percentage=0 # Show initial progress message set_progress_str 0 'Running initial configuration steps' [[ ${#ntp_servers[@]} -gt 0 ]] && configure_ntp >> $setup_log 2>&1 reserve_ports set_path if [[ $is_reinstall ]]; then reinstall_init fi disable_auto_start { mark_version; clear_manager; } >> $setup_log 2>&1 if [[ $is_manager || $is_import ]]; then { generate_passwords; secrets_pillar; } >> $setup_log 2>&1 fi if [[ $is_manager || $is_import || $is_helix ]]; then add_socore_user_manager >> $setup_log 2>&1 fi if [[ $is_manager && ! $is_eval ]]; then add_soremote_user_manager >> $setup_log 2>&1 fi host_pillar >> $setup_log 2>&1 ntp_pillar >> $setup_log 2>&1 if [[ $is_minion || $is_import ]]; then set_updates >> $setup_log 2>&1 fi if [[ ( $is_manager || $is_import ) && $is_airgap ]]; then info "Creating airgap repo" create_repo >> $setup_log 2>&1 airgap_rules >> $setup_log 2>&1 fi if [[ $is_minion ]]; then set_progress_str 1 'Configuring firewall' set_initial_firewall_policy >> $setup_log 2>&1 fi set_progress_str 2 'Updating packages' # Import the gpg keys gpg_rpm_import >> $setup_log 2>&1 info "Disabling fastestmirror" [[ $OS == 'centos' ]] && disable_fastestmirror if [[ ! $is_airgap ]]; then securityonion_repo >> $setup_log 2>&1 update_packages >> $setup_log 2>&1 else airgap_repo >> $setup_log 2>&1 fi if [[ $is_sensor || $is_helix || $is_import ]]; then set_progress_str 3 'Generating sensor pillar' generate_sensor_vars sensor_pillar >> $setup_log 2>&1 if [[ $is_sensor || $is_helix ]]; then steno_pillar >> $setup_log fi fi if [[ $is_sensor || $is_helix ]]; then set_progress_str 4 'Configuring sensor interface' configure_network_sensor >> $setup_log 2>&1 fi set_progress_str 5 'Installing Salt and dependencies' saltify 2>> $setup_log set_progress_str 6 'Installing Docker and dependencies' docker_install >> $setup_log 2>&1 set_progress_str 7 'Generating patch pillar' patch_pillar >> $setup_log 2>&1 set_progress_str 8 'Initializing Salt minion' configure_minion "$minion_type" >> $setup_log 2>&1 check_sos_appliance >> $setup_log 2>&1 update_sudoers_for_testing >> $setup_log 2>&1 if [[ $is_manager || $is_helix || $is_import ]]; then set_progress_str 9 'Configuring Salt master' { create_local_directories; addtotab_generate_templates; copy_salt_master_config; setup_salt_master_dirs; firewall_generate_templates; } >> $setup_log 2>&1 set_progress_str 10 'Updating sudoers file for soremote user' update_sudoers >> $setup_log 2>&1 set_progress_str 11 'Generating manager global pillar' #minio_generate_keys manager_global >> $setup_log 2>&1 set_progress_str 12 'Generating manager pillar' manager_pillar >> $setup_log 2>&1 zeek_logs_enabled >> $setup_log 2>&1 fi set_progress_str 16 'Running first Salt checkin' salt_firstcheckin >> $setup_log 2>&1 if [[ $is_helix ]]; then set_progress_str 17 'Generating the FireEye pillar' fireeye_pillar >> $setup_log 2>&1 fi if [[ $is_node ]]; then set_progress_str 18 'Setting node type' set_node_type >> $setup_log 2>&1 if ! [[ $is_manager || $is_helix ]]; then set_progress_str 19 'Generating search node pillar' elasticsearch_pillar >> $setup_log 2>&1 fi fi if [[ $is_minion ]]; then set_progress_str 20 'Accepting Salt key on manager' retry 20 10 accept_salt_key_remote "going to be accepted" >> $setup_log 2>&1 fi if [[ $is_manager || $is_import || $is_helix ]]; then set_progress_str 20 'Accepting Salt key' retry 20 10 "salt-key -ya $MINION_ID" "going to be accepted" >> $setup_log 2>&1 fi set_progress_str 21 'Copying minion pillars to manager' copy_minion_tmp_files >> $setup_log 2>&1 if [[ $is_minion ]]; then set_progress_str 22 'Checking if the Salt Minion needs to be updated' salt-call state.apply -l info salt.minion >> $setup_log 2>&1 fi set_progress_str 23 'Generating CA and checking in' salt_checkin >> $setup_log 2>&1 if [[ $is_manager || $is_helix || $is_import ]]; then set_progress_str 25 'Configuring firewall' set_initial_firewall_policy >> $setup_log 2>&1 # create these so the registry state can add so-registry to /opt/so/conf/so-status/so-status.conf mkdir -p /opt/so/conf/so-status/ >> $setup_log 2>&1 touch /opt/so/conf/so-status/so-status.conf >> $setup_log 2>&1 if [[ "$setup_type" == 'iso' ]]; then set_progress_str 26 'Copying containers from iso' else set_progress_str 26 'Downloading containers from the internet' fi import_registry_docker >> $setup_log 2>&1 salt-call state.apply -l info registry >> $setup_log 2>&1 docker_seed_registry # ~ 60% when finished set_progress_str 60 "$(print_salt_state_apply 'manager')" salt-call state.apply -l info manager >> $setup_log 2>&1 fi set_progress_str 61 "$(print_salt_state_apply 'firewall')" salt-call state.apply -l info firewall >> $setup_log 2>&1 if [ $OS = 'centos' ]; then set_progress_str 61 'Installing Yum utilities' salt-call state.apply -l info yum.packages >> $setup_log 2>&1 fi set_progress_str 62 "$(print_salt_state_apply 'common')" salt-call state.apply -l info common >> $setup_log 2>&1 if [[ ! $is_helix ]]; then set_progress_str 62 "$(print_salt_state_apply 'nginx')" salt-call state.apply -l info nginx >> $setup_log 2>&1 fi if [[ $is_manager || $is_helix || $is_import ]]; then set_progress_str 63 "$(print_salt_state_apply 'idstools')" create_local_nids_rules >> $setup_log 2>&1 salt-call state.apply -l info idstools >> $setup_log 2>&1 set_progress_str 63 "$(print_salt_state_apply 'suricata.manager')" salt-call state.apply -l info suricata.manager >> $setup_log 2>&1 fi if [[ $is_manager || $is_node || $is_import || $is_helix ]]; then set_progress_str 64 "$(print_salt_state_apply 'elasticsearch')" salt-call state.apply -l info elasticsearch >> $setup_log 2>&1 fi if [[ $is_sensor || $is_import ]]; then set_progress_str 65 "$(print_salt_state_apply 'pcap')" salt-call state.apply -l info pcap >> $setup_log 2>&1 fi if [[ $is_sensor || $is_import || $is_helix ]]; then set_progress_str 66 "$(print_salt_state_apply 'suricata')" salt-call state.apply -l info suricata >> $setup_log 2>&1 if [[ $(lookup_pillar "mdengine") == 'ZEEK' ]]; then set_progress_str 67 "$(print_salt_state_apply 'zeek')" salt-call state.apply -l info zeek >> $setup_log 2>&1 fi fi if [[ $is_node ]]; then set_progress_str 68 "$(print_salt_state_apply 'curator')" salt-call state.apply -l info curator >> $setup_log 2>&1 fi if [[ $is_manager || $is_import ]]; then set_progress_str 69 "$(print_salt_state_apply 'soc')" salt-call state.apply -l info soc >> $setup_log 2>&1 set_progress_str 70 "$(print_salt_state_apply 'kibana')" salt-call state.apply -l info kibana >> $setup_log 2>&1 set_progress_str 70 "Setting up default Space in Kibana" so-kibana-space-defaults >> $setup_log 2>&1 fi if [[ "$PLAYBOOK" = 1 ]]; then set_progress_str 71 "$(print_salt_state_apply 'playbook.db_init')" salt-call state.apply -l info playbook.db_init >> $setup_log 2>&1 set_progress_str 71 "$(print_salt_state_apply 'playbook')" salt-call state.apply -l info playbook >> $setup_log 2>&1 set_progress_str 71 "$(print_salt_state_apply 'playbook.automation_user_create')" salt-call state.apply -l info playbook.automation_user_create >> $setup_log 2>&1 fi if [[ $is_manager ]]; then set_progress_str 72 "$(print_salt_state_apply 'elastalert')" salt-call state.apply -l info elastalert >> $setup_log 2>&1 set_progress_str 73 "$(print_salt_state_apply 'soctopus')" salt-call state.apply -l info soctopus >> $setup_log 2>&1 if [[ "$PLAYBOOK" = 1 ]]; then set_progress_str 73 "Update playbook rules" so-playbook-ruleupdate >> /root/setup_playbook_rule_update.log 2>&1 & fi fi if [[ "$OSQUERY" = 1 ]]; then set_progress_str 75 "$(print_salt_state_apply 'fleet.event_enable-fleet')" salt-call state.apply -l info fleet.event_enable-fleet >> $setup_log 2>&1 set_progress_str 75 "$(print_salt_state_apply 'fleet')" salt-call state.apply -l info fleet >> $setup_log 2>&1 set_progress_str 76 "$(print_salt_state_apply 'redis')" salt-call state.apply -l info redis >> $setup_log 2>&1 if [[ $is_fleet_standalone && $FLEETCUSTOMHOSTNAME != '' ]]; then set_progress_str 77 "$(print_salt_state_apply 'fleet.event_update-custom-hostname')" pillar_override="{\"global\":{\"fleet_custom_hostname\": \"$FLEETCUSTOMHOSTNAME\"}}" salt-call state.apply -l info fleet.event_update-custom-hostname pillar="$pillar_override" >> $setup_log 2>&1 fi set_progress_str 78 "$(print_salt_state_apply 'so-fleet-setup')" so-fleet-setup "$FLEETNODEUSER" "$FLEETNODEPASSWD1" >> $setup_log 2>&1 fi if [[ "$WAZUH" = 1 ]]; then set_progress_str 79 "$(print_salt_state_apply 'wazuh')" salt-call state.apply -l info wazuh >> $setup_log 2>&1 fi if [[ "$THEHIVE" = 1 ]]; then set_progress_str 80 "$(print_salt_state_apply 'thehive')" salt-call state.apply -l info thehive >> $setup_log 2>&1 fi if [[ "$STRELKA" = 1 ]]; then if [[ $is_sensor ]]; then set_progress_str 81 "$(print_salt_state_apply 'strelka')" salt-call state.apply -l info strelka >> $setup_log 2>&1 fi if [[ "$STRELKARULES" = 1 ]]; then logCmd /usr/sbin/so-yara-update else info "Skipping running yara update: STRELKARULES='$STRELKARULES'" fi fi if [[ $is_manager || $is_import ]]; then set_progress_str 82 "$(print_salt_state_apply 'utility')" salt-call state.apply -l info utility >> $setup_log 2>&1 fi if [[ ( $is_helix || $is_manager || $is_node ) && ! $is_eval ]]; then set_progress_str 83 "$(print_salt_state_apply 'logstash')" salt-call state.apply -l info logstash >> $setup_log 2>&1 set_progress_str 84 "$(print_salt_state_apply 'filebeat')" salt-call state.apply -l info filebeat >> $setup_log 2>&1 fi set_progress_str 85 'Applying finishing touches' filter_unused_nics >> $setup_log 2>&1 network_setup >> $setup_log 2>&1 so-ssh-harden >> $setup_log 2>&1 if [[ $is_manager || $is_import ]]; then set_progress_str 87 'Adding user to SOC' add_web_user >> $setup_log 2>&1 fi set_progress_str 90 'Enabling checkin at boot' checkin_at_boot >> $setup_log 2>&1 set_progress_str 95 'Verifying setup' salt-call -l info state.highstate >> $setup_log 2>&1 } | progress success=$(tail -10 $setup_log | grep Failed | awk '{ print $2}') if [[ $success != 0 ]]; then SO_ERROR=1; fi # Check entire setup log for errors or unexpected salt states and ensure cron jobs are not reporting errors to root's mailbox # Ignore "Status .* was not found" due to output from salt http.query or http.wait_for_successful_query states used with retry if grep -q -E "ERROR|Result: False" $setup_log | grep -qvE "Status .* was not found" || [[ -s /var/spool/mail/root && "$setup_type" == "iso" ]]; then SO_ERROR=1 grep --color=never "ERROR" "$setup_log" | grep -qvE "Status .* was not found" > "$error_log" fi if [[ -n $SO_ERROR ]]; then echo "Errors detected during setup; skipping post-setup steps to allow for analysis of failures." >> $setup_log 2>&1 SKIP_REBOOT=1 whiptail_setup_failed else echo "Successfully completed setup! Continuing with post-installation steps" >> $setup_log 2>&1 { export percentage=95 # set to last percentage used in previous subshell if [[ -n $ALLOW_ROLE && -n $ALLOW_CIDR ]]; then set_progress_str 96 "Stopping SOC prior to adjusting firewall rules" so-soc-stop # Stop SOC so it doesn't accept external requests prior to the reboot set_progress_str 97 "Running so-allow -${ALLOW_ROLE} for ${ALLOW_CIDR}" IP=$ALLOW_CIDR so-allow -$ALLOW_ROLE >> $setup_log 2>&1 fi if [[ $is_manager ]]; then set_progress_str 98 "Generating archive for setup directory" generate_repo_tarball >> "$setup_log" 2>&1 fi if [[ $THEHIVE == 1 ]]; then set_progress_str 99 'Waiting for TheHive to start up' check_hive_init >> $setup_log 2>&1 fi } | whiptail_gauge_post_setup "Running post-installation steps..." whiptail_setup_complete [[ $setup_type != 'iso' ]] && whitpail_ssh_warning echo "Post-installation steps have completed." >> $setup_log 2>&1 fi install_cleanup >> "$setup_log" 2>&1 if [[ -z $SKIP_REBOOT ]]; then shutdown -r now; else exit; fi