diff --git a/pillar/data/addtotab.sh b/pillar/data/addtotab.sh index ac3d913a5..271558295 100644 --- a/pillar/data/addtotab.sh +++ b/pillar/data/addtotab.sh @@ -54,7 +54,8 @@ if [ $TYPE == 'evaltab' ] || [ $TYPE == 'standalonetab' ]; then salt-call state.apply utility queue=True fi fi -#if [ $TYPE == 'nodestab' ]; then +if [ $TYPE == 'nodestab' ]; then + salt-call state.apply elasticsearch queue=True # echo " nodetype: $NODETYPE" >> $local_salt_dir/pillar/data/$TYPE.sls # echo " hotname: $HOTNAME" >> $local_salt_dir/pillar/data/$TYPE.sls -#fi +fi diff --git a/pillar/top.sls b/pillar/top.sls index 77db6fe60..627fed80b 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -82,6 +82,7 @@ base: - elasticsearch.search - global - minions.{{ grains.id }} + - data.nodestab '*_import': - zeeklogs diff --git a/salt/common/tools/sbin/so-rule-update b/salt/common/tools/sbin/so-rule-update index ee6ac37df..397719d61 100755 --- a/salt/common/tools/sbin/so-rule-update +++ b/salt/common/tools/sbin/so-rule-update @@ -10,4 +10,4 @@ got_root() { } got_root -docker exec so-idstools /bin/bash -c 'cd /opt/so/idstools/etc && idstools-rulecat' +docker exec so-idstools /bin/bash -c "cd /opt/so/idstools/etc && idstools-rulecat $1" diff --git a/salt/elasticsearch/files/elasticsearch.yml b/salt/elasticsearch/files/elasticsearch.yml index 18d1c9c81..1ad65c43f 100644 --- a/salt/elasticsearch/files/elasticsearch.yml +++ b/salt/elasticsearch/files/elasticsearch.yml @@ -1,18 +1,19 @@ {%- set NODE_ROUTE_TYPE = salt['pillar.get']('elasticsearch:node_route_type', 'hot') %} -{%- if salt['pillar.get']('elasticsearch:hot_warm_enabled') or salt['pillar.get']('elasticsearch:true_cluster') %} -{%- set ESCLUSTERNAME = salt['pillar.get']('elasticsearch:true_cluster_name', '') %} +{%- set NODEIP = salt['pillar.get']('elasticsearch:mainip') %} +{%- set FEATURES = salt['pillar.get']('elastic:features', False) %} +{%- set TRUECLUSTER = salt['pillar.get']('elasticsearch:true_cluster', False) %} +{%- if TRUECLUSTER is sameas true %} + {%- set ESCLUSTERNAME = salt['pillar.get']('elasticsearch:true_cluster_name') %} {%- else %} -{%- set ESCLUSTERNAME = salt['pillar.get']('elasticsearch:esclustername', '') %} + {%- set ESCLUSTERNAME = salt['pillar.get']('elasticsearch:esclustername') %} {%- endif %} -{%- set NODEIP = salt['pillar.get']('elasticsearch:mainip', '') -%} -{% set FEATURES = salt['pillar.get']('elastic:features', False) %} cluster.name: "{{ ESCLUSTERNAME }}" network.host: 0.0.0.0 # minimum_master_nodes need to be explicitly set when bound on a public IP # set to 1 to allow single node clusters # Details: https://github.com/elastic/elasticsearch/pull/17288 -discovery.zen.minimum_master_nodes: 1 +#discovery.zen.minimum_master_nodes: 1 # This is a test -- if this is here, then the volume is mounted correctly. path.logs: /var/log/elasticsearch action.destructive_requires_name: true @@ -37,11 +38,30 @@ cluster.routing.allocation.disk.watermark.flood_stage: 98% #xpack.security.http.ssl.client_authentication: none #xpack.security.authc: # anonymous: -# username: anonymous_user -# roles: superuser -# authz_exception: true +# username: anonymous_user +# roles: superuser +# authz_exception: true {%- endif %} -node.attr.box_type: {{ NODE_ROUTE_TYPE }} -node.name: {{ ESCLUSTERNAME }} +node.name: {{ grains.host }} script.max_compilations_rate: 1000/1m +{%- if TRUECLUSTER is sameas true %} + {%- if grains.role == 'so-manager' %} + {%- if salt['pillar.get']('nodestab', {}) %} +node.roles: [ master, data, remote_cluster_client ] +discovery.seed_hosts: + - {{ grains.master }} + {%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).items() %} + - {{ SN.split('_')|first }} + {%- endfor %} + {%- endif %} + {%- else %} +node.roles: [ data, ingest ] +node.attr.box_type: {{ NODE_ROUTE_TYPE }} +discovery.seed_hosts: + - {{ grains.master }} + {%- endif %} +{%- endif %} +{%- if TRUECLUSTER is sameas false %} +node.attr.box_type: {{ NODE_ROUTE_TYPE }} +{%- endif %} indices.query.bool.max_clause_count: 1500 diff --git a/salt/elasticsearch/files/ingest/suricata.ftp_data b/salt/elasticsearch/files/ingest/suricata.ftp_data new file mode 100644 index 000000000..2867fbab0 --- /dev/null +++ b/salt/elasticsearch/files/ingest/suricata.ftp_data @@ -0,0 +1,10 @@ +{ + "description" : "suricata.ftp_data", + "processors" : [ + { "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } }, + { "rename": { "field": "message2.app_proto", "target_field": "network.protocol", "ignore_missing": true } }, + { "rename": { "field": "message2.ftp_data.command", "target_field": "ftp.command", "ignore_missing": true } }, + { "rename": { "field": "message2.ftp_data.filename","target_field": "ftp.argument", "ignore_missing": true } }, + { "pipeline": { "name": "common" } } + ] +} diff --git a/salt/elasticsearch/init.sls b/salt/elasticsearch/init.sls index 0b28ee6d1..3e0bac708 100644 --- a/salt/elasticsearch/init.sls +++ b/salt/elasticsearch/init.sls @@ -21,22 +21,22 @@ {% set IMAGEREPO = salt['pillar.get']('global:imagerepo') %} {% set MANAGER = salt['grains.get']('master') %} {% set FEATURES = salt['pillar.get']('elastic:features', False) %} -{%- set NODEIP = salt['pillar.get']('elasticsearch:mainip', '') -%} +{% set NODEIP = salt['pillar.get']('elasticsearch:mainip', '') -%} +{% set TRUECLUSTER = salt['pillar.get']('elasticsearch:true_cluster', False) %} - -{%- if FEATURES is sameas true %} +{% if FEATURES is sameas true %} {% set FEATUREZ = "-features" %} {% else %} {% set FEATUREZ = '' %} {% endif %} {% if grains['role'] in ['so-eval','so-managersearch', 'so-manager', 'so-standalone', 'so-import'] %} - {% set esclustername = salt['pillar.get']('manager:esclustername', '') %} - {% set esheap = salt['pillar.get']('manager:esheap', '') %} + {% set esclustername = salt['pillar.get']('manager:esclustername') %} + {% set esheap = salt['pillar.get']('manager:esheap') %} {% set ismanager = True %} {% elif grains['role'] in ['so-node','so-heavynode'] %} - {% set esclustername = salt['pillar.get']('elasticsearch:esclustername', '') %} - {% set esheap = salt['pillar.get']('elasticsearch:esheap', '') %} + {% set esclustername = salt['pillar.get']('elasticsearch:esclustername') %} + {% set esheap = salt['pillar.get']('elasticsearch:esheap') %} {% set ismanager = False %} {% endif %} @@ -188,16 +188,16 @@ so-elasticsearch: - name: so-elasticsearch - user: elasticsearch - extra_hosts: - - {{ grains.host }}:{{ NODEIP }} - {%- if ismanager %} - {%- if salt['pillar.get']('nodestab', {}) %} - {%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).items() %} - - {{ SN.split('_')|first }}:{{ SNDATA.ip }} - {%- endfor %} - {%- endif %} - {%- endif %} + - "{{ grains.host }}:{{ NODEIP }}" + {% if salt['pillar.get']('nodestab', {}) %} + {% for SN, SNDATA in salt['pillar.get']('nodestab', {}).items() %} + - "{{ SN.split('_')|first }}:{{ SNDATA.ip }}" + {% endfor %} + {% endif %} - environment: + {% if TRUECLUSTER is sameas false or (TRUECLUSTER is sameas true and not salt['pillar.get']('nodestab', {})) %} - discovery.type=single-node + {% endif %} - ES_JAVA_OPTS=-Xms{{ esheap }} -Xmx{{ esheap }} ulimits: - memlock=-1:-1 diff --git a/salt/utility/bin/crossthestreams b/salt/utility/bin/crossthestreams index 6998c7669..490c7b548 100644 --- a/salt/utility/bin/crossthestreams +++ b/salt/utility/bin/crossthestreams @@ -1,8 +1,8 @@ #!/bin/bash {% set ES = salt['pillar.get']('manager:mainip', '') %} -{%- set MANAGER = salt['grains.get']('master') %} +{% set MANAGER = salt['grains.get']('master') %} {% set FEATURES = salt['pillar.get']('elastic:features', False) %} - +{% set TRUECLUSTER = salt['pillar.get']('elasticsearch:true_cluster', False) %} # Wait for ElasticSearch to come up, so that we can query for version infromation echo -n "Waiting for ElasticSearch..." @@ -34,9 +34,10 @@ echo "Applying cross cluster search config..." -d "{\"persistent\": {\"search\": {\"remote\": {\"{{ MANAGER }}\": {\"seeds\": [\"127.0.0.1:9300\"]}}}}}" # Add all the search nodes to cross cluster searching. - -{%- if salt['pillar.get']('nodestab', {}) %} - {%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).items() %} +{%- if TRUECLUSTER is sameas false %} + {%- if salt['pillar.get']('nodestab', {}) %} + {%- for SN, SNDATA in salt['pillar.get']('nodestab', {}).items() %} curl -XPUT -L http://{{ ES }}:9200/_cluster/settings -H'Content-Type: application/json' -d '{"persistent": {"search": {"remote": {"{{ SN }}": {"skip_unavailable": "true", "seeds": ["{{ SN.split('_')|first }}:9300"]}}}}}' - {%- endfor %} + {%- endfor %} + {%- endif %} {%- endif %} diff --git a/setup/so-functions b/setup/so-functions index b3e016cfa..6a6f42dc7 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1177,15 +1177,23 @@ manager_global() { "elastic:"\ " features: False"\ "elasticsearch:"\ - " replicas: 0"\ - " true_cluster: False"\ - " true_cluster_name: 'so'"\ + " replicas: 0" >> "$global_pillar" + if [ -n "$ESCLUSTERNAME" ]; then + printf '%s\n'\ + " true_cluster: True"\ + " true_cluster_name: '$ESCLUSTERNAME'" >> "$global_pillar" + else + printf '%s\n'\ + " true_cluster: False"\ + " true_cluster_name: 'so'" >> "$global_pillar" + fi + printf '%s\n'\ " discovery_nodes: 1"\ " hot_warm_enabled: False"\ " cluster_routing_allocation_disk.threshold_enabled: true"\ - " cluster_routing_allocation_disk_watermark_low: '95%'"\ - " cluster_routing_allocation_disk_watermark_high: '98%'"\ - " cluster_routing_allocation_disk_watermark_flood_stage: '98%'"\ + " cluster_routing_allocation_disk_watermark_low: '95%'"\ + " cluster_routing_allocation_disk_watermark_high: '98%'"\ + " cluster_routing_allocation_disk_watermark_flood_stage: '98%'"\ " index_settings:"\ " so-beats:"\ " shards: 1"\ @@ -1301,8 +1309,15 @@ elasticsearch_pillar() { "elasticsearch:"\ " mainip: '$MAINIP'"\ " mainint: '$MNIC'"\ - " esheap: '$NODE_ES_HEAP_SIZE'"\ - " esclustername: {{ grains.host }}"\ + " esheap: '$NODE_ES_HEAP_SIZE'" >> "$pillar_file" + if [ -n "$ESCLUSTERNAME" ]; then + printf '%s\n'\ + " esclustername: $ESCLUSTERNAME" >> "$pillar_file" + else + printf '%s\n'\ + " esclustername: {{ grains.host }}" >> "$pillar_file" + fi + printf '%s\n'\ " node_type: '$NODETYPE'"\ " es_port: $node_es_port"\ " log_size_limit: $log_size_limit"\ diff --git a/setup/so-setup b/setup/so-setup index 8ee236bf1..ccfa87a59 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -336,6 +336,11 @@ fi if [[ $is_manager && ! $is_eval ]]; then whiptail_manager_adv + if [ "$MANAGERADV" = 'ADVANCED' ]; then + if [ "$install_type" = 'MANAGER' ] || [ "$install_type" = 'MANAGERSEARCH' ]; then + whiptail_manager_adv_escluster + fi + fi whiptail_zeek_version # Don't run this function for now since Snort is not yet supported # whiptail_nids @@ -741,7 +746,7 @@ fi set_progress_str 81 "$(print_salt_state_apply 'strelka')" salt-call state.apply -l info strelka >> $setup_log 2>&1 fi - if [[ $STRELKARULES == 1 ]]; then + if [[ "$STRELKARULES" == 1 ]]; then /usr/sbin/so-yara-update >> $setup_log 2>&1 fi fi diff --git a/setup/so-whiptail b/setup/so-whiptail index 11d968910..7b105bb8e 100755 --- a/setup/so-whiptail +++ b/setup/so-whiptail @@ -31,24 +31,6 @@ whiptail_airgap() { whiptail_check_exitstatus $exitstatus } -whiptail_basic_zeek() { - - [ -n "$TESTING" ] && return - - 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 - - BASICZEEK=$(whiptail --title "Security Onion Setup" --inputbox \ - "Enter the number of zeek processes:" 10 75 "$PROCS" 3>&1 1>&2 2>&3) - - local exitstatus=$? - whiptail_check_exitstatus $exitstatus -} - whiptail_basic_suri() { [ -n "$TESTING" ] && return @@ -68,15 +50,10 @@ whiptail_basic_suri() { } -whiptail_zeek_pins() { +whiptail_basic_zeek() { [ -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 @@ -84,13 +61,11 @@ whiptail_zeek_pins() { local PROCS=$lb_procs fi - ZEEKPINS=$(whiptail --noitem --title "Pin Zeek CPUS" --checklist "Please select $PROCS cores to pin Zeek to:" 20 75 12 "${cpu_core_list_whiptail[@]}" 3>&1 1>&2 2>&3 ) + BASICZEEK=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter the number of zeek processes:" 10 75 "$PROCS" 3>&1 1>&2 2>&3) + local exitstatus=$? whiptail_check_exitstatus $exitstatus - - ZEEKPINS=$(echo "$ZEEKPINS" | tr -d '"') - - IFS=' ' read -ra ZEEKPINS <<< "$ZEEKPINS" } whiptail_zeek_version() { @@ -103,47 +78,6 @@ whiptail_zeek_version() { 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 "NIC Setup" --$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 "NIC Setup" --$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 - if [[ "${nmcli_dev_status_list}" =~ $bond_nic\:unmanaged ]]; then - whiptail \ - --title "Security Onion Setup" \ - --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 } whiptail_bond_nics_mtu() { @@ -187,6 +121,13 @@ whiptail_check_exitstatus() { esac } +whiptail_components_adv_warning() { + + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" --msgbox "Please keep in mind the more services that you enable the more RAM that is required." 8 75 +} + whiptail_create_admin_user() { [ -n "$TESTING" ] && return @@ -294,13 +235,6 @@ whiptail_create_web_user() { whiptail_check_exitstatus $exitstatus } -whiptail_invalid_user_warning() { - - [ -n "$TESTING" ] && return - - whiptail --title "Security Onion Setup" --msgbox "Please enter a valid email address." 8 75 -} - whiptail_create_web_user_password1() { [ -n "$TESTING" ] && return @@ -546,11 +480,26 @@ whiptail_eval_adv() { whiptail_check_exitstatus $exitstatus } -whiptail_components_adv_warning() { +whiptail_fleet_custom_hostname() { [ -n "$TESTING" ] && return - whiptail --title "Security Onion Setup" --msgbox "Please keep in mind the more services that you enable the more RAM that is required." 8 75 + FLEETCUSTOMHOSTNAME=$(whiptail --title "Security Onion Install" --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 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 "Security Onion Setup" --gauge "$msg" 6 60 96 + fi } whiptail_helix_apikey() { @@ -677,6 +626,27 @@ whiptail_install_type_other() { export install_type } +whiptail_invalid_pass_characters_warning() { + + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" --msgbox "Password is invalid. Please exclude single quotes, double quotes and backslashes from the password." 8 75 +} + +whiptail_invalid_pass_warning() { + + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" --msgbox "Please choose a more secure password." 8 75 +} + +whiptail_invalid_user_warning() { + + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" --msgbox "Please enter a valid email address." 8 75 +} + whiptail_log_size_limit() { [ -n "$TESTING" ] && return @@ -691,6 +661,17 @@ whiptail_log_size_limit() { } +whiptail_make_changes() { + + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" --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 @@ -765,43 +746,6 @@ whiptail_management_nic() { } -whiptail_nids() { - - [ -n "$TESTING" ] && return - - NIDS=$(whiptail --title "Security Onion Setup" --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_oinkcode() { - - [ -n "$TESTING" ] && return - - OINKCODE=$(whiptail --title "Security Onion Setup" --inputbox \ - "Enter your ET Pro or oinkcode:" 10 75 XXXXXXX 3>&1 1>&2 2>&3) - - local exitstatus=$? - whiptail_check_exitstatus $exitstatus - -} - -whiptail_make_changes() { - - [ -n "$TESTING" ] && return - - whiptail --title "Security Onion Setup" --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_server() { [ -n "$TESTING" ] && return @@ -851,6 +795,30 @@ whiptail_manager_adv() { } +# Ask if you want to do true clustering +whiptail_manager_adv_escluster(){ + + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" --yesno \ + "Do you want to set up a traditional ES cluster?" 8 75 + + local exitstatus=$? + + if [[ $exitstatus == 0 ]]; then + whiptail_manager_adv_escluster_name + fi +} + +# Get a cluster name +whiptail_manager_adv_escluster_name(){ + + [ -n "$TESTING" ] && return + + ESCLUSTERNAME=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter a name for your ES cluster!" 10 75 securityonion 3>&1 1>&2 2>&3) +} + # Ask which additional components to install whiptail_manager_adv_service_zeeklogs() { @@ -905,6 +873,54 @@ whiptail_manager_adv_service_zeeklogs() { } +whiptail_manager_updates() { + + [ -n "$TESTING" ] && return + + local update_string + update_string=$(whiptail --title "Security Onion Setup" --radiolist \ + "How would you like to download OS package updates for your grid?" 20 75 4 \ + "MANAGER" "Manager node is proxy for updates" ON \ + "OPEN" "Each node connects to the Internet for updates" OFF 3>&1 1>&2 2>&3 ) + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + + case "$update_string" in + 'MANAGER') + export MANAGERUPDATES='1' + ;; + *) + export MANAGERUPDATES='0' + ;; + esac + +} + +whiptail_manager_updates_warning() { + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup"\ + --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_nids() { + + [ -n "$TESTING" ] && return + + NIDS=$(whiptail --title "Security Onion Setup" --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 @@ -990,6 +1006,18 @@ whiptail_node_ls_input_threads() { } +whiptail_oinkcode() { + + [ -n "$TESTING" ] && return + + OINKCODE=$(whiptail --title "Security Onion Setup" --inputbox \ + "Enter your ET Pro or oinkcode:" 10 75 XXXXXXX 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"> @@ -1144,6 +1172,21 @@ whiptail_patch_schedule_select_hours() { } +whiptail_requirements_error() { + + local requirement_needed=$1 + local current_val=$2 + local needed_val=$3 + + [ -n "$TESTING" ] && return + + whiptail --title "Security Onion Setup" \ + --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 @@ -1175,6 +1218,46 @@ whiptail_sensor_config() { } +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 "NIC Setup" --$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 "NIC Setup" --$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 + if [[ "${nmcli_dev_status_list}" =~ $bond_nic\:unmanaged ]]; then + whiptail \ + --title "Security Onion Setup" \ + --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 +} + whiptail_set_hostname() { [ -n "$TESTING" ] && return @@ -1295,15 +1378,30 @@ whiptail_so_allow() { fi } -whiptail_gauge_post_setup() { +whiptail_storage_requirements() { + local mount=$1 + local current_val=$2 + local needed_val=$3 - if [ -n "$TESTING" ]; then - cat >> $setup_log 2>&1 - else - local msg=$1 + [ -n "$TESTING" ] && return - whiptail --title "Security Onion Setup" --gauge "$msg" 6 60 96 - fi + 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/2.1/hardware.html for more information. + + Press YES to continue anyway, or press NO to cancel. + EOM + + whiptail \ + --title "Security Onion Setup" \ + --yesno "$message" \ + 14 75 + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus } whiptail_strelka_rules() { @@ -1346,40 +1444,6 @@ whiptail_suricata_pins() { } -whiptail_manager_updates() { - - [ -n "$TESTING" ] && return - - local update_string - update_string=$(whiptail --title "Security Onion Setup" --radiolist \ - "How would you like to download OS package updates for your grid?" 20 75 4 \ - "MANAGER" "Manager node is proxy for updates" ON \ - "OPEN" "Each node connects to the Internet for updates" OFF 3>&1 1>&2 2>&3 ) - local exitstatus=$? - whiptail_check_exitstatus $exitstatus - - case "$update_string" in - 'MANAGER') - export MANAGERUPDATES='1' - ;; - *) - export MANAGERUPDATES='0' - ;; - esac - -} - -whiptail_manager_updates_warning() { - [ -n "$TESTING" ] && return - - whiptail --title "Security Onion Setup"\ - --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_node_updates() { [ -n "$TESTING" ] && return @@ -1417,3 +1481,40 @@ whiptail_you_sure() { 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 "Pin Zeek CPUS" --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" +} + +whiptail_zeek_version() { + + [ -n "$TESTING" ] && return + + ZEEKVERSION=$(whiptail --title "Security Onion Setup" --radiolist "What tool would you like to use to generate metadata?" 20 75 4 "ZEEK" "Zeek (formerly known as Bro)" ON \ + "SURICATA" "Suricata" OFF 3>&1 1>&2 2>&3) + + local exitstatus=$? + whiptail_check_exitstatus $exitstatus + +}