Last active
June 16, 2022 16:24
-
-
Save nebriv/7c3a158756de05d159f316c44258b170 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Copyright 2014-2022 Security Onion Solutions, LLC | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# 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 | |
detect_os | |
is_analyst= | |
if [ "$setup_type" = 'analyst' ]; then | |
is_analyst=true | |
# Check to see if this is an ISO | |
if [ -d /root/SecurityOnion ]; then | |
is_analyst_iso=true | |
fi | |
fi | |
if [[ "$setup_type" == 'iso' ]]; then | |
if [[ $is_centos ]]; then | |
is_iso=true | |
else | |
echo "Only use 'so-setup iso' for an ISO install on CentOS. Please run 'so-setup network' instead." | |
exit 1 | |
fi | |
fi | |
# Check to see if this is an analyst install. If it is let's run things differently | |
if [[ $is_analyst ]]; then | |
# Make sure it's CentOS | |
if [[ ! $is_centos ]]; then | |
echo "Analyst Workstation is only supported on CentOS 7" | |
exit 1 | |
fi | |
if ! whiptail_analyst_install; then | |
if [[ $is_analyst_iso ]]; then | |
if whiptail_analyst_nongrid_iso; then | |
# Remove setup from auto launching | |
parse_install_username | |
sed -i '$ d' /home/$INSTALLUSERNAME/.bash_profile >> "$setup_log" 2>&1 | |
echo "Enabling graphical interface and setting it to load at boot" | |
systemctl set-default graphical.target | |
startx | |
exit 0 | |
else | |
# Abort! | |
exit 0 | |
fi | |
else | |
if whiptail_analyst_nongrid_network; then | |
echo "" | |
echo "" | |
echo "Kicking off the automated setup of the analyst workstation. This can take a while depending on your network connection." | |
echo "" | |
echo "" | |
analyst_salt_local | |
else | |
# Abort! | |
exit 0 | |
fi | |
fi | |
fi | |
# If you got this far then you want to join the grid | |
is_minion=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 msg=${1:-'Please wait while installing...'} | |
if [ $automated == no ]; then | |
whiptail --title "$whiptail_title" --gauge "$msg" 6 70 0 # append to text | |
else | |
cat >> $setup_log 2>&1 | |
fi | |
} | |
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 | analyst) # Accepted values | |
echo "Beginning Security Onion $setup_type install" >> $setup_log 2>&1 | |
;; | |
*) | |
echo "Invalid install type, must be 'iso', 'network' or 'analyst'." | 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 [[ $is_analyst ]]; then | |
collect_hostname | |
if [[ $is_analyst_iso ]]; then | |
# Prompt Network Setup | |
whiptail_management_nic | |
whiptail_dhcp_or_static | |
if [ "$address_type" != 'DHCP' ]; then | |
collect_int_ip_mask | |
collect_gateway | |
collect_dns | |
collect_dns_domain | |
fi | |
fi | |
if [[ ! $is_analyst_iso ]]; then | |
# This should be a network install | |
whiptail_network_notice | |
whiptail_dhcp_warn | |
whiptail_management_nic | |
fi | |
whiptail_network_init_notice | |
network_init | |
printf '%s\n' \ | |
"MNIC=$MNIC" \ | |
"HOSTNAME=$HOSTNAME" > "$net_init_file" | |
set_main_ip | |
compare_main_nic_ip | |
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 | |
compare_main_nic_ip | |
whiptail_net_setup_complete | |
else | |
true | |
fi | |
fi | |
if [[ ! $is_analyst ]]; then | |
whiptail_install_type | |
fi | |
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" = 'IDH' ]; then | |
is_minion=true | |
is_idh=true | |
IDH=1 | |
elif [ "$install_type" = 'HELIXSENSOR' ]; then | |
is_helix=true | |
elif [ "$install_type" = 'IMPORT' ]; then | |
is_import=true | |
elif [ "$install_type" = 'RECEIVER' ]; then | |
is_minion=true | |
is_receiver=true | |
elif [ "$install_type" = 'ANALYST' ]; then | |
if [ "$setup_type" != 'analyst' ]; then | |
exec bash so-setup analyst | |
fi | |
fi | |
if [[ $is_manager || $is_import ]]; then | |
check_elastic_license | |
fi | |
if ! [[ -f $install_opt_file ]]; then | |
if [[ $is_manager && $is_sensor ]]; then | |
check_requirements "standalone" | |
elif [[ $is_fleet_standalone ]]; then | |
check_requirements "dist" "fleet" | |
elif [[ $is_idh ]]; then | |
check_requirements "dist" "idh" | |
elif [[ $is_sensor && ! $is_eval ]]; then | |
check_requirements "dist" "sensor" | |
elif [[ $is_distmanager || $is_minion ]] && [[ ! ( $is_import || $is_analyst ) ]]; 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 | |
[[ ! ( $is_eval || $is_import ) ]] && 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 | |
compare_main_nic_ip | |
if [[ $is_minion ]]; then | |
collect_mngr_hostname | |
add_mngr_ip_to_hosts | |
whiptail_ssh_key_copy_notice | |
copy_ssh_key >> $setup_log 2>&1 | |
fi | |
if [[ $is_idh ]]; then | |
collect_idh_services | |
collect_idh_preferences | |
fi | |
# Check if this is an airgap install | |
if [[ ( $is_manager || $is_import) && $is_iso ]]; then | |
whiptail_airgap | |
if [[ "$INTERWEBS" == 'AIRGAP' ]]; then | |
is_airgap=true | |
fi | |
elif [[ $is_minion && ( $is_iso || $is_analyst ) ]]; then | |
$sshcmd -i /root/.ssh/so.key soremote@"$MSRV" [[ -f /etc/yum.repos.d/airgap_repo.repo ]] >> $setup_log 2>&1 | |
airgap_check=$? | |
[[ $airgap_check == 0 ]] && is_airgap=true >> $setup_log 2>&1 | |
fi | |
reset_proxy | |
if [[ -z $is_airgap ]]; then | |
collect_net_method | |
[[ -n "$so_proxy" ]] && set_proxy >> $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 | |
else | |
rm -rf $install_opt_file >> "$setup_log" 2>&1 | |
fi | |
if [[ -z $is_airgap ]]; then | |
percentage=0 | |
{ | |
installer_progress_loop 'Running preflight checks...' & | |
progress_bg_proc=$! | |
./so-preflight true "$setup_log" >> $setup_log 2>&1 | |
preflight_ret=$? | |
echo "$preflight_ret" > /tmp/preflight_ret | |
kill -9 "$progress_bg_proc" | |
wait "$progress_bg_proc" &> /dev/null | |
} | progress '...' | |
[[ -f /tmp/preflight_ret ]] && preflight_ret=$(cat /tmp/preflight_ret) | |
rm /tmp/preflight_ret | |
if [[ -n $preflight_ret && $preflight_ret -gt 0 ]] && ! ( whiptail_preflight_err ); then | |
whiptail_cancel | |
fi | |
fi | |
percentage=0 | |
{ | |
installer_progress_loop 'Checking that all required packages are installed and enabled...' & # 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}') | |
if [[ $is_analyst ]]; then | |
MINION_ID=$(echo "${short_name}_workstation" | tr '[:upper:]' '[:lower:]') | |
fi | |
if [[ ! $is_analyst ]]; then | |
MINION_ID=$(echo "${short_name}_${install_type}" | tr '[:upper:]' '[:lower:]') | |
fi | |
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_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} | |
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 | |
echo "Verifying all network devices are managed by Network Manager that should be" >> "$setup_log" 2>&1 | |
check_network_manager_conf | |
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 | |
#set base elasticsearch heap size | |
if [[ $is_helix || $is_manager || $is_node || $is_import ]]; then | |
es_heapsize | |
fi | |
#set base logstash heap size | |
if [[ $is_helix || $is_manager || $is_node || $is_import || $is_receiver ]]; then | |
ls_heapsize | |
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_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 || $is_analyst ) ]] && collect_ntp_servers | |
if [[ ($is_node || $is_receiver) && ! $is_eval ]]; then | |
whiptail_node_advanced | |
if [ "$NODESETUP" == 'NODEADVANCED' ]; then | |
if [[ ! $is_receiver ]]; then | |
collect_node_es_heap | |
collect_es_space_limit | |
fi | |
collect_node_ls_heap | |
collect_node_ls_pipeline_worker_count | |
collect_node_ls_pipeline_batch_size | |
collect_node_ls_input | |
else | |
if [[ ! $is_receiver ]]; then | |
NODE_ES_HEAP_SIZE=$ES_HEAP_SIZE | |
fi | |
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 | |
if [[ ! $is_analyst ]]; then | |
reserve_ports | |
fi | |
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 | |
if [[ ! $is_analyst ]]; then | |
host_pillar >> $setup_log 2>&1 | |
fi | |
if [[ $is_analyst ]]; then | |
analyst_workstation_pillar | |
fi | |
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" | |
[[ $is_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 | |
# if [[ ! $is_analyst ]]; then | |
# set_progress_str 6 'Installing Docker and dependencies' | |
# docker_install >> $setup_log 2>&1 | |
# fi | |
# 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 | |
# if [[ ! $is_analyst ]]; then | |
# check_sos_appliance >> $setup_log 2>&1 | |
# fi | |
# 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_node || $is_receiver) && !($is_manager || $is_helix) ]]; then | |
set_progress_str 19 'Generating logstash pillar' | |
logstash_pillar >> $setup_log 2>&1 | |
fi | |
if [[ $is_idh ]]; then | |
# Write out services to minion pillar file | |
set_progress_str 19 'Generating IDH services pillar' | |
write_out_idh_services | |
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 | |
if [[ $is_manager || $is_helix || $is_import ]]; then | |
set_progress_str 23 'Generating CA' | |
generate_ca >> $setup_log 2>&1 | |
fi | |
if [[ ! $is_analyst ]]; then | |
set_progress_str 24 'Generating SSL' | |
generate_ssl >> $setup_log 2>&1 | |
fi | |
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 | |
echo "Executing so-elastic-auth..." >> $setup_log 2>&1 | |
ELASTIC_AUTH_SKIP_HIGHSTATE=true bash /opt/so/saltstack/default/salt/common/tools/sbin/so-elastic-auth true >> $setup_log 2>&1 | |
echo "Finished so-elastic-auth..." >> $setup_log 2>&1 | |
fi | |
if [[ ! $is_analyst ]]; then | |
set_progress_str 61 "$(print_salt_state_apply 'firewall')" | |
salt-call state.apply -l info firewall >> $setup_log 2>&1 | |
fi | |
if [[ $is_centos ]]; then | |
set_progress_str 61 'Installing Yum utilities' | |
salt-call state.apply -l info yum.packages >> $setup_log 2>&1 | |
fi | |
if [[ ! $is_analyst ]]; then | |
set_progress_str 62 "$(print_salt_state_apply 'common')" | |
salt-call state.apply -l info common >> $setup_log 2>&1 | |
fi | |
if [[ ! $is_helix && ! $is_receiver && ! $is_idh && ! $is_analyst ]]; 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.so_config_load >> $setup_log 2>&1 | |
salt-call state.apply -l info kibana.so_securitySolution_load >> $setup_log 2>&1 | |
salt-call state.apply -l info kibana.so_dashboard_load >> $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 | |
if [[ "$GRAFANA" = 1 ]]; then | |
set_progress_str 74 "Installing InfluxDB and Grafana" | |
salt-call state.apply -l info influxdb >> $setup_log 2>&1 | |
salt-call state.apply -l info grafana >> $setup_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 | |
rm -f /etc/pki/managerssl.crt | |
salt-call state.apply -l info ssl >> $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 [[ $is_idh ]]; then | |
set_progress_str 79 "$(print_salt_state_apply 'idh')" | |
salt-call state.apply -l info idh >> $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 [[ "$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 | |
if [[ ! $is_analyst ]]; then | |
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 | |
fi | |
if [[ $is_manager || $is_import ]]; then | |
set_progress_str 87 'Adding user to SOC' | |
add_web_user >> $setup_log 2>&1 | |
fi | |
if [[ $is_analyst ]]; then | |
# Remove access to the manager from the analyst workstation | |
rm -rf /root/.ssh/so.key* | |
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 queue=True >> $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 | |
# Uncaught exception, closing connection|Exception in callback None - this is seen during influxdb / http.wait_for_successful_query state for ubuntu reinstall | |
if grep -E "ERROR|Result: False" $setup_log | grep -qvE "Status .* was not found|An exception occurred in this state|Uncaught exception, closing connection|Exception in callback None|deprecation: ERROR|code: 100" || [[ -s /var/spool/mail/root && "$setup_type" == "iso" ]]; then | |
SO_ERROR=1 | |
grep --color=never "ERROR" "$setup_log" | grep -qvE "Status .* was not found|An exception occurred in this state|Uncaught exception, closing connection|Exception in callback None|deprecation: ERROR|code: 100" > "$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 [[ -n $LEARN_LOGSCAN_ENABLE ]]; then | |
set_progress_str 99 'Enabling logscan' | |
so-learn enable logscan --apply >> $setup_log 2>&1 | |
fi | |
if [[ -n $ENDGAMEHOST ]]; then | |
set_progress_str 99 'Configuring firewall for Endgame SMP' | |
so-firewall --apply includehost endgame $ENDGAMEHOST >> $setup_log 2>&1 | |
fi | |
} | whiptail_gauge_post_setup "Running post-installation steps..." | |
echo "Post-installation steps have completed. Awaiting user input to clean up installer." >> $setup_log 2>&1 | |
whiptail_setup_complete | |
[[ $setup_type != 'iso' && ! $is_idh ]] && whiptail_ssh_warning | |
fi | |
install_cleanup >> "$setup_log" 2>&1 | |
if [[ -z $SKIP_REBOOT ]]; then shutdown -r now; else exit; fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment