#!/bin/bash
# Copyright 2014-2023 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 .
whiptail_airgap() {
[ -n "$TESTING" ] && return
local node_str='node'
[[ $is_manager || $is_import ]] && node_str='manager'
INTERWEBS=$(whiptail --title "$whiptail_title" --menu \
"How should this $node_str be installed?" 10 60 2 \
"Standard " "This $node_str has internet accesss" \
"Airgap " "This $node_str does not have internet access" 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
INTERWEBS=$(echo "${INTERWEBS^^}" | tr -d ' ')
}
whiptail_analyst_install() {
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
Welcome to the Security Onion Analyst Workstation install!
Would you like to join this workstation to an existing grid?
EOM
whiptail --title "$whiptail_title" \
--yesno "$message" 11 75 --defaultno
}
whiptail_analyst_nongrid_iso() {
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
You have selected this Analyst workstation to be independent.
Would you still like to have the graphical interface loaded at boot?
NOTE: Selecting no will exit without making changes.
EOM
whiptail --title "$whiptail_title" \
--yesno "$message" 11 75 --defaultno
}
whiptail_analyst_nongrid_network() {
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
You have selected this Analyst workstation to be independent.
Would you still like to install and load the graphical interface?
NOTE: Selecting no will exit without making changes.
EOM
whiptail --title "$whiptail_title" \
--yesno "$message" 11 75 --defaultno
}
whiptail_avoid_default_hostname() {
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
To prevent hostname conflicts, avoid using the default 'securityonion' hostname in a distributed environment.
You can choose to use this default hostname anyway, or change it to a new hostname.
EOM
whiptail --title "$whiptail_title" \
--yesno "$message" 11 75 \
--yes-button "Use Anyway" --no-button "Change" --defaultno
}
whiptail_basic_suri() {
[ -n "$TESTING" ] && return
BASICSURI=$(whiptail --title "$whiptail_title" --inputbox \
"Enter the number of Suricata processes:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_basic_zeek() {
[ -n "$TESTING" ] && return
BASICZEEK=$(whiptail --title "$whiptail_title" --inputbox \
"Enter the number of Zeek processes:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_bond_nics_mtu() {
[ -n "$TESTING" ] && return
# Set the MTU on the monitor interface
MTU=$(whiptail --title "$whiptail_title" --inputbox \
"Enter the MTU for the monitor NICs:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_cancel() {
[ -z "$TESTING" ] && whiptail --title "$whiptail_title" --msgbox "Cancelling Setup." 8 75
if [ -d "/root/installtmp" ]; then
{
echo "/root/installtmp exists";
install_cleanup;
echo "/root/installtmp removed";
} >> $setup_log 2>&1
fi
title "User cancelled setup."
exit 1
}
whiptail_check_exitstatus() {
case $1 in
1)
whiptail_cancel
;;
255)
whiptail --title "$whiptail_title" --msgbox "Whiptail error occured, exiting. Check log for details." 8 75
exit
;;
esac
}
whiptail_create_admin_user() {
[ -n "$TESTING" ] && return
ADMINUSER=$(whiptail --title "$whiptail_title" --inputbox \
"Please enter a username for a new system admin user: \nThe local onion account will be disabled during this install" 10 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_admin_user_password1() {
[ -n "$TESTING" ] && return
ADMINPASS1=$(whiptail --title "$whiptail_title" --passwordbox \
"Enter a password for $ADMINUSER:" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_admin_user_password2() {
[ -n "$TESTING" ] && return
ADMINPASS2=$(whiptail --title "$whiptail_title" --passwordbox \
"Re-enter a password for $ADMINUSER:" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_fleet_node_user() {
[ -n "$TESTING" ] && return
FLEETNODEUSER=$(whiptail --title "$whiptail_title" --inputbox \
"Please enter an email for use as the username for the Fleet admin user:" 10 60 "$1" 3>&1 1>&2 2>&3)
}
whiptail_create_fleet_node_user_password1() {
[ -n "$TESTING" ] && return
FLEETNODEPASSWD1=$(whiptail --title "$whiptail_title" --passwordbox \
"Enter a password for $FLEETNODEUSER:" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_fleet_node_user_password2() {
[ -n "$TESTING" ] && return
FLEETNODEPASSWD2=$(whiptail --title "$whiptail_title" --passwordbox \
"Re-enter a password for $FLEETNODEUSER:" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_soremote_user() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --msgbox "Set a password for the soremote user. This account is used for adding sensors remotely." 8 75
}
whiptail_create_soremote_user_password1() {
[ -n "$TESTING" ] && return
SOREMOTEPASS1=$(whiptail --title "$whiptail_title" --passwordbox \
"Enter a password for user soremote:" 10 75 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_soremote_user_password2() {
[ -n "$TESTING" ] && return
SOREMOTEPASS2=$(whiptail --title "$whiptail_title" --passwordbox \
"Re-enter a password for user soremote:" 10 75 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_web_user() {
[ -n "$TESTING" ] && return
WEBUSER=$(whiptail --title "$whiptail_title" --inputbox \
"Please enter an email address to create an administrator account for the web interface.\n\nThis will also be used for Elasticsearch, Kibana, and Fleet." 12 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_web_user_password1() {
[ -n "$TESTING" ] && return
WEBPASSWD1=$(whiptail --title "$whiptail_title" --passwordbox \
"Enter a password for $WEBUSER:" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_web_user_password2() {
[ -n "$TESTING" ] && return
WEBPASSWD2=$(whiptail --title "$whiptail_title" --passwordbox \
"Re-enter a password for $WEBUSER:" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_requirements_error() {
local requirement_needed=$1
local current_val=$2
local needed_val=$3
[ -n "$TESTING" ] && return
if [[ $(echo "$requirement_needed" | tr '[:upper:]' '[:lower:]') == 'nics' ]]; then
whiptail --title "$whiptail_title" \
--msgbox "This machine currently has $current_val $requirement_needed, but needs $needed_val to meet minimum requirements. Select OK to exit setup and reconfigure the machine." 10 75
# Same as whiptail_cancel, but changed the wording to exit instead of cancel.
whiptail --title "$whiptail_title" --msgbox "Exiting Setup. No changes have been made." 8 75
if [ -d "/root/installtmp" ]; then
{
echo "/root/installtmp exists";
install_cleanup;
echo "/root/installtmp removed";
} >> $setup_log 2>&1
fi
exit
else
whiptail --title "$whiptail_title" \
--yesno "This machine currently has $current_val $requirement_needed, but needs $needed_val to meet minimum requirements. Select YES to continue anyway, or select NO to cancel." 10 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
fi
}
whiptail_storage_requirements() {
local mount=$1
local current_val=$2
local needed_val=$3
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
Free space on mount point '${mount}' is currently ${current_val}.
You need ${needed_val} to meet minimum requirements.
Visit https://docs.securityonion.net/en/latest/hardware.html for more information.
Select YES to continue anyway, or select NO to cancel.
EOM
whiptail \
--title "$whiptail_title" \
--yesno "$message" \
14 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_dhcp_or_static() {
[ -n "$TESTING" ] && return
address_type=$(whiptail --title "$whiptail_title" --radiolist \
"Choose how to set up your management interface:" 20 78 4 \
"STATIC" "Set a static IPv4 address" ON \
"DHCP" "Use DHCP to configure the Management Interface" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
if [[ $address_type == "DHCP" ]]; then
whiptail_dhcp_warn
fi
export address_type
}
whiptail_dhcp_warn() {
[ -n "$TESTING" ] && return
if [[ $setup_type == "iso" ]]; then
local interaction_text="Select YES to keep DHCP or NO to go back."
local window_type="yesno"
else
local interaction_text="Press ENTER to continue."
local window_type="msgbox"
fi
read -r -d '' dhcp_message <<- EOM
WARNING: Using DHCP can cause problems if your IP address changes. If you want to use DHCP, make sure that you have a DHCP reservation so that this does not occur. Otherwise, use a static IP address to be safe.
$interaction_text
EOM
whiptail \
--title "$whiptail_title" \
--"$window_type" "$dhcp_message" \
14 75
local exitstatus=$?
if [[ $setup_type == "iso" ]]; then
case $exitstatus in
1)
whiptail_dhcp_or_static
;;
255)
whiptail --title "$whiptail_title" --msgbox "Whiptail error occured, exiting. Check log for details." 8 75
exit
;;
esac
else
whiptail_check_exitstatus $exitstatus
fi
}
whiptail_dockernet_check(){
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno \
"Do you want to keep the default Docker IP range?\n\nIf you are unsure, please accept the default option of Yes." 10 75
}
whiptail_dockernet_net() {
[ -n "$TESTING" ] && return
DOCKERNET=$(whiptail --title "$whiptail_title" --inputbox \
"\nEnter a /24 size network range for docker to use WITHOUT the /24 suffix. This range will be used on ALL nodes." 11 65 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_enable_components() {
[ -n "$TESTING" ] && return
GRAFANA=0
OSQUERY=0
WAZUH=0
THEHIVE=0
PLAYBOOK=0
STRELKA=0
description="Choose optional services to be enabled for this installation. Be aware that the more services you enable the more RAM that is required."
if [[ $is_eval ]]; then
COMPONENTS=$(whiptail --title "$whiptail_title" --checklist \
"$description" 20 75 8 \
GRAFANA "Enable Grafana for system monitoring" ON \
OSQUERY "Enable Fleet with osquery" ON \
WAZUH "Enable Wazuh" ON \
PLAYBOOK "Enable Playbook" ON \
STRELKA "Enable Strelka" ON 3>&1 1>&2 2>&3)
else
COMPONENTS=$(whiptail --title "$whiptail_title" --checklist \
"$description" 20 75 7 \
OSQUERY "Enable Fleet with osquery" ON \
WAZUH "Enable Wazuh" ON \
PLAYBOOK "Enable Playbook" ON \
STRELKA "Enable Strelka" ON 3>&1 1>&2 2>&3)
export "GRAFANA=1"
fi
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
COMPONENTS=$(echo "$COMPONENTS" | tr -d '"')
IFS=' ' read -ra COMPONENTS <<< "$COMPONENTS"
# Set any variables to 1 if they exist in COMPONENTS
for component in "${COMPONENTS[@]}"; do
export "$component=1"
done
}
whiptail_end_settings() {
[ -n "$TESTING" ] && return
# BASIC INFO (NETWORK, HOSTNAME, DESCRIPTION, ETC)
read -r -d '' end_msg <<- EOM
Security Onion Version: $SOVERSION
Node Type: $install_type
Hostname: $HOSTNAME
EOM
if [[ $is_idh ]]; then
__append_end_msg "IDH Services Enabled:"
for service in ${idh_services[@]}; do
__append_end_msg "- $service"
done
fi
[[ -n $NODE_DESCRIPTION ]] && __append_end_msg "Description: $NODE_DESCRIPTION"
[[ $is_airgap ]] && __append_end_msg "Airgap: True"
if [[ $is_minion ]]; then
__append_end_msg "Manager Hostname: $MSRV"
__append_end_msg "Manager IP: $MSRVIP"
fi
[[ $is_iso ]] && __append_end_msg "Network: $address_type"
__append_end_msg "Management NIC: $MNIC"
__append_end_msg "Management IP: $MAINIP"
if [[ $address_type == 'STATIC' ]]; then
__append_end_msg "Gateway: $MGATEWAY"
__append_end_msg "DNS: $MDNS"
__append_end_msg "DNS Domain: $MSEARCH"
fi
if [[ -n $so_proxy ]]; then
__append_end_msg "Proxy:"
__append_end_msg " Server URL: $proxy_addr"
[[ -n $proxy_user ]] && __append_end_msg " User: $proxy_user"
else
__append_end_msg "Proxy: N/A"
fi
if [[ $is_sensor ]]; then
__append_end_msg "Bond NIC(s):"
for nic in "${BNICS[@]}"; do
__append_end_msg " - $nic"
done
[[ -n $MTU ]] && __append_end_msg "MTU: $MTU"
fi
local homenet_arr
if [[ -n $HNMANAGER ]]; then
__append_end_msg "Home Network(s):"
IFS="," read -r -a homenet_arr <<< "$HNMANAGER"
for net in "${homenet_arr[@]}"; do
__append_end_msg " - $net"
done
elif [[ -n $HNSENSOR ]]; then
__append_end_msg "Home Network(s):"
IFS="," read -r -a homenet_arr <<< "$HNSENSOR"
for net in "${homenet_arr[@]}"; do
__append_end_msg " - $net"
done
fi
[[ -n $REDIRECTIT ]] && __append_end_msg "Access URL: https://${REDIRECTIT}"
[[ -n $ALLOW_CIDR ]] && __append_end_msg "Allowed IP or Subnet: $ALLOW_CIDR"
[[ -n $WEBUSER ]] && __append_end_msg "Web User: $WEBUSER"
[[ -n $FLEETNODEUSER ]] && __append_end_msg "Fleet User: $FLEETNODEUSER"
[[ -n $FLEETCUSTOMHOSTNAME ]] && __append_end_msg "Fleet Custom Hostname: $FLEETCUSTOMHOSTNAME"
if [[ $is_manager ]]; then
__append_end_msg "Enabled Optional Components:"
for component in "${COMPONENTS[@]}"; do
__append_end_msg " - $component"
done
fi
# METADATA / IDS
if [[ -n $ZEEKVERSION ]]; then
local md_tool_string=${ZEEKVERSION,;}
md_tool_string=${md_tool_string^}
__append_end_msg "Metadata Tool: $md_tool_string"
fi
[[ -n $RULESETUP ]] && __append_end_msg "IDS Ruleset: $RULESETUP"
[[ -n $OINKCODE ]] && __append_end_msg "Oinkcode: $OINKCODE"
# PATCH SCHEDULE
if [[ -n $PATCHSCHEDULENAME ]]; then
__append_end_msg "Patch Schedule:"
if [[ $PATCHSCHEDULENAME == 'auto'|| $PATCHSCHEDULENAME == 'manual' ]]; then
__append_end_msg " Type: $PATCHSCHEDULENAME"
else
__append_end_msg " Name: $PATCHSCHEDULENAME"
fi
if [[ ${#PATCHSCHEDULEDAYS[@]} -gt 0 ]]; then
__append_end_msg " Day(s):"
for day in "${PATCHSCHEDULEDAYS[@]}"; do
__append_end_msg " - $day"
done
fi
if [[ ${#PATCHSCHEDULEHOURS[@]} -gt 0 ]]; then
__append_end_msg " Hours(s):"
for hour in "${PATCHSCHEDULEHOURS[@]}"; do
__append_end_msg " - $hour"
done
fi
fi
# MISC
[[ $is_helix ]] && __append_end_msg "Helix API key: $HELIXAPIKEY"
[[ -n $DOCKERNET ]] && __append_end_msg "Docker network: $DOCKERNET"
if [[ -n $MANAGERUPDATES ]]; then
__append_end_msg "OS Package Updates: Manager"
else
__append_end_msg "OS Package Updates: Open"
fi
if [[ ${#ntp_servers[@]} -gt 0 ]]; then
__append_end_msg "NTP Servers:"
for server in "${ntp_servers[@]}"; do
__append_end_msg " - $server"
done
fi
if [[ $NSMSETUP != 'ADVANCED' ]]; then
[[ -n $BASICZEEK ]] && __append_end_msg "Zeek Processes: $BASICZEEK"
[[ -n $BASICSURI ]] && __append_end_msg "Suricata Processes: $BASICSURI"
fi
# ADVANCED OR REGULAR
if [[ $NODESETUP == 'NODEADVANCED' ]]; then
__append_end_msg "Advanced Node Settings:"
if [[ ! $is_receiver ]]; then
__append_end_msg " Elasticsearch Heap Size: $NODE_ES_HEAP_SIZE"
__append_end_msg " Elasticsearch Storage Space: ${log_size_limit}GB"
fi
__append_end_msg " Logstash Heap Size: $NODE_LS_HEAP_SIZE"
__append_end_msg " Logstash Worker Count: $LSPIPELINEWORKERS"
__append_end_msg " Logstash Batch Size: $LSPIPELINEBATCH"
__append_end_msg " Logstash Input Threads: $LSINPUTTHREADS"
else
if [[ ! $is_analyst ]]; then
if [[ ! $is_receiver ]]; then
__append_end_msg "Elasticsearch Heap Size: $NODE_ES_HEAP_SIZE"
__append_end_msg "Elasticsearch Storage Space: ${log_size_limit}GB"
fi
__append_end_msg "Logstash Heap Size: $NODE_LS_HEAP_SIZE"
__append_end_msg "Logstash Worker Count: $LSPIPELINEWORKERS"
__append_end_msg "Logstash Batch Size: $LSPIPELINEBATCH"
__append_end_msg "Logstash Input Threads: $LSINPUTTHREADS"
fi
fi
# ADVANCED
if [[ $MANAGERADV == 'ADVANCED' ]]; then
__append_end_msg "Advanced Manager Settings:"
[[ -n $ESCLUSTERNAME ]] && __append_end_msg " ES Cluster Name: $ESCLUSTERNAME"
if [[ ${#BLOGS[@]} -gt 0 ]]; then
__append_end_msg " Zeek Logs Enabled:"
for log in "${BLOGS[@]}"; do
__append_end_msg " - $log"
done
fi
fi
if [[ $NSMSETUP == 'ADVANCED' ]]; then
__append_end_msg "Advanced NSM Settings:"
if [[ ${#ZEEKPINS[@]} -gt 0 ]]; then
local zeek_pin_str
for core in "${ZEEKPINS[@]}"; do
zeek_pin_str="${zeek_pin_str}${core},"
done
zeek_pin_str=${zeek_pin_str%,}
__append_end_msg " Zeek Pinned Cores: ${zeek_pin_str}"
fi
if [[ ${#SURIPINS[@]} -gt 0 ]]; then
local suri_pin_str
for core in "${SURIPINS[@]}"; do
suri_pin_str="${suri_pin_str}${core},"
done
suri_pin_str=${suri_pin_str%,}
__append_end_msg " Suricata Pinned Cores: ${suri_pin_str}"
fi
fi
local msg
read -r -d '' msg <<-EOM
$end_msg
Press TAB to select yes or no.
EOM
whiptail --title "The following options have been set, would you like to proceed?" --yesno "$msg" 24 75 --scrolltext
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
echo "$end_msg" > /root/install_summary
printf '%s\n' 'Install summary:' "$end_msg" >> "$setup_log"
}
__append_end_msg() {
local newline=$1
read -r -d '' end_msg <<- EOM
$end_msg
$newline
EOM
}
whiptail_eval_adv() {
[ -n "$TESTING" ] && return
EVALADVANCED=$(whiptail --title "$whiptail_title" --radiolist \
"Choose your eval install:" 20 75 4 \
"BASIC" "Install basic components for evaluation" ON \
"ADVANCED" "Choose additional components to be installed" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_fleet_custom_hostname() {
[ -n "$TESTING" ] && return
FLEETCUSTOMHOSTNAME=$(whiptail --title "$whiptail_title" --inputbox \
"What FQDN should osquery clients use for connections to this Fleet node? Leave blank if the local system hostname will be used." 10 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_gauge_post_setup() {
if [ -n "$TESTING" ]; then
cat >> $setup_log 2>&1
else
local msg=$1
whiptail --title "$whiptail_title" --gauge "$msg" 6 60 96
fi
}
whiptail_helix_apikey() {
[ -n "$TESTING" ] && return
HELIXAPIKEY=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your Helix API Key: \n \nThis can be set later using so-helix-apikey" 10 75 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus
}
#TODO: Combine these two functions
whiptail_homenet_manager() {
[ -n "$TESTING" ] && return
HNMANAGER=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your home network(s), separating CIDR blocks with a comma (,):" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
export HNMANAGER
}
whiptail_homenet_sensor_inherit() {
[ -n "$TESTING" ] && return
# Ask to inherit from manager
whiptail --title "$whiptail_title" --yesno "Do you want to inherit the HOME_NET from the Manager?" 8 75
}
whiptail_homenet_sensor() {
[ -n "$TESTING" ] && return
HNSENSOR=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your home network(s), separating CIDR blocks with a comma (,):" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
export HNSENSOR
}
whiptail_idh_preferences() {
[ -n "$TESTING" ] && return
idh_preferences=$(whiptail --title "$whiptail_title" --radiolist \
"\nBy default, the IDH services selected in the previous screen will be bound to all interfaces and IP addresses on this system.\n\nIf you would like to prevent IDH services from being published on this system's management IP, you can select the option below." 20 75 5 \
"$MAINIP" "Disable IDH services on this management IP " OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_idh_services() {
[ -n "$TESTING" ] && return
idh_services=$(whiptail --title "$whiptail_title" --radiolist \
"\nThe IDH node can mimic many different services.\n\nChoose one of the common options along with their default ports (TCP) or select the Custom option to build a customized set of services." 20 75 5 \
"Linux Webserver (NAS Skin)" "Apache (80), FTP (21), SSH (22)" ON \
"MySQL Server" "MySQL (3306), SSH (22)" OFF \
"MSSQL Server" "Microsoft SQL (1433), VNC (5900)" OFF \
"Custom" "Select a custom set of services" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_idh_services_custom() {
[ -n "$TESTING" ] && return
idh_services=$(whiptail --title "$whiptail_title" --checklist \
"\nThe IDH node can mimic many different services.\n\nChoose one or more of the following services along with their default ports. Some services have additional configuration options, please consult the documentation for further information." 25 75 8 \
"FTP" " TCP/21, Additional Configuration Available " OFF \
"Git" " TCP/9418 " OFF \
"HTTP" " TCP/80, Additional Configuration Available " OFF \
"HTTPPROXY" " TCP/8080, Additional Configuration Available " OFF \
"MSSQL" " TCP/1433 " OFF \
"MySQL" " TCP/3306, Additional Configuration Available " OFF \
"NTP" " UDP/123 " OFF \
"REDIS" " TCP/6379 " OFF \
"SNMP" " UDP/161 " OFF \
"SSH" " TCP/22, Additional Configuration Available " OFF \
"TELNET" " TCP/23, Additional Configuration Available " OFF \
"TFTP" " UDP/69 " OFF \
"VNC" " TCP/5900 " OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_install_type() {
[ -n "$TESTING" ] && return
# What kind of install are we doing?
install_type=$(whiptail --title "$whiptail_title" --radiolist \
"Choose install type. \nSee https://docs.securityonion.net/architecture for details." 13 65 5 \
"EVAL" "Evaluation mode (not for production) " ON \
"STANDALONE" "Standalone production install " OFF \
"DISTRIBUTED" "Distributed install submenu " OFF \
"IMPORT" "Standalone to import PCAP or log files " OFF \
"OTHER" "Other install types" OFF \
3>&1 1>&2 2>&3
)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
if [[ $install_type == "DISTRIBUTED" ]]; then
whiptail_install_type_dist
if [[ $dist_option == "NEWDEPLOYMENT" ]]; then
whiptail_install_type_dist_new
else
whiptail_install_type_dist_existing
fi
elif [[ $install_type == "OTHER" ]]; then
whiptail_install_type_other
fi
export install_type
}
whiptail_install_type_dist() {
[ -n "$TESTING" ] && return
dist_option=$(whiptail --title "$whiptail_title" --menu "Do you want to start a new deployment or join this box to \nan existing deployment?" 11 75 2 \
"New Deployment " "Create a new Security Onion deployment" \
"Existing Deployment " "Join to an existing Security Onion deployment " \
3>&1 1>&2 2>&3
)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
dist_option=$(echo "${dist_option^^}" | tr -d ' ')
}
whiptail_install_type_dist_new() {
[ -n "$TESTING" ] && return
local mngr_msg
read -r -d '' mngr_msg <<- EOM
Choose a distributed manager type to start a new grid.
See https://docs.securityonion.net/architecture for details.
Note: MANAGER is the recommended option for most users. MANAGERSEARCH should only be used in very specific situations.
EOM
install_type=$(whiptail --title "$whiptail_title" --radiolist "$mngr_msg" 15 75 2 \
"MANAGER" "New grid, requires separate search node(s) " ON \
"MANAGERSEARCH" "New grid, separate search node(s) are optional " OFF \
3>&1 1>&2 2>&3
)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_install_type_dist_existing() {
[ -n "$TESTING" ] && return
local node_msg
read -r -d '' node_msg <<- EOM
Choose a distributed node type to join to an existing grid. See https://docs.securityonion.net/architecture for details.
Note: Heavy nodes (HEAVYNODE) are NOT recommended for most users.
EOM
install_type=$(whiptail --title "$whiptail_title" --radiolist "$node_msg" 19 58 6 \
"SENSOR" "Create a forward only sensor " ON \
"SEARCHNODE" "Add a search node with parsing " OFF \
"FLEET" "Dedicated Fleet Osquery Node " OFF \
"HEAVYNODE" "Sensor + Search Node " OFF \
"IDH" "Intrusion Detection Honeypot Node " OFF \
"RECEIVER" "Receiver Node " OFF \
3>&1 1>&2 2>&3
# "HOTNODE" "Add Hot Node (Uses Elastic Clustering)" OFF \ # TODO
# "WARMNODE" "Add Warm Node to existing Hot or Search node" OFF \ # TODO
# "WAZUH" "Stand Alone Wazuh Server" OFF \ # TODO
# "STRELKA" "Stand Alone Strelka Node" OFF \ # TODO
)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_install_type_other() {
[ -n "$TESTING" ] && return
install_type=$(whiptail --title "$whiptail_title" --radiolist \
"Choose node type:" 9 65 2 \
"ANALYST" "Setup will run 'so-setup analyst' " ON \
"HELIXSENSOR" "Create a Helix sensor " OFF \
3>&1 1>&2 2>&3
)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
export install_type
}
whiptail_invalid_input() { # TODO: This should accept a list of arguments to specify what general pattern the input should follow
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --msgbox " Invalid input, please try again." 7 40
}
whiptail_invalid_proxy() {
[ -n "$TESTING" ] && return
local message
read -r -d '' message <<- EOM
Could not reach test url using proxy ${proxy_addr}.
Error was: ${proxy_test_err}
EOM
whiptail --title "$whiptail_title" --yesno "$message" --yes-button "Enter Again" --no-button "Skip" 11 60
}
whiptail_invalid_string() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --msgbox "Invalid input, please try again.\n\nThe $1 cannot contain spaces." 9 45
}
whiptail_invalid_pass_characters_warning() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --msgbox "Password is invalid. Please exclude single quotes, double quotes, dollar signs, and backslashes from the password." 8 75
}
whiptail_invalid_pass_warning() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --msgbox "Please choose a more secure password." 8 75
}
whiptail_invalid_user_warning() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --msgbox "Please enter a valid email address." 8 75
}
whiptail_invalid_hostname() {
[ -n "$TESTING" ] && return
local is_manager_hostname
is_manager_hostname="$1"
local error_message
read -r -d '' error_message <<- EOM
Please choose a valid hostname. It cannot be localhost. It must contain only the ASCII letters 'A-Z' and 'a-z' (case-sensitive), the digits '0' through '9', and hyphen ('-').
EOM
if [[ $is_manager_hostname = 0 ]]; then
local error_message
read -r -d '' error_message <<- EOM
Please enter a valid hostname. The manager hostname cannot be localhost or the chosen hostname for this machine.
EOM
fi
whiptail --title "$whiptail_title" \
--msgbox "$error_message" 10 75
}
whiptail_log_size_limit() {
[ -n "$TESTING" ] && return
case $install_type in
STANDALONE | EVAL | HEAVYNODE)
percentage=50
;;
*)
percentage=80
;;
esac
read -r -d '' message <<- EOM
Please specify the amount of disk space (in GB) you would like to allocate for Elasticsearch data storage.
By default, this is set to ${percentage}% of the disk space allotted for /nsm.
EOM
log_size_limit=$(whiptail --title "$whiptail_title" --inputbox "$message" 11 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_first_menu_iso() {
[ -n "$TESTING" ] && return
option=$(whiptail --title "$whiptail_title" --menu "Select an option" 10 75 2 \
"Install " "Run the standard Security Onion installation " \
"Configure Network " "Configure networking only " \
3>&1 1>&2 2>&3
)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
option=$(echo "${option^^}" | tr -d ' ')
}
whiptail_make_changes() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno "We are going to set this machine up as a $install_type. Please press YES to make changes or NO to cancel." 8 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_management_interface_dns() {
[ -n "$TESTING" ] && return
MDNS=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your DNS servers separated by commas:" 10 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_management_interface_dns_search() {
[ -n "$TESTING" ] && return
MSEARCH=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your DNS search domain:" 10 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_management_interface_gateway() {
[ -n "$TESTING" ] && return
MGATEWAY=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your gateway's IPv4 address:" 10 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_management_interface_ip_mask() {
[ -n "$TESTING" ] && return
local msg
read -r -d '' msg <<- EOM
What IPv4 address would you like to assign to this Security Onion installation?
Please enter the IPv4 address with CIDR mask
(e.g. 192.168.1.2/24):
EOM
manager_ip_mask=$(whiptail --title "$whiptail_title" --inputbox "$msg" 12 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_management_nic() {
[ -n "$TESTING" ] && return
filter_unused_nics
MNIC=$(whiptail --title "$whiptail_title" --radiolist "Please select your management NIC:" 20 75 12 "${nic_list[@]}" 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
while [ -z "$MNIC" ]
do
MNIC=$(whiptail --title "$whiptail_title" --radiolist "Please select your management NIC:" 20 75 12 "${nic_list[@]}" 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
done
}
whiptail_net_method() {
[ -n "$TESTING" ] && return
local pkg_mngr
if [[ $OS = 'centos' ]]; then pkg_mngr="yum"; else pkg_mngr='apt'; fi
read -r -d '' options_msg <<- EOM
"Direct" - Internet requests connect directly to the Internet.
EOM
local options=(
" Direct " ""
)
local proxy_desc="proxy the traffic for git, docker client, wget, curl, ${pkg_mngr}, and various other SO components through a separate server in your environment."
if [[ $is_minion ]]; then
read -r -d '' options_msg <<- EOM
${options_msg}
"Direct + Manager" - all traffic passes to the Internet normally, but ${pkg_mngr} updates will instead be pulled from ${mngr_article} manager.
"Proxy" - ${proxy_desc}
"Proxy + Manager" - proxy all traffic from the "Proxy" option except ${pkg_mngr} updates, which will instead pull from the manager.
EOM
options+=(
" Direct + Manager " ""
" Proxy " ""
" Proxy + Manager " ""
)
local height=25
else
read -r -d '' options_msg <<- EOM
${options_msg}
"Proxy" - ${proxy_desc}
EOM
options+=(
" Proxy " ""
)
local height=17
fi
local msg
read -r -d '' msg <<- EOM
How would you like to connect to the Internet?
$options_msg
EOM
local option_count=$(( ${#options[@]} / 2 ))
network_traffic=$(whiptail --title "$whiptail_title" --menu "$msg" $height 75 $option_count "${options[@]}" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
network_traffic=$(echo "${network_traffic^^}" | tr -d ' ' | tr '+' '_')
}
whiptail_net_setup_complete() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" \
--msgbox "Successfully set up networking, setup will now exit." 7 75
exit 0
}
whiptail_network_init_notice() {
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
Setup will now initialize networking.
Select OK to continue.
EOM
whiptail --title "$whiptail_title" --msgbox "$message" 9 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_management_server() {
[ -n "$TESTING" ] && return
MSRV=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your Manager Server hostname: \nIt is CASE SENSITIVE!" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_manager_ip() {
[ -n "$TESTING" ] && return
MSRVIP=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your Manager Server IP Address:" 10 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
# Ask if you want to do advanced setup of the Manager
whiptail_manager_adv() {
[ -n "$TESTING" ] && return
MANAGERADV=$(whiptail --title "$whiptail_title" --radiolist \
"Choose which type of manager to install:" 20 75 4 \
"BASIC" "Install manager with recommended settings" ON \
"ADVANCED" "Do additional configuration to the manager" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
# Ask if you want to do true clustering
whiptail_manager_adv_escluster(){
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno \
"Do you want to set up a traditional ES cluster for using replicas and/or Hot-Warm indices? Recommended only for those who have experience with ES clustering! " 12 75
}
# Get a cluster name
whiptail_manager_adv_escluster_name(){
[ -n "$TESTING" ] && return
ESCLUSTERNAME=$(whiptail --title "$whiptail_title" --inputbox \
"Enter a name for your ES cluster!" 10 75 "$1" 3>&1 1>&2 2>&3)
}
# Ask which additional components to install
whiptail_manager_adv_service_zeeklogs() {
[ -n "$TESTING" ] && return
BLOGS=$(whiptail --title "$whiptail_title" --checklist "Please select logs to send:" 24 75 12 \
"conn" "" ON \
"dce_rpc" "" ON \
"dhcp" "" ON \
"dnp3" "" ON \
"dns" "" ON \
"dpd" "" ON \
"files" "" ON \
"ftp" "" ON \
"http" "" ON \
"intel" "" ON \
"irc" "" ON \
"kerberos" "" ON \
"modbus" "" ON \
"notice" "" ON \
"ntlm" "" ON \
"pe" "" ON \
"radius" "" ON \
"rfb" "" ON \
"rdp" "" ON \
"sip" "" ON \
"smb_files" "" ON \
"smb_mapping" "" ON \
"smtp" "" ON \
"snmp" "" ON \
"software" "" ON \
"ssh" "" ON \
"ssl" "" ON \
"syslog" "" ON \
"tunnel" "" ON \
"weird" "" ON \
"mysql" "" ON \
"socks" "" ON \
"x509" "" ON \
"bacnet" "" ON \
"bacnet_discovery" "" ON \
"bacnet_property" "" ON \
"bsap_ip_header" "" ON \
"bsap_ip_rdb" "" ON \
"bsap_ip_unknown" "" ON \
"bsap_serial_header" "" ON \
"bsap_serial_rdb" "" ON \
"bsap_serial_rdb_ext" "" ON \
"bsap_serial_unknown" "" ON \
"cip" "" ON \
"cip_identity" "" ON \
"cip_io" "" ON \
"cotp" "" ON \
"dnp3_control" "" ON \
"dnp3_objects" "" ON \
"ecat_aoe_info" "" ON \
"ecat_arp_info" "" OFF \
"ecat_coe_info" "" ON \
"ecat_dev_info" "" ON \
"ecat_foe_info" "" ON \
"ecat_log_address" "" ON \
"ecat_registers" "" ON \
"ecat_soe_info" "" ON \
"enip" "" ON \
"modbus_detailed" "" ON \
"modbus_mask_write_register" "" ON \
"modbus_read_write_multiple_registers" "" ON \
"opcua_binary" "" ON \
"opcua_binary_activate_session" "" ON \
"opcua_binary_activate_session_client_software_cert" "" ON \
"opcua_binary_activate_session_diagnostic_info" "" ON \
"opcua_binary_activate_session_locale_id" "" ON \
"opcua_binary_browse" "" ON \
"opcua_binary_browse_description" "" ON \
"opcua_binary_browse_diagnostic_info" "" ON \
"opcua_binary_browse_request_continuation_point" "" ON \
"opcua_binary_browse_response_references" "" ON \
"opcua_binary_browse_result" "" ON \
"opcua_binary_create_session" "" ON \
"opcua_binary_create_session_discovery" "" ON \
"opcua_binary_create_session_endpoints" "" ON \
"opcua_binary_create_session_user_token" "" ON \
"opcua_binary_create_subscription" "" ON \
"opcua_binary_diag_info_detail" "" ON \
"opcua_binary_get_endpoints" "" ON \
"opcua_binary_get_endpoints_description" "" ON \
"opcua_binary_get_endpoints_discovery" "" ON \
"opcua_binary_get_endpoints_locale_id" "" ON \
"opcua_binary_get_endpoints_profile_uri" "" ON \
"opcua_binary_get_endpoints_user_token" "" ON \
"opcua_binary_opensecure_channel" "" ON \
"opcua_binary_read" "" ON \
"opcua_binary_read_array_dims" "" ON \
"opcua_binary_read_array_dims_link" "" ON \
"opcua_binary_read_diagnostic_info" "" ON \
"opcua_binary_read_extension_object" "" ON \
"opcua_binary_read_extension_object_link" "" ON \
"opcua_binary_read_nodes_to_read" "" ON \
"opcua_binary_read_results" "" ON \
"opcua_binary_read_results_link" "" ON \
"opcua_binary_read_status_code" "" ON \
"opcua_binary_read_variant_data" "" ON \
"opcua_binary_read_variant_data_link" "" ON \
"opcua_binary_status_code_detail" "" ON \
"profinet" "" ON \
"profinet_dce_rpc" "" ON \
"profinet_debug" "" ON \
"s7comm" "" ON \
"s7comm_plus" "" ON \
"s7comm_read_szl" "" ON \
"s7comm_upload_download" "" ON \
"stun" "" ON \
"stun_nat" "" ON \
"tds" "" ON \
"tds_rpc" "" ON \
"tds_sql_batch" "" ON \
"wireguard" "" ON 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
BLOGS=$(echo "$BLOGS" | tr -d '"')
IFS=' ' read -ra BLOGS <<< "$BLOGS"
}
whiptail_manager_error() {
[ -n "$TESTING" ] && return
local msg
read -r -d '' msg <<- EOM
Setup could not determine if the manager $MSRV is in a good state.
Continuing without verifying all services on the manager are running may result in a failure.
Would you like to continue anyway?
EOM
whiptail --title "$whiptail_title" --yesno "$msg" 13 75 || whiptail_check_exitstatus 1
}
whiptail_manager_updates_warning() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title"\
--msgbox "Updating through the manager node requires the manager to have internet access, press ENTER to continue."\
8 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_manager_unreachable() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --msgbox "Setup cannot determine if $1 is listening on port 22. Please check the address entered and try again." 7 75
}
whiptail_metadata_tool() {
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
What tool would you like to use to generate metadata?
This question is asking specifically about metadata, which would be things like the connection log, DNS log, HTTP log, etc. This does not include NIDS alerts.
If you choose Zeek for metadata, Suricata will still run to generate NIDS alerts.
If you choose Suricata for metadata, it will generate NIDS alerts and metadata, and Zeek will not run at all.
EOM
# Legacy variable naming
ZEEKVERSION=$(whiptail --title "$whiptail_title" --menu "$message" 20 75 2 \
"Zeek " "Use Zeek (Bro) for metadata and Suricata for NIDS alerts" \
"Suricata " "Use Suricata for both metadata and NIDS alerts" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
ZEEKVERSION=$(echo "${ZEEKVERSION^^}" | tr -d ' ')
}
whiptail_nids() {
[ -n "$TESTING" ] && return
NIDS=$(whiptail --title "$whiptail_title" --radiolist \
"Choose which IDS to run: \n\n(Snort 3.0 support will be added once it is out of beta.)" 25 75 4 \
"Suricata" "Suricata" ON \
"Snort" "Placeholder for Snort 3.0 " OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_network_notice() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno "Since this is a network install we assume the management interface, DNS, Hostname, etc are already set up. Select YES to continue." 8 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_net_reinit() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno "The management interface has already been configured. Do you want to reconfigure it?" 8 75
}
whiptail_node_advanced() {
[ -n "$TESTING" ] && return
NODESETUP=$(whiptail --title "$whiptail_title" --radiolist \
"What type of config would you like to use?:" 20 75 4 \
"NODEBASIC" "Install Search Node with recommended settings" ON \
"NODEADVANCED" "Advanced Node Setup" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_node_description() {
[ -n "$TESTING" ] && return
NODE_DESCRIPTION=$(whiptail --title "$whiptail_title" \
--inputbox "Enter a short description for the node or press ENTER to leave blank:" 10 75 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_node_es_heap() {
[ -n "$TESTING" ] && return
NODE_ES_HEAP_SIZE=$(whiptail --title "$whiptail_title" --inputbox \
"Enter ES heap size:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_node_ls_heap() {
[ -n "$TESTING" ] && return
NODE_LS_HEAP_SIZE=$(whiptail --title "$whiptail_title" --inputbox \
"Enter Logstash heap size:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_node_ls_input_threads() {
[ -n "$TESTING" ] && return
LSINPUTTHREADS=$(whiptail --title "$whiptail_title" --inputbox \
"Enter number of Logstash input threads:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_node_ls_pipline_batchsize() {
[ -n "$TESTING" ] && return
LSPIPELINEBATCH=$(whiptail --title "$whiptail_title" --inputbox \
"Enter Logstash pipeline batch size:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_node_ls_pipeline_worker() {
[ -n "$TESTING" ] && return
LSPIPELINEWORKERS=$(whiptail --title "$whiptail_title" --inputbox \
"Enter number of Logstash pipeline workers:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_ntp_ask() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno "Would you like to configure ntp servers?" 7 44
}
whiptail_ntp_servers() {
[ -n "$TESTING" ] && return
ntp_string=$(whiptail --title "$whiptail_title" \
--inputbox "Input the NTP server(s) you would like to use, separated by commas:" 8 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_oinkcode() {
[ -n "$TESTING" ] && return
OINKCODE=$(whiptail --title "$whiptail_title" --inputbox \
"Enter your ET Pro or oinkcode:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
#TODO: helper function to display error message or exit if batch mode
# exit_if_batch <"Error string">
whiptail_error_message() {
local error_message=$1 # message to be displayed
whiptail --title "$whiptail_title" --msgbox "$error_message" 10 75
}
whiptail_passwords_dont_match() {
whiptail --title "$whiptail_title" --msgbox "Passwords don't match. Please re-enter." 8 75
}
whiptail_patch_name_new_schedule() {
[ -n "$TESTING" ] && return
PATCHSCHEDULENAME=$(whiptail --title "$whiptail_title" --inputbox \
"What name do you want to give this OS patch schedule? This schedule needs to be named uniquely. Available schedules can be found on the manager under /opt/so/salt/patch/os/schedules/.yml" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_patch_schedule() {
[ -n "$TESTING" ] && return
patch_schedule=$(whiptail --title "$whiptail_title" --radiolist \
"Choose OS patch schedule.\n\nThis schedule will update the operating system packages but will NOT update Security Onion related tools such as Zeek, Elasticsearch, Kibana, SaltStack, etc." 20 75 5 \
"Automatic" "Updates installed every 8 hours if available" ON \
"Manual" "Updates will be installed manually" OFF \
"Import Schedule" "Import named schedule on following screen" OFF \
"New Schedule" "Configure and name new schedule on next screen" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_patch_schedule_import() {
[ -n "$TESTING" ] && return
unset PATCHSCHEDULENAME
PATCHSCHEDULENAME=$(whiptail --title "$whiptail_title" --inputbox \
"Enter the name of the OS patch schedule you want to inherit. \nAvailable schedules can be found on the manager under /opt/so/salt/patch/os/schedules/.yml" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_patch_schedule_select_days() {
[ -n "$TESTING" ] && return
# Select the days to patch
PATCHSCHEDULEDAYS=$(whiptail --title "$whiptail_title" --checklist \
"Which days do you want to apply OS patches?" 15 75 8 \
Monday "" OFF \
Tuesday "" ON \
Wednesday "" OFF \
Thursday "" OFF \
Friday "" OFF \
Saturday "" OFF \
Sunday "" OFF 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
PATCHSCHEDULEDAYS=$(echo "$PATCHSCHEDULEDAYS" | tr -d '"')
IFS=' ' read -ra PATCHSCHEDULEDAYS <<< "$PATCHSCHEDULEDAYS"
}
whiptail_patch_schedule_select_hours() {
[ -n "$TESTING" ] && return
# Select the hours to patch
PATCHSCHEDULEHOURS=$(whiptail --title "$whiptail_title" --checklist \
"At which time, UTC, do you want to apply OS patches on the selected days?" 22 75 13 \
00:00 "" OFF \
01:00 "" OFF \
02:00 "" ON \
03:00 "" OFF \
04:00 "" OFF \
05:00 "" OFF \
06:00 "" OFF \
07:00 "" OFF \
08:00 "" OFF \
09:00 "" OFF \
10:00 "" OFF \
11:00 "" OFF \
12:00 "" OFF \
13:00 "" OFF \
14:00 "" OFF \
15:00 "" OFF \
16:00 "" OFF \
17:00 "" OFF \
18:00 "" OFF \
19:00 "" OFF \
20:00 "" OFF \
21:00 "" OFF \
22:00 "" OFF \
23:00 "" OFF 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
PATCHSCHEDULEHOURS=$(echo "$PATCHSCHEDULEHOURS" | tr -d '"')
IFS=' ' read -ra PATCHSCHEDULEHOURS <<< "$PATCHSCHEDULEHOURS"
}
whiptail_preflight_err() {
[ -n "$TESTING" ] && return 1
read -r -d '' message <<- EOM
The so-preflight script failed checking one or more URLs required by setup. Check $setup_log for more details.
Would you like to exit setup?
EOM
whiptail --title "$whiptail_title" \
--yesno "$message" 11 75 \
--yes-button "Continue" --no-button "Exit" --defaultno
}
whiptail_proxy_ask() {
[ -n "$TESTING" ] && return
local pkg_mngr
if [[ $OS = 'centos' ]]; then pkg_mngr="yum"; else pkg_mngr='apt'; fi
whiptail --title "$whiptail_title" --yesno "Do you want to proxy the traffic for git, docker client, wget, curl, ${pkg_mngr}, and various other SO components through a separate server in your environment?" 9 65 --defaultno
}
whiptail_proxy_addr() {
[ -n "$TESTING" ] && return
local message
read -r -d '' message <<- EOM
Please input the proxy server you wish to use, including the URL prefix (ex: https://your.proxy.com:1234).
If your proxy requires a username and password do not include them in your input. Setup will ask for those values next.
EOM
proxy_addr=$(whiptail --title "$whiptail_title" --inputbox "$message" 13 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_proxy_auth_ask() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno "Does your proxy require authentication?" 7 60
}
whiptail_proxy_auth_user() {
[ -n "$TESTING" ] && return
proxy_user=$(whiptail --title "$whiptail_title" --inputbox "Please input the proxy user:" 8 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_proxy_auth_pass() {
local arg=$1
[ -n "$TESTING" ] && return
proxy_pass=$(whiptail --title "$whiptail_title" --passwordbox "Please input the proxy password:" 8 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_requirements_error() {
local requirement_needed=$1
local current_val=$2
local needed_val=$3
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" \
--yesno "This machine currently has $current_val $requirement_needed, but needs $needed_val to meet minimum requirements. Press YES to continue anyway, or press NO to cancel." 10 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_rule_setup() {
[ -n "$TESTING" ] && return
# Get pulled pork info
RULESETUP=$(whiptail --title "$whiptail_title" --radiolist \
"Which IDS ruleset would you like to use?\n\nThis manager server is responsible for downloading the IDS ruleset from the Internet.\n\nSensors then pull a copy of this ruleset from the manager server.\n\nIf you select a commercial ruleset, it is your responsibility to purchase enough licenses for all of your sensors in compliance with your vendor's policies." 20 75 4 \
"ETOPEN" "Emerging Threats Open" ON \
"ETPRO" "Emerging Threats PRO" OFF \
"TALOS" "Snort Subscriber ruleset - Experimental" OFF \
3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_sensor_config() {
[ -n "$TESTING" ] && return
NSMSETUP=$(whiptail --title "$whiptail_title" --radiolist \
"What type of configuration would you like to use?" 20 75 4 \
"BASIC" "Install NSM components with recommended settings" ON \
"ADVANCED" "Configure each component individually" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_sensor_nics() {
[ -n "$TESTING" ] && return
filter_unused_nics
if [[ $is_ec2 ]]; then
local menu_text="Please select NIC for the Monitor Interface:"
local list_type="radiolist"
else
local menu_text="Please add NICs to the Monitor Interface:"
local list_type="checklist"
fi
BNICS=$(whiptail --title "$whiptail_title" --$list_type "$menu_text" 20 75 12 "${nic_list[@]}" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
while [ -z "$BNICS" ]
do
BNICS=$(whiptail --title "$whiptail_title" --$list_type "$menu_text" 20 75 12 "${nic_list[@]}" 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
done
BNICS=$(echo "$BNICS" | tr -d '"')
IFS=' ' read -ra BNICS <<< "$BNICS"
for bond_nic in "${BNICS[@]}"; do
for dev_status in "${nmcli_dev_status_list[@]}"; do
if [[ $dev_status == "${bond_nic}:unmanaged" ]]; then
whiptail \
--title "$whiptail_title" \
--msgbox "$bond_nic is unmanaged by Network Manager. Please remove it from other network management tools then re-run setup." \
8 75
exit
fi
done
done
}
whiptail_set_hostname() {
[ -n "$TESTING" ] && return
HOSTNAME=$(whiptail --title "$whiptail_title" --inputbox \
"Enter the hostname (not FQDN) you would like to set:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_set_redirect() {
[ -n "$TESTING" ] && return
local options=()
options+=( "IP" "Use IP address to access the web interface" ON )
[[ $no_use_hostname != true ]] && options+=( "HOSTNAME" "Use hostname to access the web interface" OFF )
options+=("OTHER" "Use a different name like a FQDN or Load Balancer" OFF)
REDIRECTINFO=$(whiptail --title "$whiptail_title" --radiolist \
"How would you like to access the web interface?\n\nSecurity Onion uses strict cookie enforcement, so whatever you choose here will be the only way that you can access the web interface.\n\nIf you choose something other than IP address, then you'll need to ensure that you can resolve the name via DNS or hosts entry. If you are unsure, please select IP." 20 75 4 \
"${options[@]}" \
3>&1 1>&2 2>&3
)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_set_redirect_host() {
[ -n "$TESTING" ] && return
REDIRECTHOST=$(whiptail --title "$whiptail_title" --inputbox \
"Enter the Hostname, IP, or FQDN you would like to use for the web interface:" 10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_setup_complete() {
[ -n "$TESTING" ] && return
if [[ -n "$REDIRECTIT" && $is_manager = true ]]; then
if [[ -n $ALLOW_CIDR ]]; then
local sentence_prefix="Access"
else
local sentence_prefix="Run so-allow after reboot to access"
fi
local accessMessage="\n${sentence_prefix} the web interface at: https://${REDIRECTIT}\n"
elif [[ $is_idh ]]; then
local accessMessage="\nSSH for this node has been moved to TCP/2222, accessible only from the Manager node.\n"
else
local accessMessage=""
fi
read -r -d '' message <<- EOM
Finished ${install_type} installation.
$accessMessage
Press ENTER to reboot.
EOM
whiptail --title "$whiptail_title" --msgbox "$message" 12 75
}
whiptail_setup_failed() {
[ -n "$TESTING" ] && return
local check_err_msg
local height
[ -f "$error_log" ] && check_err_msg="A summary of errors can be found in $error_log.\n"
if [[ -n $check_err_msg ]]; then height=11; else height=10; fi
read -r -d '' message <<- EOM
Install had a problem. Please see $setup_log for details.\n
$check_err_msg
Press Ok to exit.
EOM
whiptail --title "$whiptail_title" --msgbox "$message" $height 75
}
whiptail_so_allow_yesno() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" \
--yesno "Do you want to run so-allow to allow other machines to access this Security Onion installation via the web interface?" \
8 75
}
whiptail_so_allow() {
[ -n "$TESTING" ] && return
ALLOW_CIDR=$(whiptail --title "$whiptail_title" \
--inputbox "Enter a single IP address or an IP range, in CIDR notation, to allow:" \
10 75 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$?
export ALLOW_ROLE='a'
export ALLOW_CIDR
whiptail_check_exitstatus $exitstatus
}
whiptail_ssh_key_copy_notice() {
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
Setup will now copy the ssh key for soremote to the manager. This will bring you to the command line temporarily to accept the manager's ED25519 certificate and enter the password for soremote.
Select OK to continue.
EOM
whiptail --title "$whiptail_title" --msgbox "$message" 11 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_ssh_warning() {
[ -n "$TESTING" ] && return
local msg
read -r -d '' msg <<- EOM
NOTE: You will receive a warning upon SSH reconnect that the host key has changed.
This is expected due to hardening of the OpenSSH server config.
The host key algorithm will now be ED25519, follow the instructions given by your SSH client to remove the old key fingerprint then retry the connection.
EOM
whiptail --msgbox "$msg" 14 75
}
whiptail_storage_requirements() {
local mount=$1
local current_val=$2
local needed_val=$3
[ -n "$TESTING" ] && return
read -r -d '' message <<- EOM
Free space on mount point '${mount}' is currently ${current_val}.
You need ${needed_val} to meet minimum requirements.
Visit https://docs.securityonion.net/en/latest/hardware.html for more information.
Press YES to continue anyway, or press NO to cancel.
EOM
whiptail \
--title "$whiptail_title" \
--yesno "$message" \
14 75
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_strelka_rules() {
[ -n "$TESTING" ] && return
whiptail --title "$whiptail_title" --yesno "Do you want to enable the default YARA rules for Strelka?" 8 75
local exitstatus=$?
if [[ $exitstatus == 0 ]]; then export STRELKARULES=1; fi
}
whiptail_suricata_pins() {
[ -n "$TESTING" ] && return
local filtered_core_list
readarray -t filtered_core_list <<< "$(echo "${cpu_core_list[@]}" "${ZEEKPINS[@]}" | xargs -n1 | sort | uniq -u | awk '{print $1}')"
local filtered_core_str=()
for item in "${filtered_core_list[@]}"; do
filtered_core_str+=("$item" "")
done
if [[ $is_node && $is_sensor && ! $is_eval ]]; then
local PROCS=$(expr $lb_procs / 2)
if [ "$PROCS" -lt 1 ]; then PROCS=1; else PROCS=$PROCS; fi
else
local PROCS=$lb_procs
fi
SURIPINS=$(whiptail --noitem --title "$whiptail_title" --checklist "Please select $PROCS cores to pin Suricata to:" 20 75 12 "${filtered_core_str[@]}" 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
SURIPINS=$(echo "$SURIPINS" | tr -d '"')
IFS=' ' read -ra SURIPINS <<< "$SURIPINS"
}
# shellcheck disable=2120
whiptail_uppercase_warning() {
[ -n "$TESTING" ] && return
local type=$1
local msg
if [[ -z $type ]]; then
type="hostname"
read -r -d '' msg <<- EOM
The value "$HOSTNAME" contains uppercase characters.
Continuing with this hostname could render the system unusable in certain cases, and will also disable the option later in setup to access Security Onion's web interface via the hostname.
EOM
else
read -r -d '' msg <<- EOM
The value "$REDIRECTHOST" contains uppercase characters.
Continuing with this value could render the system unusable in certain cases.
EOM
fi
read -r -d '' msg <<- EOM
$msg
For best results, it is recommended to only use lowercase ${type}s with Security Onion. For more information see https://docs.securityonion.com/uppercase (URL TBD)
EOM
whiptail --title "$whiptail_title" --yesno "$msg" --yes-button "Continue anyway" --no-button "Go back" --defaultno 16 75
}
whiptail_you_sure() {
[ -n "$TESTING" ] && return
read -r -d '' you_sure_text <<- EOM
Welcome to Security Onion Setup!
You can use Setup for several different use cases, from a small standalone installation to a large distributed deployment for your enterprise. Don't forget to review the documentation at:
https://docs.securityonion.net
Setup uses keyboard navigation and you can use arrow keys to move around. Certain screens may provide a list and ask you to select one or more items from that list. You can use [SPACE] to select items and [ENTER] to proceed to the next screen.
Would you like to continue?
EOM
whiptail \
--title "$whiptail_title" \
--yesno "$you_sure_text" \
20 75
local exitstatus=$?
return $exitstatus
}
whiptail_zeek_pins() {
[ -n "$TESTING" ] && return
local cpu_core_list_whiptail=()
for item in "${cpu_core_list[@]}"; do
cpu_core_list_whiptail+=("$item" "OFF")
done
if [[ $is_smooshed ]]; then
local PROCS=$(expr $lb_procs / 2)
if [ "$PROCS" -lt 1 ]; then PROCS=1; else PROCS=$PROCS; fi
else
local PROCS=$lb_procs
fi
ZEEKPINS=$(whiptail --noitem --title "$whiptail_title" --checklist "Please select $PROCS cores to pin Zeek to:" 20 75 12 "${cpu_core_list_whiptail[@]}" 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
ZEEKPINS=$(echo "$ZEEKPINS" | tr -d '"')
IFS=' ' read -ra ZEEKPINS <<< "$ZEEKPINS"
}