diff --git a/salt/common/tools/sbin/so-common b/salt/common/tools/sbin/so-common index ccf211637..a2c28587d 100755 --- a/salt/common/tools/sbin/so-common +++ b/salt/common/tools/sbin/so-common @@ -436,6 +436,20 @@ valid_proxy() { [[ $has_prefix == true ]] && [[ $valid_url == true ]] && return 0 || return 1 } +valid_ntp_list() { + local string=$1 + local ntp_arr + IFS="," read -r -a ntp_arr <<< "$string" + + for ntp in "${ntp_arr[@]}"; do + if ! valid_ip4 "$ntp" && ! valid_hostname "$ntp" && ! valid_fqdn "$ntp"; then + return 1 + fi + done + + return 0 +} + valid_string() { local str=$1 local min_length=${2:-1} diff --git a/setup/so-functions b/setup/so-functions index aff7a8375..2732a0ee9 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -395,7 +395,7 @@ collect_hostname() { if [[ $HOSTNAME == 'securityonion' ]]; then # Will only check HOSTNAME=securityonion once if ! (whiptail_avoid_default_hostname); then - whiptail_set_hostname + whiptail_set_hostname "$HOSTNAME" fi fi @@ -481,6 +481,22 @@ collect_node_ls_pipeline_worker_count() { done } +collect_ntp_servers() { + if whiptail_ntp_ask; then + [[ $is_airgap ]] && ntp_string="" + whiptail_ntp_servers "$ntp_string" + + while ! valid_ntp_list "$ntp_string"; do + whiptail_invalid_input + whiptail_ntp_servers "$ntp_string" + done + + IFS="," read -r -a ntp_servers <<< "$ntp_string" # Split string on commas into array + else + ntp_servers=() + fi +} + collect_oinkcode() { whiptail_oinkcode @@ -576,7 +592,7 @@ collect_proxy_details() { else so_proxy="$proxy_addr" fi - export proxy + export so_proxy fi } @@ -697,6 +713,42 @@ configure_minion() { } >> "$setup_log" 2>&1 } +configure_ntp() { + local chrony_conf=/etc/chrony.conf + + # Install chrony if it isn't already installed + if ! command -v chronyc &> /dev/null; then + yum -y install chrony + fi + + [[ -f $chrony_conf ]] && mv $chrony_conf "$chrony_conf.bak" + + printf '%s\n' "# NTP server list" > $chrony_conf + + # Build list of servers + for addr in "${ntp_servers[@]}"; do + echo "server $addr iburst" >> $chrony_conf + done + + printf '\n%s\n' "# Config options" >> $chrony_conf + + printf '%s\n' \ + 'driftfile /var/lib/chrony/drift' \ + 'makestep 1.0 3' \ + 'rtcsync' \ + 'logdir /var/log/chrony' >> $chrony_conf + + systemctl enable chronyd + systemctl restart chronyd + + # Tell the chrony daemon to sync time & update the system time + # Since these commands only make a call to chronyd, wait after each command to make sure the changes are made + printf "Syncing chrony time to server: " + chronyc -a 'burst 4/4' && sleep 30 + printf "Forcing chrony to update the time: " + chronyc -a makestep && sleep 30 +} + checkin_at_boot() { local minion_config=/etc/salt/minion @@ -1505,8 +1557,7 @@ manager_pillar() { printf '%s\n'\ " kratoskey: '$KRATOSKEY'"\ "" >> "$pillar_file" - - } +} manager_global() { local global_pillar="$local_salt_dir/pillar/global.sls" @@ -1530,7 +1581,6 @@ manager_global() { "global:"\ " soversion: '$SOVERSION'"\ " hnmanager: '$HNMANAGER'"\ - " ntpserver: '$NTPSERVER'"\ " dockernet: '$DOCKERNET'"\ " mdengine: '$ZEEKVERSION'"\ " ids: '$NIDS'"\ @@ -1684,7 +1734,6 @@ manager_global() { " bip: '$DOCKERBIP'"\ "redis_settings:"\ " redis_maxmemory: 812" >> "$global_pillar" - printf '%s\n' '----' >> "$setup_log" 2>&1 } @@ -1747,6 +1796,19 @@ network_setup() { } >> "$setup_log" 2>&1 } +ntp_pillar() { + local pillar_file="$temp_install_dir"/pillar/minions/"$MINION_ID".sls + + if [[ ${#ntp_servers[@]} -gt 0 ]]; then + printf '%s\n'\ + "ntp:"\ + " servers:" >> "$pillar_file" + for addr in "${ntp_servers[@]}"; do + printf '%s\n' " - '$addr'" >> "$pillar_file" + done + fi +} + parse_install_username() { # parse out the install username so things copy correctly INSTALLUSERNAME=${SUDO_USER:-${USER}} diff --git a/setup/so-setup b/setup/so-setup index 9beb11cec..e2c866964 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -299,6 +299,10 @@ if ! [[ -f $install_opt_file ]]; then source "$net_init_file" fi + if [[ $is_minion ]] || [[ $reinit_networking ]] || [[ $is_iso ]] && ! [[ -f $net_init_file ]]; then + whiptail_management_interface_setup + fi + if [[ $reinit_networking ]] || ! [[ -f $net_init_file ]]; then network_init fi @@ -316,10 +320,6 @@ if ! [[ -f $install_opt_file ]]; then [[ -n "$so_proxy" ]] && set_proxy >> $setup_log 2>&1 fi - if [[ $is_minion ]] || [[ $reinit_networking ]] || [[ $is_iso ]] && ! [[ -f $net_init_file ]]; then - whiptail_management_interface_setup - fi - if [[ $is_minion ]]; then add_mngr_ip_to_hosts fi @@ -535,6 +535,8 @@ if [[ $is_sensor && ! $is_eval ]]; then fi fi +[[ $is_iso ]] && collect_ntp_servers + if [[ $is_node && ! $is_eval ]]; then whiptail_node_advanced if [ "$NODESETUP" == 'NODEADVANCED' ]; then @@ -582,6 +584,8 @@ set_redirect >> $setup_log 2>&1 # Show initial progress message set_progress_str 0 'Running initial configuration steps' + [[ ${#ntp_servers[@]} -gt 0 ]] && configure_ntp >> $setup_log 2>&1 + reserve_ports set_path @@ -614,6 +618,8 @@ set_redirect >> $setup_log 2>&1 fi host_pillar >> $setup_log 2>&1 + ntp_pillar >> $setup_log 2>&1 + if [[ $is_minion || $is_import ]]; then set_updates >> $setup_log 2>&1 diff --git a/setup/so-variables b/setup/so-variables index a2fdf03c6..676cba4f0 100644 --- a/setup/so-variables +++ b/setup/so-variables @@ -72,3 +72,6 @@ export install_opt_file net_init_file=/root/net_init export net_init_file + +ntp_string="0.pool.ntp.org,1.pool.ntp.org" +export ntp_string diff --git a/setup/so-whiptail b/setup/so-whiptail index a0425b5af..00397a6fa 100755 --- a/setup/so-whiptail +++ b/setup/so-whiptail @@ -1105,6 +1105,22 @@ whiptail_node_ls_pipeline_worker() { } +whiptail_ntp_ask() { + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" --yesno "Would you like to configure ntp servers?" 7 44 +} + +whiptail_ntp_servers() { + [ -n "$TESTING" ] && return + + ntp_string=$(whiptail --title "Security Onion Setup" \ + --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 @@ -1271,11 +1287,7 @@ whiptail_proxy_auth_pass() { [ -n "$TESTING" ] && return - if [[ $arg != 'confirm' ]]; then - proxy_pass=$(whiptail --title "Security Onion Setup" --passwordbox "Please input the proxy password:" 8 60 3>&1 1>&2 2>&3) - else - proxy_pass_confirm=$(whiptail --title "Security Onion Setup" --passwordbox "Please confirm the proxy password:" 8 60 3>&1 1>&2 2>&3) - fi + proxy_pass=$(whiptail --title "Security Onion Setup" --passwordbox "Please input the proxy password:" 8 60 3>&1 1>&2 2>&3) local exitstatus=$? whiptail_check_exitstatus $exitstatus