#!/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 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.apply influxdb -l info" 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 download the code if required fi