mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2025-12-06 17:22:49 +01:00
Compare commits
96 Commits
delta
...
TOoSmOotH-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63bb44886e | ||
|
|
9c06713f32 | ||
|
|
23da0d4ba0 | ||
|
|
d5f2cfb354 | ||
|
|
fb5ad4193d | ||
|
|
1f5f283c06 | ||
|
|
cf048030c4 | ||
|
|
2d716b44a8 | ||
|
|
d70d652310 | ||
|
|
c5db7c8752 | ||
|
|
6f42ff3442 | ||
|
|
433dab7376 | ||
|
|
97c1a46013 | ||
|
|
fbe97221bb | ||
|
|
841ce6b6ec | ||
|
|
dd0b4c3820 | ||
|
|
b407c68d88 | ||
|
|
5b6a7035af | ||
|
|
12d490ad4a | ||
|
|
76cbd18d2c | ||
|
|
a7337c95e1 | ||
|
|
3f7c3326ea | ||
|
|
bf41de8c14 | ||
|
|
136a829509 | ||
|
|
bcec999be4 | ||
|
|
7c73b4713f | ||
|
|
45b4b1d963 | ||
|
|
fcfd74ec1e | ||
|
|
68b0cd7549 | ||
|
|
715d801ce8 | ||
|
|
4a810696e7 | ||
|
|
6b525a2c21 | ||
|
|
a5d8385f07 | ||
|
|
211bf7e77b | ||
|
|
1542b74133 | ||
|
|
4314c79f85 | ||
|
|
da9717bc79 | ||
|
|
045cf7866c | ||
|
|
431e0b0780 | ||
|
|
e782266caa | ||
|
|
a4666b2c08 | ||
|
|
dcc3206e51 | ||
|
|
8358b6ea6f | ||
|
|
d1a66a91c6 | ||
|
|
7fdcb92614 | ||
|
|
cec1890b6b | ||
|
|
b1b66045ea | ||
|
|
33b22bf2e4 | ||
|
|
3a38886345 | ||
|
|
7be70faab6 | ||
|
|
2729fdbea6 | ||
|
|
bfd08d1d2e | ||
|
|
fed75c7b39 | ||
|
|
3427df2a54 | ||
|
|
be11c718f6 | ||
|
|
235dfd78f1 | ||
|
|
7c8b9b4374 | ||
|
|
7762faf075 | ||
|
|
80fbb31372 | ||
|
|
7c45db2295 | ||
|
|
0545e1d33b | ||
|
|
08147e27b0 | ||
|
|
c9153617be | ||
|
|
245ceb2d49 | ||
|
|
4c65975907 | ||
|
|
dfef7036ce | ||
|
|
44594ba726 | ||
|
|
1876c4d9df | ||
|
|
a2ff66b5d0 | ||
|
|
e3972dc5af | ||
|
|
18c0f197b2 | ||
|
|
5b371c220c | ||
|
|
78c193f0a2 | ||
|
|
274295bc97 | ||
|
|
6c7ef622c1 | ||
|
|
da1cac0d53 | ||
|
|
a84df14137 | ||
|
|
4a49f9d004 | ||
|
|
1eb4b5379a | ||
|
|
35c7fc06d7 | ||
|
|
b69d453a68 | ||
|
|
b7e1989d45 | ||
|
|
4ffbb0bbd9 | ||
|
|
92be8df95d | ||
|
|
b1acbf3114 | ||
|
|
8043e09ec1 | ||
|
|
25c746bb14 | ||
|
|
a91e8b26f6 | ||
|
|
e826ea5d04 | ||
|
|
23a9780ebb | ||
|
|
9cb8ebbaa7 | ||
|
|
03892bad5e | ||
|
|
77fef02116 | ||
|
|
f3328c41fb | ||
|
|
23ae259c82 | ||
|
|
45f25ca62d |
2
.github/workflows/pythontest.yml
vendored
2
.github/workflows/pythontest.yml
vendored
@@ -4,7 +4,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- "salt/sensoroni/files/analyzers/**"
|
- "salt/sensoroni/files/analyzers/**"
|
||||||
- "salt/manager/tools/sbin"
|
- "salt/manager/tools/sbin/**"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -172,7 +172,15 @@ MANAGER_HOSTNAME = socket.gethostname()
|
|||||||
|
|
||||||
def _download_image():
|
def _download_image():
|
||||||
"""
|
"""
|
||||||
Download and validate the Oracle Linux KVM image.
|
Download and validate the Oracle Linux KVM image with retry logic and progress monitoring.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Detects stalled downloads (no progress for 30 seconds)
|
||||||
|
- Retries up to 3 times on failure
|
||||||
|
- Connection timeout of 30 seconds
|
||||||
|
- Read timeout of 60 seconds
|
||||||
|
- Cleans up partial downloads on failure
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if successful or file exists with valid checksum, False on error
|
bool: True if successful or file exists with valid checksum, False on error
|
||||||
"""
|
"""
|
||||||
@@ -186,44 +194,106 @@ def _download_image():
|
|||||||
|
|
||||||
log.info("Starting image download process")
|
log.info("Starting image download process")
|
||||||
|
|
||||||
try:
|
# Retry configuration
|
||||||
# Download file
|
max_attempts = 3
|
||||||
log.info("Downloading Oracle Linux KVM image from %s to %s", IMAGE_URL, IMAGE_PATH)
|
retry_delay = 5 # seconds to wait between retry attempts
|
||||||
response = requests.get(IMAGE_URL, stream=True)
|
stall_timeout = 30 # seconds without progress before considering download stalled
|
||||||
response.raise_for_status()
|
connection_timeout = 30 # seconds to establish connection
|
||||||
|
read_timeout = 60 # seconds to wait for data chunks
|
||||||
|
|
||||||
# Get total file size for progress tracking
|
for attempt in range(1, max_attempts + 1):
|
||||||
total_size = int(response.headers.get('content-length', 0))
|
log.info("Download attempt %d of %d", attempt, max_attempts)
|
||||||
downloaded_size = 0
|
|
||||||
last_log_time = 0
|
|
||||||
|
|
||||||
# Save file with progress logging
|
try:
|
||||||
with salt.utils.files.fopen(IMAGE_PATH, 'wb') as f:
|
# Download file with timeouts
|
||||||
for chunk in response.iter_content(chunk_size=8192):
|
log.info("Downloading Oracle Linux KVM image from %s to %s", IMAGE_URL, IMAGE_PATH)
|
||||||
f.write(chunk)
|
response = requests.get(
|
||||||
downloaded_size += len(chunk)
|
IMAGE_URL,
|
||||||
|
stream=True,
|
||||||
|
timeout=(connection_timeout, read_timeout)
|
||||||
|
)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
# Log progress every second
|
# Get total file size for progress tracking
|
||||||
current_time = time.time()
|
total_size = int(response.headers.get('content-length', 0))
|
||||||
if current_time - last_log_time >= 1:
|
downloaded_size = 0
|
||||||
progress = (downloaded_size / total_size) * 100 if total_size > 0 else 0
|
last_log_time = 0
|
||||||
log.info("Progress - %.1f%% (%d/%d bytes)",
|
last_progress_time = time.time()
|
||||||
progress, downloaded_size, total_size)
|
last_downloaded_size = 0
|
||||||
last_log_time = current_time
|
|
||||||
|
|
||||||
# Validate downloaded file
|
# Save file with progress logging and stall detection
|
||||||
if not _validate_image_checksum(IMAGE_PATH, IMAGE_SHA256):
|
with salt.utils.files.fopen(IMAGE_PATH, 'wb') as f:
|
||||||
os.unlink(IMAGE_PATH)
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
return False
|
if chunk: # filter out keep-alive new chunks
|
||||||
|
f.write(chunk)
|
||||||
|
downloaded_size += len(chunk)
|
||||||
|
current_time = time.time()
|
||||||
|
|
||||||
log.info("Successfully downloaded and validated Oracle Linux KVM image")
|
# Check for stalled download
|
||||||
return True
|
if downloaded_size > last_downloaded_size:
|
||||||
|
# Progress made, reset stall timer
|
||||||
|
last_progress_time = current_time
|
||||||
|
last_downloaded_size = downloaded_size
|
||||||
|
elif current_time - last_progress_time > stall_timeout:
|
||||||
|
# No progress for stall_timeout seconds
|
||||||
|
raise Exception(
|
||||||
|
f"Download stalled: no progress for {stall_timeout} seconds "
|
||||||
|
f"at {downloaded_size}/{total_size} bytes"
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
# Log progress every second
|
||||||
log.error("Error downloading hypervisor image: %s", str(e))
|
if current_time - last_log_time >= 1:
|
||||||
if os.path.exists(IMAGE_PATH):
|
progress = (downloaded_size / total_size) * 100 if total_size > 0 else 0
|
||||||
os.unlink(IMAGE_PATH)
|
log.info("Progress - %.1f%% (%d/%d bytes)",
|
||||||
return False
|
progress, downloaded_size, total_size)
|
||||||
|
last_log_time = current_time
|
||||||
|
|
||||||
|
# Validate downloaded file
|
||||||
|
log.info("Download complete, validating checksum...")
|
||||||
|
if not _validate_image_checksum(IMAGE_PATH, IMAGE_SHA256):
|
||||||
|
log.error("Checksum validation failed on attempt %d", attempt)
|
||||||
|
os.unlink(IMAGE_PATH)
|
||||||
|
if attempt < max_attempts:
|
||||||
|
log.info("Will retry download...")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
log.error("All download attempts failed due to checksum mismatch")
|
||||||
|
return False
|
||||||
|
|
||||||
|
log.info("Successfully downloaded and validated Oracle Linux KVM image")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except requests.exceptions.Timeout as e:
|
||||||
|
log.error("Download attempt %d failed: Timeout - %s", attempt, str(e))
|
||||||
|
if os.path.exists(IMAGE_PATH):
|
||||||
|
os.unlink(IMAGE_PATH)
|
||||||
|
if attempt < max_attempts:
|
||||||
|
log.info("Will retry download in %d seconds...", retry_delay)
|
||||||
|
time.sleep(retry_delay)
|
||||||
|
else:
|
||||||
|
log.error("All download attempts failed due to timeout")
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
log.error("Download attempt %d failed: Network error - %s", attempt, str(e))
|
||||||
|
if os.path.exists(IMAGE_PATH):
|
||||||
|
os.unlink(IMAGE_PATH)
|
||||||
|
if attempt < max_attempts:
|
||||||
|
log.info("Will retry download in %d seconds...", retry_delay)
|
||||||
|
time.sleep(retry_delay)
|
||||||
|
else:
|
||||||
|
log.error("All download attempts failed due to network errors")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
log.error("Download attempt %d failed: %s", attempt, str(e))
|
||||||
|
if os.path.exists(IMAGE_PATH):
|
||||||
|
os.unlink(IMAGE_PATH)
|
||||||
|
if attempt < max_attempts:
|
||||||
|
log.info("Will retry download in %d seconds...", retry_delay)
|
||||||
|
time.sleep(retry_delay)
|
||||||
|
else:
|
||||||
|
log.error("All download attempts failed")
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def _check_ssh_keys_exist():
|
def _check_ssh_keys_exist():
|
||||||
"""
|
"""
|
||||||
@@ -419,25 +489,28 @@ def _ensure_hypervisor_host_dir(minion_id: str = None):
|
|||||||
log.error(f"Error creating hypervisor host directory: {str(e)}")
|
log.error(f"Error creating hypervisor host directory: {str(e)}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _apply_dyanno_hypervisor_state():
|
def _apply_dyanno_hypervisor_state(status):
|
||||||
"""
|
"""
|
||||||
Apply the soc.dyanno.hypervisor state on the salt master.
|
Apply the soc.dyanno.hypervisor state on the salt master.
|
||||||
|
|
||||||
This function applies the soc.dyanno.hypervisor state on the salt master
|
This function applies the soc.dyanno.hypervisor state on the salt master
|
||||||
to update the hypervisor annotation and ensure all hypervisor host directories exist.
|
to update the hypervisor annotation and ensure all hypervisor host directories exist.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
status: Status passed to the hypervisor annotation state
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if state was applied successfully, False otherwise
|
bool: True if state was applied successfully, False otherwise
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
log.info("Applying soc.dyanno.hypervisor state on salt master")
|
log.info(f"Applying soc.dyanno.hypervisor state on salt master with status: {status}")
|
||||||
|
|
||||||
# Initialize the LocalClient
|
# Initialize the LocalClient
|
||||||
local = salt.client.LocalClient()
|
local = salt.client.LocalClient()
|
||||||
|
|
||||||
# Target the salt master to apply the soc.dyanno.hypervisor state
|
# Target the salt master to apply the soc.dyanno.hypervisor state
|
||||||
target = MANAGER_HOSTNAME + '_*'
|
target = MANAGER_HOSTNAME + '_*'
|
||||||
state_result = local.cmd(target, 'state.apply', ['soc.dyanno.hypervisor', "pillar={'baseDomain': {'status': 'PreInit'}}", 'concurrent=True'], tgt_type='glob')
|
state_result = local.cmd(target, 'state.apply', ['soc.dyanno.hypervisor', f"pillar={{'baseDomain': {{'status': '{status}'}}}}", 'concurrent=True'], tgt_type='glob')
|
||||||
log.debug(f"state_result: {state_result}")
|
log.debug(f"state_result: {state_result}")
|
||||||
# Check if state was applied successfully
|
# Check if state was applied successfully
|
||||||
if state_result:
|
if state_result:
|
||||||
@@ -454,17 +527,17 @@ def _apply_dyanno_hypervisor_state():
|
|||||||
success = False
|
success = False
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
log.info("Successfully applied soc.dyanno.hypervisor state")
|
log.info(f"Successfully applied soc.dyanno.hypervisor state with status: {status}")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
log.error("Failed to apply soc.dyanno.hypervisor state")
|
log.error(f"Failed to apply soc.dyanno.hypervisor state with status: {status}")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
log.error("No response from salt master when applying soc.dyanno.hypervisor state")
|
log.error(f"No response from salt master when applying soc.dyanno.hypervisor state with status: {status}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(f"Error applying soc.dyanno.hypervisor state: {str(e)}")
|
log.error(f"Error applying soc.dyanno.hypervisor state with status: {status}: {str(e)}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _apply_cloud_config_state():
|
def _apply_cloud_config_state():
|
||||||
@@ -598,11 +671,6 @@ def setup_environment(vm_name: str = 'sool9', disk_size: str = '220G', minion_id
|
|||||||
log.warning("Failed to apply salt.cloud.config state, continuing with setup")
|
log.warning("Failed to apply salt.cloud.config state, continuing with setup")
|
||||||
# We don't return an error here as we want to continue with the setup process
|
# We don't return an error here as we want to continue with the setup process
|
||||||
|
|
||||||
# Apply the soc.dyanno.hypervisor state on the salt master
|
|
||||||
if not _apply_dyanno_hypervisor_state():
|
|
||||||
log.warning("Failed to apply soc.dyanno.hypervisor state, continuing with setup")
|
|
||||||
# We don't return an error here as we want to continue with the setup process
|
|
||||||
|
|
||||||
log.info("Starting setup_environment in setup_hypervisor runner")
|
log.info("Starting setup_environment in setup_hypervisor runner")
|
||||||
|
|
||||||
# Check if environment is already set up
|
# Check if environment is already set up
|
||||||
@@ -616,9 +684,12 @@ def setup_environment(vm_name: str = 'sool9', disk_size: str = '220G', minion_id
|
|||||||
|
|
||||||
# Handle image setup if needed
|
# Handle image setup if needed
|
||||||
if not image_valid:
|
if not image_valid:
|
||||||
|
_apply_dyanno_hypervisor_state('ImageDownloadStart')
|
||||||
log.info("Starting image download/validation process")
|
log.info("Starting image download/validation process")
|
||||||
if not _download_image():
|
if not _download_image():
|
||||||
log.error("Image download failed")
|
log.error("Image download failed")
|
||||||
|
# Update hypervisor annotation with failure status
|
||||||
|
_apply_dyanno_hypervisor_state('ImageDownloadFailed')
|
||||||
return {
|
return {
|
||||||
'success': False,
|
'success': False,
|
||||||
'error': 'Image download failed',
|
'error': 'Image download failed',
|
||||||
@@ -631,6 +702,8 @@ def setup_environment(vm_name: str = 'sool9', disk_size: str = '220G', minion_id
|
|||||||
log.info("Setting up SSH keys")
|
log.info("Setting up SSH keys")
|
||||||
if not _setup_ssh_keys():
|
if not _setup_ssh_keys():
|
||||||
log.error("SSH key setup failed")
|
log.error("SSH key setup failed")
|
||||||
|
# Update hypervisor annotation with failure status
|
||||||
|
_apply_dyanno_hypervisor_state('SSHKeySetupFailed')
|
||||||
return {
|
return {
|
||||||
'success': False,
|
'success': False,
|
||||||
'error': 'SSH key setup failed',
|
'error': 'SSH key setup failed',
|
||||||
@@ -655,6 +728,12 @@ def setup_environment(vm_name: str = 'sool9', disk_size: str = '220G', minion_id
|
|||||||
success = vm_result.get('success', False)
|
success = vm_result.get('success', False)
|
||||||
log.info("Setup environment completed with status: %s", "SUCCESS" if success else "FAILED")
|
log.info("Setup environment completed with status: %s", "SUCCESS" if success else "FAILED")
|
||||||
|
|
||||||
|
# Update hypervisor annotation with success status
|
||||||
|
if success:
|
||||||
|
_apply_dyanno_hypervisor_state('PreInit')
|
||||||
|
else:
|
||||||
|
_apply_dyanno_hypervisor_state('SetupFailed')
|
||||||
|
|
||||||
# If setup was successful and we have a minion_id, run highstate
|
# If setup was successful and we have a minion_id, run highstate
|
||||||
if success and minion_id:
|
if success and minion_id:
|
||||||
log.info("Running highstate on hypervisor %s", minion_id)
|
log.info("Running highstate on hypervisor %s", minion_id)
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
|
{% set PCAP_BPF_STATUS = 0 %}
|
||||||
|
{% set STENO_BPF_COMPILED = "" %}
|
||||||
|
|
||||||
{% if GLOBALS.pcap_engine == "TRANSITION" %}
|
{% if GLOBALS.pcap_engine == "TRANSITION" %}
|
||||||
{% set PCAPBPF = ["ip and host 255.255.255.1 and port 1"] %}
|
{% set PCAPBPF = ["ip and host 255.255.255.1 and port 1"] %}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -8,3 +11,11 @@
|
|||||||
{{ MACROS.remove_comments(BPFMERGED, 'pcap') }}
|
{{ MACROS.remove_comments(BPFMERGED, 'pcap') }}
|
||||||
{% set PCAPBPF = BPFMERGED.pcap %}
|
{% set PCAPBPF = BPFMERGED.pcap %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if PCAPBPF %}
|
||||||
|
{% set PCAP_BPF_CALC = salt['cmd.run_all']('/usr/sbin/so-bpf-compile ' ~ GLOBALS.sensor.interface ~ ' ' ~ PCAPBPF|join(" "), cwd='/root') %}
|
||||||
|
{% if PCAP_BPF_CALC['retcode'] == 0 %}
|
||||||
|
{% set PCAP_BPF_STATUS = 1 %}
|
||||||
|
{% set STENO_BPF_COMPILED = ",\\\"--filter=" + PCAP_BPF_CALC['stdout'] + "\\\"" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
bpf:
|
bpf:
|
||||||
pcap:
|
pcap:
|
||||||
description: List of BPF filters to apply to Stenographer.
|
description: List of BPF filters to apply to the PCAP engine.
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
helpLink: bpf.html
|
helpLink: bpf.html
|
||||||
suricata:
|
suricata:
|
||||||
description: List of BPF filters to apply to Suricata.
|
description: List of BPF filters to apply to Suricata. This will apply to alerts and, if enabled, to metadata and PCAP logs generated by Suricata.
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
helpLink: bpf.html
|
helpLink: bpf.html
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
||||||
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
||||||
|
{% set SURICATA_BPF_STATUS = 0 %}
|
||||||
{% import 'bpf/macros.jinja' as MACROS %}
|
{% import 'bpf/macros.jinja' as MACROS %}
|
||||||
|
|
||||||
{{ MACROS.remove_comments(BPFMERGED, 'suricata') }}
|
{{ MACROS.remove_comments(BPFMERGED, 'suricata') }}
|
||||||
|
|
||||||
{% set SURICATABPF = BPFMERGED.suricata %}
|
{% set SURICATABPF = BPFMERGED.suricata %}
|
||||||
|
|
||||||
|
{% if SURICATABPF %}
|
||||||
|
{% set SURICATA_BPF_CALC = salt['cmd.run_all']('/usr/sbin/so-bpf-compile ' ~ GLOBALS.sensor.interface ~ ' ' ~ SURICATABPF|join(" "), cwd='/root') %}
|
||||||
|
{% if SURICATA_BPF_CALC['retcode'] == 0 %}
|
||||||
|
{% set SURICATA_BPF_STATUS = 1 %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
||||||
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
||||||
|
{% set ZEEK_BPF_STATUS = 0 %}
|
||||||
{% import 'bpf/macros.jinja' as MACROS %}
|
{% import 'bpf/macros.jinja' as MACROS %}
|
||||||
|
|
||||||
{{ MACROS.remove_comments(BPFMERGED, 'zeek') }}
|
{{ MACROS.remove_comments(BPFMERGED, 'zeek') }}
|
||||||
|
|
||||||
{% set ZEEKBPF = BPFMERGED.zeek %}
|
{% set ZEEKBPF = BPFMERGED.zeek %}
|
||||||
|
|
||||||
|
{% if ZEEKBPF %}
|
||||||
|
{% set ZEEK_BPF_CALC = salt['cmd.run_all']('/usr/sbin/so-bpf-compile ' ~ GLOBALS.sensor.interface ~ ' ' ~ ZEEKBPF|join(" "), cwd='/root') %}
|
||||||
|
{% if ZEEK_BPF_CALC['retcode'] == 0 %}
|
||||||
|
{% set ZEEK_BPF_STATUS = 1 %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -29,9 +29,26 @@ fi
|
|||||||
|
|
||||||
interface="$1"
|
interface="$1"
|
||||||
shift
|
shift
|
||||||
tcpdump -i $interface -ddd $@ | tail -n+2 |
|
|
||||||
while read line; do
|
# Capture tcpdump output and exit code
|
||||||
|
tcpdump_output=$(tcpdump -i "$interface" -ddd "$@" 2>&1)
|
||||||
|
tcpdump_exit=$?
|
||||||
|
|
||||||
|
if [ $tcpdump_exit -ne 0 ]; then
|
||||||
|
echo "$tcpdump_output" >&2
|
||||||
|
exit $tcpdump_exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process the output, skipping the first line
|
||||||
|
echo "$tcpdump_output" | tail -n+2 | while read -r line; do
|
||||||
cols=( $line )
|
cols=( $line )
|
||||||
printf "%04x%02x%02x%08x" ${cols[0]} ${cols[1]} ${cols[2]} ${cols[3]}
|
printf "%04x%02x%02x%08x" "${cols[0]}" "${cols[1]}" "${cols[2]}" "${cols[3]}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Check if the pipeline succeeded
|
||||||
|
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
exit 0
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ is_manager_node() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is_sensor_node() {
|
is_sensor_node() {
|
||||||
# Check to see if this is a sensor (forward) node
|
# Check to see if this is a sensor node
|
||||||
is_single_node_grid && return 0
|
is_single_node_grid && return 0
|
||||||
grep "role: so-" /etc/salt/grains | grep -E "sensor|heavynode" &> /dev/null
|
grep "role: so-" /etc/salt/grains | grep -E "sensor|heavynode" &> /dev/null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ elasticfleet:
|
|||||||
logging:
|
logging:
|
||||||
zeek:
|
zeek:
|
||||||
excluded:
|
excluded:
|
||||||
- analyzer
|
|
||||||
- broker
|
- broker
|
||||||
- capture_loss
|
- capture_loss
|
||||||
- cluster
|
- cluster
|
||||||
|
|||||||
@@ -1,15 +1,79 @@
|
|||||||
{
|
{
|
||||||
"description" : "suricata.alert",
|
"description": "suricata.alert",
|
||||||
"processors" : [
|
"processors": [
|
||||||
{ "set": { "if": "ctx.event?.imported != true", "field": "_index", "value": "logs-suricata.alerts-so" } },
|
{
|
||||||
{ "set": { "field": "tags","value": "alert" }},
|
"set": {
|
||||||
{ "rename":{ "field": "message2.alert", "target_field": "rule", "ignore_failure": true } },
|
"if": "ctx.event?.imported != true",
|
||||||
{ "rename":{ "field": "rule.signature", "target_field": "rule.name", "ignore_failure": true } },
|
"field": "_index",
|
||||||
{ "rename":{ "field": "rule.ref", "target_field": "rule.version", "ignore_failure": true } },
|
"value": "logs-suricata.alerts-so"
|
||||||
{ "rename":{ "field": "rule.signature_id", "target_field": "rule.uuid", "ignore_failure": true } },
|
}
|
||||||
{ "rename":{ "field": "rule.signature_id", "target_field": "rule.signature", "ignore_failure": true } },
|
},
|
||||||
{ "rename":{ "field": "message2.payload_printable", "target_field": "network.data.decoded", "ignore_failure": true } },
|
{
|
||||||
{ "dissect": { "field": "rule.rule", "pattern": "%{?prefix}content:\"%{dns.query_name}\"%{?remainder}", "ignore_missing": true, "ignore_failure": true } },
|
"set": {
|
||||||
{ "pipeline": { "name": "common.nids" } }
|
"field": "tags",
|
||||||
]
|
"value": "alert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.alert",
|
||||||
|
"target_field": "rule",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "rule.signature",
|
||||||
|
"target_field": "rule.name",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "rule.ref",
|
||||||
|
"target_field": "rule.version",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "rule.signature_id",
|
||||||
|
"target_field": "rule.uuid",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "rule.signature_id",
|
||||||
|
"target_field": "rule.signature",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.payload_printable",
|
||||||
|
"target_field": "network.data.decoded",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dissect": {
|
||||||
|
"field": "rule.rule",
|
||||||
|
"pattern": "%{?prefix}content:\"%{dns.query_name}\"%{?remainder}",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"name": "common.nids"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,155 @@
|
|||||||
{
|
{
|
||||||
"description" : "suricata.common",
|
"description": "suricata.common",
|
||||||
"processors" : [
|
"processors": [
|
||||||
{ "json": { "field": "message", "target_field": "message2", "ignore_failure": true } },
|
{
|
||||||
{ "rename": { "field": "message2.pkt_src", "target_field": "network.packet_source","ignore_failure": true } },
|
"json": {
|
||||||
{ "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_failure": true } },
|
"field": "message",
|
||||||
{ "rename": { "field": "message2.in_iface", "target_field": "observer.ingress.interface.name", "ignore_failure": true } },
|
"target_field": "message2",
|
||||||
{ "rename": { "field": "message2.flow_id", "target_field": "log.id.uid", "ignore_failure": true } },
|
"ignore_failure": true
|
||||||
{ "rename": { "field": "message2.src_ip", "target_field": "source.ip", "ignore_failure": true } },
|
}
|
||||||
{ "rename": { "field": "message2.src_port", "target_field": "source.port", "ignore_failure": true } },
|
},
|
||||||
{ "rename": { "field": "message2.dest_ip", "target_field": "destination.ip", "ignore_failure": true } },
|
{
|
||||||
{ "rename": { "field": "message2.dest_port", "target_field": "destination.port", "ignore_failure": true } },
|
"rename": {
|
||||||
{ "rename": { "field": "message2.vlan", "target_field": "network.vlan.id", "ignore_failure": true } },
|
"field": "message2.pkt_src",
|
||||||
{ "rename": { "field": "message2.community_id", "target_field": "network.community_id", "ignore_missing": true } },
|
"target_field": "network.packet_source",
|
||||||
{ "rename": { "field": "message2.xff", "target_field": "xff.ip", "ignore_missing": true } },
|
"ignore_failure": true
|
||||||
{ "set": { "field": "event.dataset", "value": "{{ message2.event_type }}" } },
|
}
|
||||||
{ "set": { "field": "observer.name", "value": "{{agent.name}}" } },
|
},
|
||||||
{ "set": { "field": "event.ingested", "value": "{{@timestamp}}" } },
|
{
|
||||||
{ "date": { "field": "message2.timestamp", "target_field": "@timestamp", "formats": ["ISO8601", "UNIX"], "timezone": "UTC", "ignore_failure": true } },
|
"rename": {
|
||||||
{ "remove":{ "field": "agent", "ignore_failure": true } },
|
"field": "message2.proto",
|
||||||
{"append":{"field":"related.ip","value":["{{source.ip}}","{{destination.ip}}"],"allow_duplicates":false,"ignore_failure":true}},
|
"target_field": "network.transport",
|
||||||
{
|
"ignore_failure": true
|
||||||
"script": {
|
}
|
||||||
"source": "boolean isPrivate(def ip) { if (ip == null) return false; int dot1 = ip.indexOf('.'); if (dot1 == -1) return false; int dot2 = ip.indexOf('.', dot1 + 1); if (dot2 == -1) return false; int first = Integer.parseInt(ip.substring(0, dot1)); if (first == 10) return true; if (first == 192 && ip.startsWith('168.', dot1 + 1)) return true; if (first == 172) { int second = Integer.parseInt(ip.substring(dot1 + 1, dot2)); return second >= 16 && second <= 31; } return false; } String[] fields = new String[] {\"source\", \"destination\"}; for (int i = 0; i < fields.length; i++) { def field = fields[i]; def ip = ctx[field]?.ip; if (ip != null) { if (ctx.network == null) ctx.network = new HashMap(); if (isPrivate(ip)) { if (ctx.network.private_ip == null) ctx.network.private_ip = new ArrayList(); if (!ctx.network.private_ip.contains(ip)) ctx.network.private_ip.add(ip); } else { if (ctx.network.public_ip == null) ctx.network.public_ip = new ArrayList(); if (!ctx.network.public_ip.contains(ip)) ctx.network.public_ip.add(ip); } } }",
|
},
|
||||||
"ignore_failure": false
|
{
|
||||||
}
|
"rename": {
|
||||||
},
|
"field": "message2.in_iface",
|
||||||
{ "pipeline": { "if": "ctx?.event?.dataset != null", "name": "suricata.{{event.dataset}}" } }
|
"target_field": "observer.ingress.interface.name",
|
||||||
]
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.flow_id",
|
||||||
|
"target_field": "log.id.uid",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.src_ip",
|
||||||
|
"target_field": "source.ip",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.src_port",
|
||||||
|
"target_field": "source.port",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dest_ip",
|
||||||
|
"target_field": "destination.ip",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dest_port",
|
||||||
|
"target_field": "destination.port",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.vlan",
|
||||||
|
"target_field": "network.vlan.id",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.community_id",
|
||||||
|
"target_field": "network.community_id",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.xff",
|
||||||
|
"target_field": "xff.ip",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"field": "event.dataset",
|
||||||
|
"value": "{{ message2.event_type }}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"field": "observer.name",
|
||||||
|
"value": "{{agent.name}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"field": "event.ingested",
|
||||||
|
"value": "{{@timestamp}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": {
|
||||||
|
"field": "message2.timestamp",
|
||||||
|
"target_field": "@timestamp",
|
||||||
|
"formats": [
|
||||||
|
"ISO8601",
|
||||||
|
"UNIX"
|
||||||
|
],
|
||||||
|
"timezone": "UTC",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"remove": {
|
||||||
|
"field": "agent",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"append": {
|
||||||
|
"field": "related.ip",
|
||||||
|
"value": [
|
||||||
|
"{{source.ip}}",
|
||||||
|
"{{destination.ip}}"
|
||||||
|
],
|
||||||
|
"allow_duplicates": false,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "boolean isPrivate(def ip) { if (ip == null) return false; int dot1 = ip.indexOf('.'); if (dot1 == -1) return false; int dot2 = ip.indexOf('.', dot1 + 1); if (dot2 == -1) return false; int first = Integer.parseInt(ip.substring(0, dot1)); if (first == 10) return true; if (first == 192 && ip.startsWith('168.', dot1 + 1)) return true; if (first == 172) { int second = Integer.parseInt(ip.substring(dot1 + 1, dot2)); return second >= 16 && second <= 31; } return false; } String[] fields = new String[] {\"source\", \"destination\"}; for (int i = 0; i < fields.length; i++) { def field = fields[i]; def ip = ctx[field]?.ip; if (ip != null) { if (ctx.network == null) ctx.network = new HashMap(); if (isPrivate(ip)) { if (ctx.network.private_ip == null) ctx.network.private_ip = new ArrayList(); if (!ctx.network.private_ip.contains(ip)) ctx.network.private_ip.add(ip); } else { if (ctx.network.public_ip == null) ctx.network.public_ip = new ArrayList(); if (!ctx.network.public_ip.contains(ip)) ctx.network.public_ip.add(ip); } } }",
|
||||||
|
"ignore_failure": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.capture_file",
|
||||||
|
"target_field": "suricata.capture_file",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"if": "ctx?.event?.dataset != null",
|
||||||
|
"name": "suricata.{{event.dataset}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,136 @@
|
|||||||
{
|
{
|
||||||
"description" : "suricata.dns",
|
"description": "suricata.dns",
|
||||||
"processors" : [
|
"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": {
|
||||||
{ "rename": { "field": "message2.dns.type", "target_field": "dns.query.type", "ignore_missing": true } },
|
"field": "message2.proto",
|
||||||
{ "rename": { "field": "message2.dns.tx_id", "target_field": "dns.id", "ignore_missing": true } },
|
"target_field": "network.transport",
|
||||||
{ "rename": { "field": "message2.dns.version", "target_field": "dns.version", "ignore_missing": true } },
|
"ignore_missing": true
|
||||||
{ "rename": { "field": "message2.dns.rrname", "target_field": "dns.query.name", "ignore_missing": true } },
|
}
|
||||||
{ "rename": { "field": "message2.dns.rrtype", "target_field": "dns.query.type_name", "ignore_missing": true } },
|
},
|
||||||
{ "rename": { "field": "message2.dns.flags", "target_field": "dns.flags", "ignore_missing": true } },
|
{
|
||||||
{ "rename": { "field": "message2.dns.qr", "target_field": "dns.qr", "ignore_missing": true } },
|
"rename": {
|
||||||
{ "rename": { "field": "message2.dns.rd", "target_field": "dns.recursion.desired", "ignore_missing": true } },
|
"field": "message2.app_proto",
|
||||||
{ "rename": { "field": "message2.dns.ra", "target_field": "dns.recursion.available", "ignore_missing": true } },
|
"target_field": "network.protocol",
|
||||||
{ "rename": { "field": "message2.dns.rcode", "target_field": "dns.response.code_name", "ignore_missing": true } },
|
"ignore_missing": true
|
||||||
{ "rename": { "field": "message2.dns.grouped.A", "target_field": "dns.answers.data", "ignore_missing": true } },
|
}
|
||||||
{ "rename": { "field": "message2.dns.grouped.CNAME", "target_field": "dns.answers.name", "ignore_missing": true } },
|
},
|
||||||
{ "pipeline": { "if": "ctx.dns.query?.name != null && ctx.dns.query.name.contains('.')", "name": "dns.tld" } },
|
{
|
||||||
{ "pipeline": { "name": "common" } }
|
"rename": {
|
||||||
]
|
"field": "message2.dns.type",
|
||||||
|
"target_field": "dns.query.type",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.tx_id",
|
||||||
|
"target_field": "dns.tx_id",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.id",
|
||||||
|
"target_field": "dns.id",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.version",
|
||||||
|
"target_field": "dns.version",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"name": "suricata.dnsv3",
|
||||||
|
"ignore_missing_pipeline": true,
|
||||||
|
"if": "ctx?.dns?.version != null && ctx?.dns?.version == 3",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.rrname",
|
||||||
|
"target_field": "dns.query.name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.rrtype",
|
||||||
|
"target_field": "dns.query.type_name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.flags",
|
||||||
|
"target_field": "dns.flags",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.qr",
|
||||||
|
"target_field": "dns.qr",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.rd",
|
||||||
|
"target_field": "dns.recursion.desired",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.ra",
|
||||||
|
"target_field": "dns.recursion.available",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.opcode",
|
||||||
|
"target_field": "dns.opcode",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.rcode",
|
||||||
|
"target_field": "dns.response.code_name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.grouped.A",
|
||||||
|
"target_field": "dns.answers.data",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.grouped.CNAME",
|
||||||
|
"target_field": "dns.answers.name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"if": "ctx.dns.query?.name != null && ctx.dns.query.name.contains('.')",
|
||||||
|
"name": "dns.tld"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"name": "common"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
56
salt/elasticsearch/files/ingest/suricata.dnsv3
Normal file
56
salt/elasticsearch/files/ingest/suricata.dnsv3
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"processors": [
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.dns.queries",
|
||||||
|
"target_field": "dns.queries",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx?.dns?.queries != null && ctx?.dns?.queries.length > 0) {\n if (ctx.dns == null) {\n ctx.dns = new HashMap();\n }\n if (ctx.dns.query == null) {\n ctx.dns.query = new HashMap();\n }\n ctx.dns.query.name = ctx?.dns?.queries[0].rrname;\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx?.dns?.queries != null && ctx?.dns?.queries.length > 0) {\n if (ctx.dns == null) {\n ctx.dns = new HashMap();\n }\n if (ctx.dns.query == null) {\n ctx.dns.query = new HashMap();\n }\n ctx.dns.query.type_name = ctx?.dns?.queries[0].rrtype;\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foreach": {
|
||||||
|
"field": "dns.queries",
|
||||||
|
"processor": {
|
||||||
|
"rename": {
|
||||||
|
"field": "_ingest._value.rrname",
|
||||||
|
"target_field": "_ingest._value.name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foreach": {
|
||||||
|
"field": "dns.queries",
|
||||||
|
"processor": {
|
||||||
|
"rename": {
|
||||||
|
"field": "_ingest._value.rrtype",
|
||||||
|
"target_field": "_ingest._value.type_name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"name": "suricata.tld",
|
||||||
|
"ignore_missing_pipeline": true,
|
||||||
|
"if": "ctx?.dns?.queries != null && ctx?.dns?.queries.length > 0",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
52
salt/elasticsearch/files/ingest/suricata.tld
Normal file
52
salt/elasticsearch/files/ingest/suricata.tld
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"processors": [
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n if (q.name != null && q.name.contains('.')) {\n q.top_level_domain = q.name.substring(q.name.lastIndexOf('.') + 1);\n }\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n if (q.name != null && q.name.contains('.')) {\n q.query_without_tld = q.name.substring(0, q.name.lastIndexOf('.'));\n }\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n if (q.query_without_tld != null && q.query_without_tld.contains('.')) {\n q.parent_domain = q.query_without_tld.substring(q.query_without_tld.lastIndexOf('.') + 1);\n }\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n if (q.query_without_tld != null && q.query_without_tld.contains('.')) {\n q.subdomain = q.query_without_tld.substring(0, q.query_without_tld.lastIndexOf('.'));\n }\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n if (q.parent_domain != null && q.top_level_domain != null) {\n q.highest_registered_domain = q.parent_domain + \".\" + q.top_level_domain;\n }\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n if (q.subdomain != null) {\n q.subdomain_length = q.subdomain.length();\n }\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n if (q.parent_domain != null) {\n q.parent_domain_length = q.parent_domain.length();\n }\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns != null && ctx.dns.queries != null) {\n for (def q : ctx.dns.queries) {\n q.remove('query_without_tld');\n }\n}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
61
salt/elasticsearch/files/ingest/zeek.analyzer
Normal file
61
salt/elasticsearch/files/ingest/zeek.analyzer
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"description": "zeek.analyzer",
|
||||||
|
"processors": [
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"field": "event.dataset",
|
||||||
|
"value": "analyzer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"remove": {
|
||||||
|
"field": [
|
||||||
|
"host"
|
||||||
|
],
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"json": {
|
||||||
|
"field": "message",
|
||||||
|
"target_field": "message2",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"field": "network.protocol",
|
||||||
|
"copy_from": "message2.analyzer_name",
|
||||||
|
"ignore_empty_value": true,
|
||||||
|
"if": "ctx?.message2?.analyzer_kind == 'protocol'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"field": "network.protocol",
|
||||||
|
"ignore_empty_value": true,
|
||||||
|
"if": "ctx?.message2?.analyzer_kind != 'protocol'",
|
||||||
|
"copy_from": "message2.proto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lowercase": {
|
||||||
|
"field": "network.protocol",
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.failure_reason",
|
||||||
|
"target_field": "error.reason",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"name": "zeek.common"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,35 +1,227 @@
|
|||||||
{
|
{
|
||||||
"description" : "zeek.dns",
|
"description": "zeek.dns",
|
||||||
"processors" : [
|
"processors": [
|
||||||
{ "set": { "field": "event.dataset", "value": "dns" } },
|
{
|
||||||
{ "remove": { "field": ["host"], "ignore_failure": true } },
|
"set": {
|
||||||
{ "json": { "field": "message", "target_field": "message2", "ignore_failure": true } },
|
"field": "event.dataset",
|
||||||
{ "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } },
|
"value": "dns"
|
||||||
{ "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } },
|
}
|
||||||
{ "rename": { "field": "message2.trans_id", "target_field": "dns.id", "ignore_missing": true } },
|
},
|
||||||
{ "rename": { "field": "message2.rtt", "target_field": "event.duration", "ignore_missing": true } },
|
{
|
||||||
{ "rename": { "field": "message2.query", "target_field": "dns.query.name", "ignore_missing": true } },
|
"remove": {
|
||||||
{ "rename": { "field": "message2.qclass", "target_field": "dns.query.class", "ignore_missing": true } },
|
"field": [
|
||||||
{ "rename": { "field": "message2.qclass_name", "target_field": "dns.query.class_name", "ignore_missing": true } },
|
"host"
|
||||||
{ "rename": { "field": "message2.qtype", "target_field": "dns.query.type", "ignore_missing": true } },
|
],
|
||||||
{ "rename": { "field": "message2.qtype_name", "target_field": "dns.query.type_name", "ignore_missing": true } },
|
"ignore_failure": true
|
||||||
{ "rename": { "field": "message2.rcode", "target_field": "dns.response.code", "ignore_missing": true } },
|
}
|
||||||
{ "rename": { "field": "message2.rcode_name", "target_field": "dns.response.code_name", "ignore_missing": true } },
|
},
|
||||||
{ "rename": { "field": "message2.AA", "target_field": "dns.authoritative", "ignore_missing": true } },
|
{
|
||||||
{ "rename": { "field": "message2.TC", "target_field": "dns.truncated", "ignore_missing": true } },
|
"json": {
|
||||||
{ "rename": { "field": "message2.RD", "target_field": "dns.recursion.desired", "ignore_missing": true } },
|
"field": "message",
|
||||||
{ "rename": { "field": "message2.RA", "target_field": "dns.recursion.available", "ignore_missing": true } },
|
"target_field": "message2",
|
||||||
{ "rename": { "field": "message2.Z", "target_field": "dns.reserved", "ignore_missing": true } },
|
"ignore_failure": true
|
||||||
{ "rename": { "field": "message2.answers", "target_field": "dns.answers.name", "ignore_missing": true } },
|
}
|
||||||
{ "foreach": {"field": "dns.answers.name","processor": {"pipeline": {"name": "common.ip_validation"}},"if": "ctx.dns != null && ctx.dns.answers != null && ctx.dns.answers.name != null","ignore_failure": true}},
|
},
|
||||||
{ "foreach": {"field": "temp._valid_ips","processor": {"append": {"field": "dns.resolved_ip","allow_duplicates": false,"value": "{{{_ingest._value}}}","ignore_failure": true}},"ignore_failure": true}},
|
{
|
||||||
{ "script": { "source": "if (ctx.dns.resolved_ip != null && ctx.dns.resolved_ip instanceof List) {\n ctx.dns.resolved_ip.removeIf(item -> item == null || item.toString().trim().isEmpty());\n }","ignore_failure": true }},
|
"dot_expander": {
|
||||||
{ "remove": {"field": ["temp"], "ignore_missing": true ,"ignore_failure": true } },
|
"field": "id.orig_h",
|
||||||
{ "rename": { "field": "message2.TTLs", "target_field": "dns.ttls", "ignore_missing": true } },
|
"path": "message2",
|
||||||
{ "rename": { "field": "message2.rejected", "target_field": "dns.query.rejected", "ignore_missing": true } },
|
"ignore_failure": true
|
||||||
{ "script": { "lang": "painless", "source": "ctx.dns.query.length = ctx.dns.query.name.length()", "ignore_failure": true } },
|
}
|
||||||
{ "set": { "if": "ctx._index == 'so-zeek'", "field": "_index", "value": "so-zeek_dns", "override": true } },
|
},
|
||||||
{ "pipeline": { "if": "ctx.dns?.query?.name != null && ctx.dns.query.name.contains('.')", "name": "dns.tld" } },
|
{
|
||||||
{ "pipeline": { "name": "zeek.common" } }
|
"rename": {
|
||||||
]
|
"field": "message2.proto",
|
||||||
|
"target_field": "network.transport",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.trans_id",
|
||||||
|
"target_field": "dns.id",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.rtt",
|
||||||
|
"target_field": "event.duration",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.query",
|
||||||
|
"target_field": "dns.query.name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.qclass",
|
||||||
|
"target_field": "dns.query.class",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.qclass_name",
|
||||||
|
"target_field": "dns.query.class_name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.qtype",
|
||||||
|
"target_field": "dns.query.type",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.qtype_name",
|
||||||
|
"target_field": "dns.query.type_name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.rcode",
|
||||||
|
"target_field": "dns.response.code",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.rcode_name",
|
||||||
|
"target_field": "dns.response.code_name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.AA",
|
||||||
|
"target_field": "dns.authoritative",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.TC",
|
||||||
|
"target_field": "dns.truncated",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.RD",
|
||||||
|
"target_field": "dns.recursion.desired",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.RA",
|
||||||
|
"target_field": "dns.recursion.available",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.Z",
|
||||||
|
"target_field": "dns.reserved",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.answers",
|
||||||
|
"target_field": "dns.answers.name",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foreach": {
|
||||||
|
"field": "dns.answers.name",
|
||||||
|
"processor": {
|
||||||
|
"pipeline": {
|
||||||
|
"name": "common.ip_validation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"if": "ctx.dns != null && ctx.dns.answers != null && ctx.dns.answers.name != null",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"foreach": {
|
||||||
|
"field": "temp._valid_ips",
|
||||||
|
"processor": {
|
||||||
|
"append": {
|
||||||
|
"field": "dns.resolved_ip",
|
||||||
|
"allow_duplicates": false,
|
||||||
|
"value": "{{{_ingest._value}}}",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"if": "ctx.dns != null && ctx.dns.answers != null && ctx.dns.answers.name != null",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"source": "if (ctx.dns.resolved_ip != null && ctx.dns.resolved_ip instanceof List) {\n ctx.dns.resolved_ip.removeIf(item -> item == null || item.toString().trim().isEmpty());\n }",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"remove": {
|
||||||
|
"field": [
|
||||||
|
"temp"
|
||||||
|
],
|
||||||
|
"ignore_missing": true,
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.TTLs",
|
||||||
|
"target_field": "dns.ttls",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rename": {
|
||||||
|
"field": "message2.rejected",
|
||||||
|
"target_field": "dns.query.rejected",
|
||||||
|
"ignore_missing": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": {
|
||||||
|
"lang": "painless",
|
||||||
|
"source": "ctx.dns.query.length = ctx.dns.query.name.length()",
|
||||||
|
"ignore_failure": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"set": {
|
||||||
|
"if": "ctx._index == 'so-zeek'",
|
||||||
|
"field": "_index",
|
||||||
|
"value": "so-zeek_dns",
|
||||||
|
"override": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"if": "ctx.dns?.query?.name != null && ctx.dns.query.name.contains('.')",
|
||||||
|
"name": "dns.tld"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pipeline": {
|
||||||
|
"name": "zeek.common"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"description" : "zeek.dpd",
|
|
||||||
"processors" : [
|
|
||||||
{ "set": { "field": "event.dataset", "value": "dpd" } },
|
|
||||||
{ "remove": { "field": ["host"], "ignore_failure": true } },
|
|
||||||
{ "json": { "field": "message", "target_field": "message2", "ignore_failure": true } },
|
|
||||||
{ "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } },
|
|
||||||
{ "rename": { "field": "message2.id.orig_h", "target_field": "source.ip", "ignore_missing": true } },
|
|
||||||
{ "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } },
|
|
||||||
{ "rename": { "field": "message2.id.orig_p", "target_field": "source.port", "ignore_missing": true } },
|
|
||||||
{ "dot_expander": { "field": "id.resp_h", "path": "message2", "ignore_failure": true } },
|
|
||||||
{ "rename": { "field": "message2.id.resp_h", "target_field": "destination.ip", "ignore_missing": true } },
|
|
||||||
{ "dot_expander": { "field": "id.resp_p", "path": "message2", "ignore_failure": true } },
|
|
||||||
{ "rename": { "field": "message2.id.resp_p", "target_field": "destination.port", "ignore_missing": true } },
|
|
||||||
{ "rename": { "field": "message2.proto", "target_field": "network.protocol", "ignore_missing": true } },
|
|
||||||
{ "rename": { "field": "message2.analyzer", "target_field": "observer.analyzer", "ignore_missing": true } },
|
|
||||||
{ "rename": { "field": "message2.failure_reason", "target_field": "error.reason", "ignore_missing": true } },
|
|
||||||
{ "pipeline": { "name": "zeek.common" } }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -841,6 +841,10 @@
|
|||||||
"type": "long"
|
"type": "long"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"capture_file": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ fail() {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
echo -e "\nDISCLAIMER: Script output is based on current data patterns, but are approximations soley intended to assist with getting a general ILM policy configured."
|
echo -e "\nDISCLAIMER: Script output is based on current data patterns, but are approximations solely intended to assist with getting a general ILM policy configured."
|
||||||
|
|
||||||
ORG_ID=$(lookup_org_id)
|
ORG_ID=$(lookup_org_id)
|
||||||
[ -n "$ORG_ID" ] || fail "Unable to resolve InfluxDB org id"
|
[ -n "$ORG_ID" ] || fail "Unable to resolve InfluxDB org id"
|
||||||
@@ -756,7 +756,7 @@ if [ "$should_trigger_recommendations" = true ]; then
|
|||||||
|
|
||||||
ilm_output=$(so-elasticsearch-query "${index}/_ilm/explain" --fail 2>/dev/null) || true
|
ilm_output=$(so-elasticsearch-query "${index}/_ilm/explain" --fail 2>/dev/null) || true
|
||||||
if [ -n "$ilm_output" ]; then
|
if [ -n "$ilm_output" ]; then
|
||||||
policy=$(echo "$ilm_output" | jq --arg idx "$index" -r ".indices[$idx].policy // empty" 2>/dev/null)
|
policy=$(echo "$ilm_output" | jq -r '.indices | to_entries | .[0].value.policy // empty' 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
if [ -n "$policy" ] && [ -n "${policy_ages[$policy]:-}" ]; then
|
if [ -n "$policy" ] && [ -n "${policy_ages[$policy]:-}" ]; then
|
||||||
delete_min_age=${policy_ages[$policy]}
|
delete_min_age=${policy_ages[$policy]}
|
||||||
@@ -1024,8 +1024,12 @@ else
|
|||||||
if [ "$ilm_indices_immediate" -gt 0 ]; then
|
if [ "$ilm_indices_immediate" -gt 0 ]; then
|
||||||
echo -e "${BOLD}Deleting now:${NC} $ilm_indices_immediate indices (~${ilm_delete_immediate_gb} GB, $ilm_shards_immediate shards)"
|
echo -e "${BOLD}Deleting now:${NC} $ilm_indices_immediate indices (~${ilm_delete_immediate_gb} GB, $ilm_shards_immediate shards)"
|
||||||
fi
|
fi
|
||||||
if [ "$ilm_indices_7d" -gt 0 ]; then
|
if [ "$ilm_indices_30d" -gt 0 ]; then
|
||||||
echo -e "${BOLD}Storage to be freed (7d):${NC} $ilm_indices_7d indices (~${ilm_delete_7d_gb} GB, $ilm_shards_7d shards)"
|
if [ "$ilm_delete_scheduled_30d" -gt 0 ] && [ "$ilm_indices_scheduled_30d" -gt 0 ]; then
|
||||||
|
echo -e "${BOLD}Storage to be freed (30d):${NC} $ilm_indices_30d indices (~${ilm_delete_30d_gb} GB, $ilm_shards_30d shards)"
|
||||||
|
elif [ "$ilm_indices_7d" -gt 0 ]; then
|
||||||
|
echo -e "${BOLD}Storage to be freed (7d):${NC} $ilm_indices_7d indices (~${ilm_delete_7d_gb} GB, $ilm_shards_7d shards)"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_title "LOG" "Retention Projection"
|
log_title "LOG" "Retention Projection"
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ used during VM provisioning to add dedicated NSM storage volumes.
|
|||||||
This command creates and attaches a volume with the following settings:
|
This command creates and attaches a volume with the following settings:
|
||||||
- VM Name: `vm1_sensor`
|
- VM Name: `vm1_sensor`
|
||||||
- Volume Size: `500` GB
|
- Volume Size: `500` GB
|
||||||
- Volume Path: `/nsm/libvirt/volumes/vm1_sensor-nsm.img`
|
- Volume Path: `/nsm/libvirt/volumes/vm1_sensor-nsm-<epoch_timestamp>.img`
|
||||||
- Device: `/dev/vdb` (virtio-blk)
|
- Device: `/dev/vdb` (virtio-blk)
|
||||||
- VM remains stopped after attachment
|
- VM remains stopped after attachment
|
||||||
|
|
||||||
@@ -75,7 +75,8 @@ used during VM provisioning to add dedicated NSM storage volumes.
|
|||||||
|
|
||||||
- The script automatically stops the VM if it's running before creating and attaching the volume.
|
- The script automatically stops the VM if it's running before creating and attaching the volume.
|
||||||
- Volumes are created with full pre-allocation for optimal performance.
|
- Volumes are created with full pre-allocation for optimal performance.
|
||||||
- Volume files are stored in `/nsm/libvirt/volumes/` with naming pattern `<vm_name>-nsm.img`.
|
- Volume files are stored in `/nsm/libvirt/volumes/` with naming pattern `<vm_name>-nsm-<epoch_timestamp>.img`.
|
||||||
|
- The epoch timestamp ensures unique volume names and prevents conflicts.
|
||||||
- Volumes are attached as `/dev/vdb` using virtio-blk for high performance.
|
- Volumes are attached as `/dev/vdb` using virtio-blk for high performance.
|
||||||
- The script checks available disk space before creating the volume.
|
- The script checks available disk space before creating the volume.
|
||||||
- Ownership is set to `qemu:qemu` with permissions `640`.
|
- Ownership is set to `qemu:qemu` with permissions `640`.
|
||||||
@@ -142,6 +143,7 @@ import socket
|
|||||||
import subprocess
|
import subprocess
|
||||||
import pwd
|
import pwd
|
||||||
import grp
|
import grp
|
||||||
|
import time
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from so_vm_utils import start_vm, stop_vm
|
from so_vm_utils import start_vm, stop_vm
|
||||||
@@ -242,10 +244,13 @@ def create_volume_file(vm_name, size_gb, logger):
|
|||||||
Raises:
|
Raises:
|
||||||
VolumeCreationError: If volume creation fails
|
VolumeCreationError: If volume creation fails
|
||||||
"""
|
"""
|
||||||
# Define volume path (directory already created in main())
|
# Generate epoch timestamp for unique volume naming
|
||||||
volume_path = os.path.join(VOLUME_DIR, f"{vm_name}-nsm.img")
|
epoch_timestamp = int(time.time())
|
||||||
|
|
||||||
# Check if volume already exists
|
# Define volume path with epoch timestamp for uniqueness
|
||||||
|
volume_path = os.path.join(VOLUME_DIR, f"{vm_name}-nsm-{epoch_timestamp}.img")
|
||||||
|
|
||||||
|
# Check if volume already exists (shouldn't be possible with timestamp)
|
||||||
if os.path.exists(volume_path):
|
if os.path.exists(volume_path):
|
||||||
logger.error(f"VOLUME: Volume already exists: {volume_path}")
|
logger.error(f"VOLUME: Volume already exists: {volume_path}")
|
||||||
raise VolumeCreationError(f"Volume already exists: {volume_path}")
|
raise VolumeCreationError(f"Volume already exists: {volume_path}")
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ def showUsage(args):
|
|||||||
print(' Where:', file=sys.stderr)
|
print(' Where:', file=sys.stderr)
|
||||||
print(' YAML_FILE - Path to the file that will be modified. Ex: /opt/so/conf/service/conf.yaml', file=sys.stderr)
|
print(' YAML_FILE - Path to the file that will be modified. Ex: /opt/so/conf/service/conf.yaml', file=sys.stderr)
|
||||||
print(' KEY - YAML key, does not support \' or " characters at this time. Ex: level1.level2', file=sys.stderr)
|
print(' KEY - YAML key, does not support \' or " characters at this time. Ex: level1.level2', file=sys.stderr)
|
||||||
print(' VALUE - Value to set for a given key', file=sys.stderr)
|
print(' VALUE - Value to set for a given key. Can be a literal value or file:<path> to load from a YAML file.', file=sys.stderr)
|
||||||
print(' LISTITEM - Item to append to a given key\'s list value', file=sys.stderr)
|
print(' LISTITEM - Item to append to a given key\'s list value. Can be a literal value or file:<path> to load from a YAML file.', file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +58,13 @@ def appendItem(content, key, listItem):
|
|||||||
|
|
||||||
|
|
||||||
def convertType(value):
|
def convertType(value):
|
||||||
if isinstance(value, str) and len(value) > 0 and (not value.startswith("0") or len(value) == 1):
|
if isinstance(value, str) and value.startswith("file:"):
|
||||||
|
path = value[5:] # Remove "file:" prefix
|
||||||
|
if not os.path.exists(path):
|
||||||
|
print(f"File '{path}' does not exist.", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
return loadYaml(path)
|
||||||
|
elif isinstance(value, str) and len(value) > 0 and (not value.startswith("0") or len(value) == 1):
|
||||||
if "." in value:
|
if "." in value:
|
||||||
try:
|
try:
|
||||||
value = float(value)
|
value = float(value)
|
||||||
|
|||||||
@@ -361,6 +361,29 @@ class TestRemove(unittest.TestCase):
|
|||||||
self.assertEqual(soyaml.convertType("FALSE"), False)
|
self.assertEqual(soyaml.convertType("FALSE"), False)
|
||||||
self.assertEqual(soyaml.convertType(""), "")
|
self.assertEqual(soyaml.convertType(""), "")
|
||||||
|
|
||||||
|
def test_convert_file(self):
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Create a temporary YAML file
|
||||||
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
|
||||||
|
f.write("test:\n - name: hi\n color: blue\n")
|
||||||
|
temp_file = f.name
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = soyaml.convertType(f"file:{temp_file}")
|
||||||
|
expected = {"test": [{"name": "hi", "color": "blue"}]}
|
||||||
|
self.assertEqual(result, expected)
|
||||||
|
finally:
|
||||||
|
os.unlink(temp_file)
|
||||||
|
|
||||||
|
def test_convert_file_nonexistent(self):
|
||||||
|
with self.assertRaises(SystemExit) as cm:
|
||||||
|
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
||||||
|
soyaml.convertType("file:/nonexistent/file.yaml")
|
||||||
|
self.assertEqual(cm.exception.code, 1)
|
||||||
|
self.assertIn("File '/nonexistent/file.yaml' does not exist.", mock_stderr.getvalue())
|
||||||
|
|
||||||
def test_get_int(self):
|
def test_get_int(self):
|
||||||
with patch('sys.stdout', new=StringIO()) as mock_stdout:
|
with patch('sys.stdout', new=StringIO()) as mock_stdout:
|
||||||
filename = "/tmp/so-yaml_test-get.yaml"
|
filename = "/tmp/so-yaml_test-get.yaml"
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ check_os_updates() {
|
|||||||
if [[ "$confirm" == [cC] ]]; then
|
if [[ "$confirm" == [cC] ]]; then
|
||||||
echo "Continuing without updating packages"
|
echo "Continuing without updating packages"
|
||||||
elif [[ "$confirm" == [uU] ]]; then
|
elif [[ "$confirm" == [uU] ]]; then
|
||||||
echo "Applying Grid Updates"
|
echo "Applying Grid Updates. The following patch.os salt state may take a while depending on how many packages need to be updated."
|
||||||
update_flag=true
|
update_flag=true
|
||||||
else
|
else
|
||||||
echo "Exiting soup"
|
echo "Exiting soup"
|
||||||
@@ -1318,6 +1318,8 @@ upgrade_salt() {
|
|||||||
fi
|
fi
|
||||||
# Else do Ubuntu things
|
# Else do Ubuntu things
|
||||||
elif [[ $is_deb ]]; then
|
elif [[ $is_deb ]]; then
|
||||||
|
# ensure these files don't exist when upgrading from 3006.9 to 3006.16
|
||||||
|
rm -f /etc/apt/keyrings/salt-archive-keyring-2023.pgp /etc/apt/sources.list.d/salt.list
|
||||||
echo "Removing apt hold for Salt."
|
echo "Removing apt hold for Salt."
|
||||||
echo ""
|
echo ""
|
||||||
apt-mark unhold "salt-common"
|
apt-mark unhold "salt-common"
|
||||||
@@ -1679,7 +1681,7 @@ This appears to be a distributed deployment. Other nodes should update themselve
|
|||||||
|
|
||||||
Each minion is on a random 15 minute check-in period and things like network bandwidth can be a factor in how long the actual upgrade takes. If you have a heavy node on a slow link, it is going to take a while to get the containers to it. Depending on what changes happened between the versions, Elasticsearch might not be able to talk to said heavy node until the update is complete.
|
Each minion is on a random 15 minute check-in period and things like network bandwidth can be a factor in how long the actual upgrade takes. If you have a heavy node on a slow link, it is going to take a while to get the containers to it. Depending on what changes happened between the versions, Elasticsearch might not be able to talk to said heavy node until the update is complete.
|
||||||
|
|
||||||
If it looks like you’re missing data after the upgrade, please avoid restarting services and instead make sure at least one search node has completed its upgrade. The best way to do this is to run 'sudo salt-call state.highstate' from a search node and make sure there are no errors. Typically if it works on one node it will work on the rest. Forward nodes are less complex and will update as they check in so you can monitor those from the Grid section of SOC.
|
If it looks like you’re missing data after the upgrade, please avoid restarting services and instead make sure at least one search node has completed its upgrade. The best way to do this is to run 'sudo salt-call state.highstate' from a search node and make sure there are no errors. Typically if it works on one node it will work on the rest. Sensor nodes are less complex and will update as they check in so you can monitor those from the Grid section of SOC.
|
||||||
|
|
||||||
For more information, please see $DOC_BASE_URL/soup.html#distributed-deployments.
|
For more information, please see $DOC_BASE_URL/soup.html#distributed-deployments.
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,9 @@
|
|||||||
|
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from "pcap/config.map.jinja" import PCAPMERGED %}
|
{% from "pcap/config.map.jinja" import PCAPMERGED %}
|
||||||
{% from 'bpf/pcap.map.jinja' import PCAPBPF %}
|
{% from 'bpf/pcap.map.jinja' import PCAPBPF, PCAP_BPF_STATUS, PCAP_BPF_CALC, STENO_BPF_COMPILED %}
|
||||||
|
|
||||||
{% set BPF_COMPILED = "" %}
|
|
||||||
|
|
||||||
# PCAP Section
|
# PCAP Section
|
||||||
|
|
||||||
stenographergroup:
|
stenographergroup:
|
||||||
group.present:
|
group.present:
|
||||||
- name: stenographer
|
- name: stenographer
|
||||||
@@ -40,18 +37,12 @@ pcap_sbin:
|
|||||||
- group: 939
|
- group: 939
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
{% if PCAPBPF %}
|
{% if PCAPBPF and not PCAP_BPF_STATUS %}
|
||||||
{% set BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + PCAPBPF|join(" "),cwd='/root') %}
|
stenoPCAPbpfcompilationfailure:
|
||||||
{% if BPF_CALC['stderr'] == "" %}
|
|
||||||
{% set BPF_COMPILED = ",\\\"--filter=" + BPF_CALC['stdout'] + "\\\"" %}
|
|
||||||
{% else %}
|
|
||||||
|
|
||||||
bpfcompilationfailure:
|
|
||||||
test.configurable_test_state:
|
test.configurable_test_state:
|
||||||
- changes: False
|
- changes: False
|
||||||
- result: False
|
- result: False
|
||||||
- comment: "BPF Compilation Failed - Discarding Specified BPF"
|
- comment: "BPF Syntax Error - Discarding Specified BPF. Error: {{ PCAP_BPF_CALC['stderr'] }}"
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
stenoconf:
|
stenoconf:
|
||||||
@@ -64,7 +55,7 @@ stenoconf:
|
|||||||
- template: jinja
|
- template: jinja
|
||||||
- defaults:
|
- defaults:
|
||||||
PCAPMERGED: {{ PCAPMERGED }}
|
PCAPMERGED: {{ PCAPMERGED }}
|
||||||
BPF_COMPILED: "{{ BPF_COMPILED }}"
|
STENO_BPF_COMPILED: "{{ STENO_BPF_COMPILED }}"
|
||||||
|
|
||||||
stenoca:
|
stenoca:
|
||||||
file.directory:
|
file.directory:
|
||||||
|
|||||||
@@ -6,6 +6,6 @@
|
|||||||
, "Interface": "{{ pillar.sensor.interface }}"
|
, "Interface": "{{ pillar.sensor.interface }}"
|
||||||
, "Port": 1234
|
, "Port": 1234
|
||||||
, "Host": "127.0.0.1"
|
, "Host": "127.0.0.1"
|
||||||
, "Flags": ["-v", "--blocks={{ PCAPMERGED.config.blocks }}", "--preallocate_file_mb={{ PCAPMERGED.config.preallocate_file_mb }}", "--aiops={{ PCAPMERGED.config.aiops }}", "--uid=stenographer", "--gid=stenographer"{{ BPF_COMPILED }}]
|
, "Flags": ["-v", "--blocks={{ PCAPMERGED.config.blocks }}", "--preallocate_file_mb={{ PCAPMERGED.config.preallocate_file_mb }}", "--aiops={{ PCAPMERGED.config.aiops }}", "--uid=stenographer", "--gid=stenographer"{{ STENO_BPF_COMPILED }}]
|
||||||
, "CertPath": "/etc/stenographer/certs"
|
, "CertPath": "/etc/stenographer/certs"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ pcap:
|
|||||||
description: By default, Stenographer limits the number of files in the pcap directory to 30000 to avoid limitations with the ext3 filesystem. However, if you're using the ext4 or xfs filesystems, then it is safe to increase this value. So if you have a large amount of storage and find that you only have 3 weeks worth of PCAP on disk while still having plenty of free space, then you may want to increase this default setting.
|
description: By default, Stenographer limits the number of files in the pcap directory to 30000 to avoid limitations with the ext3 filesystem. However, if you're using the ext4 or xfs filesystems, then it is safe to increase this value. So if you have a large amount of storage and find that you only have 3 weeks worth of PCAP on disk while still having plenty of free space, then you may want to increase this default setting.
|
||||||
helpLink: stenographer.html
|
helpLink: stenographer.html
|
||||||
diskfreepercentage:
|
diskfreepercentage:
|
||||||
description: Stenographer will purge old PCAP on a regular basis to keep the disk free percentage at this level. If you have a distributed deployment with dedicated forward nodes, then the default value of 10 should be reasonable since Stenographer should be the main consumer of disk space in the /nsm partition. However, if you have systems that run both Stenographer and Elasticsearch at the same time (like eval and standalone installations), then you’ll want to make sure that this value is no lower than 21 so that you avoid Elasticsearch hitting its watermark setting at 80% disk usage. If you have an older standalone installation, then you may need to manually change this value to 21.
|
description: Stenographer will purge old PCAP on a regular basis to keep the disk free percentage at this level. If you have a distributed deployment with dedicated Sensor nodes, then the default value of 10 should be reasonable since Stenographer should be the main consumer of disk space in the /nsm partition. However, if you have systems that run both Stenographer and Elasticsearch at the same time (like eval and standalone installations), then you’ll want to make sure that this value is no lower than 21 so that you avoid Elasticsearch hitting its watermark setting at 80% disk usage. If you have an older standalone installation, then you may need to manually change this value to 21.
|
||||||
helpLink: stenographer.html
|
helpLink: stenographer.html
|
||||||
blocks:
|
blocks:
|
||||||
description: The number of 1MB packet blocks used by Stenographer and AF_PACKET to store packets in memory, per thread. You shouldn't need to change this.
|
description: The number of 1MB packet blocks used by Stenographer and AF_PACKET to store packets in memory, per thread. You shouldn't need to change this.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||||
{% if sls.split('.')[0] in allowed_states %}
|
{% if sls.split('.')[0] in allowed_states %}
|
||||||
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from 'docker/docker.map.jinja' import DOCKER %}
|
{% from 'docker/docker.map.jinja' import DOCKER %}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
@@ -57,6 +58,17 @@ so-dockerregistry:
|
|||||||
- x509: registry_crt
|
- x509: registry_crt
|
||||||
- x509: registry_key
|
- x509: registry_key
|
||||||
|
|
||||||
|
wait_for_so-dockerregistry:
|
||||||
|
http.wait_for_successful_query:
|
||||||
|
- name: 'https://{{ GLOBALS.registry_host }}:5000/v2/'
|
||||||
|
- ssl: True
|
||||||
|
- verify_ssl: False
|
||||||
|
- status: 200
|
||||||
|
- wait_for: 120
|
||||||
|
- request_interval: 5
|
||||||
|
- require:
|
||||||
|
- docker_container: so-dockerregistry
|
||||||
|
|
||||||
delete_so-dockerregistry_so-status.disabled:
|
delete_so-dockerregistry_so-status.disabled:
|
||||||
file.uncomment:
|
file.uncomment:
|
||||||
- name: /opt/so/conf/so-status/so-status.conf
|
- name: /opt/so/conf/so-status/so-status.conf
|
||||||
|
|||||||
@@ -727,7 +727,8 @@ def check_hypervisor_disk_space(hypervisor: str, size_gb: int) -> Tuple[bool, Op
|
|||||||
result = local.cmd(
|
result = local.cmd(
|
||||||
hypervisor_minion,
|
hypervisor_minion,
|
||||||
'cmd.run',
|
'cmd.run',
|
||||||
["df -BG /nsm/libvirt/volumes | tail -1 | awk '{print $4}' | sed 's/G//'"]
|
["df -BG /nsm/libvirt/volumes | tail -1 | awk '{print $4}' | sed 's/G//'"],
|
||||||
|
kwarg={'python_shell': True}
|
||||||
)
|
)
|
||||||
|
|
||||||
if not result or hypervisor_minion not in result:
|
if not result or hypervisor_minion not in result:
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#======================================================================================================================
|
#======================================================================================================================
|
||||||
set -o nounset # Treat unset variables as an error
|
set -o nounset # Treat unset variables as an error
|
||||||
|
|
||||||
__ScriptVersion="2025.02.24"
|
__ScriptVersion="2025.09.03"
|
||||||
__ScriptName="bootstrap-salt.sh"
|
__ScriptName="bootstrap-salt.sh"
|
||||||
|
|
||||||
__ScriptFullName="$0"
|
__ScriptFullName="$0"
|
||||||
@@ -48,6 +48,7 @@ __ScriptArgs="$*"
|
|||||||
# * BS_GENTOO_USE_BINHOST: If 1 add `--getbinpkg` to gentoo's emerge
|
# * BS_GENTOO_USE_BINHOST: If 1 add `--getbinpkg` to gentoo's emerge
|
||||||
# * BS_SALT_MASTER_ADDRESS: The IP or DNS name of the salt-master the minion should connect to
|
# * BS_SALT_MASTER_ADDRESS: The IP or DNS name of the salt-master the minion should connect to
|
||||||
# * BS_SALT_GIT_CHECKOUT_DIR: The directory where to clone Salt on git installations
|
# * BS_SALT_GIT_CHECKOUT_DIR: The directory where to clone Salt on git installations
|
||||||
|
# * BS_TMP_DIR: The directory to use for executing the installation (defaults to /tmp)
|
||||||
#======================================================================================================================
|
#======================================================================================================================
|
||||||
|
|
||||||
|
|
||||||
@@ -171,12 +172,12 @@ __check_config_dir() {
|
|||||||
|
|
||||||
case "$CC_DIR_NAME" in
|
case "$CC_DIR_NAME" in
|
||||||
http://*|https://*)
|
http://*|https://*)
|
||||||
__fetch_url "/tmp/${CC_DIR_BASE}" "${CC_DIR_NAME}"
|
__fetch_url "${_TMP_DIR}/${CC_DIR_BASE}" "${CC_DIR_NAME}"
|
||||||
CC_DIR_NAME="/tmp/${CC_DIR_BASE}"
|
CC_DIR_NAME="${_TMP_DIR}/${CC_DIR_BASE}"
|
||||||
;;
|
;;
|
||||||
ftp://*)
|
ftp://*)
|
||||||
__fetch_url "/tmp/${CC_DIR_BASE}" "${CC_DIR_NAME}"
|
__fetch_url "${_TMP_DIR}/${CC_DIR_BASE}" "${CC_DIR_NAME}"
|
||||||
CC_DIR_NAME="/tmp/${CC_DIR_BASE}"
|
CC_DIR_NAME="${_TMP_DIR}/${CC_DIR_BASE}"
|
||||||
;;
|
;;
|
||||||
*://*)
|
*://*)
|
||||||
echoerror "Unsupported URI scheme for $CC_DIR_NAME"
|
echoerror "Unsupported URI scheme for $CC_DIR_NAME"
|
||||||
@@ -194,22 +195,22 @@ __check_config_dir() {
|
|||||||
|
|
||||||
case "$CC_DIR_NAME" in
|
case "$CC_DIR_NAME" in
|
||||||
*.tgz|*.tar.gz)
|
*.tgz|*.tar.gz)
|
||||||
tar -zxf "${CC_DIR_NAME}" -C /tmp
|
tar -zxf "${CC_DIR_NAME}" -C ${_TMP_DIR}
|
||||||
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tgz")
|
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tgz")
|
||||||
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tar.gz")
|
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tar.gz")
|
||||||
CC_DIR_NAME="/tmp/${CC_DIR_BASE}"
|
CC_DIR_NAME="${_TMP_DIR}/${CC_DIR_BASE}"
|
||||||
;;
|
;;
|
||||||
*.tbz|*.tar.bz2)
|
*.tbz|*.tar.bz2)
|
||||||
tar -xjf "${CC_DIR_NAME}" -C /tmp
|
tar -xjf "${CC_DIR_NAME}" -C ${_TMP_DIR}
|
||||||
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tbz")
|
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tbz")
|
||||||
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tar.bz2")
|
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tar.bz2")
|
||||||
CC_DIR_NAME="/tmp/${CC_DIR_BASE}"
|
CC_DIR_NAME="${_TMP_DIR}/${CC_DIR_BASE}"
|
||||||
;;
|
;;
|
||||||
*.txz|*.tar.xz)
|
*.txz|*.tar.xz)
|
||||||
tar -xJf "${CC_DIR_NAME}" -C /tmp
|
tar -xJf "${CC_DIR_NAME}" -C ${_TMP_DIR}
|
||||||
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".txz")
|
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".txz")
|
||||||
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tar.xz")
|
CC_DIR_BASE=$(basename "${CC_DIR_BASE}" ".tar.xz")
|
||||||
CC_DIR_NAME="/tmp/${CC_DIR_BASE}"
|
CC_DIR_NAME="${_TMP_DIR}/${CC_DIR_BASE}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -245,6 +246,7 @@ __check_unparsed_options() {
|
|||||||
#----------------------------------------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
_KEEP_TEMP_FILES=${BS_KEEP_TEMP_FILES:-$BS_FALSE}
|
_KEEP_TEMP_FILES=${BS_KEEP_TEMP_FILES:-$BS_FALSE}
|
||||||
_TEMP_CONFIG_DIR="null"
|
_TEMP_CONFIG_DIR="null"
|
||||||
|
_TMP_DIR=${BS_TMP_DIR:-"/tmp"}
|
||||||
_SALTSTACK_REPO_URL="https://github.com/saltstack/salt.git"
|
_SALTSTACK_REPO_URL="https://github.com/saltstack/salt.git"
|
||||||
_SALT_REPO_URL=${_SALTSTACK_REPO_URL}
|
_SALT_REPO_URL=${_SALTSTACK_REPO_URL}
|
||||||
_TEMP_KEYS_DIR="null"
|
_TEMP_KEYS_DIR="null"
|
||||||
@@ -281,7 +283,7 @@ _SIMPLIFY_VERSION=$BS_TRUE
|
|||||||
_LIBCLOUD_MIN_VERSION="0.14.0"
|
_LIBCLOUD_MIN_VERSION="0.14.0"
|
||||||
_EXTRA_PACKAGES=""
|
_EXTRA_PACKAGES=""
|
||||||
_HTTP_PROXY=""
|
_HTTP_PROXY=""
|
||||||
_SALT_GIT_CHECKOUT_DIR=${BS_SALT_GIT_CHECKOUT_DIR:-/tmp/git/salt}
|
_SALT_GIT_CHECKOUT_DIR=${BS_SALT_GIT_CHECKOUT_DIR:-${_TMP_DIR}/git/salt}
|
||||||
_NO_DEPS=$BS_FALSE
|
_NO_DEPS=$BS_FALSE
|
||||||
_FORCE_SHALLOW_CLONE=$BS_FALSE
|
_FORCE_SHALLOW_CLONE=$BS_FALSE
|
||||||
_DISABLE_SSL=$BS_FALSE
|
_DISABLE_SSL=$BS_FALSE
|
||||||
@@ -367,7 +369,7 @@ __usage() {
|
|||||||
also be specified. Salt installation will be ommitted, but some of the
|
also be specified. Salt installation will be ommitted, but some of the
|
||||||
dependencies could be installed to write configuration with -j or -J.
|
dependencies could be installed to write configuration with -j or -J.
|
||||||
-d Disables checking if Salt services are enabled to start on system boot.
|
-d Disables checking if Salt services are enabled to start on system boot.
|
||||||
You can also do this by touching /tmp/disable_salt_checks on the target
|
You can also do this by touching ${BS_TMP_DIR}/disable_salt_checks on the target
|
||||||
host. Default: \${BS_FALSE}
|
host. Default: \${BS_FALSE}
|
||||||
-D Show debug output
|
-D Show debug output
|
||||||
-f Force shallow cloning for git installations.
|
-f Force shallow cloning for git installations.
|
||||||
@@ -424,6 +426,9 @@ __usage() {
|
|||||||
-r Disable all repository configuration performed by this script. This
|
-r Disable all repository configuration performed by this script. This
|
||||||
option assumes all necessary repository configuration is already present
|
option assumes all necessary repository configuration is already present
|
||||||
on the system.
|
on the system.
|
||||||
|
-T If set this overrides the use of /tmp for script execution. This is
|
||||||
|
to allow for systems in which noexec is applied to temp filesystem mounts
|
||||||
|
for security reasons
|
||||||
-U If set, fully upgrade the system prior to bootstrapping Salt
|
-U If set, fully upgrade the system prior to bootstrapping Salt
|
||||||
-v Display script version
|
-v Display script version
|
||||||
-V Install Salt into virtualenv
|
-V Install Salt into virtualenv
|
||||||
@@ -436,7 +441,7 @@ __usage() {
|
|||||||
EOT
|
EOT
|
||||||
} # ---------- end of function __usage ----------
|
} # ---------- end of function __usage ----------
|
||||||
|
|
||||||
while getopts ':hvnDc:g:Gx:k:s:MSWNXCPFUKIA:i:Lp:dH:bflV:J:j:rR:aqQ' opt
|
while getopts ':hvnDc:g:Gx:k:s:MSWNXCPFUKIA:i:Lp:dH:bflV:J:j:rR:T:aqQ' opt
|
||||||
do
|
do
|
||||||
case "${opt}" in
|
case "${opt}" in
|
||||||
|
|
||||||
@@ -478,6 +483,7 @@ do
|
|||||||
a ) _PIP_ALL=$BS_TRUE ;;
|
a ) _PIP_ALL=$BS_TRUE ;;
|
||||||
r ) _DISABLE_REPOS=$BS_TRUE ;;
|
r ) _DISABLE_REPOS=$BS_TRUE ;;
|
||||||
R ) _CUSTOM_REPO_URL=$OPTARG ;;
|
R ) _CUSTOM_REPO_URL=$OPTARG ;;
|
||||||
|
T ) _TMP_DIR="$OPTARG" ;;
|
||||||
J ) _CUSTOM_MASTER_CONFIG=$OPTARG ;;
|
J ) _CUSTOM_MASTER_CONFIG=$OPTARG ;;
|
||||||
j ) _CUSTOM_MINION_CONFIG=$OPTARG ;;
|
j ) _CUSTOM_MINION_CONFIG=$OPTARG ;;
|
||||||
q ) _QUIET_GIT_INSTALLATION=$BS_TRUE ;;
|
q ) _QUIET_GIT_INSTALLATION=$BS_TRUE ;;
|
||||||
@@ -495,10 +501,10 @@ done
|
|||||||
shift $((OPTIND-1))
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
# Define our logging file and pipe paths
|
# Define our logging file and pipe paths
|
||||||
LOGFILE="/tmp/$( echo "$__ScriptName" | sed s/.sh/.log/g )"
|
LOGFILE="${_TMP_DIR}/$( echo "$__ScriptName" | sed s/.sh/.log/g )"
|
||||||
LOGPIPE="/tmp/$( echo "$__ScriptName" | sed s/.sh/.logpipe/g )"
|
LOGPIPE="${_TMP_DIR}/$( echo "$__ScriptName" | sed s/.sh/.logpipe/g )"
|
||||||
# Ensure no residual pipe exists
|
# Ensure no residual pipe exists
|
||||||
rm "$LOGPIPE" 2>/dev/null
|
rm -f "$LOGPIPE" 2>/dev/null
|
||||||
|
|
||||||
# Create our logging pipe
|
# Create our logging pipe
|
||||||
# On FreeBSD we have to use mkfifo instead of mknod
|
# On FreeBSD we have to use mkfifo instead of mknod
|
||||||
@@ -534,7 +540,7 @@ exec 2>"$LOGPIPE"
|
|||||||
# 14 SIGALRM
|
# 14 SIGALRM
|
||||||
# 15 SIGTERM
|
# 15 SIGTERM
|
||||||
#----------------------------------------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
APT_ERR=$(mktemp /tmp/apt_error.XXXXXX)
|
APT_ERR=$(mktemp ${_TMP_DIR}/apt_error.XXXXXX)
|
||||||
__exit_cleanup() {
|
__exit_cleanup() {
|
||||||
EXIT_CODE=$?
|
EXIT_CODE=$?
|
||||||
|
|
||||||
@@ -927,6 +933,11 @@ if [ -d "${_VIRTUALENV_DIR}" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Make sure the designated temp directory exists
|
||||||
|
if [ ! -d "${_TMP_DIR}" ]; then
|
||||||
|
mkdir -p "${_TMP_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
#--- FUNCTION -------------------------------------------------------------------------------------------------------
|
#--- FUNCTION -------------------------------------------------------------------------------------------------------
|
||||||
# NAME: __fetch_url
|
# NAME: __fetch_url
|
||||||
# DESCRIPTION: Retrieves a URL and writes it to a given path
|
# DESCRIPTION: Retrieves a URL and writes it to a given path
|
||||||
@@ -1941,11 +1952,6 @@ __wait_for_apt(){
|
|||||||
# Timeout set at 15 minutes
|
# Timeout set at 15 minutes
|
||||||
WAIT_TIMEOUT=900
|
WAIT_TIMEOUT=900
|
||||||
|
|
||||||
## see if sync'ing the clocks helps
|
|
||||||
if [ -f /usr/sbin/hwclock ]; then
|
|
||||||
/usr/sbin/hwclock -s
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run our passed in apt command
|
# Run our passed in apt command
|
||||||
"${@}" 2>"$APT_ERR"
|
"${@}" 2>"$APT_ERR"
|
||||||
APT_RETURN=$?
|
APT_RETURN=$?
|
||||||
@@ -1996,14 +2002,14 @@ __apt_get_upgrade_noinput() {
|
|||||||
#----------------------------------------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
__temp_gpg_pub() {
|
__temp_gpg_pub() {
|
||||||
if __check_command_exists mktemp; then
|
if __check_command_exists mktemp; then
|
||||||
tempfile="$(mktemp /tmp/salt-gpg-XXXXXXXX.pub 2>/dev/null)"
|
tempfile="$(mktemp ${_TMP_DIR}/salt-gpg-XXXXXXXX.pub 2>/dev/null)"
|
||||||
|
|
||||||
if [ -z "$tempfile" ]; then
|
if [ -z "$tempfile" ]; then
|
||||||
echoerror "Failed to create temporary file in /tmp"
|
echoerror "Failed to create temporary file in ${_TMP_DIR}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
tempfile="/tmp/salt-gpg-$$.pub"
|
tempfile="${_TMP_DIR}/salt-gpg-$$.pub"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $tempfile
|
echo $tempfile
|
||||||
@@ -2043,7 +2049,7 @@ __rpm_import_gpg() {
|
|||||||
__fetch_url "$tempfile" "$url" || return 1
|
__fetch_url "$tempfile" "$url" || return 1
|
||||||
|
|
||||||
# At least on CentOS 8, a missing newline at the end causes:
|
# At least on CentOS 8, a missing newline at the end causes:
|
||||||
# error: /tmp/salt-gpg-n1gKUb1u.pub: key 1 not an armored public key.
|
# error: ${_TMP_DIR}/salt-gpg-n1gKUb1u.pub: key 1 not an armored public key.
|
||||||
# shellcheck disable=SC1003,SC2086
|
# shellcheck disable=SC1003,SC2086
|
||||||
sed -i -e '$a\' $tempfile
|
sed -i -e '$a\' $tempfile
|
||||||
|
|
||||||
@@ -2109,7 +2115,7 @@ __git_clone_and_checkout() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
__SALT_GIT_CHECKOUT_PARENT_DIR=$(dirname "${_SALT_GIT_CHECKOUT_DIR}" 2>/dev/null)
|
__SALT_GIT_CHECKOUT_PARENT_DIR=$(dirname "${_SALT_GIT_CHECKOUT_DIR}" 2>/dev/null)
|
||||||
__SALT_GIT_CHECKOUT_PARENT_DIR="${__SALT_GIT_CHECKOUT_PARENT_DIR:-/tmp/git}"
|
__SALT_GIT_CHECKOUT_PARENT_DIR="${__SALT_GIT_CHECKOUT_PARENT_DIR:-${_TMP_DIR}/git}"
|
||||||
__SALT_CHECKOUT_REPONAME="$(basename "${_SALT_GIT_CHECKOUT_DIR}" 2>/dev/null)"
|
__SALT_CHECKOUT_REPONAME="$(basename "${_SALT_GIT_CHECKOUT_DIR}" 2>/dev/null)"
|
||||||
__SALT_CHECKOUT_REPONAME="${__SALT_CHECKOUT_REPONAME:-salt}"
|
__SALT_CHECKOUT_REPONAME="${__SALT_CHECKOUT_REPONAME:-salt}"
|
||||||
[ -d "${__SALT_GIT_CHECKOUT_PARENT_DIR}" ] || mkdir "${__SALT_GIT_CHECKOUT_PARENT_DIR}"
|
[ -d "${__SALT_GIT_CHECKOUT_PARENT_DIR}" ] || mkdir "${__SALT_GIT_CHECKOUT_PARENT_DIR}"
|
||||||
@@ -2162,7 +2168,7 @@ __git_clone_and_checkout() {
|
|||||||
|
|
||||||
if [ "$__SHALLOW_CLONE" -eq $BS_TRUE ]; then
|
if [ "$__SHALLOW_CLONE" -eq $BS_TRUE ]; then
|
||||||
# Let's try 'treeless' cloning to speed up. Treeless cloning omits trees and blobs ('files')
|
# Let's try 'treeless' cloning to speed up. Treeless cloning omits trees and blobs ('files')
|
||||||
# but includes metadata (commit history, tags, branches etc.
|
# but includes metadata (commit history, tags, branches etc.
|
||||||
# Test for "--filter" option introduced in git 2.19, the minimal version of git where the treeless
|
# Test for "--filter" option introduced in git 2.19, the minimal version of git where the treeless
|
||||||
# cloning we need actually works
|
# cloning we need actually works
|
||||||
if [ "$(git clone 2>&1 | grep 'filter')" != "" ]; then
|
if [ "$(git clone 2>&1 | grep 'filter')" != "" ]; then
|
||||||
@@ -2390,14 +2396,14 @@ __overwriteconfig() {
|
|||||||
|
|
||||||
# Make a tempfile to dump any python errors into.
|
# Make a tempfile to dump any python errors into.
|
||||||
if __check_command_exists mktemp; then
|
if __check_command_exists mktemp; then
|
||||||
tempfile="$(mktemp /tmp/salt-config-XXXXXXXX 2>/dev/null)"
|
tempfile="$(mktemp ${_TMP_DIR}/salt-config-XXXXXXXX 2>/dev/null)"
|
||||||
|
|
||||||
if [ -z "$tempfile" ]; then
|
if [ -z "$tempfile" ]; then
|
||||||
echoerror "Failed to create temporary file in /tmp"
|
echoerror "Failed to create temporary file in ${_TMP_DIR}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
tempfile="/tmp/salt-config-$$"
|
tempfile="${_TMP_DIR}/salt-config-$$"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$_PY_EXE" ]; then
|
if [ -n "$_PY_EXE" ]; then
|
||||||
@@ -2760,8 +2766,8 @@ __install_salt_from_repo() {
|
|||||||
echoinfo "Installing salt using ${_py_exe}, $(${_py_exe} --version)"
|
echoinfo "Installing salt using ${_py_exe}, $(${_py_exe} --version)"
|
||||||
cd "${_SALT_GIT_CHECKOUT_DIR}" || return 1
|
cd "${_SALT_GIT_CHECKOUT_DIR}" || return 1
|
||||||
|
|
||||||
mkdir -p /tmp/git/deps
|
mkdir -p ${_TMP_DIR}/git/deps
|
||||||
echodebug "Created directory /tmp/git/deps"
|
echodebug "Created directory ${_TMP_DIR}/git/deps"
|
||||||
|
|
||||||
if [ ${DISTRO_NAME_L} = "ubuntu" ] && [ "$DISTRO_MAJOR_VERSION" -eq 22 ]; then
|
if [ ${DISTRO_NAME_L} = "ubuntu" ] && [ "$DISTRO_MAJOR_VERSION" -eq 22 ]; then
|
||||||
echodebug "Ubuntu 22.04 has problem with base.txt requirements file, not parsing sys_platform == 'win32', upgrading from default pip works"
|
echodebug "Ubuntu 22.04 has problem with base.txt requirements file, not parsing sys_platform == 'win32', upgrading from default pip works"
|
||||||
@@ -2774,7 +2780,7 @@ __install_salt_from_repo() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f /tmp/git/deps/*
|
rm -f ${_TMP_DIR}/git/deps/*
|
||||||
|
|
||||||
echodebug "Installing Salt requirements from PyPi, ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} -r requirements/static/ci/py${_py_version}/linux.txt"
|
echodebug "Installing Salt requirements from PyPi, ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} -r requirements/static/ci/py${_py_version}/linux.txt"
|
||||||
${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} -r "requirements/static/ci/py${_py_version}/linux.txt"
|
${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --ignore-installed ${_PIP_INSTALL_ARGS} -r "requirements/static/ci/py${_py_version}/linux.txt"
|
||||||
@@ -2799,7 +2805,7 @@ __install_salt_from_repo() {
|
|||||||
|
|
||||||
echodebug "Running '${_py_exe} setup.py --salt-config-dir=$_SALT_ETC_DIR --salt-cache-dir=${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS} bdist_wheel'"
|
echodebug "Running '${_py_exe} setup.py --salt-config-dir=$_SALT_ETC_DIR --salt-cache-dir=${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS} bdist_wheel'"
|
||||||
${_py_exe} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS}" bdist_wheel || return 1
|
${_py_exe} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS}" bdist_wheel || return 1
|
||||||
mv dist/salt*.whl /tmp/git/deps/ || return 1
|
mv dist/salt*.whl ${_TMP_DIR}/git/deps/ || return 1
|
||||||
|
|
||||||
cd "${__SALT_GIT_CHECKOUT_PARENT_DIR}" || return 1
|
cd "${__SALT_GIT_CHECKOUT_PARENT_DIR}" || return 1
|
||||||
|
|
||||||
@@ -2813,14 +2819,14 @@ __install_salt_from_repo() {
|
|||||||
${_pip_cmd} install --force-reinstall --break-system-packages "${_arch_dep}"
|
${_pip_cmd} install --force-reinstall --break-system-packages "${_arch_dep}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echodebug "Running '${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall ${_PIP_INSTALL_ARGS} /tmp/git/deps/salt*.whl'"
|
echodebug "Running '${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall ${_PIP_INSTALL_ARGS} ${_TMP_DIR}/git/deps/salt*.whl'"
|
||||||
|
|
||||||
echodebug "Running ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall ${_PIP_INSTALL_ARGS} --global-option=--salt-config-dir=$_SALT_ETC_DIR --salt-cache-dir=${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS} /tmp/git/deps/salt*.whl"
|
echodebug "Running ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall ${_PIP_INSTALL_ARGS} --global-option=--salt-config-dir=$_SALT_ETC_DIR --salt-cache-dir=${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS} ${_TMP_DIR}/git/deps/salt*.whl"
|
||||||
|
|
||||||
${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall \
|
${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall \
|
||||||
${_PIP_INSTALL_ARGS} \
|
${_PIP_INSTALL_ARGS} \
|
||||||
--global-option="--salt-config-dir=$_SALT_ETC_DIR --salt-cache-dir=${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS}" \
|
--global-option="--salt-config-dir=$_SALT_ETC_DIR --salt-cache-dir=${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS}" \
|
||||||
/tmp/git/deps/salt*.whl || return 1
|
${_TMP_DIR}/git/deps/salt*.whl || return 1
|
||||||
|
|
||||||
echoinfo "Checking if Salt can be imported using ${_py_exe}"
|
echoinfo "Checking if Salt can be imported using ${_py_exe}"
|
||||||
CHECK_SALT_SCRIPT=$(cat << EOM
|
CHECK_SALT_SCRIPT=$(cat << EOM
|
||||||
@@ -6295,8 +6301,8 @@ __get_packagesite_onedir_latest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__install_saltstack_photon_onedir_repository() {
|
__install_saltstack_vmware_photon_os_onedir_repository() {
|
||||||
echodebug "__install_saltstack_photon_onedir_repository() entry"
|
echodebug "__install_saltstack_vmware_photon_os_onedir_repository() entry"
|
||||||
|
|
||||||
if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then
|
if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then
|
||||||
echoerror "Python version is no longer supported, only Python 3"
|
echoerror "Python version is no longer supported, only Python 3"
|
||||||
@@ -6376,8 +6382,8 @@ __install_saltstack_photon_onedir_repository() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_deps() {
|
install_vmware_photon_os_deps() {
|
||||||
echodebug "install_photon_deps() entry"
|
echodebug "install_vmware_photon_os_deps() entry"
|
||||||
|
|
||||||
if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then
|
if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then
|
||||||
echoerror "Python version is no longer supported, only Python 3"
|
echoerror "Python version is no longer supported, only Python 3"
|
||||||
@@ -6406,8 +6412,8 @@ install_photon_deps() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_stable_post() {
|
install_vmware_photon_os_stable_post() {
|
||||||
echodebug "install_photon_stable_post() entry"
|
echodebug "install_vmware_photon_os_stable_post() entry"
|
||||||
|
|
||||||
for fname in api master minion syndic; do
|
for fname in api master minion syndic; do
|
||||||
# Skip salt-api since the service should be opt-in and not necessarily started on boot
|
# Skip salt-api since the service should be opt-in and not necessarily started on boot
|
||||||
@@ -6424,8 +6430,8 @@ install_photon_stable_post() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_git_deps() {
|
install_vmware_photon_os_git_deps() {
|
||||||
echodebug "install_photon_git_deps() entry"
|
echodebug "install_vmware_photon_os_git_deps() entry"
|
||||||
|
|
||||||
if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then
|
if [ -n "$_PY_EXE" ] && [ "$_PY_MAJOR_VERSION" -ne 3 ]; then
|
||||||
echoerror "Python version is no longer supported, only Python 3"
|
echoerror "Python version is no longer supported, only Python 3"
|
||||||
@@ -6463,7 +6469,7 @@ install_photon_git_deps() {
|
|||||||
|
|
||||||
__PACKAGES="python${PY_PKG_VER}-devel python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc glibc-devel linux-devel.x86_64 cython${PY_PKG_VER}"
|
__PACKAGES="python${PY_PKG_VER}-devel python${PY_PKG_VER}-pip python${PY_PKG_VER}-setuptools gcc glibc-devel linux-devel.x86_64 cython${PY_PKG_VER}"
|
||||||
|
|
||||||
echodebug "install_photon_git_deps() distro major version, ${DISTRO_MAJOR_VERSION}"
|
echodebug "install_vmware_photon_os_git_deps() distro major version, ${DISTRO_MAJOR_VERSION}"
|
||||||
|
|
||||||
## Photon 5 container is missing systemd on default installation
|
## Photon 5 container is missing systemd on default installation
|
||||||
if [ "${DISTRO_MAJOR_VERSION}" -lt 5 ]; then
|
if [ "${DISTRO_MAJOR_VERSION}" -lt 5 ]; then
|
||||||
@@ -6489,8 +6495,8 @@ install_photon_git_deps() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_git() {
|
install_vmware_photon_os_git() {
|
||||||
echodebug "install_photon_git() entry"
|
echodebug "install_vmware_photon_os_git() entry"
|
||||||
|
|
||||||
if [ "${_PY_EXE}" != "" ]; then
|
if [ "${_PY_EXE}" != "" ]; then
|
||||||
_PYEXE=${_PY_EXE}
|
_PYEXE=${_PY_EXE}
|
||||||
@@ -6500,7 +6506,7 @@ install_photon_git() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
install_photon_git_deps
|
install_vmware_photon_os_git_deps
|
||||||
|
|
||||||
if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then
|
if [ -f "${_SALT_GIT_CHECKOUT_DIR}/salt/syspaths.py" ]; then
|
||||||
${_PYEXE} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --prefix=/usr || return 1
|
${_PYEXE} setup.py --salt-config-dir="$_SALT_ETC_DIR" --salt-cache-dir="${_SALT_CACHE_DIR}" ${SETUP_PY_INSTALL_ARGS} install --prefix=/usr || return 1
|
||||||
@@ -6510,8 +6516,8 @@ install_photon_git() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_git_post() {
|
install_vmware_photon_os_git_post() {
|
||||||
echodebug "install_photon_git_post() entry"
|
echodebug "install_vmware_photon_os_git_post() entry"
|
||||||
|
|
||||||
for fname in api master minion syndic; do
|
for fname in api master minion syndic; do
|
||||||
# Skip if not meant to be installed
|
# Skip if not meant to be installed
|
||||||
@@ -6543,9 +6549,9 @@ install_photon_git_post() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_restart_daemons() {
|
install_vmware_photon_os_restart_daemons() {
|
||||||
[ "$_START_DAEMONS" -eq $BS_FALSE ] && return
|
[ "$_START_DAEMONS" -eq $BS_FALSE ] && return
|
||||||
echodebug "install_photon_restart_daemons() entry"
|
echodebug "install_vmware_photon_os_restart_daemons() entry"
|
||||||
|
|
||||||
|
|
||||||
for fname in api master minion syndic; do
|
for fname in api master minion syndic; do
|
||||||
@@ -6567,8 +6573,8 @@ install_photon_restart_daemons() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_check_services() {
|
install_vmware_photon_os_check_services() {
|
||||||
echodebug "install_photon_check_services() entry"
|
echodebug "install_vmware_photon_os_check_services() entry"
|
||||||
|
|
||||||
for fname in api master minion syndic; do
|
for fname in api master minion syndic; do
|
||||||
# Skip salt-api since the service should be opt-in and not necessarily started on boot
|
# Skip salt-api since the service should be opt-in and not necessarily started on boot
|
||||||
@@ -6585,8 +6591,8 @@ install_photon_check_services() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_onedir_deps() {
|
install_vmware_photon_os_onedir_deps() {
|
||||||
echodebug "install_photon_onedir_deps() entry"
|
echodebug "install_vmware_photon_os_onedir_deps() entry"
|
||||||
|
|
||||||
|
|
||||||
if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then
|
if [ "$_UPGRADE_SYS" -eq $BS_TRUE ]; then
|
||||||
@@ -6600,17 +6606,17 @@ install_photon_onedir_deps() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$_DISABLE_REPOS" -eq "$BS_FALSE" ]; then
|
if [ "$_DISABLE_REPOS" -eq "$BS_FALSE" ]; then
|
||||||
__install_saltstack_photon_onedir_repository || return 1
|
__install_saltstack_vmware_photon_os_onedir_repository || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If -R was passed, we need to configure custom repo url with rsync-ed packages
|
# If -R was passed, we need to configure custom repo url with rsync-ed packages
|
||||||
# Which was handled in __install_saltstack_rhel_repository buu that hanlded old-stable which is for
|
# Which was handled in __install_saltstack_rhel_repository buu that hanlded old-stable which is for
|
||||||
# releases which are End-Of-Life. This call has its own check in case -r was passed without -R.
|
# releases which are End-Of-Life. This call has its own check in case -r was passed without -R.
|
||||||
if [ "$_CUSTOM_REPO_URL" != "null" ]; then
|
if [ "$_CUSTOM_REPO_URL" != "null" ]; then
|
||||||
__install_saltstack_photon_onedir_repository || return 1
|
__install_saltstack_vmware_photon_os_onedir_repository || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__PACKAGES="procps-ng sudo shadow"
|
__PACKAGES="procps-ng sudo shadow wget"
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
__tdnf_install_noinput ${__PACKAGES} || return 1
|
__tdnf_install_noinput ${__PACKAGES} || return 1
|
||||||
@@ -6626,9 +6632,9 @@ install_photon_onedir_deps() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
install_photon_onedir() {
|
install_vmware_photon_os_onedir() {
|
||||||
|
|
||||||
echodebug "install_photon_onedir() entry"
|
echodebug "install_vmware_photon_os_onedir() entry"
|
||||||
|
|
||||||
STABLE_REV=$ONEDIR_REV
|
STABLE_REV=$ONEDIR_REV
|
||||||
_GENERIC_PKG_VERSION=""
|
_GENERIC_PKG_VERSION=""
|
||||||
@@ -6672,9 +6678,9 @@ install_photon_onedir() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
install_photon_onedir_post() {
|
install_vmware_photon_os_onedir_post() {
|
||||||
STABLE_REV=$ONEDIR_REV
|
STABLE_REV=$ONEDIR_REV
|
||||||
install_photon_stable_post || return 1
|
install_vmware_photon_os_stable_post || return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -7797,7 +7803,7 @@ install_macosx_git_deps() {
|
|||||||
export PATH=/usr/local/bin:$PATH
|
export PATH=/usr/local/bin:$PATH
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__fetch_url "/tmp/get-pip.py" "https://bootstrap.pypa.io/get-pip.py" || return 1
|
__fetch_url "${_TMP_DIR}/get-pip.py" "https://bootstrap.pypa.io/get-pip.py" || return 1
|
||||||
|
|
||||||
if [ -n "$_PY_EXE" ]; then
|
if [ -n "$_PY_EXE" ]; then
|
||||||
_PYEXE="${_PY_EXE}"
|
_PYEXE="${_PY_EXE}"
|
||||||
@@ -7807,7 +7813,7 @@ install_macosx_git_deps() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Install PIP
|
# Install PIP
|
||||||
$_PYEXE /tmp/get-pip.py || return 1
|
$_PYEXE ${_TMP_DIR}/get-pip.py || return 1
|
||||||
|
|
||||||
# shellcheck disable=SC2119
|
# shellcheck disable=SC2119
|
||||||
__git_clone_and_checkout || return 1
|
__git_clone_and_checkout || return 1
|
||||||
@@ -7819,9 +7825,9 @@ install_macosx_stable() {
|
|||||||
|
|
||||||
install_macosx_stable_deps || return 1
|
install_macosx_stable_deps || return 1
|
||||||
|
|
||||||
__fetch_url "/tmp/${PKG}" "${SALTPKGCONFURL}" || return 1
|
__fetch_url "${_TMP_DIR}/${PKG}" "${SALTPKGCONFURL}" || return 1
|
||||||
|
|
||||||
/usr/sbin/installer -pkg "/tmp/${PKG}" -target / || return 1
|
/usr/sbin/installer -pkg "${_TMP_DIR}/${PKG}" -target / || return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -7830,9 +7836,9 @@ install_macosx_onedir() {
|
|||||||
|
|
||||||
install_macosx_onedir_deps || return 1
|
install_macosx_onedir_deps || return 1
|
||||||
|
|
||||||
__fetch_url "/tmp/${PKG}" "${SALTPKGCONFURL}" || return 1
|
__fetch_url "${_TMP_DIR}/${PKG}" "${SALTPKGCONFURL}" || return 1
|
||||||
|
|
||||||
/usr/sbin/installer -pkg "/tmp/${PKG}" -target / || return 1
|
/usr/sbin/installer -pkg "${_TMP_DIR}/${PKG}" -target / || return 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ sensoroni:
|
|||||||
sensoronikey:
|
sensoronikey:
|
||||||
soc_host:
|
soc_host:
|
||||||
suripcap:
|
suripcap:
|
||||||
pcapMaxCount: 999999
|
pcapMaxCount: 100000
|
||||||
analyzers:
|
analyzers:
|
||||||
echotrail:
|
echotrail:
|
||||||
base_url: https://api.echotrail.io/insights/
|
base_url: https://api.echotrail.io/insights/
|
||||||
|
|||||||
@@ -1364,6 +1364,8 @@ soc:
|
|||||||
cases: soc
|
cases: soc
|
||||||
filedatastore:
|
filedatastore:
|
||||||
jobDir: jobs
|
jobDir: jobs
|
||||||
|
retryFailureIntervalMs: 600000
|
||||||
|
retryFailureMaxAttempts: 5
|
||||||
kratos:
|
kratos:
|
||||||
hostUrl:
|
hostUrl:
|
||||||
hydra:
|
hydra:
|
||||||
@@ -1744,7 +1746,7 @@ soc:
|
|||||||
showSubtitle: true
|
showSubtitle: true
|
||||||
- name: DPD
|
- name: DPD
|
||||||
description: Dynamic Protocol Detection errors
|
description: Dynamic Protocol Detection errors
|
||||||
query: 'tags:dpd | groupby error.reason'
|
query: '(tags:dpd OR tags:analyzer) | groupby error.reason'
|
||||||
showSubtitle: true
|
showSubtitle: true
|
||||||
- name: Files
|
- name: Files
|
||||||
description: Files grouped by mimetype
|
description: Files grouped by mimetype
|
||||||
@@ -2010,7 +2012,7 @@ soc:
|
|||||||
query: 'tags:dns | groupby dns.query.name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby dns.highest_registered_domain | groupby dns.parent_domain | groupby dns.query.type_name | groupby dns.response.code_name | groupby dns.answers.name | groupby destination.as.organization.name'
|
query: 'tags:dns | groupby dns.query.name | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby dns.highest_registered_domain | groupby dns.parent_domain | groupby dns.query.type_name | groupby dns.response.code_name | groupby dns.answers.name | groupby destination.as.organization.name'
|
||||||
- name: DPD
|
- name: DPD
|
||||||
description: DPD (Dynamic Protocol Detection) errors
|
description: DPD (Dynamic Protocol Detection) errors
|
||||||
query: 'tags:dpd | groupby error.reason | groupby -sankey error.reason source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby network.protocol | groupby destination.as.organization.name'
|
query: '(tags:dpd OR tags:analyzer) | groupby error.reason | groupby -sankey error.reason source.ip | groupby source.ip | groupby -sankey source.ip destination.ip | groupby destination.ip | groupby destination.port | groupby network.protocol | groupby destination.as.organization.name'
|
||||||
- name: Files
|
- name: Files
|
||||||
description: Files seen in network traffic
|
description: Files seen in network traffic
|
||||||
query: 'tags:file | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.bytes.total | groupby source.ip | groupby destination.ip | groupby destination.as.organization.name'
|
query: 'tags:file | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.bytes.total | groupby source.ip | groupby destination.ip | groupby destination.as.organization.name'
|
||||||
@@ -2552,6 +2554,7 @@ soc:
|
|||||||
assistant:
|
assistant:
|
||||||
enabled: false
|
enabled: false
|
||||||
investigationPrompt: Investigate Alert ID {socId}
|
investigationPrompt: Investigate Alert ID {socId}
|
||||||
|
compressContextPrompt: Summarize the conversation for context compaction
|
||||||
thresholdColorRatioLow: 0.5
|
thresholdColorRatioLow: 0.5
|
||||||
thresholdColorRatioMed: 0.75
|
thresholdColorRatioMed: 0.75
|
||||||
thresholdColorRatioMax: 1
|
thresholdColorRatioMax: 1
|
||||||
@@ -2561,13 +2564,22 @@ soc:
|
|||||||
contextLimitSmall: 200000
|
contextLimitSmall: 200000
|
||||||
contextLimitLarge: 1000000
|
contextLimitLarge: 1000000
|
||||||
lowBalanceColorAlert: 500000
|
lowBalanceColorAlert: 500000
|
||||||
|
enabled: true
|
||||||
- id: sonnet-4.5
|
- id: sonnet-4.5
|
||||||
displayName: Claude Sonnet 4.5
|
displayName: Claude Sonnet 4.5
|
||||||
contextLimitSmall: 200000
|
contextLimitSmall: 200000
|
||||||
contextLimitLarge: 1000000
|
contextLimitLarge: 1000000
|
||||||
lowBalanceColorAlert: 500000
|
lowBalanceColorAlert: 500000
|
||||||
|
enabled: true
|
||||||
- id: gptoss-120b
|
- id: gptoss-120b
|
||||||
displayName: GPT-OSS 120B
|
displayName: GPT-OSS 120B
|
||||||
contextLimitSmall: 128000
|
contextLimitSmall: 128000
|
||||||
contextLimitLarge: 128000
|
contextLimitLarge: 128000
|
||||||
lowBalanceColorAlert: 500000
|
lowBalanceColorAlert: 500000
|
||||||
|
enabled: true
|
||||||
|
- id: qwen-235b
|
||||||
|
displayName: QWEN 235B
|
||||||
|
contextLimitSmall: 256000
|
||||||
|
contextLimitLarge: 256000
|
||||||
|
lowBalanceColorAlert: 500000
|
||||||
|
enabled: true
|
||||||
|
|||||||
@@ -43,10 +43,26 @@
|
|||||||
|
|
||||||
No Virtual Machines Found
|
No Virtual Machines Found
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- else %}
|
{%- elif baseDomainStatus == 'ImageDownloadStart' %}
|
||||||
|
#### INFO
|
||||||
|
|
||||||
|
Base domain image download started.
|
||||||
|
{%- elif baseDomainStatus == 'ImageDownloadFailed' %}
|
||||||
|
#### ERROR
|
||||||
|
|
||||||
|
Base domain image download failed. Please check the salt-master log for details and verify network connectivity.
|
||||||
|
{%- elif baseDomainStatus == 'SSHKeySetupFailed' %}
|
||||||
|
#### ERROR
|
||||||
|
|
||||||
|
SSH key setup failed. Please check the salt-master log for details.
|
||||||
|
{%- elif baseDomainStatus == 'SetupFailed' %}
|
||||||
#### WARNING
|
#### WARNING
|
||||||
|
|
||||||
Base domain has not been initialized.
|
Setup failed. Please check the salt-master log for details.
|
||||||
|
{%- elif baseDomainStatus == 'PreInit' %}
|
||||||
|
#### WARNING
|
||||||
|
|
||||||
|
Base domain has not been initialized. Waiting for hypervisor to highstate.
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
|||||||
@@ -424,6 +424,17 @@ soc:
|
|||||||
description: The maximum number of documents to request in a single Elasticsearch scroll request.
|
description: The maximum number of documents to request in a single Elasticsearch scroll request.
|
||||||
bulkIndexWorkerCount:
|
bulkIndexWorkerCount:
|
||||||
description: The number of worker threads to use when bulk indexing data into Elasticsearch. A value below 1 will default to the number of CPUs available.
|
description: The number of worker threads to use when bulk indexing data into Elasticsearch. A value below 1 will default to the number of CPUs available.
|
||||||
|
filedatastore:
|
||||||
|
jobDir:
|
||||||
|
description: The location where local job files are stored on the manager.
|
||||||
|
global: True
|
||||||
|
advanced: True
|
||||||
|
retryFailureIntervalMs:
|
||||||
|
description: The interval, in milliseconds, to wait before attempting to reprocess a failed job.
|
||||||
|
global: True
|
||||||
|
retryFailureMaxAttempts:
|
||||||
|
description: The max number of attempts to process a job, in the event the job fails to complete.
|
||||||
|
global: True
|
||||||
sostatus:
|
sostatus:
|
||||||
refreshIntervalMs:
|
refreshIntervalMs:
|
||||||
description: Duration (in milliseconds) between refreshes of the grid status. Shortening this duration may not have expected results, as the backend systems feeding this sostatus data will continue their updates as scheduled.
|
description: Duration (in milliseconds) between refreshes of the grid status. Shortening this duration may not have expected results, as the backend systems feeding this sostatus data will continue their updates as scheduled.
|
||||||
@@ -606,6 +617,9 @@ soc:
|
|||||||
investigationPrompt:
|
investigationPrompt:
|
||||||
description: Prompt given to Onion AI when beginning an investigation.
|
description: Prompt given to Onion AI when beginning an investigation.
|
||||||
global: True
|
global: True
|
||||||
|
compressContextPrompt:
|
||||||
|
description: Prompt given to Onion AI when summarizing a conversation in order to compress context.
|
||||||
|
global: True
|
||||||
thresholdColorRatioLow:
|
thresholdColorRatioLow:
|
||||||
description: Lower visual context color change threshold.
|
description: Lower visual context color change threshold.
|
||||||
global: True
|
global: True
|
||||||
@@ -648,6 +662,9 @@ soc:
|
|||||||
label: Low Balance Color Alert
|
label: Low Balance Color Alert
|
||||||
forcedType: int
|
forcedType: int
|
||||||
required: True
|
required: True
|
||||||
|
- field: enabled
|
||||||
|
label: Enabled
|
||||||
|
forcedType: bool
|
||||||
apiTimeoutMs:
|
apiTimeoutMs:
|
||||||
description: Duration (in milliseconds) to wait for a response from the SOC server API before giving up and showing an error on the SOC UI.
|
description: Duration (in milliseconds) to wait for a response from the SOC server API before giving up and showing an error on the SOC UI.
|
||||||
global: True
|
global: True
|
||||||
|
|||||||
@@ -7,9 +7,47 @@
|
|||||||
{% if sls.split('.')[0] in allowed_states %}
|
{% if sls.split('.')[0] in allowed_states %}
|
||||||
|
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from 'bpf/suricata.map.jinja' import SURICATABPF %}
|
|
||||||
{% from 'suricata/map.jinja' import SURICATAMERGED %}
|
{% from 'suricata/map.jinja' import SURICATAMERGED %}
|
||||||
{% set BPF_STATUS = 0 %}
|
{% from 'bpf/suricata.map.jinja' import SURICATABPF, SURICATA_BPF_STATUS, SURICATA_BPF_CALC %}
|
||||||
|
|
||||||
|
suridir:
|
||||||
|
file.directory:
|
||||||
|
- name: /opt/so/conf/suricata
|
||||||
|
- user: 940
|
||||||
|
- group: 940
|
||||||
|
|
||||||
|
{% if GLOBALS.pcap_engine in ["SURICATA", "TRANSITION"] %}
|
||||||
|
{% from 'bpf/pcap.map.jinja' import PCAPBPF, PCAP_BPF_STATUS, PCAP_BPF_CALC %}
|
||||||
|
# BPF compilation and configuration
|
||||||
|
{% if PCAPBPF and not PCAP_BPF_STATUS %}
|
||||||
|
suriPCAPbpfcompilationfailure:
|
||||||
|
test.configurable_test_state:
|
||||||
|
- changes: False
|
||||||
|
- result: False
|
||||||
|
- comment: "BPF Syntax Error - Discarding Specified BPF. Error: {{ PCAP_BPF_CALC['stderr'] }}"
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# BPF applied to all of Suricata - alerts/metadata/pcap
|
||||||
|
suribpf:
|
||||||
|
file.managed:
|
||||||
|
- name: /opt/so/conf/suricata/bpf
|
||||||
|
- user: 940
|
||||||
|
- group: 940
|
||||||
|
{% if SURICATA_BPF_STATUS %}
|
||||||
|
- contents: {{ SURICATABPF }}
|
||||||
|
{% else %}
|
||||||
|
- contents:
|
||||||
|
- ""
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if SURICATABPF and not SURICATA_BPF_STATUS %}
|
||||||
|
suribpfcompilationfailure:
|
||||||
|
test.configurable_test_state:
|
||||||
|
- changes: False
|
||||||
|
- result: False
|
||||||
|
- comment: "BPF Syntax Error - Discarding Specified BPF. Error: {{ SURICATA_BPF_CALC['stderr'] }}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Add Suricata Group
|
# Add Suricata Group
|
||||||
suricatagroup:
|
suricatagroup:
|
||||||
@@ -49,18 +87,11 @@ suricata_sbin_jinja:
|
|||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
|
|
||||||
suridir:
|
|
||||||
file.directory:
|
|
||||||
- name: /opt/so/conf/suricata
|
|
||||||
- user: 940
|
|
||||||
- group: 940
|
|
||||||
|
|
||||||
suriruledir:
|
suriruledir:
|
||||||
file.directory:
|
file.directory:
|
||||||
- name: /opt/so/conf/suricata/rules
|
- name: /opt/so/conf/suricata/rules
|
||||||
- user: 940
|
- user: 940
|
||||||
- group: 940
|
- group: 940
|
||||||
- makedirs: True
|
|
||||||
|
|
||||||
surilogdir:
|
surilogdir:
|
||||||
file.directory:
|
file.directory:
|
||||||
@@ -136,32 +167,6 @@ suriclassifications:
|
|||||||
- user: 940
|
- user: 940
|
||||||
- group: 940
|
- group: 940
|
||||||
|
|
||||||
# BPF compilation and configuration
|
|
||||||
{% if SURICATABPF %}
|
|
||||||
{% set BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + SURICATABPF|join(" "),cwd='/root') %}
|
|
||||||
{% if BPF_CALC['stderr'] == "" %}
|
|
||||||
{% set BPF_STATUS = 1 %}
|
|
||||||
{% else %}
|
|
||||||
suribpfcompilationfailure:
|
|
||||||
test.configurable_test_state:
|
|
||||||
- changes: False
|
|
||||||
- result: False
|
|
||||||
- comment: "BPF Syntax Error - Discarding Specified BPF"
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
suribpf:
|
|
||||||
file.managed:
|
|
||||||
- name: /opt/so/conf/suricata/bpf
|
|
||||||
- user: 940
|
|
||||||
- group: 940
|
|
||||||
{% if BPF_STATUS %}
|
|
||||||
- contents: {{ SURICATABPF }}
|
|
||||||
{% else %}
|
|
||||||
- contents:
|
|
||||||
- ""
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
so-suricata-eve-clean:
|
so-suricata-eve-clean:
|
||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-suricata-eve-clean
|
- name: /usr/sbin/so-suricata-eve-clean
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ suricata:
|
|||||||
threads: 1
|
threads: 1
|
||||||
tpacket-v3: "yes"
|
tpacket-v3: "yes"
|
||||||
ring-size: 5000
|
ring-size: 5000
|
||||||
block-size: 32768
|
block-size: 69632
|
||||||
block-timeout: 10
|
block-timeout: 10
|
||||||
use-emergency-flush: "yes"
|
use-emergency-flush: "yes"
|
||||||
buffer-size: 32768
|
buffer-size: 32768
|
||||||
@@ -97,6 +97,11 @@ suricata:
|
|||||||
- 4789
|
- 4789
|
||||||
TEREDO_PORTS:
|
TEREDO_PORTS:
|
||||||
- 3544
|
- 3544
|
||||||
|
SIP_PORTS:
|
||||||
|
- 5060
|
||||||
|
- 5061
|
||||||
|
GENEVE_PORTS:
|
||||||
|
- 6081
|
||||||
default-log-dir: /var/log/suricata/
|
default-log-dir: /var/log/suricata/
|
||||||
stats:
|
stats:
|
||||||
enabled: "yes"
|
enabled: "yes"
|
||||||
@@ -134,14 +139,6 @@ suricata:
|
|||||||
header: X-Forwarded-For
|
header: X-Forwarded-For
|
||||||
unified2-alert:
|
unified2-alert:
|
||||||
enabled: "no"
|
enabled: "no"
|
||||||
http-log:
|
|
||||||
enabled: "no"
|
|
||||||
filename: http.log
|
|
||||||
append: "yes"
|
|
||||||
tls-log:
|
|
||||||
enabled: "no"
|
|
||||||
filename: tls.log
|
|
||||||
append: "yes"
|
|
||||||
tls-store:
|
tls-store:
|
||||||
enabled: "no"
|
enabled: "no"
|
||||||
pcap-log:
|
pcap-log:
|
||||||
@@ -157,9 +154,6 @@ suricata:
|
|||||||
totals: "yes"
|
totals: "yes"
|
||||||
threads: "no"
|
threads: "no"
|
||||||
null-values: "yes"
|
null-values: "yes"
|
||||||
syslog:
|
|
||||||
enabled: "no"
|
|
||||||
facility: local5
|
|
||||||
drop:
|
drop:
|
||||||
enabled: "no"
|
enabled: "no"
|
||||||
file-store:
|
file-store:
|
||||||
@@ -206,6 +200,9 @@ suricata:
|
|||||||
enabled: "yes"
|
enabled: "yes"
|
||||||
detection-ports:
|
detection-ports:
|
||||||
dp: 443
|
dp: 443
|
||||||
|
ja3-fingerprints: auto
|
||||||
|
ja4-fingerprints: auto
|
||||||
|
encryption-handling: track-only
|
||||||
dcerpc:
|
dcerpc:
|
||||||
enabled: "yes"
|
enabled: "yes"
|
||||||
ftp:
|
ftp:
|
||||||
@@ -255,19 +252,21 @@ suricata:
|
|||||||
libhtp:
|
libhtp:
|
||||||
default-config:
|
default-config:
|
||||||
personality: IDS
|
personality: IDS
|
||||||
request-body-limit: 100kb
|
request-body-limit: 100 KiB
|
||||||
response-body-limit: 100kb
|
response-body-limit: 100 KiB
|
||||||
request-body-minimal-inspect-size: 32kb
|
request-body-minimal-inspect-size: 32 KiB
|
||||||
request-body-inspect-window: 4kb
|
request-body-inspect-window: 4 KiB
|
||||||
response-body-minimal-inspect-size: 40kb
|
response-body-minimal-inspect-size: 40 KiB
|
||||||
response-body-inspect-window: 16kb
|
response-body-inspect-window: 16 KiB
|
||||||
response-body-decompress-layer-limit: 2
|
response-body-decompress-layer-limit: 2
|
||||||
http-body-inline: auto
|
http-body-inline: auto
|
||||||
swf-decompression:
|
swf-decompression:
|
||||||
enabled: "yes"
|
enabled: "no"
|
||||||
type: both
|
type: both
|
||||||
compress-depth: 0
|
compress-depth: 100 KiB
|
||||||
decompress-depth: 0
|
decompress-depth: 100 KiB
|
||||||
|
randomize-inspection-sizes: "yes"
|
||||||
|
randomize-inspection-range: 10
|
||||||
double-decode-path: "no"
|
double-decode-path: "no"
|
||||||
double-decode-query: "no"
|
double-decode-query: "no"
|
||||||
server-config:
|
server-config:
|
||||||
@@ -401,8 +400,12 @@ suricata:
|
|||||||
vxlan:
|
vxlan:
|
||||||
enabled: true
|
enabled: true
|
||||||
ports: $VXLAN_PORTS
|
ports: $VXLAN_PORTS
|
||||||
erspan:
|
geneve:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
ports: $GENEVE_PORTS
|
||||||
|
max-layers: 16
|
||||||
|
recursion-level:
|
||||||
|
use-for-tracking: true
|
||||||
detect:
|
detect:
|
||||||
profile: medium
|
profile: medium
|
||||||
custom-values:
|
custom-values:
|
||||||
@@ -422,7 +425,12 @@ suricata:
|
|||||||
spm-algo: auto
|
spm-algo: auto
|
||||||
luajit:
|
luajit:
|
||||||
states: 128
|
states: 128
|
||||||
|
security:
|
||||||
|
lua:
|
||||||
|
allow-rules: false
|
||||||
|
max-bytes: 500000
|
||||||
|
max-instructions: 500000
|
||||||
|
allow-restricted-functions: false
|
||||||
profiling:
|
profiling:
|
||||||
rules:
|
rules:
|
||||||
enabled: "yes"
|
enabled: "yes"
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
|
|
||||||
{# before we change outputs back to list, enable pcap-log if suricata is the pcapengine #}
|
{# before we change outputs back to list, enable pcap-log if suricata is the pcapengine #}
|
||||||
{% if GLOBALS.pcap_engine in ["SURICATA", "TRANSITION"] %}
|
{% if GLOBALS.pcap_engine in ["SURICATA", "TRANSITION"] %}
|
||||||
|
|
||||||
|
{% from 'bpf/pcap.map.jinja' import PCAPBPF, PCAP_BPF_STATUS %}
|
||||||
|
{% if PCAPBPF and PCAP_BPF_STATUS %}
|
||||||
|
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'bpf-filter': PCAPBPF|join(" ")}) %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'enabled': 'yes'}) %}
|
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'enabled': 'yes'}) %}
|
||||||
{# move the items in suricata.pcap into suricata.config.outputs.pcap-log. these items were placed under suricata.config for ease of access in SOC #}
|
{# move the items in suricata.pcap into suricata.config.outputs.pcap-log. these items were placed under suricata.config for ease of access in SOC #}
|
||||||
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'compression': SURICATAMERGED.pcap.compression}) %}
|
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'compression': SURICATAMERGED.pcap.compression}) %}
|
||||||
|
|||||||
@@ -190,6 +190,8 @@ suricata:
|
|||||||
FTP_PORTS: *suriportgroup
|
FTP_PORTS: *suriportgroup
|
||||||
VXLAN_PORTS: *suriportgroup
|
VXLAN_PORTS: *suriportgroup
|
||||||
TEREDO_PORTS: *suriportgroup
|
TEREDO_PORTS: *suriportgroup
|
||||||
|
SIP_PORTS: *suriportgroup
|
||||||
|
GENEVE_PORTS: *suriportgroup
|
||||||
outputs:
|
outputs:
|
||||||
eve-log:
|
eve-log:
|
||||||
types:
|
types:
|
||||||
@@ -209,7 +211,7 @@ suricata:
|
|||||||
helpLink: suricata.html
|
helpLink: suricata.html
|
||||||
pcap-log:
|
pcap-log:
|
||||||
enabled:
|
enabled:
|
||||||
description: This value is ignored by SO. pcapengine in globals takes precidence.
|
description: This value is ignored by SO. pcapengine in globals takes precedence.
|
||||||
readonly: True
|
readonly: True
|
||||||
helpLink: suricata.html
|
helpLink: suricata.html
|
||||||
advanced: True
|
advanced: True
|
||||||
@@ -297,3 +299,10 @@ suricata:
|
|||||||
ports:
|
ports:
|
||||||
description: Ports to listen for. This should be a variable.
|
description: Ports to listen for. This should be a variable.
|
||||||
helpLink: suricata.html
|
helpLink: suricata.html
|
||||||
|
geneve:
|
||||||
|
enabled:
|
||||||
|
description: Enable VXLAN capabilities.
|
||||||
|
helpLink: suricata.html
|
||||||
|
ports:
|
||||||
|
description: Ports to listen for. This should be a variable.
|
||||||
|
helpLink: suricata.html
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ suricata:
|
|||||||
#custom: [Accept-Encoding, Accept-Language, Authorization]
|
#custom: [Accept-Encoding, Accept-Language, Authorization]
|
||||||
# dump-all-headers: none
|
# dump-all-headers: none
|
||||||
- dns:
|
- dns:
|
||||||
version: 2
|
version: 3
|
||||||
enabled: "yes"
|
enabled: "yes"
|
||||||
#requests: "no"
|
#requests: "no"
|
||||||
#responses: "no"
|
#responses: "no"
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
|
|
||||||
. /usr/sbin/so-common
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
retry 60 3 'docker exec so-suricata /opt/suricata/bin/suricatasc -c reload-rules /var/run/suricata/suricata-command.socket' '{"message": "done", "return": "OK"}' || fail "The Suricata container was not ready in time."
|
retry 60 3 'docker exec so-suricata /opt/suricata/bin/suricatasc -c reload-rules /var/run/suricata/suricata-command.socket' '{"message":"done","return":"OK"}' || fail "The Suricata container was not ready in time."
|
||||||
retry 60 3 'docker exec so-suricata /opt/suricata/bin/suricatasc -c ruleset-reload-nonblocking /var/run/suricata/suricata-command.socket' '{"message": "done", "return": "OK"}' || fail "The Suricata container was not ready in time."
|
retry 60 3 'docker exec so-suricata /opt/suricata/bin/suricatasc -c ruleset-reload-nonblocking /var/run/suricata/suricata-command.socket' '{"message":"done","return":"OK"}' || fail "The Suricata container was not ready in time."
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from "zeek/config.map.jinja" import ZEEKMERGED %}
|
{% from "zeek/config.map.jinja" import ZEEKMERGED %}
|
||||||
{% from 'bpf/zeek.map.jinja' import ZEEKBPF %}
|
{% from 'bpf/zeek.map.jinja' import ZEEKBPF, ZEEK_BPF_STATUS, ZEEK_BPF_CALC %}
|
||||||
{% set BPF_STATUS = 0 %}
|
|
||||||
|
|
||||||
# Add Zeek group
|
# Add Zeek group
|
||||||
zeekgroup:
|
zeekgroup:
|
||||||
@@ -158,18 +157,13 @@ zeekja4cfg:
|
|||||||
- user: 937
|
- user: 937
|
||||||
- group: 939
|
- group: 939
|
||||||
|
|
||||||
# BPF compilation and configuration
|
# BPF compilation failed
|
||||||
{% if ZEEKBPF %}
|
{% if ZEEKBPF and not ZEEK_BPF_STATUS %}
|
||||||
{% set BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + ZEEKBPF|join(" "),cwd='/root') %}
|
|
||||||
{% if BPF_CALC['stderr'] == "" %}
|
|
||||||
{% set BPF_STATUS = 1 %}
|
|
||||||
{% else %}
|
|
||||||
zeekbpfcompilationfailure:
|
zeekbpfcompilationfailure:
|
||||||
test.configurable_test_state:
|
test.configurable_test_state:
|
||||||
- changes: False
|
- changes: False
|
||||||
- result: False
|
- result: False
|
||||||
- comment: "BPF Syntax Error - Discarding Specified BPF"
|
- comment: "BPF Syntax Error - Discarding Specified BPF. Error: {{ ZEEK_BPF_CALC['stderr'] }}"
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
zeekbpf:
|
zeekbpf:
|
||||||
@@ -177,7 +171,7 @@ zeekbpf:
|
|||||||
- name: /opt/so/conf/zeek/bpf
|
- name: /opt/so/conf/zeek/bpf
|
||||||
- user: 940
|
- user: 940
|
||||||
- group: 940
|
- group: 940
|
||||||
{% if BPF_STATUS %}
|
{% if ZEEK_BPF_STATUS %}
|
||||||
- contents: {{ ZEEKBPF }}
|
- contents: {{ ZEEKBPF }}
|
||||||
{% else %}
|
{% else %}
|
||||||
- contents:
|
- contents:
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ zeek:
|
|||||||
- protocols/ssh/geo-data
|
- protocols/ssh/geo-data
|
||||||
- protocols/ssh/detect-bruteforcing
|
- protocols/ssh/detect-bruteforcing
|
||||||
- protocols/ssh/interesting-hostnames
|
- protocols/ssh/interesting-hostnames
|
||||||
- protocols/http/detect-sqli
|
- protocols/http/detect-sql-injection
|
||||||
- frameworks/files/hash-all-files
|
- frameworks/files/hash-all-files
|
||||||
- frameworks/files/detect-MHR
|
- frameworks/files/detect-MHR
|
||||||
- policy/frameworks/notice/extend-email/hostnames
|
- policy/frameworks/notice/extend-email/hostnames
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export {
|
|||||||
option JA4S_enabled: bool = F;
|
option JA4S_enabled: bool = F;
|
||||||
option JA4S_raw: bool = F;
|
option JA4S_raw: bool = F;
|
||||||
|
|
||||||
|
option JA4D_enabled: bool = F;
|
||||||
|
|
||||||
option JA4H_enabled: bool = F;
|
option JA4H_enabled: bool = F;
|
||||||
option JA4H_raw: bool = F;
|
option JA4H_raw: bool = F;
|
||||||
|
|
||||||
|
|||||||
@@ -502,6 +502,7 @@ configure_minion() {
|
|||||||
minion_type=desktop
|
minion_type=desktop
|
||||||
fi
|
fi
|
||||||
info "Configuring minion type as $minion_type"
|
info "Configuring minion type as $minion_type"
|
||||||
|
logCmd "mkdir -p /etc/salt/minion.d"
|
||||||
echo "role: so-$minion_type" > /etc/salt/grains
|
echo "role: so-$minion_type" > /etc/salt/grains
|
||||||
|
|
||||||
local minion_config=/etc/salt/minion
|
local minion_config=/etc/salt/minion
|
||||||
@@ -541,20 +542,6 @@ configure_minion() {
|
|||||||
"log_file: /opt/so/log/salt/minion"\
|
"log_file: /opt/so/log/salt/minion"\
|
||||||
"#startup_states: highstate" >> "$minion_config"
|
"#startup_states: highstate" >> "$minion_config"
|
||||||
|
|
||||||
# At the time the so-managerhype node does not yet have the bridge configured.
|
|
||||||
# The so-hypervisor node doesn't either, but it doesn't cause issues here.
|
|
||||||
local usebr0=false
|
|
||||||
if [ "$minion_type" == 'hypervisor' ]; then
|
|
||||||
usebr0=true
|
|
||||||
fi
|
|
||||||
local pillar_json="{\"host\": {\"mainint\": \"$MNIC\"}, \"usebr0\": $usebr0}"
|
|
||||||
info "Running: salt-call state.apply salt.mine_functions --local --file-root=../salt/ -l info pillar='$pillar_json'"
|
|
||||||
salt-call state.apply salt.mine_functions --local --file-root=../salt/ -l info pillar="$pillar_json"
|
|
||||||
|
|
||||||
{
|
|
||||||
logCmd "systemctl enable salt-minion";
|
|
||||||
logCmd "systemctl restart salt-minion";
|
|
||||||
} >> "$setup_log" 2>&1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkin_at_boot() {
|
checkin_at_boot() {
|
||||||
@@ -729,7 +716,7 @@ configure_network_sensor() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Create the bond interface only if it doesn't already exist
|
# Create the bond interface only if it doesn't already exist
|
||||||
nmcli -f name,uuid -p con | grep -q '$INTERFACE'
|
nmcli -f name,uuid -p con | grep -q "$INTERFACE"
|
||||||
local found_int=$?
|
local found_int=$?
|
||||||
|
|
||||||
if [[ $found_int != 0 ]]; then
|
if [[ $found_int != 0 ]]; then
|
||||||
@@ -798,25 +785,18 @@ configure_hyper_bridge() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
copy_salt_master_config() {
|
copy_salt_master_config() {
|
||||||
|
logCmd "mkdir /etc/salt"
|
||||||
title "Copy the Salt master config template to the proper directory"
|
title "Copy the Salt master config template to the proper directory"
|
||||||
if [ "$setup_type" = 'iso' ]; then
|
if [ "$setup_type" = 'iso' ]; then
|
||||||
logCmd "cp /root/SecurityOnion/files/salt/master/master /etc/salt/master"
|
logCmd "cp /root/SecurityOnion/files/salt/master/master /etc/salt/master"
|
||||||
#logCmd "cp /root/SecurityOnion/files/salt/master/salt-master.service /usr/lib/systemd/system/salt-master.service"
|
|
||||||
else
|
else
|
||||||
logCmd "cp ../files/salt/master/master /etc/salt/master"
|
logCmd "cp ../files/salt/master/master /etc/salt/master"
|
||||||
#logCmd "cp ../files/salt/master/salt-master.service /usr/lib/systemd/system/salt-master.service"
|
|
||||||
fi
|
fi
|
||||||
info "Copying pillar and salt files in $temp_install_dir to $local_salt_dir"
|
info "Copying pillar and salt files in $temp_install_dir to $local_salt_dir"
|
||||||
logCmd "cp -R $temp_install_dir/pillar/ $local_salt_dir/"
|
logCmd "cp -R $temp_install_dir/pillar/ $local_salt_dir/"
|
||||||
if [ -d "$temp_install_dir"/salt ] ; then
|
if [ -d "$temp_install_dir"/salt ] ; then
|
||||||
logCmd "cp -R $temp_install_dir/salt/ $local_salt_dir/"
|
logCmd "cp -R $temp_install_dir/salt/ $local_salt_dir/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Restart the service so it picks up the changes
|
|
||||||
logCmd "systemctl daemon-reload"
|
|
||||||
logCmd "systemctl enable salt-master"
|
|
||||||
logCmd "systemctl restart salt-master"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_local_nids_rules() {
|
create_local_nids_rules() {
|
||||||
@@ -1941,11 +1921,12 @@ repo_sync_local() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
saltify() {
|
saltify() {
|
||||||
info "Installing Salt"
|
|
||||||
SALTVERSION=$(grep "version:" ../salt/salt/master.defaults.yaml | grep -o "[0-9]\+\.[0-9]\+")
|
SALTVERSION=$(grep "version:" ../salt/salt/master.defaults.yaml | grep -o "[0-9]\+\.[0-9]\+")
|
||||||
|
info "Installing Salt $SALTVERSION"
|
||||||
|
chmod u+x ../salt/salt/scripts/bootstrap-salt.sh
|
||||||
if [[ $is_deb ]]; then
|
if [[ $is_deb ]]; then
|
||||||
|
|
||||||
DEBIAN_FRONTEND=noninteractive retry 150 20 "apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" upgrade" >> "$setup_log" 2>&1 || fail_setup
|
DEBIAN_FRONTEND=noninteractive retry 30 10 "apt-get -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" upgrade" >> "$setup_log" 2>&1 || fail_setup
|
||||||
if [ $OSVER == "focal" ]; then update-alternatives --install /usr/bin/python python /usr/bin/python3.10 10; fi
|
if [ $OSVER == "focal" ]; then update-alternatives --install /usr/bin/python python /usr/bin/python3.10 10; fi
|
||||||
local pkg_arr=(
|
local pkg_arr=(
|
||||||
'apache2-utils'
|
'apache2-utils'
|
||||||
@@ -1958,16 +1939,11 @@ saltify() {
|
|||||||
'jq'
|
'jq'
|
||||||
'gnupg'
|
'gnupg'
|
||||||
)
|
)
|
||||||
retry 150 20 "apt-get -y install ${pkg_arr[*]}" || fail_setup
|
retry 30 10 "apt-get -y install ${pkg_arr[*]}" || fail_setup
|
||||||
|
|
||||||
logCmd "mkdir -vp /etc/apt/keyrings"
|
logCmd "mkdir -vp /etc/apt/keyrings"
|
||||||
logCmd "wget -q --inet4-only -O /etc/apt/keyrings/docker.pub https://download.docker.com/linux/ubuntu/gpg"
|
logCmd "wget -q --inet4-only -O /etc/apt/keyrings/docker.pub https://download.docker.com/linux/ubuntu/gpg"
|
||||||
|
|
||||||
# Download public key
|
|
||||||
logCmd "curl -fsSL -o /etc/apt/keyrings/salt-archive-keyring-2023.pgp https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public"
|
|
||||||
# Create apt repo target configuration
|
|
||||||
echo "deb [signed-by=/etc/apt/keyrings/salt-archive-keyring-2023.pgp arch=amd64] https://packages.broadcom.com/artifactory/saltproject-deb/ stable main" | sudo tee /etc/apt/sources.list.d/salt.list
|
|
||||||
|
|
||||||
if [[ $is_ubuntu ]]; then
|
if [[ $is_ubuntu ]]; then
|
||||||
# Add Docker Repo
|
# Add Docker Repo
|
||||||
add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
||||||
@@ -1978,45 +1954,50 @@ saltify() {
|
|||||||
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $OSVER stable" > /etc/apt/sources.list.d/docker.list
|
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $OSVER stable" > /etc/apt/sources.list.d/docker.list
|
||||||
fi
|
fi
|
||||||
|
|
||||||
logCmd "apt-key add /etc/apt/keyrings/salt-archive-keyring-2023.pgp"
|
|
||||||
|
|
||||||
#logCmd "apt-key add /opt/so/gpg/SALTSTACK-GPG-KEY.pub"
|
|
||||||
logCmd "apt-key add /etc/apt/keyrings/docker.pub"
|
logCmd "apt-key add /etc/apt/keyrings/docker.pub"
|
||||||
|
|
||||||
# Add SO Saltstack Repo
|
retry 30 10 "apt-get update" "" "Err:" || fail_setup
|
||||||
#echo "deb https://repo.securityonion.net/file/securityonion-repo/ubuntu/20.04/amd64/salt3004.2/ focal main" > /etc/apt/sources.list.d/saltstack.list
|
|
||||||
|
|
||||||
# Ain't nothing but a GPG
|
|
||||||
|
|
||||||
retry 150 20 "apt-get update" "" "Err:" || fail_setup
|
|
||||||
if [[ $waitforstate ]]; then
|
if [[ $waitforstate ]]; then
|
||||||
retry 150 20 "apt-get -y install salt-common=$SALTVERSION salt-minion=$SALTVERSION salt-master=$SALTVERSION" || fail_setup
|
retry 30 10 "bash ../salt/salt/scripts/bootstrap-salt.sh -M -X stable $SALTVERSION" || fail_setup
|
||||||
retry 150 20 "apt-mark hold salt-minion salt-common salt-master" || fail_setup
|
retry 30 10 "apt-mark hold salt-minion salt-common salt-master" || fail_setup
|
||||||
retry 150 20 "apt-get -y install python3-pip python3-dateutil python3-m2crypto python3-packaging python3-influxdb python3-lxml" || exit 1
|
retry 30 10 "apt-get -y install python3-pip python3-dateutil python3-m2crypto python3-packaging python3-influxdb python3-lxml" || exit 1
|
||||||
else
|
else
|
||||||
retry 150 20 "apt-get -y install salt-common=$SALTVERSION salt-minion=$SALTVERSION" || fail_setup
|
retry 30 10 "bash ../salt/salt/scripts/bootstrap-salt.sh -X stable $SALTVERSION" || fail_setup
|
||||||
retry 150 20 "apt-mark hold salt-minion salt-common" || fail_setup
|
retry 30 10 "apt-mark hold salt-minion salt-common" || fail_setup
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $is_rpm ]]; then
|
if [[ $is_rpm ]]; then
|
||||||
if [[ $waitforstate ]]; then
|
if [[ $waitforstate ]]; then
|
||||||
# install all for a manager
|
# install all for a manager
|
||||||
logCmd "dnf -y install salt-$SALTVERSION salt-master-$SALTVERSION salt-minion-$SALTVERSION"
|
retry 30 10 "bash ../salt/salt/scripts/bootstrap-salt.sh -r -M -X stable $SALTVERSION" || fail_setup
|
||||||
else
|
else
|
||||||
# We just need the minion
|
# just a minion
|
||||||
if [[ $is_airgap ]]; then
|
retry 30 10 "bash ../salt/salt/scripts/bootstrap-salt.sh -r -X stable $SALTVERSION" || fail_setup
|
||||||
logCmd "dnf -y install salt salt-minion"
|
|
||||||
else
|
|
||||||
logCmd "dnf -y install salt-$SALTVERSION salt-minion-$SALTVERSION"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
logCmd "mkdir -p /etc/salt/minion.d"
|
|
||||||
salt_install_module_deps
|
salt_install_module_deps
|
||||||
salt_patch_x509_v2
|
salt_patch_x509_v2
|
||||||
|
|
||||||
|
# At the time the so-managerhype node does not yet have the bridge configured.
|
||||||
|
# The so-hypervisor node doesn't either, but it doesn't cause issues here.
|
||||||
|
local usebr0=false
|
||||||
|
if [ "$minion_type" == 'hypervisor' ]; then
|
||||||
|
usebr0=true
|
||||||
|
fi
|
||||||
|
local pillar_json="{\"host\": {\"mainint\": \"$MNIC\"}, \"usebr0\": $usebr0}"
|
||||||
|
info "Running: salt-call state.apply salt.mine_functions --local --file-root=../salt/ -l info pillar='$pillar_json'"
|
||||||
|
salt-call state.apply salt.mine_functions --local --file-root=../salt/ -l info pillar="$pillar_json"
|
||||||
|
|
||||||
|
if [[ $waitforstate ]]; then
|
||||||
|
logCmd "systemctl enable salt-master";
|
||||||
|
logCmd "systemctl start salt-master";
|
||||||
|
fi
|
||||||
|
|
||||||
|
logCmd "systemctl enable salt-minion";
|
||||||
|
logCmd "systemctl restart salt-minion";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
salt_install_module_deps() {
|
salt_install_module_deps() {
|
||||||
|
|||||||
@@ -745,13 +745,12 @@ if ! [[ -f $install_opt_file ]]; then
|
|||||||
securityonion_repo
|
securityonion_repo
|
||||||
# Update existing packages
|
# Update existing packages
|
||||||
update_packages
|
update_packages
|
||||||
# Install salt
|
# Put salt-master config in place
|
||||||
saltify
|
|
||||||
# Start the master service
|
|
||||||
copy_salt_master_config
|
copy_salt_master_config
|
||||||
configure_minion "$minion_type"
|
configure_minion "$minion_type"
|
||||||
|
# Install salt
|
||||||
|
saltify
|
||||||
check_sos_appliance
|
check_sos_appliance
|
||||||
|
|
||||||
logCmd "salt-key -yd $MINION_ID"
|
logCmd "salt-key -yd $MINION_ID"
|
||||||
sleep 2 # Debug RSA Key format errors
|
sleep 2 # Debug RSA Key format errors
|
||||||
logCmd "salt-call state.show_top"
|
logCmd "salt-call state.show_top"
|
||||||
@@ -852,8 +851,8 @@ if ! [[ -f $install_opt_file ]]; then
|
|||||||
gpg_rpm_import
|
gpg_rpm_import
|
||||||
securityonion_repo
|
securityonion_repo
|
||||||
update_packages
|
update_packages
|
||||||
saltify
|
|
||||||
configure_minion "$minion_type"
|
configure_minion "$minion_type"
|
||||||
|
saltify
|
||||||
check_sos_appliance
|
check_sos_appliance
|
||||||
drop_install_options
|
drop_install_options
|
||||||
hypervisor_local_states
|
hypervisor_local_states
|
||||||
|
|||||||
@@ -676,8 +676,8 @@ whiptail_install_type_dist_existing() {
|
|||||||
EOM
|
EOM
|
||||||
|
|
||||||
install_type=$(whiptail --title "$whiptail_title" --menu "$node_msg" 19 75 7 \
|
install_type=$(whiptail --title "$whiptail_title" --menu "$node_msg" 19 75 7 \
|
||||||
"SENSOR" "Create a forward only sensor " \
|
"SENSOR" "Add a Sensor Node for monitoring network traffic " \
|
||||||
"SEARCHNODE" "Add a search node with parsing " \
|
"SEARCHNODE" "Add a Search Node with parsing " \
|
||||||
"FLEET" "Dedicated Elastic Fleet Node " \
|
"FLEET" "Dedicated Elastic Fleet Node " \
|
||||||
"HEAVYNODE" "Sensor + Search Node " \
|
"HEAVYNODE" "Sensor + Search Node " \
|
||||||
"IDH" "Intrusion Detection Honeypot Node " \
|
"IDH" "Intrusion Detection Honeypot Node " \
|
||||||
|
|||||||
Reference in New Issue
Block a user