mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2026-11-15 08:54:09 +01:00
Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bc3ae6b26 | ||
|
|
40a30f6908 | ||
|
|
1fd37251c9 | ||
|
|
4a5253f688 | ||
|
|
ec220572f0 | ||
|
|
b7b00f8233 | ||
|
|
45d2b29a42 | ||
|
|
7b494439e7 | ||
|
|
9a8dc097b2 | ||
|
|
274da18929 | ||
|
|
99a8ad2d4b | ||
|
|
bd9cdeadef | ||
|
|
bdf01a5a5a | ||
|
|
1849c74cea | ||
|
|
021b069706 | ||
|
|
824d674eec | ||
|
|
d43791c63e | ||
|
|
4dc7f2d97c | ||
|
|
092be7f222 | ||
|
|
340e7928f6 |
No files matched your search
@@ -14,6 +14,7 @@ body:
|
|||||||
- 3.2.0
|
- 3.2.0
|
||||||
- 3.3.0
|
- 3.3.0
|
||||||
- 3.4.0
|
- 3.4.0
|
||||||
|
- 3.5.0
|
||||||
- Other (please provide detail below)
|
- Other (please provide detail below)
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
+11
-11
@@ -1,17 +1,17 @@
|
|||||||
### 3.3.0-20260911 ISO image released on 2026/09/11
|
### 3.4.0-20261102 ISO image released on 2026/11/02
|
||||||
|
|
||||||
|
|
||||||
### Download and Verify
|
### Download and Verify
|
||||||
|
|
||||||
3.3.0-20260911 ISO image:
|
3.4.0-20261102 ISO image:
|
||||||
https://download.securityonion.net/file/securityonion/securityonion-3.3.0-20260911.iso
|
https://download.securityonion.net/file/securityonion/securityonion-3.4.0-20261102.iso
|
||||||
|
|
||||||
MD5: 12B18433D3A2198A185892FF79CF638F
|
MD5: FB0380AE996E175D6CC7E7A35D8CC178
|
||||||
SHA1: 2B3C2E1FA7A78ED1F956E7EDCC12E32593C14EEE
|
SHA1: D8960F1DA352710BCA209773BF0B3AE8791D0D1B
|
||||||
SHA256: 0938C73B76CE30EC9E4394D312C79EA7CAC721B6818541697279A6221F7D870D
|
SHA256: DFC4C87668836852A328EC7A0B755C8C1511FF0E43D423DEE23047A95F676D99
|
||||||
|
|
||||||
Signature for ISO image:
|
Signature for ISO image:
|
||||||
https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.3.0-20260911.iso.sig
|
https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.4.0-20261102.iso.sig
|
||||||
|
|
||||||
Signing key:
|
Signing key:
|
||||||
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/main/KEYS
|
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/main/KEYS
|
||||||
@@ -25,22 +25,22 @@ wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/
|
|||||||
|
|
||||||
Download the signature file for the ISO:
|
Download the signature file for the ISO:
|
||||||
```
|
```
|
||||||
wget https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.3.0-20260911.iso.sig
|
wget https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.4.0-20261102.iso.sig
|
||||||
```
|
```
|
||||||
|
|
||||||
Download the ISO image:
|
Download the ISO image:
|
||||||
```
|
```
|
||||||
wget https://download.securityonion.net/file/securityonion/securityonion-3.3.0-20260911.iso
|
wget https://download.securityonion.net/file/securityonion/securityonion-3.4.0-20261102.iso
|
||||||
```
|
```
|
||||||
|
|
||||||
Verify the downloaded ISO image using the signature file:
|
Verify the downloaded ISO image using the signature file:
|
||||||
```
|
```
|
||||||
gpg --verify securityonion-3.3.0-20260911.iso.sig securityonion-3.3.0-20260911.iso
|
gpg --verify securityonion-3.4.0-20261102.iso.sig securityonion-3.4.0-20261102.iso
|
||||||
```
|
```
|
||||||
|
|
||||||
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
|
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
|
||||||
```
|
```
|
||||||
gpg: Signature made Fri 11 Sep 2026 11:23:56 AM EDT using RSA key ID FE507013
|
gpg: Signature made Sat 31 Oct 2026 09:27:50 AM EDT using RSA key ID FE507013
|
||||||
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
|
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
|
||||||
gpg: WARNING: This key is not certified with a trusted signature!
|
gpg: WARNING: This key is not certified with a trusted signature!
|
||||||
gpg: There is no indication that the signature belongs to the owner.
|
gpg: There is no indication that the signature belongs to the owner.
|
||||||
|
|||||||
@@ -438,6 +438,10 @@ install_networkminer:
|
|||||||
pkg.latest:
|
pkg.latest:
|
||||||
- name: securityonion-networkminer
|
- name: securityonion-networkminer
|
||||||
|
|
||||||
|
install_so_crates:
|
||||||
|
pkg.latest:
|
||||||
|
- name: securityonion-so-crates
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
desktop_packages_os_fail:
|
desktop_packages_os_fail:
|
||||||
|
|||||||
@@ -107,6 +107,12 @@ so-elasticsearch-system-indices-patch:
|
|||||||
- file: so-elasticsearch-system-indices-patch-script
|
- file: so-elasticsearch-system-indices-patch-script
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
so-elasticsearch-ilm-policy-reload:
|
||||||
|
file.absent:
|
||||||
|
- name: /opt/so/state/esilm.txt
|
||||||
|
- onchanges:
|
||||||
|
- file: so-elasticsearch-ilm-policy-load-script
|
||||||
|
|
||||||
# heavynodes will only load ILM policies for SO managed indices. (Indicies defined in elasticsearch/defaults.yaml)
|
# heavynodes will only load ILM policies for SO managed indices. (Indicies defined in elasticsearch/defaults.yaml)
|
||||||
so-elasticsearch-ilm-policy-load:
|
so-elasticsearch-ilm-policy-load:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
@@ -115,8 +121,9 @@ so-elasticsearch-ilm-policy-load:
|
|||||||
- require:
|
- require:
|
||||||
- docker_container: so-elasticsearch
|
- docker_container: so-elasticsearch
|
||||||
- file: so-elasticsearch-ilm-policy-load-script
|
- file: so-elasticsearch-ilm-policy-load-script
|
||||||
- onchanges:
|
- http: wait_for_so-elasticsearch
|
||||||
- file: so-elasticsearch-ilm-policy-load-script
|
- file: so-elasticsearch-ilm-policy-reload
|
||||||
|
- unless: test -f /opt/so/state/esilm.txt
|
||||||
|
|
||||||
so-elasticsearch-templates-reload:
|
so-elasticsearch-templates-reload:
|
||||||
file.absent:
|
file.absent:
|
||||||
|
|||||||
@@ -7,11 +7,17 @@
|
|||||||
. /usr/sbin/so-common
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
MAX_JOBS=${MAX_ILM_JOBS:-10}
|
MAX_JOBS=${MAX_ILM_JOBS:-10}
|
||||||
|
ILM_STATEFILE=/opt/so/state/esilm.txt
|
||||||
|
rm -f "$ILM_STATEFILE"
|
||||||
|
|
||||||
|
check_elasticsearch_responsive
|
||||||
|
|
||||||
|
ILM_TMP_DIR=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$ILM_TMP_DIR"' EXIT
|
||||||
# Lock used to serialize block writes so concurrent jobs never interleave their output.
|
# Lock used to serialize block writes so concurrent jobs never interleave their output.
|
||||||
ILM_OUTPUT_LOCK=$(mktemp)
|
ILM_OUTPUT_LOCK="$ILM_TMP_DIR/output.lock"
|
||||||
ILM_FAIL_FILE=$(mktemp)
|
ILM_FAIL_FILE="$ILM_TMP_DIR/failed"
|
||||||
trap 'rm -f "$ILM_OUTPUT_LOCK" "$ILM_FAIL_FILE"' EXIT
|
touch "$ILM_FAIL_FILE"
|
||||||
|
|
||||||
# Policies are loaded concurrently (up to MAX_JOBS at a time) for speed. Each policy's block is
|
# Policies are loaded concurrently (up to MAX_JOBS at a time) for speed. Each policy's block is
|
||||||
# printed the moment its curl returns, so output appears in COMPLETION ORDER, not the order
|
# printed the moment its curl returns, so output appears in COMPLETION ORDER, not the order
|
||||||
@@ -20,13 +26,30 @@ echo "Loading ILM policies concurrently; output below appears in completion orde
|
|||||||
echo
|
echo
|
||||||
|
|
||||||
put_policy() {
|
put_policy() {
|
||||||
local desc="$1" policyname="$2" data="$3" result rc=0
|
local desc="$1" policyname="$2" data="$3" rc=1 attempt out http_code body result reason tmpdata
|
||||||
if ! result=$(curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L --fail \
|
tmpdata=$(mktemp "$ILM_TMP_DIR/${policyname}.XXXXXX.json")
|
||||||
-X PUT "https://localhost:9200/_ilm/policy/${policyname}" \
|
printf '%s' "$data" >"$tmpdata"
|
||||||
-H 'Content-Type: application/json' -d"${data}" 2>&1); then
|
|
||||||
rc=1
|
for attempt in 1 2 3; do
|
||||||
elif ! jq -e '.acknowledged == true' <<<"$result" >/dev/null 2>&1; then
|
out=$(so-elasticsearch-query "_ilm/policy/${policyname}" -d@"${tmpdata}" -XPUT -w '\n%{http_code}' 2>/dev/null)
|
||||||
rc=1
|
http_code=${out##*$'\n'} body=${out%$'\n'*}
|
||||||
|
|
||||||
|
if [[ "$http_code" == 200 ]] && jq -e '.acknowledged == true' <<<"$body" >/dev/null 2>&1; then
|
||||||
|
rc=0
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
# 429 = ES rejected/throttled (may succeed later); other 4xx will not
|
||||||
|
[[ "$http_code" == 4?? && "$http_code" != 429 ]] && break
|
||||||
|
(( attempt < 3 )) && sleep 3
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( rc == 0 )); then
|
||||||
|
result='{"acknowledged":true}'
|
||||||
|
else
|
||||||
|
result=${body:-"HTTP ${http_code:-000}"}
|
||||||
|
# flatten tabs/newlines so the TAB fail-file stays one record
|
||||||
|
reason=$(jq -r '(if (.error|type) == "object" then (.error.reason // .error.type) elif (.error|type) == "string" then .error else empty end) // empty | tostring | gsub("[\t\r\n]+"; " ")' <<<"$body" 2>/dev/null)
|
||||||
|
reason="HTTP ${http_code:-000}${reason:+: ${reason}}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# curl above ran in parallel; serialize just this block write so concurrent jobs never interleave.
|
# curl above ran in parallel; serialize just this block write so concurrent jobs never interleave.
|
||||||
@@ -34,7 +57,7 @@ put_policy() {
|
|||||||
flock 200
|
flock 200
|
||||||
printf 'Setting up %s policy...\n%s\n\n' "${desc}" "${result}"
|
printf 'Setting up %s policy...\n%s\n\n' "${desc}" "${result}"
|
||||||
if (( rc != 0 )); then
|
if (( rc != 0 )); then
|
||||||
printf '%s\n' "${policyname}" >>"$ILM_FAIL_FILE"
|
printf '%s\t%s\n' "${policyname}" "${reason}" >>"$ILM_FAIL_FILE"
|
||||||
fi
|
fi
|
||||||
} 200>>"${ILM_OUTPUT_LOCK}"
|
} 200>>"${ILM_OUTPUT_LOCK}"
|
||||||
|
|
||||||
@@ -82,10 +105,15 @@ wait || true
|
|||||||
|
|
||||||
if [[ -s "$ILM_FAIL_FILE" ]]; then
|
if [[ -s "$ILM_FAIL_FILE" ]]; then
|
||||||
echo "ERROR: Failed to load ILM policy(s):"
|
echo "ERROR: Failed to load ILM policy(s):"
|
||||||
while read -r POLICY; do
|
while IFS=$'\t' read -r POLICY REASON; do
|
||||||
echo " - $POLICY"
|
if [[ -n "$REASON" ]]; then
|
||||||
|
echo " - ${POLICY}: ${REASON}"
|
||||||
|
else
|
||||||
|
echo " - ${POLICY}"
|
||||||
|
fi
|
||||||
done < "$ILM_FAIL_FILE"
|
done < "$ILM_FAIL_FILE"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo "Successfully loaded all ILM policies."
|
echo "Successfully loaded all ILM policies."
|
||||||
|
touch "$ILM_STATEFILE"
|
||||||
fi
|
fi
|
||||||
@@ -121,9 +121,6 @@ check_err() {
|
|||||||
161)
|
161)
|
||||||
echo 'Required intermediate Elasticsearch upgrade not complete'
|
echo 'Required intermediate Elasticsearch upgrade not complete'
|
||||||
;;
|
;;
|
||||||
162)
|
|
||||||
echo 'One or more Elastic Agent nodes do not support the x86-64-v3 CPU instruction set'
|
|
||||||
;;
|
|
||||||
170)
|
170)
|
||||||
echo "Intermediate upgrade completed successfully to $next_step_so_version, but next soup to Security Onion $originally_requested_so_version could not be started automatically."
|
echo "Intermediate upgrade completed successfully to $next_step_so_version, but next soup to Security Onion $originally_requested_so_version could not be started automatically."
|
||||||
echo "Start soup again manually to continue the upgrade to Security Onion $originally_requested_so_version."
|
echo "Start soup again manually to continue the upgrade to Security Onion $originally_requested_so_version."
|
||||||
@@ -351,83 +348,6 @@ check_cluster_health() {
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
no_soup_for_you() {
|
|
||||||
echo ""
|
|
||||||
echo "No soup for you!"
|
|
||||||
exit 162
|
|
||||||
}
|
|
||||||
|
|
||||||
check_cpu_compatibility() {
|
|
||||||
# Roles running a container built from the so-elastic-agent image; mirrors the
|
|
||||||
# elasticagent and elasticfleet entries in salt/reactor/pillar_push_map.yaml.
|
|
||||||
local cpu_target='G@role:so-heavynode or G@role:so-eval or G@role:so-fleet or G@role:so-import or G@role:so-manager or G@role:so-managerhype or G@role:so-managersearch or G@role:so-standalone'
|
|
||||||
local expected_nodes cpu_results node result confirm
|
|
||||||
local -a unsupported=() offline=()
|
|
||||||
|
|
||||||
echo "Checking that Elastic Agent nodes support the x86-64-v3 CPU instruction set now required by Elastic."
|
|
||||||
|
|
||||||
if [[ "$SKIP_CPU_CHECK" == "true" ]]; then
|
|
||||||
printf "\nSkipping the x86-64-v3 CPU check because --skip-cpu-check was specified.\n\n"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Nodes that never answer are absent from the results, so diff against who should have.
|
|
||||||
expected_nodes=$(salt -C "$cpu_target" --preview-target --out=json 2>/dev/null | jq -r '.[]?') || true
|
|
||||||
if [[ -z "$expected_nodes" ]]; then
|
|
||||||
printf "\nCould not determine which nodes run the Elastic Agent, so the x86-64-v3 CPU check cannot run.\n"
|
|
||||||
no_soup_for_you
|
|
||||||
fi
|
|
||||||
|
|
||||||
cpu_results=$(salt -t 30 -C "$cpu_target" cmd.run "/lib64/ld-linux-x86-64.so.2 --help | grep x86-64-v3" --out=json 2>/dev/null) || true
|
|
||||||
|
|
||||||
while IFS= read -r node; do
|
|
||||||
[[ -z "$node" ]] && continue
|
|
||||||
result=$(jq -r --arg node "$node" '.[$node] // empty' <<< "$cpu_results" 2>/dev/null)
|
|
||||||
if [[ -z "$result" || "$result" == *"did not return"* ]]; then
|
|
||||||
offline+=("$node")
|
|
||||||
elif [[ "$result" != *"x86-64-v3 (supported"* ]]; then
|
|
||||||
# glibc appends "(supported, searched)" only when supported; the open paren keeps
|
|
||||||
# this from matching a future "(unsupported".
|
|
||||||
unsupported+=("$node")
|
|
||||||
fi
|
|
||||||
done <<< "$expected_nodes"
|
|
||||||
|
|
||||||
if [[ ${#unsupported[@]} -eq 0 && ${#offline[@]} -eq 0 ]]; then
|
|
||||||
printf "\nAll Elastic Agent nodes support x86-64-v3. We can proceed with SOUP.\n\n"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
if [[ ${#unsupported[@]} -gt 0 ]]; then
|
|
||||||
echo "The following node(s) do NOT support the x86-64-v3 CPU instruction set:"
|
|
||||||
printf ' %s\n' "${unsupported[@]}"
|
|
||||||
echo ""
|
|
||||||
echo "Upstream Elastic now builds its binaries for x86-64-v3, so these nodes can no"
|
|
||||||
echo "longer run Elastic. Upgrading them WILL BREAK them."
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
if [[ ${#offline[@]} -gt 0 ]]; then
|
|
||||||
echo "The following node(s) did not respond and could not be checked:"
|
|
||||||
printf ' %s\n' "${offline[@]}"
|
|
||||||
echo ""
|
|
||||||
echo "These nodes are offline, so we cannot confirm they support x86-64-v3, which"
|
|
||||||
echo "upstream Elastic now requires."
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n $UNATTENDED ]]; then
|
|
||||||
echo "Unattended mode cannot prompt for an override. Re-run soup interactively, or pass --skip-cpu-check to bypass this check."
|
|
||||||
no_soup_for_you
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -rp "Type 'override' to continue anyway, or press Enter to exit: " confirm
|
|
||||||
if [[ "${confirm,,}" == "override" ]]; then
|
|
||||||
printf "\nOverride accepted. Continuing at your own risk.\n\n"
|
|
||||||
else
|
|
||||||
no_soup_for_you
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
check_fleet_server() {
|
check_fleet_server() {
|
||||||
echo "Checking that Elastic Fleet Server is responding."
|
echo "Checking that Elastic Fleet Server is responding."
|
||||||
# Modeled on the wait_for_so-elastic-fleet state check in elasticfleet/enabled.sls,
|
# Modeled on the wait_for_so-elastic-fleet state check in elasticfleet/enabled.sls,
|
||||||
@@ -2168,8 +2088,6 @@ main() {
|
|||||||
echo "Let's see if we need to update Security Onion."
|
echo "Let's see if we need to update Security Onion."
|
||||||
upgrade_check
|
upgrade_check
|
||||||
|
|
||||||
check_cpu_compatibility
|
|
||||||
|
|
||||||
upgrade_space
|
upgrade_space
|
||||||
|
|
||||||
echo "Verifying Elasticsearch version compatibility across the grid before upgrading."
|
echo "Verifying Elasticsearch version compatibility across the grid before upgrading."
|
||||||
@@ -2448,17 +2366,6 @@ fi
|
|||||||
echo "### soup has been served at $(date) ###"
|
echo "### soup has been served at $(date) ###"
|
||||||
}
|
}
|
||||||
|
|
||||||
SKIP_CPU_CHECK=false
|
|
||||||
declare -a SOUP_ARGS=()
|
|
||||||
for arg in "$@"; do
|
|
||||||
if [[ "$arg" == "--skip-cpu-check" ]]; then
|
|
||||||
SKIP_CPU_CHECK=true
|
|
||||||
else
|
|
||||||
SOUP_ARGS+=("$arg")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
set -- "${SOUP_ARGS[@]}"
|
|
||||||
|
|
||||||
while getopts ":b:f:y" opt; do
|
while getopts ":b:f:y" opt; do
|
||||||
case ${opt} in
|
case ${opt} in
|
||||||
b )
|
b )
|
||||||
@@ -2482,7 +2389,7 @@ while getopts ":b:f:y" opt; do
|
|||||||
ISOLOC="$OPTARG"
|
ISOLOC="$OPTARG"
|
||||||
;;
|
;;
|
||||||
\? )
|
\? )
|
||||||
echo "Usage: soup [-b] [-y] [-f <iso location>] [--skip-cpu-check]"
|
echo "Usage: soup [-b] [-y] [-f <iso location>]"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
: )
|
: )
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ include:
|
|||||||
- nginx.config
|
- nginx.config
|
||||||
- nginx.sostatus
|
- nginx.sostatus
|
||||||
|
|
||||||
|
fleet_beats_dir_nginx:
|
||||||
|
file.directory:
|
||||||
|
- name: /nsm/elastic-fleet/artifacts/beats
|
||||||
|
- makedirs: True
|
||||||
|
- show_changes: False
|
||||||
|
|
||||||
{% if GLOBALS.role != 'so-fleet' %}
|
{% if GLOBALS.role != 'so-fleet' %}
|
||||||
{% set container_config = 'so-nginx' %}
|
{% set container_config = 'so-nginx' %}
|
||||||
make-rule-dir-nginx:
|
make-rule-dir-nginx:
|
||||||
@@ -54,9 +60,9 @@ so-nginx:
|
|||||||
- /opt/so/log/nginx/:/var/log/nginx:rw
|
- /opt/so/log/nginx/:/var/log/nginx:rw
|
||||||
- /opt/so/tmp/nginx/:/var/lib/nginx:rw
|
- /opt/so/tmp/nginx/:/var/lib/nginx:rw
|
||||||
- /opt/so/tmp/nginx/:/run:rw
|
- /opt/so/tmp/nginx/:/run:rw
|
||||||
- /nsm/elastic-fleet/so_agent-installers/:/opt/socore/html/packages
|
- /nsm/elastic-fleet/artifacts/beats/:/opt/socore/elastic-artifacts/artifacts/beats:ro
|
||||||
- /nsm/elastic-fleet/artifacts/:/opt/socore/html/artifacts
|
|
||||||
{% if GLOBALS.is_manager %}
|
{% if GLOBALS.is_manager %}
|
||||||
|
- /nsm/elastic-fleet/so_agent-installers/:/opt/socore/html/packages
|
||||||
- /etc/pki/managerssl.crt:/etc/pki/nginx/server.crt:ro
|
- /etc/pki/managerssl.crt:/etc/pki/nginx/server.crt:ro
|
||||||
- /etc/pki/managerssl.key:/etc/pki/nginx/server.key:ro
|
- /etc/pki/managerssl.key:/etc/pki/nginx/server.key:ro
|
||||||
# ATT&CK Navigator binds
|
# ATT&CK Navigator binds
|
||||||
@@ -106,6 +112,7 @@ so-nginx:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
- require:
|
- require:
|
||||||
- file: nginxconf
|
- file: nginxconf
|
||||||
|
- file: fleet_beats_dir_nginx
|
||||||
{% if GLOBALS.is_manager %}
|
{% if GLOBALS.is_manager %}
|
||||||
{% if NGINXMERGED.ssl.replace_cert %}
|
{% if NGINXMERGED.ssl.replace_cert %}
|
||||||
- file: managerssl_key
|
- file: managerssl_key
|
||||||
|
|||||||
+16
-35
@@ -4,6 +4,8 @@
|
|||||||
{%- set role = grains.id.split('_') | last %}
|
{%- set role = grains.id.split('_') | last %}
|
||||||
{%- set influxpass = salt['pillar.get']('secrets:influx_pass') %}
|
{%- set influxpass = salt['pillar.get']('secrets:influx_pass') %}
|
||||||
{%- set influxauth = ('so:' + influxpass) | base64_encode %}
|
{%- set influxauth = ('so:' + influxpass) | base64_encode %}
|
||||||
|
{%- set all_names = [GLOBALS.hostname, GLOBALS.url_base] + NGINXMERGED.ssl.alt_names %}
|
||||||
|
{%- set full_server_name = all_names | unique | join(' ') %}
|
||||||
|
|
||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
error_log /var/log/nginx/error.log;
|
error_log /var/log/nginx/error.log;
|
||||||
@@ -39,52 +41,31 @@ http {
|
|||||||
|
|
||||||
include /etc/nginx/conf.d/*.conf;
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
|
||||||
{%- if role in ['fleet'] %}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 8443;
|
|
||||||
server_name {{ GLOBALS.hostname }};
|
|
||||||
root /opt/socore/html;
|
|
||||||
location /artifacts/ {
|
|
||||||
try_files $uri =206;
|
|
||||||
proxy_read_timeout 90;
|
|
||||||
proxy_connect_timeout 90;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header Proxy "";
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
{%- if GLOBALS.is_manager %}
|
{%- if GLOBALS.is_manager %}
|
||||||
{%- set all_names = [GLOBALS.hostname, GLOBALS.url_base] + NGINXMERGED.ssl.alt_names %}
|
|
||||||
{%- set full_server_name = all_names | unique | join(' ') %}
|
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80 default_server;
|
listen 80 default_server;
|
||||||
server_name _;
|
server_name _;
|
||||||
return 307 https://{{ GLOBALS.url_base }}$request_uri;
|
return 307 https://{{ GLOBALS.url_base }}$request_uri;
|
||||||
}
|
}
|
||||||
|
{%- endif %}
|
||||||
|
{%- if GLOBALS.is_manager or role == 'fleet' %}
|
||||||
server {
|
server {
|
||||||
listen 8443;
|
listen 8443;
|
||||||
|
{%- if GLOBALS.is_manager %}
|
||||||
server_name {{ full_server_name }};
|
server_name {{ full_server_name }};
|
||||||
root /opt/socore/html;
|
{%- else %}
|
||||||
location /artifacts/ {
|
server_name {{ GLOBALS.hostname }};
|
||||||
try_files $uri =206;
|
{%- endif %}
|
||||||
proxy_read_timeout 90;
|
root /opt/socore/elastic-artifacts;
|
||||||
proxy_connect_timeout 90;
|
location /artifacts/beats/ {
|
||||||
proxy_set_header Host $host;
|
try_files $uri =404;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
}
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
location / {
|
||||||
proxy_set_header Proxy "";
|
return 404;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{%- endif %}
|
||||||
|
{%- if GLOBALS.is_manager %}
|
||||||
server {
|
server {
|
||||||
listen 443 ssl default_server;
|
listen 443 ssl default_server;
|
||||||
http2 on;
|
http2 on;
|
||||||
|
|||||||
@@ -138,6 +138,10 @@
|
|||||||
# AGGREGATOR PLUGINS #
|
# AGGREGATOR PLUGINS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
[[aggregators.merge]]
|
||||||
|
drop_original = true
|
||||||
|
namepass = ["system", "swap", "kafka_partition"]
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# INPUT PLUGINS #
|
# INPUT PLUGINS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -289,7 +293,7 @@
|
|||||||
password = "{{ salt['pillar.get']('elasticsearch:auth:users:so_logstash_user:pass') }}"
|
password = "{{ salt['pillar.get']('elasticsearch:auth:users:so_logstash_user:pass') }}"
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% if grains.role in ['so-manager','so-managersearch','so-standalone','so-receiver'] and GLOBALS.pipeline == "KAFKA" -%}
|
{% if grains.role in ['so-manager','so-managerhype','so-managersearch','so-standalone','so-receiver'] and GLOBALS.pipeline == "KAFKA" -%}
|
||||||
[[inputs.jolokia2_agent]]
|
[[inputs.jolokia2_agent]]
|
||||||
name_prefix= "kafka_"
|
name_prefix= "kafka_"
|
||||||
urls = ["http://{{ NODEIP }}:8778/jolokia"]
|
urls = ["http://{{ NODEIP }}:8778/jolokia"]
|
||||||
@@ -346,6 +350,26 @@
|
|||||||
interval = "60s"
|
interval = "60s"
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
|
{#- These report state that changes slowly; collecting them every interval only stores duplicate rows #}
|
||||||
|
{%- set SLOWSCRIPTS = [] %}
|
||||||
|
{%- for script in ['agentstatus.sh', 'os.sh', 'features.sh', 'raid.sh', 'zeekloss.sh'] %}
|
||||||
|
{%- if script in TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]] %}
|
||||||
|
{%- do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove(script) %}
|
||||||
|
{%- do SLOWSCRIPTS.append(script) %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- if SLOWSCRIPTS | length > 0 %}
|
||||||
|
[[inputs.exec]]
|
||||||
|
commands = [
|
||||||
|
{%- for script in SLOWSCRIPTS %}
|
||||||
|
["/scripts/{{script}}"]{% if not loop.last %},{% endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
]
|
||||||
|
data_format = "influx"
|
||||||
|
timeout = "15s"
|
||||||
|
interval = "5m"
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
{%- if TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]] | length > 0 %}
|
{%- if TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]] | length > 0 %}
|
||||||
[[inputs.exec]]
|
[[inputs.exec]]
|
||||||
commands = [
|
commands = [
|
||||||
@@ -358,12 +382,6 @@
|
|||||||
timeout = "15s"
|
timeout = "15s"
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{%- if salt['pillar.get']('healthcheck:enabled', False) %}
|
|
||||||
[[inputs.file]]
|
|
||||||
files = ["/host/nsm/zeek/logs/zeek_restart.log"]
|
|
||||||
data_format = "influx"
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
[[inputs.file]]
|
[[inputs.file]]
|
||||||
files = ["/etc/telegraf/node_config.json"]
|
files = ["/etc/telegraf/node_config.json"]
|
||||||
name_override = "node_config"
|
name_override = "node_config"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
{% if GLOBALS.pipeline != 'REDIS' %}
|
{% if GLOBALS.pipeline != 'REDIS' %}
|
||||||
{# When global pipeline is not REDIS remove redis.sh script. KAFKA metrics are collected via jolokia agent. Config in telegraf.conf #}
|
{# When global pipeline is not REDIS remove redis.sh script. KAFKA metrics are collected via jolokia agent. Config in telegraf.conf #}
|
||||||
{% if GLOBALS.role in ['so-standalone', 'so-manager', 'so-managersearch', 'so-receiver', 'so-heavynode'] %}
|
{% if GLOBALS.role in ['so-standalone', 'so-manager', 'so-managerhype', 'so-managersearch', 'so-receiver', 'so-heavynode'] %}
|
||||||
{% do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove('redis.sh') %}
|
{% do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove('redis.sh') %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
# if this script isn't already running
|
# if this script isn't already running
|
||||||
if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
|
if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
|
||||||
|
|
||||||
FILES=$(ls -1x /host/nsm/strelka/unprocessed | wc -l)
|
FILES=$(find /host/nsm/strelka/unprocessed -maxdepth 1 -type f | wc -l)
|
||||||
echo "faffiles files=$FILES"
|
echo "faffiles files=$FILES"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
|
|||||||
|
|
||||||
CONTAINERSLOG=/var/log/somon/containers.log
|
CONTAINERSLOG=/var/log/somon/containers.log
|
||||||
# the collector rewrites this every minute; report nothing rather than repeating a stale
|
# the collector rewrites this every minute; report nothing rather than repeating a stale
|
||||||
# file as if it were current, in case a run was skipped or the collector is wedged
|
# file as if it were current, in case a run was skipped or the collector is wedged.
|
||||||
MAXAGE=150
|
# Kept under two collector cycles so a 60s telegraf interval can't emit the same snapshot twice.
|
||||||
|
MAXAGE=90
|
||||||
|
|
||||||
if [ -r "$CONTAINERSLOG" ]; then
|
if [ -r "$CONTAINERSLOG" ]; then
|
||||||
AGE=$(( $(date +%s) - $(stat -c %Y "$CONTAINERSLOG") ))
|
AGE=$(( $(date +%s) - $(stat -c %Y "$CONTAINERSLOG") ))
|
||||||
|
|||||||
@@ -11,27 +11,40 @@
|
|||||||
if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
|
if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
|
||||||
|
|
||||||
PREVCOUNTFILE='/tmp/eps.txt'
|
PREVCOUNTFILE='/tmp/eps.txt'
|
||||||
EVENTCOUNTCURRENT="$(curl -s localhost:9600/_node/stats | jq '.events.in')"
|
STATS="$(curl -s localhost:9600/_node/stats)"
|
||||||
|
|
||||||
if [ ! -z "$EVENTCOUNTCURRENT" ]; then
|
if echo "$STATS" | jq -e '.pipelines.search' > /dev/null 2>&1; then
|
||||||
|
STAGE=search
|
||||||
if [ -f "$PREVCOUNTFILE" ]; then
|
COUNT="$(echo "$STATS" | jq '.pipelines.search.events.out')"
|
||||||
EVENTCOUNTPREVIOUS=`cat $PREVCOUNTFILE`
|
elif echo "$STATS" | jq -e '.pipelines.receiver' > /dev/null 2>&1; then
|
||||||
else
|
STAGE=receiver
|
||||||
echo "${EVENTCOUNTCURRENT}" > $PREVCOUNTFILE
|
COUNT="$(echo "$STATS" | jq '.pipelines.receiver.events.in')"
|
||||||
exit 0
|
else
|
||||||
fi
|
exit 0
|
||||||
|
|
||||||
echo "${EVENTCOUNTCURRENT}" > $PREVCOUNTFILE
|
|
||||||
# the division by 30 is because the agent interval is 30 seconds
|
|
||||||
EVENTS=$(((EVENTCOUNTCURRENT - EVENTCOUNTPREVIOUS)/30))
|
|
||||||
if [ "$EVENTS" -lt 0 ]; then
|
|
||||||
EVENTS=0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "consumptioneps eps=${EVENTS%%.*}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! [[ "$COUNT" =~ ^[0-9]+$ ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
NOW=$(date +%s)
|
||||||
|
read -r PREVEPOCH PREVCOUNT 2>/dev/null < "$PREVCOUNTFILE"
|
||||||
|
echo "${NOW} ${COUNT}" > "$PREVCOUNTFILE"
|
||||||
|
|
||||||
|
if ! [[ "$PREVEPOCH" =~ ^[0-9]+$ && "$PREVCOUNT" =~ ^[0-9]+$ ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ELAPSED=$((NOW - PREVEPOCH))
|
||||||
|
DELTA=$((COUNT - PREVCOUNT))
|
||||||
|
if [ "$ELAPSED" -le 0 ] || [ "$DELTA" -lt 0 ]; then
|
||||||
|
EPS=0
|
||||||
|
else
|
||||||
|
EPS=$((DELTA / ELAPSED))
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "consumptioneps,stage=${STAGE} eps=${EPS}"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
@@ -10,8 +10,7 @@ if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
|
|||||||
FPS_ENABLED=$(cat /var/log/sostatus/fps_enabled)
|
FPS_ENABLED=$(cat /var/log/sostatus/fps_enabled)
|
||||||
LKS_ENABLED=$(cat /var/log/sostatus/lks_enabled)
|
LKS_ENABLED=$(cat /var/log/sostatus/lks_enabled)
|
||||||
|
|
||||||
echo "features fps=$FPS_ENABLED"
|
echo "features fps=$FPS_ENABLED,lks=$LKS_ENABLED"
|
||||||
echo "features lks=$LKS_ENABLED"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
+38
-15
@@ -976,27 +976,50 @@ docker_seed_update() {
|
|||||||
set_progress_str "$docker_seed_update_percent" "Downloading $name"
|
set_progress_str "$docker_seed_update_percent" "Downloading $name"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registry_tar_has_soversion() {
|
||||||
|
local tarfile=$1
|
||||||
|
local version=$2
|
||||||
|
|
||||||
|
[ -n "$version" ] || return 1
|
||||||
|
[ -f "$tarfile" ] || return 1
|
||||||
|
# grep -q in a pipe SIGPIPEs tar; under pipefail a match would look like failure.
|
||||||
|
grep -qF "/_manifests/tags/${version}/" < <(tar -tf "$tarfile" 2>/dev/null)
|
||||||
|
}
|
||||||
|
|
||||||
docker_seed_registry() {
|
docker_seed_registry() {
|
||||||
local VERSION="$SOVERSION"
|
local VERSION="$SOVERSION"
|
||||||
|
local REGISTRY_TAR=/nsm/docker-registry/docker/registry.tar
|
||||||
|
|
||||||
if [ -f /nsm/docker-registry/docker/registry.tar ]; then
|
if [ -f "$REGISTRY_TAR" ] && registry_tar_has_soversion "$REGISTRY_TAR" "$VERSION"; then
|
||||||
logCmd "tar xvf /nsm/docker-registry/docker/registry.tar -C /nsm/docker-registry/docker"
|
info "Extracting $REGISTRY_TAR"
|
||||||
logCmd "rm /nsm/docker-registry/docker/registry.tar"
|
if ! tar xvf "$REGISTRY_TAR" -C /nsm/docker-registry/docker >> "$setup_log" 2>&1; then
|
||||||
|
error "Failed to extract $REGISTRY_TAR"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
logCmd "rm -f $REGISTRY_TAR"
|
||||||
|
return 0
|
||||||
|
elif [ -f "$REGISTRY_TAR" ]; then
|
||||||
|
info "Not using $REGISTRY_TAR; it has no images tagged '${VERSION}'"
|
||||||
|
if [[ "$is_airgap" == true ]]; then
|
||||||
|
error "Airgap install: $REGISTRY_TAR does not match Security Onion version '${VERSION}'. Use the ISO for this version."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
elif [[ -d /nsm/docker-registry/docker/registry && ( -f /etc/SOCLOUD || "$is_airgap" == true ) ]]; then
|
elif [[ -d /nsm/docker-registry/docker/registry && ( -f /etc/SOCLOUD || "$is_airgap" == true ) ]]; then
|
||||||
echo "Using existing docker registry content"
|
echo "Using existing docker registry content"
|
||||||
else
|
return 0
|
||||||
if [ "$install_type" == 'IMPORT' ]; then
|
|
||||||
container_list 'so-import'
|
|
||||||
else
|
|
||||||
container_list
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker_seed_update_percent=25
|
|
||||||
|
|
||||||
update_docker_containers 'netinstall' '' 'docker_seed_update' '/dev/stdout' 2>&1 | tee -a "$setup_log"
|
|
||||||
# Use pipe exit status of 'update_docker_containers' for return code
|
|
||||||
return ${PIPESTATUS[0]}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$install_type" == 'IMPORT' ]; then
|
||||||
|
container_list 'so-import'
|
||||||
|
else
|
||||||
|
container_list
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker_seed_update_percent=25
|
||||||
|
|
||||||
|
update_docker_containers 'netinstall' '' 'docker_seed_update' '/dev/stdout' 2>&1 | tee -a "$setup_log"
|
||||||
|
# Use pipe exit status of 'update_docker_containers' for return code
|
||||||
|
return ${PIPESTATUS[0]}
|
||||||
}
|
}
|
||||||
|
|
||||||
elasticfleet_pillar() {
|
elasticfleet_pillar() {
|
||||||
|
|||||||
Binary file not shown.
Reference in new issue
Block a user