From 1e32a01657306619de7e9e79c1b94a20428d1ec0 Mon Sep 17 00:00:00 2001 From: Jason Ertel Date: Mon, 23 Nov 2020 18:36:19 -0500 Subject: [PATCH 01/10] Create symlink before registration otherwise registration script can't save it's state (.log) file into the conf subdir; add more logging output to track down registration failures --- salt/wazuh/files/agent/wazuh-register-agent | 3 ++- salt/wazuh/init.sls | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/salt/wazuh/files/agent/wazuh-register-agent b/salt/wazuh/files/agent/wazuh-register-agent index 6762f023d..da4870e47 100755 --- a/salt/wazuh/files/agent/wazuh-register-agent +++ b/salt/wazuh/files/agent/wazuh-register-agent @@ -55,8 +55,9 @@ register_agent() { # Adding agent and getting Id from manager echo "" echo "Adding agent:" - echo "curl -s -u $USER:**** -k -X POST -d 'name=$AGENT_NAME&ip=$AGENT_IP' $PROTOCOL://$API_IP:$API_PORT/agents" + echo "Executing: curl -s -u $USER:**** -k -X POST -d 'name=$AGENT_NAME&ip=$AGENT_IP' $PROTOCOL://$API_IP:$API_PORT/agents" API_RESULT=$(curl -s -u $USER:"$PASSWORD" -k -X POST -d 'name='$AGENT_NAME'&ip='$AGENT_IP -L $PROTOCOL://$API_IP:$API_PORT/agents) + echo "Result: $API_RESULT" echo -e $API_RESULT | grep -q "\"error\":0" 2>&1 if [ "$?" != "0" ]; then diff --git a/salt/wazuh/init.sls b/salt/wazuh/init.sls index e8e40c720..19afa48d7 100644 --- a/salt/wazuh/init.sls +++ b/salt/wazuh/init.sls @@ -128,15 +128,15 @@ whitelistmanager: - name: /usr/sbin/wazuh-manager-whitelist - cwd: / +/opt/so/conf/wazuh: + file.symlink: + - target: /nsm/wazuh/etc + wazuhagentservice: service.running: - name: wazuh-agent - enable: True -/opt/so/conf/wazuh: - file.symlink: - - target: /nsm/wazuh/etc - hidsruledir: file.directory: - name: /opt/so/rules/hids From 65334d15ea1cf806b2482ace2d511370053f55a8 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 24 Nov 2020 09:33:38 -0500 Subject: [PATCH 02/10] https://github.com/Security-Onion-Solutions/securityonion/issues/2040 --- salt/pcap/init.sls | 42 ------------------- salt/{pcap => sensoroni}/files/sensoroni.json | 5 ++- salt/sensoroni/init.sls | 41 ++++++++++++++++++ salt/top.sls | 1 + setup/so-functions | 13 +++++- setup/so-setup | 1 + 6 files changed, 59 insertions(+), 44 deletions(-) rename salt/{pcap => sensoroni}/files/sensoroni.json (76%) create mode 100644 salt/sensoroni/init.sls diff --git a/salt/pcap/init.sls b/salt/pcap/init.sls index 5a13c1231..e98bbecf5 100644 --- a/salt/pcap/init.sls +++ b/salt/pcap/init.sls @@ -45,13 +45,6 @@ stenoconfdir: - group: 939 - makedirs: True -sensoroniconfdir: - file.directory: - - name: /opt/so/conf/sensoroni - - user: 939 - - group: 939 - - makedirs: True - {% if BPF_STENO %} {% set BPF_CALC = salt['cmd.script']('/usr/sbin/so-bpf-compile', INTERFACE + ' ' + BPF_STENO|join(" "),cwd='/root') %} {% if BPF_CALC['stderr'] == "" %} @@ -77,15 +70,6 @@ stenoconf: - defaults: BPF_COMPILED: "{{ BPF_COMPILED }}" -sensoroniagentconf: - file.managed: - - name: /opt/so/conf/sensoroni/sensoroni.json - - source: salt://pcap/files/sensoroni.json - - user: 939 - - group: 939 - - mode: 600 - - template: jinja - stenoca: file.directory: - name: /opt/so/conf/steno/certs @@ -127,13 +111,6 @@ stenolog: - group: 941 - makedirs: True -sensoronilog: - file.directory: - - name: /opt/so/log/sensoroni - - user: 939 - - group: 939 - - makedirs: True - so-steno: docker_container.{{ STENOOPTIONS.status }}: - image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-steno:{{ VERSION }} @@ -170,25 +147,6 @@ so-steno_so-status.disabled: - regex: ^so-steno$ {% endif %} -so-sensoroni: - docker_container.running: - - image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-soc:{{ VERSION }} - - network_mode: host - - binds: - - /opt/so/conf/steno/certs:/etc/stenographer/certs:rw - - /nsm/pcap:/nsm/pcap:rw - - /nsm/import:/nsm/import:rw - - /nsm/pcapout:/nsm/pcapout:rw - - /opt/so/conf/sensoroni/sensoroni.json:/opt/sensoroni/sensoroni.json:ro - - /opt/so/log/sensoroni:/opt/sensoroni/logs:rw - - watch: - - file: /opt/so/conf/sensoroni/sensoroni.json - -append_so-sensoroni_so-status.conf: - file.append: - - name: /opt/so/conf/so-status/so-status.conf - - text: so-sensoroni - {% else %} pcap_state_not_allowed: diff --git a/salt/pcap/files/sensoroni.json b/salt/sensoroni/files/sensoroni.json similarity index 76% rename from salt/pcap/files/sensoroni.json rename to salt/sensoroni/files/sensoroni.json index 8a9027bd0..f7c1edc25 100644 --- a/salt/pcap/files/sensoroni.json +++ b/salt/sensoroni/files/sensoroni.json @@ -1,6 +1,7 @@ {%- set URLBASE = salt['pillar.get']('global:url_base') %} {%- set SENSORONIKEY = salt['pillar.get']('global:sensoronikey', '') -%} -{%- set CHECKININTERVALMS = salt['pillar.get']('pcap:sensor_checkin_interval_ms', 10000) -%} +{%- set CHECKININTERVALMS = salt['pillar.get']('sensoroni:sensor_checkin_interval_ms', 10000) -%} +{%- set STENOENABLED = salt['pillar.get']('steno:enabled', False) %} { "logFilename": "/opt/sensoroni/logs/sensoroni.log", "logLevel":"info", @@ -13,11 +14,13 @@ "statickeyauth": { "apiKey": "{{ SENSORONIKEY }}" }, +{%- if STENOENABLED %} "stenoquery": { "executablePath": "/opt/sensoroni/scripts/stenoquery.sh", "pcapInputPath": "/nsm/pcap", "pcapOutputPath": "/nsm/pcapout" } +{%- endif %} } } } diff --git a/salt/sensoroni/init.sls b/salt/sensoroni/init.sls new file mode 100644 index 000000000..3268e86fd --- /dev/null +++ b/salt/sensoroni/init.sls @@ -0,0 +1,41 @@ +sensoroniconfdir: + file.directory: + - name: /opt/so/conf/sensoroni + - user: 939 + - group: 939 + - makedirs: True + +sensoroniagentconf: + file.managed: + - name: /opt/so/conf/sensoroni/sensoroni.json + - source: salt://sensoroni/files/sensoroni.json + - user: 939 + - group: 939 + - mode: 600 + - template: jinja + +sensoronilog: + file.directory: + - name: /opt/so/log/sensoroni + - user: 939 + - group: 939 + - makedirs: True + +so-sensoroni: + docker_container.running: + - image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-soc:{{ VERSION }} + - network_mode: host + - binds: + - /opt/so/conf/steno/certs:/etc/stenographer/certs:rw + - /nsm/pcap:/nsm/pcap:rw + - /nsm/import:/nsm/import:rw + - /nsm/pcapout:/nsm/pcapout:rw + - /opt/so/conf/sensoroni/sensoroni.json:/opt/sensoroni/sensoroni.json:ro + - /opt/so/log/sensoroni:/opt/sensoroni/logs:rw + - watch: + - file: /opt/so/conf/sensoroni/sensoroni.json + +append_so-sensoroni_so-status.conf: + file.append: + - name: /opt/so/conf/so-status/so-status.conf + - text: so-sensoroni \ No newline at end of file diff --git a/salt/top.sls b/salt/top.sls index bbd2a862d..9d41481fe 100644 --- a/salt/top.sls +++ b/salt/top.sls @@ -44,6 +44,7 @@ base: - patch.os.schedule - motd - salt.minion-check + - sensoroni - salt.lasthighstate '*_helix and G@saltversion:{{saltversion}}': diff --git a/setup/so-functions b/setup/so-functions index f13a183f2..4ba639fa5 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1166,7 +1166,7 @@ manager_global() { " managerupdate: $MANAGERUPDATES"\ " imagerepo: '$IMAGEREPO'"\ " pipeline: 'redis'"\ - "pcap:"\ + "sensoroni:"\ " sensor_checkin_interval_ms: $SENSOR_CHECKIN_INTERVAL_MS"\ "strelka:"\ " enabled: $STRELKA"\ @@ -1968,6 +1968,17 @@ set_updates() { fi } +steno_pillar() { + + local pillar_file=$temp_install_dir/pillar/minions/$MINION_ID.sls + + # Create the stenographer pillar + printf '%s\n'\ + "steno:"\ + " enabled: True" >> "$pillar_file" + +} + mark_version() { # Drop a file with the current version echo "$SOVERSION" > /etc/soversion diff --git a/setup/so-setup b/setup/so-setup index 22e429ad4..a064de623 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -511,6 +511,7 @@ fi if [[ $is_sensor || $is_helix || $is_import ]]; then set_progress_str 4 'Generating sensor pillar' sensor_pillar >> $setup_log 2>&1 + steno_pillar >> $setup_log fi set_progress_str 5 'Installing Salt and dependencies' From 4dfd49ef393c97da2211bead39952f4f88d7c921 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 24 Nov 2020 10:11:28 -0500 Subject: [PATCH 03/10] add vars https://github.com/Security-Onion-Solutions/securityonion/issues/2040 --- salt/sensoroni/init.sls | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/salt/sensoroni/init.sls b/salt/sensoroni/init.sls index 3268e86fd..a55049c06 100644 --- a/salt/sensoroni/init.sls +++ b/salt/sensoroni/init.sls @@ -1,3 +1,7 @@ +{% set VERSION = salt['pillar.get']('global:soversion', 'HH1.2.2') %} +{% set IMAGEREPO = salt['pillar.get']('global:imagerepo') %} +{% set MANAGER = salt['grains.get']('master') %} + sensoroniconfdir: file.directory: - name: /opt/so/conf/sensoroni From e3a41c2a944370725c4baac95e102123d0d2db51 Mon Sep 17 00:00:00 2001 From: weslambert Date: Tue, 24 Nov 2020 11:20:09 -0500 Subject: [PATCH 04/10] Changes for ES7 elasticsearch.yml --- salt/thehive/etc/es/elasticsearch.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/salt/thehive/etc/es/elasticsearch.yml b/salt/thehive/etc/es/elasticsearch.yml index 7f268a671..3465ec7dc 100644 --- a/salt/thehive/etc/es/elasticsearch.yml +++ b/salt/thehive/etc/es/elasticsearch.yml @@ -4,6 +4,8 @@ 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 +discovery.type: single-node +script.allowed_types: inline transport.bind_host: 0.0.0.0 transport.publish_host: 0.0.0.0 transport.publish_port: 9500 @@ -11,6 +13,5 @@ http.host: 0.0.0.0 http.port: 9400 transport.tcp.port: 9500 transport.host: 0.0.0.0 -thread_pool.index.queue_size: 100000 thread_pool.search.queue_size: 100000 -thread_pool.bulk.queue_size: 100000 +thread_pool.write.queue_size: 10000 From 995a37743284c8b8f32079ad7f309229a0ff8698 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 24 Nov 2020 11:31:41 -0500 Subject: [PATCH 05/10] squigly comma if steno enabled https://github.com/Security-Onion-Solutions/securityonion/issues/2040 --- salt/sensoroni/files/sensoroni.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/salt/sensoroni/files/sensoroni.json b/salt/sensoroni/files/sensoroni.json index f7c1edc25..ee46b5937 100644 --- a/salt/sensoroni/files/sensoroni.json +++ b/salt/sensoroni/files/sensoroni.json @@ -1,7 +1,7 @@ -{%- set URLBASE = salt['pillar.get']('global:url_base') %} -{%- set SENSORONIKEY = salt['pillar.get']('global:sensoronikey', '') -%} -{%- set CHECKININTERVALMS = salt['pillar.get']('sensoroni:sensor_checkin_interval_ms', 10000) -%} -{%- set STENOENABLED = salt['pillar.get']('steno:enabled', False) %} +{% set URLBASE = salt['pillar.get']('global:url_base') -%} +{% set SENSORONIKEY = salt['pillar.get']('global:sensoronikey', '') -%} +{% set CHECKININTERVALMS = salt['pillar.get']('sensoroni:sensor_checkin_interval_ms', 10000) -%} +{% set STENOENABLED = salt['pillar.get']('steno:enabled', False) -%} { "logFilename": "/opt/sensoroni/logs/sensoroni.log", "logLevel":"info", @@ -13,13 +13,15 @@ "importer": {}, "statickeyauth": { "apiKey": "{{ SENSORONIKEY }}" - }, -{%- if STENOENABLED %} +{%- if STENOENABLED %} + }, "stenoquery": { "executablePath": "/opt/sensoroni/scripts/stenoquery.sh", "pcapInputPath": "/nsm/pcap", "pcapOutputPath": "/nsm/pcapout" } +{%- else %} + } {%- endif %} } } From fe2662cab82e37fbddf7ee887c0433fae0d5e6c5 Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Tue, 24 Nov 2020 11:42:03 -0500 Subject: [PATCH 06/10] dont enable steno pillar on import node https://github.com/Security-Onion-Solutions/securityonion/issues/2040 --- setup/so-setup | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup/so-setup b/setup/so-setup index a064de623..0dfbef58a 100755 --- a/setup/so-setup +++ b/setup/so-setup @@ -511,7 +511,9 @@ fi if [[ $is_sensor || $is_helix || $is_import ]]; then set_progress_str 4 'Generating sensor pillar' sensor_pillar >> $setup_log 2>&1 - steno_pillar >> $setup_log + if [[ $is_sensor || $is_helix ]]; then + steno_pillar >> $setup_log + fi fi set_progress_str 5 'Installing Salt and dependencies' From eb2364b926346dcf9cf3018ffc226592226833af Mon Sep 17 00:00:00 2001 From: weslambert Date: Tue, 24 Nov 2020 11:49:08 -0500 Subject: [PATCH 07/10] Changes for ES7 --- salt/thehive/init.sls | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/salt/thehive/init.sls b/salt/thehive/init.sls index e695c237f..c89017dda 100644 --- a/salt/thehive/init.sls +++ b/salt/thehive/init.sls @@ -89,14 +89,6 @@ so-thehive-es: - /opt/so/conf/thehive/etc/es/log4j2.properties:/usr/share/elasticsearch/config/log4j2.properties:ro - /opt/so/log/thehive:/var/log/elasticsearch:rw - environment: - - http.host=0.0.0.0 - - http.port=9400 - - transport.tcp.port=9500 - - transport.host=0.0.0.0 - - cluster.name=thehive - - thread_pool.index.queue_size=100000 - - thread_pool.search.queue_size=100000 - - thread_pool.bulk.queue_size=100000 - ES_JAVA_OPTS=-Xms512m -Xmx512m - port_bindings: - 0.0.0.0:9400:9400 @@ -164,4 +156,4 @@ thehive_state_not_allowed: test.fail_without_changes: - name: thehive_state_not_allowed -{% endif %} \ No newline at end of file +{% endif %} From 35653d2e66f63f1dd029e3ee7f2d2f77ebf80d82 Mon Sep 17 00:00:00 2001 From: weslambert Date: Tue, 24 Nov 2020 11:51:19 -0500 Subject: [PATCH 08/10] Changes for ES7 --- salt/thehive/etc/es/elasticsearch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/thehive/etc/es/elasticsearch.yml b/salt/thehive/etc/es/elasticsearch.yml index 3465ec7dc..1f1518299 100644 --- a/salt/thehive/etc/es/elasticsearch.yml +++ b/salt/thehive/etc/es/elasticsearch.yml @@ -1,4 +1,4 @@ -cluster.name: "thehive" +cluster.name: thehive network.host: 0.0.0.0 discovery.zen.minimum_master_nodes: 1 # This is a test -- if this is here, then the volume is mounted correctly. From 39bf60feb7f26ba8b9e7b484ee80bbb2653c613c Mon Sep 17 00:00:00 2001 From: weslambert Date: Tue, 24 Nov 2020 11:52:20 -0500 Subject: [PATCH 09/10] Add digit --- salt/thehive/etc/es/elasticsearch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/thehive/etc/es/elasticsearch.yml b/salt/thehive/etc/es/elasticsearch.yml index 1f1518299..8abeb2d93 100644 --- a/salt/thehive/etc/es/elasticsearch.yml +++ b/salt/thehive/etc/es/elasticsearch.yml @@ -14,4 +14,4 @@ http.port: 9400 transport.tcp.port: 9500 transport.host: 0.0.0.0 thread_pool.search.queue_size: 100000 -thread_pool.write.queue_size: 10000 +thread_pool.write.queue_size: 100000 From ea9bbfd1aa040910fdd11bd46823c76a59d77c81 Mon Sep 17 00:00:00 2001 From: Jason Ertel Date: Tue, 24 Nov 2020 13:53:16 -0500 Subject: [PATCH 10/10] Improve wazuh agent registration with retry logic to wait for manager to become ready --- salt/wazuh/files/agent/wazuh-register-agent | 63 +++++++++++++++------ salt/wazuh/init.sls | 10 ++-- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/salt/wazuh/files/agent/wazuh-register-agent b/salt/wazuh/files/agent/wazuh-register-agent index da4870e47..895fbd5d1 100755 --- a/salt/wazuh/files/agent/wazuh-register-agent +++ b/salt/wazuh/files/agent/wazuh-register-agent @@ -57,32 +57,56 @@ register_agent() { echo "Adding agent:" echo "Executing: curl -s -u $USER:**** -k -X POST -d 'name=$AGENT_NAME&ip=$AGENT_IP' $PROTOCOL://$API_IP:$API_PORT/agents" API_RESULT=$(curl -s -u $USER:"$PASSWORD" -k -X POST -d 'name='$AGENT_NAME'&ip='$AGENT_IP -L $PROTOCOL://$API_IP:$API_PORT/agents) - echo "Result: $API_RESULT" - echo -e $API_RESULT | grep -q "\"error\":0" 2>&1 + # Get agent id and key + AGENT_ID=$(echo "$API_RESULT" | jq -er ".data.id") + GOT_ID=$? + AGENT_KEY=$(echo "$API_RESULT" | jq -er ".data.key") + GOT_KEY=$? - if [ "$?" != "0" ]; then - echo -e $API_RESULT | sed -rn 's/.*"message":"(.+)".*/\1/p' + if [[ -z "$AGENT_ID" || -z "$AGENT_KEY" || $GOT_ID -ne 0 || $GOT_KEY -ne 0 ]]; then + echo "Failed Result: $API_RESULT" + return 1 else - # Get agent id and agent key - AGENT_ID=$(echo $API_RESULT | cut -d':' -f 4 | cut -d ',' -f 1) - AGENT_KEY=$(echo $API_RESULT | cut -d':' -f 5 | cut -d '}' -f 1) - echo "Agent '$AGENT_NAME' with ID '$AGENT_ID' added." echo "Key for agent '$AGENT_ID' received." # Importing key echo "" echo "Importing authentication key:" - echo "y" | /var/ossec/bin/manage_agents -i $AGENT_KEY + echo "y" | /var/ossec/bin/manage_agents -i '$AGENT_KEY' # Restarting agent echo "" echo "Restarting:" echo "" /var/ossec/bin/ossec-control restart + return 0 fi } +wait_for_manager() { + echo "Waiting for Wazuh manager to become ready..." + + maxAttempts=$1 + attempts=0 + while [[ $attempts -lt $maxAttempts ]]; do + attempts=$((attempts+1)) + AGENTS_OUTPUT=$(curl -s -u $USER:"$PASSWORD" -k -X GET -L $PROTOCOL://$API_IP:$API_PORT/agents) + MANAGER_STATUS=$(echo "$AGENTS_OUTPUT" | jq -r ".data.items[0].status") + if [ "$MANAGER_STATUS" == "Active" ]; then + echo "Wazuh manager is active, ready to proceed." + return 0 + else + echo "Received non-Active status response: " + echo "$AGENTS_OUTPUT" + echo + echo "Manager is not ready after attempt $attempts of $maxAttempts, sleeping for 30 seconds." + sleep 30 + fi + done + return 1 +} + remove_agent() { echo "Found: $AGENT_ID" echo "Removing previous registration for '$AGENT_NAME' using ID: $AGENT_ID ..." @@ -141,11 +165,18 @@ if [ -f /opt/so/conf/wazuh/initial_agent_registration.log ]; then echo "Agent $AGENT_ID already registered!" exit 0 else - echo "Waiting before registering agent..." - sleep 30s - register_agent - cleanup_creds - echo "Initial agent $AGENT_ID with IP $AGENT_IP registered on $DATE." > /opt/so/conf/wazuh/initial_agent_registration.log - exit 0 + retries=30 + if wait_for_manager $retries; then + if register_agent; then + cleanup_creds + echo "Initial agent $AGENT_ID with IP $AGENT_IP registered on $DATE." > /opt/so/conf/wazuh/initial_agent_registration.log + exit 0 + else + echo "ERROR: Failed to register agent" + fi + else + echo "ERROR: Wazuh manager did not become ready after $retries attempts; unable to proceed with registration" + fi fi -#remove_agent + +exit 1 diff --git a/salt/wazuh/init.sls b/salt/wazuh/init.sls index 19afa48d7..d78d7908a 100644 --- a/salt/wazuh/init.sls +++ b/salt/wazuh/init.sls @@ -71,7 +71,7 @@ wazuhagentconf: wazuhdir: file.directory: - - name: /nsm/wazuh + - name: /nsm/wazuh/etc - user: 945 - group: 945 - makedirs: True @@ -115,6 +115,10 @@ append_so-wazuh_so-status.conf: - name: /opt/so/conf/so-status/so-status.conf - text: so-wazuh +/opt/so/conf/wazuh: + file.symlink: + - target: /nsm/wazuh/etc + # Register the agent registertheagent: cmd.run: @@ -128,10 +132,6 @@ whitelistmanager: - name: /usr/sbin/wazuh-manager-whitelist - cwd: / -/opt/so/conf/wazuh: - file.symlink: - - target: /nsm/wazuh/etc - wazuhagentservice: service.running: - name: wazuh-agent