Files
securityonion/setup/so-setup
2023-02-21 11:52:37 -05:00

643 lines
16 KiB
Bash
Executable File

#!/bin/bash
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
# 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
# This is for automation
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
# Let's see what OS we are dealing with here
detect_os
# Check to see if this is the setup type of "analyst".
is_analyst=
if [ "$setup_type" = 'analyst' ]; then
is_analyst=true
# Check to see if this is an ISO. Usually this dir on exists on ISO installs.
if [ -d /root/SecurityOnion ]; then
is_analyst_iso=true
fi
fi
# Make sure if ISO is specified that we are dealing with CentOS or Rocky
title "Detecting if this is an ISO install"
if [[ "$setup_type" == 'iso' ]]; then
if [[ $is_centos || $is_rocky ]]; then
is_iso=true
else
echo "Only use 'so-setup iso' for an ISO install on Security Onion ISO images. 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
title "This is an analyst workstation install"
# Make sure it's CentOS or Rocky Linux
if [[ ! $is_centos ]]; then
info "Analyst Workstation is only supported on CentOS 7 or Rocky Linux 8"
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
info "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
info ""
info ""
info "Kicking off the automated setup of the analyst workstation. This can take a while depending on your network connection."
info ""
info ""
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
title "Checking to see if install has run before"
if [[ -f /root/accept_changes ]]; then
is_reinstall=true
whiptail_reinstall
info "Old setup detected. Moving the last setup.log to setup.log.bak"
mv "$setup_log" "$setup_log.bak"
[ -f "$error_log" ] && mv "$error_log" "$error_log.bak"
reinstall_init
reset_proxy
fi
title "Parsing Username for Install"
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
# Add the progress function for manager node type installs
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 using automation let's do automation things.
if [[ -f automation/$automation && $(basename $automation) == $automation ]]; then
info "Preselecting variable values based on automated setup: $automation"
source automation/$automation
automated=yes
attempt=1
attempts=60
ip a | grep "$MNIC:" | grep "state UP" >> $setup_log 2>&1
while [ $? -ne 0 ]; do
logCmd "ip a"
if [ $attempt -gt $attempts ]; then
error "Network unavailable - setup cannot continue"
exit 1
fi
info "Waiting for network to come up (attempt $attempt of $attempts)"
attempt=$((attempt + 1))
info "Sleeping 10s to try again"
sleep 10;
logCmd "ip a | grep '$MNIC:' | grep 'state UP'"
done
info "Network is up on $MNIC"
fi
# Make sure the setup type is suppoted.
case "$setup_type" in
iso | network | analyst) # Accepted values
info "Beginning Security Onion $setup_type install"
;;
*)
error "Invalid install type, must be 'iso', 'network' or 'analyst'."
exit 1
;;
esac
# Allow execution of SO tools during setup
local_sbin="$(pwd)/../salt/common/tools/sbin"
export PATH=$PATH:$local_sbin
# Ubuntu whiptail pallete to make it look the same as CentOS and Rocky.
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)
info "Setup is running on TTY $TTY"
if echo $TTY | grep -q "/dev/tty"; then
CONSOLEBLANK=$(cat /sys/module/kernel/parameters/consoleblank)
info "Kernel consoleblank value before: $CONSOLEBLANK"
if [ $CONSOLEBLANK -gt 0 ]; then
info "Running 'setterm -blank 0' for TTY $TTY"
TERM=linux setterm -blank 0 >$TTY <$TTY
CONSOLEBLANK=$(cat /sys/module/kernel/parameters/consoleblank)
info "Kernel consoleblank value after: $CONSOLEBLANK"
fi
fi
fi
# Begin prompting the user with whiptail.
if ! [[ -f $install_opt_file ]]; then
if (whiptail_you_sure); then
true
else
error "User cancelled setup."
whiptail_cancel
fi
# If this is an analyst install lets streamline the process.
if [[ $is_analyst ]]; then
# Prompt for hostname
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
# Warn about the dangers of DHCP
whiptail_dhcp_warn
whiptail_management_nic
fi
# Initializing the network based on the previous information
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
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
# Process the install type
process_installtype
# If this is not an automated install prompt
if ! [[ -f $install_opt_file ]]; then
# If you are a manager ask ALL the manager things here. I know there is code re-use but this makes it easier to add new roles.
if [[ $is_eval ]]; then
waitforstate=true
ubuntu_check
monints=true
check_elastic_license
check_requirements "manager"
networking_needful
collect_net_method
collect_dockernet
if [[ $is_iso ]]; then
whiptail_airgap
fi
detect_cloud
set_minion_info
set_default_log_size >> $setup_log 2>&1
info "Verifying all network devices are managed by Network Manager that should be"
check_network_manager_conf
set_network_dev_status_list
whiptail_sensor_nics
calculate_useable_cores
collect_webuser_inputs
get_redirect
collect_so_allow
whiptail_end_settings
elif [[ $is_standalone ]]; then
waitforstate=true
ubuntu_check
monints=true
check_elastic_license
check_requirements "manager"
networking_needful
collect_net_method
collect_dockernet
if [[ $is_iso ]]; then
whiptail_airgap
fi
detect_cloud
set_minion_info
set_default_log_size >> $setup_log 2>&1
info "Verifying all network devices are managed by Network Manager that should be"
check_network_manager_conf
set_network_dev_status_list
whiptail_sensor_nics
calculate_useable_cores
collect_webuser_inputs
get_redirect
collect_so_allow
whiptail_end_settings
elif [[ $is_manager ]]; then
check_elastic_license
waitforstate=true
ubuntu_check
check_requirements "manager"
networking_needful
collect_net_method
collect_dockernet
if [[ $is_iso ]]; then
whiptail_airgap
fi
detect_cloud
set_minion_info
set_default_log_size >> $setup_log 2>&1
info "Verifying all network devices are managed by Network Manager that should be"
check_network_manager_conf
set_network_dev_status_list
calculate_useable_cores
collect_webuser_inputs
get_redirect
collect_so_allow
whiptail_end_settings
elif [[ $is_managersearch ]]; then
check_elastic_license
waitforstate=true
ubuntu_check
check_requirements "manager"
networking_needful
collect_net_method
collect_dockernet
if [[ $is_iso ]]; then
whiptail_airgap
fi
detect_cloud
set_minion_info
set_default_log_size >> $setup_log 2>&1
info "Verifying all network devices are managed by Network Manager that should be"
check_network_manager_conf
set_network_dev_status_list
calculate_useable_cores
collect_webuser_inputs
get_redirect
collect_so_allow
whiptail_end_settings
elif [[ $is_sensor ]]; then
ubuntu_check
monints=true
check_requirements "sensor"
calculate_useable_cores
networking_needful
check_network_manager_conf
set_network_dev_status_list
collect_mngr_hostname
add_mngr_ip_to_hosts
check_manager_connection
detect_cloud
whiptail_sensor_nics
set_minion_info
whiptail_end_settings
elif [[ $is_searchnode ]]; then
ubuntu_check
check_requirements "elasticsearch"
networking_needful
check_network_manager_conf
set_network_dev_status_list
collect_mngr_hostname
add_mngr_ip_to_hosts
check_manager_connection
detect_cloud
set_minion_info
whiptail_end_settings
elif [[ $is_heavynode ]]; then
ubuntu_check
monints=true
check_requirements "heavynode"
calculate_useable_cores
networking_needful
collect_mngr_hostname
add_mngr_ip_to_hosts
check_manager_connection
set_minion_info
whiptail_end_settings
elif [[ $is_idh ]]; then
ubuntu_check
check_requirements "idh"
networking_needful
collect_mngr_hostname
add_mngr_ip_to_hosts
check_manager_connection
collect_idh_services
collect_idh_preferences
set_minion_info
whiptail_end_settings
elif [[ $is_import ]]; then
ubuntu_check
waitforstate=true
monints=true
check_elastic_license
check_requirements "import"
networking_needful
if [[ $is_iso ]]; then
whiptail_airgap
fi
detect_cloud
set_minion_info
set_default_log_size >> $setup_log 2>&1
info "Verifying all network devices are managed by Network Manager that should be"
check_network_manager_conf
set_network_dev_status_list
calculate_useable_cores
collect_webuser_inputs
get_redirect
collect_so_allow
whiptail_end_settings
elif [[ $is_receiver ]]; then
ubuntu_check
check_requirements "receiver"
networking_needful
collect_mngr_hostname
add_mngr_ip_to_hosts
check_manager_connection
set_minion_info
whiptail_end_settings
fi
if [[ $waitforstate ]]; then
touch /root/accept_changes
make_some_dirs
percentage=0
es_heapsize
ls_heapsize
if [[ $needs_proxy ]]; then
set_proxy
fi
set_redirect
# Generate Interface Vars
generate_interface_vars
if [[ $monints ]]; then
configure_network_sensor
fi
info "Reserving ports"
reserve_ports
info "Setting Paths"
# Set the paths
set_path
echo "Disable auto start of setup"
# Disable the setup from prompting at login
disable_auto_start
info "Setting the version"
# Set the version
mark_version
info "Clearing the old manager"
# Remove old manager if re-install
clear_manager
info "Generating Secrets"
# Generate passwords
generate_passwords
info "Populating the secrets pillar"
# Create the secrets pillar
secrets_pillar
info "Add socore user"
# Add the socore user
add_socore_user_manager
create_local_directories
setup_salt_master_dirs
create_manager_pillars
info "Generating the minion pillar"
# Create the minion defaults
export NODETYPE=$install_type
export MINION_ID=$MINION_ID
export ES_HEAP_SIZE=$ES_HEAP_SIZE
export MNIC=$MNIC
export NODE_DESCRIPTION=$NODE_DESCRIPTION
export MAINIP=$MAINIP
export PATCHSCHEDULENAME=$PATCHSCHEDULENAME
export INTERFACE="bond0"
export CORECOUNT=$lb_procs
export LSHOSTNAME=$HOSTNAME
export LSHEAP=$LS_HEAP_SIZE
export CPUCORES=$num_cpu_cores
logCmd "so-minion -o=setup"
title "Creating Global SLS"
if [[ $is_airgap ]]; then
# Airgap Rules
airgap_rules
fi
manager_pillar
# Set up the repo to point to local file https://access.redhat.com/solutions/1355683
# reposync down the files is network and createrepo if CentOS
# Import the GPG keys
gpg_rpm_import
# Create the local repo and point the box to use the local repo
securityonion_repo
# Update existing packages
update_packages
# Install salt
saltify
# Start the master service
copy_salt_master_config
configure_minion "$minion_type"
logCmd "salt-key -yd $MINION_ID"
logCmd "salt-call state.show_top"
logCmd "salt-key -ya $MINION_ID"
logCmd "salt-call state.apply salt.helper-packages"
logCmd "salt-call state.apply common.packages"
logCmd "salt-call state.apply common"
logCmd "salt-call state.apply docker"
firewall_generate_templates
set_initial_firewall_policy
generate_ca
generate_ssl
logCmd "salt-call state.apply -l info firewall"
# create these so the registry state can add so-registry to /opt/so/conf/so-status/so-status.conf
logCmd "mkdir -p /opt/so/conf/so-status/ "
logCmd "touch /opt/so/conf/so-status/so-status.conf"
title "Importing Registry Docker"
import_registry_docker
title "Applying the registry state"
logCmd "salt-call state.apply -l info registry"
title "Seeding the docker registry"
docker_seed_registry
title "Applying the manager state"
logCmd "salt-call state.apply -l info manager"
logCmd "salt-call state.highstate -l info"
add_web_user
info "Restarting SOC to pick up initial user"
logCmd "so-soc-restart"
title "Setting up Elastic Fleet"
logCmd "so-elastic-fleet-setup"
if [[ ! $is_import ]]; then
title "Setting up Playbook"
logCmd "so-playbook-reset"
fi
checkin_at_boot
set_initial_firewall_access
verify_setup
else
touch /root/accept_changes
mkdir -p /opt/so
es_heapsize
ls_heapsize
generate_interface_vars
if [[ $monints ]]; then
configure_network_sensor
fi
reserve_ports
# Set the version
mark_version
info "Clearing the old manager"
# Remove old manager if re-install
clear_manager
gpg_rpm_import
securityonion_repo
update_packages
saltify
configure_minion "$minion_type"
drop_install_options
checkin_at_boot
logCmd "salt-call state.apply setup.highstate_cron --local --file-root=../salt/"
verify_setup
fi
# Need to make sure the latest install is located on the web server of the manager to check the versions and donwload the code if required
fi