mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2026-02-21 06:25:27 +01:00
Merge pull request #15491 from Security-Onion-Solutions/bravo
Upgrade Salt 3006.19
This commit is contained in:
@@ -995,7 +995,9 @@ up_to_2.4.210() {
|
||||
# Elastic Update for this release, so download Elastic Agent files
|
||||
determine_elastic_agent_upgrade
|
||||
create_ca_pillar
|
||||
|
||||
# This state is used to deal with the breaking change introduced in 3006.17 - https://docs.saltproject.io/en/3006/topics/releases/3006.17.html
|
||||
# This is the only way the state is called so we can use concurrent=True
|
||||
salt-call state.apply salt.master.add_minimum_auth_version --file-root=$UPDATE_DIR/salt --local concurrent=True
|
||||
INSTALLEDVERSION=2.4.210
|
||||
}
|
||||
|
||||
|
||||
73
salt/salt/engines/master/minimum_auth_version.py
Normal file
73
salt/salt/engines/master/minimum_auth_version.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
import salt.client
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
TIMESTAMP_FILE = '/opt/so/state/mav_engine_start_time'
|
||||
|
||||
def _get_start_time():
|
||||
"""Read persisted start time from file, or create one if it doesn't exist."""
|
||||
if os.path.exists(TIMESTAMP_FILE):
|
||||
with open(TIMESTAMP_FILE, 'r') as f:
|
||||
timestamp = f.read().strip()
|
||||
start_time = datetime.fromisoformat(timestamp)
|
||||
log.info("Loaded existing start time from %s: %s", TIMESTAMP_FILE, start_time)
|
||||
return start_time
|
||||
|
||||
start_time = datetime.now()
|
||||
with open(TIMESTAMP_FILE, 'w') as f:
|
||||
f.write(start_time.isoformat())
|
||||
log.info("No existing start time found. Persisted new start time: %s", start_time)
|
||||
return start_time
|
||||
|
||||
|
||||
def _clear_start_time():
|
||||
"""Remove the persisted timestamp file after successful completion."""
|
||||
if os.path.exists(TIMESTAMP_FILE):
|
||||
os.remove(TIMESTAMP_FILE)
|
||||
log.info("Removed timestamp file %s", TIMESTAMP_FILE)
|
||||
|
||||
|
||||
def start(wait_days=7):
|
||||
"""
|
||||
This engine waits for the specified number of days, then changes minimum_auth_version.
|
||||
|
||||
Args:
|
||||
wait_days: Days to wait before taking action (default: 7)
|
||||
"""
|
||||
log.info(
|
||||
"Starting minimum_auth_version engine - Wait time: %d days",
|
||||
wait_days
|
||||
)
|
||||
|
||||
start_time = _get_start_time()
|
||||
wait_delta = timedelta(days=wait_days)
|
||||
mav_removed = False
|
||||
caller = salt.client.Caller()
|
||||
|
||||
while True:
|
||||
if not mav_removed:
|
||||
elapsed = datetime.now() - start_time
|
||||
|
||||
if elapsed >= wait_delta:
|
||||
log.info("Changing minimum_auth_version")
|
||||
_clear_start_time()
|
||||
result = caller.cmd('state.apply', 'salt.master.remove_minimum_auth_version', queue=True)
|
||||
# We shouldn't reach this line since the above line should remove the engine and restart salt-master
|
||||
log.info("State apply result: %s", result)
|
||||
mav_removed = True
|
||||
else:
|
||||
target_time = start_time + wait_delta
|
||||
log.info("minimum_auth_version will be changed within an hour of %s", target_time.strftime('%m-%d-%Y %H:%M'))
|
||||
|
||||
time.sleep(3600) # Check hourly
|
||||
@@ -1,4 +1,4 @@
|
||||
# version cannot be used elsewhere in this pillar as soup is grepping for it to determine if Salt needs to be patched
|
||||
salt:
|
||||
master:
|
||||
version: '3006.16'
|
||||
version: '3006.19'
|
||||
|
||||
23
salt/salt/master/add_minimum_auth_version.sls
Normal file
23
salt/salt/master/add_minimum_auth_version.sls
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
|
||||
# This state is to be used during soup preupgrade_changes, and run when the salt-master has been stopped. Soup will later start the salt-master.
|
||||
# This state is used to deal with the breaking change introduced in 3006.17 - https://docs.saltproject.io/en/3006/topics/releases/3006.17.html
|
||||
|
||||
|
||||
set_minimum_auth_version_0:
|
||||
file.managed:
|
||||
- name: /etc/salt/master.d/minimum_auth_version.conf
|
||||
- source: salt://salt/master/files/minimum_auth_version.conf
|
||||
|
||||
add_minimum_auth_version_engine_config:
|
||||
file.managed:
|
||||
- name: /etc/salt/master.d/minimum_auth_version_engine.conf
|
||||
- source: salt://salt/master/files/minimum_auth_version_engine.conf
|
||||
|
||||
add_minimum_auth_version_engine:
|
||||
file.managed:
|
||||
- name: /etc/salt/engines/minimum_auth_version.py
|
||||
- source: salt://salt/engines/master/minimum_auth_version.py
|
||||
1
salt/salt/master/files/minimum_auth_version.conf
Normal file
1
salt/salt/master/files/minimum_auth_version.conf
Normal file
@@ -0,0 +1 @@
|
||||
minimum_auth_version: 0
|
||||
3
salt/salt/master/files/minimum_auth_version_engine.conf
Normal file
3
salt/salt/master/files/minimum_auth_version_engine.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
engines:
|
||||
- minimum_auth_version:
|
||||
wait_days: 7
|
||||
21
salt/salt/master/remove_minimum_auth_version.sls
Normal file
21
salt/salt/master/remove_minimum_auth_version.sls
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
|
||||
include:
|
||||
- salt.master
|
||||
|
||||
unset_minimum_auth_version_0:
|
||||
file.absent:
|
||||
- name: /etc/salt/master.d/minimum_auth_version.conf
|
||||
|
||||
remove_minimum_auth_version_engine_config:
|
||||
file.absent:
|
||||
- name: /etc/salt/master.d/minimum_auth_version_engine.conf
|
||||
|
||||
remove_minimum_auth_version_engine:
|
||||
file.absent:
|
||||
- name: /etc/salt/engines/minimum_auth_version.py
|
||||
- watch_in:
|
||||
- service: salt_master_service
|
||||
@@ -1,5 +1,5 @@
|
||||
# version cannot be used elsewhere in this pillar as soup is grepping for it to determine if Salt needs to be patched
|
||||
salt:
|
||||
minion:
|
||||
version: '3006.16'
|
||||
version: '3006.19'
|
||||
check_threshold: 3600 # in seconds, threshold used for so-salt-minion-check. any value less than 600 seconds may cause a lot of salt-minion restarts since the job to touch the file occurs every 5-8 minutes by default
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#======================================================================================================================
|
||||
set -o nounset # Treat unset variables as an error
|
||||
|
||||
__ScriptVersion="2025.09.03"
|
||||
__ScriptVersion="2026.01.22"
|
||||
__ScriptName="bootstrap-salt.sh"
|
||||
|
||||
__ScriptFullName="$0"
|
||||
@@ -369,7 +369,7 @@ __usage() {
|
||||
also be specified. Salt installation will be ommitted, but some of the
|
||||
dependencies could be installed to write configuration with -j or -J.
|
||||
-d Disables checking if Salt services are enabled to start on system boot.
|
||||
You can also do this by touching ${BS_TMP_DIR}/disable_salt_checks on the target
|
||||
You can also do this by touching ${_TMP_DIR}/disable_salt_checks on the target
|
||||
host. Default: \${BS_FALSE}
|
||||
-D Show debug output
|
||||
-f Force shallow cloning for git installations.
|
||||
@@ -2819,14 +2819,25 @@ __install_salt_from_repo() {
|
||||
${_pip_cmd} install --force-reinstall --break-system-packages "${_arch_dep}"
|
||||
fi
|
||||
|
||||
echodebug "Running '${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall ${_PIP_INSTALL_ARGS} ${_TMP_DIR}/git/deps/salt*.whl'"
|
||||
_PIP_VERSION_STRING=$(${_pip_cmd} --version)
|
||||
echodebug "Installed pip version: $_PIP_VERSION_STRING"
|
||||
_PIP_MAJOR_VERSION=$(echo "$_PIP_VERSION_STRING" | sed -E 's/^pip ([0-9]+)\..*/\1/')
|
||||
|
||||
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_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 || return 1
|
||||
# The following branching can be removed once we no longer support distros that still ship with
|
||||
# versions of `pip` earlier than v22.1 such as Debian 11
|
||||
if [ "$_PIP_MAJOR_VERSION" -lt 23 ]; then
|
||||
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_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 || return 1
|
||||
else
|
||||
echodebug "Running ${_pip_cmd} install ${_USE_BREAK_SYSTEM_PACKAGES} --no-deps --force-reinstall ${_PIP_INSTALL_ARGS} --config-settings=--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_INSTALL_ARGS} \
|
||||
--config-settings="--global-option=--salt-config-dir=$_SALT_ETC_DIR --salt-cache-dir=${_SALT_CACHE_DIR} ${SETUP_PY_INSTALL_ARGS}" \
|
||||
${_TMP_DIR}/git/deps/salt*.whl || return 1
|
||||
fi
|
||||
|
||||
echoinfo "Checking if Salt can be imported using ${_py_exe}"
|
||||
CHECK_SALT_SCRIPT=$(cat << EOM
|
||||
@@ -6096,7 +6107,14 @@ install_arch_linux_git_deps() {
|
||||
}
|
||||
|
||||
install_arch_linux_onedir_deps() {
|
||||
echodebug "install_arch_linux_onedir_deps() entry"
|
||||
|
||||
# Basic tooling for download/verify/extract
|
||||
pacman -Sy --noconfirm --needed wget tar gzip gnupg ca-certificates || return 1
|
||||
|
||||
# Reuse stable deps for python-yaml etc. if you want config_salt() parity
|
||||
install_arch_linux_stable_deps || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
install_arch_linux_stable() {
|
||||
@@ -6111,7 +6129,73 @@ install_arch_linux_stable() {
|
||||
pacman -S --noconfirm --needed bash || return 1
|
||||
pacman -Su --noconfirm || return 1
|
||||
# We can now resume regular salt update
|
||||
pacman -Syu --noconfirm salt || return 1
|
||||
# Except that this hasn't been in arch repos for years;
|
||||
# so we have to build from AUR
|
||||
# We use "buildgirl" because Eve demanded it.
|
||||
build_user=${build_user:-buildgirl}
|
||||
userdel "$build_user" || true
|
||||
useradd -M -r -s /usr/bin/nologin "$build_user"
|
||||
echo "$build_user ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/"$build_user"
|
||||
rm -rf /tmp/yay-bin || true
|
||||
|
||||
git clone https://aur.archlinux.org/salt.git /tmp/yay-bin
|
||||
chown -R "$build_user":"$build_user" /tmp/yay-bin
|
||||
sudo -u "$build_user" env -i \
|
||||
HOME=/tmp \
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin \
|
||||
MAKEFLAGS="-j$(nproc)" \
|
||||
LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \
|
||||
makepkg -CcsiD /tmp/yay-bin \
|
||||
--noconfirm --needed \
|
||||
--noprogressbar || return 1
|
||||
|
||||
rm -f /etc/sudoers.d/"$build_user"
|
||||
rm -rf /tmp/yay-bin
|
||||
userdel "$build_user"
|
||||
return 0
|
||||
}
|
||||
|
||||
install_arch_linux_onedir() {
|
||||
echodebug "install_arch_linux_onedir() entry"
|
||||
|
||||
version="${ONEDIR_REV:-latest}"
|
||||
arch="x86_64"
|
||||
[ "$(uname -m)" = "aarch64" ] && arch="aarch64"
|
||||
|
||||
# Resolve "latest" to actual version
|
||||
if [ "$version" = "latest" ]; then
|
||||
version=$(wget -qO- https://api.github.com/repos/saltstack/salt/releases/latest \
|
||||
| grep -Eo '"tag_name": *"v[0-9.]+"' \
|
||||
| sed 's/"tag_name": *"v//;s/"//') || return 1
|
||||
fi
|
||||
|
||||
tarball="salt-${version}-onedir-linux-${arch}.tar.xz"
|
||||
url="https://github.com/saltstack/salt/releases/download/v${version}/${tarball}"
|
||||
extractdir="/tmp/salt-${version}-onedir-linux-${arch}"
|
||||
|
||||
echoinfo "Downloading Salt onedir: $url"
|
||||
wget -q "$url" -O "/tmp/${tarball}" || return 1
|
||||
|
||||
# Validate tarball
|
||||
if ! tar -tf "/tmp/${tarball}" >/dev/null 2>&1; then
|
||||
echoerror "Invalid or corrupt onedir tarball"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Prepare extraction
|
||||
rm -rf "$extractdir" || true
|
||||
rm -rf /opt/saltstack/salt || true
|
||||
mkdir -p "$extractdir"
|
||||
|
||||
# Extract and flatten (remove leading 'salt/' directory)
|
||||
# /tmp/salt-${version}-onedir-linux-${arch}
|
||||
tar --strip-components=1 -xf "/tmp/${tarball}" -C "$extractdir"
|
||||
|
||||
# Place into /opt
|
||||
mkdir -p /opt/saltstack/salt
|
||||
mv "$extractdir"/* /opt/saltstack/salt/ || return 1
|
||||
chmod -R 755 /opt/saltstack/salt
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -6249,17 +6333,48 @@ install_arch_check_services() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install_arch_linux_onedir() {
|
||||
install_arch_linux_stable || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
install_arch_linux_onedir_post() {
|
||||
install_arch_linux_post || return 1
|
||||
echodebug "install_arch_linux_onedir_post() entry"
|
||||
|
||||
return 0
|
||||
# Disable any distro/AUR salt units
|
||||
systemctl disable --now salt-minion.service 2>/dev/null || true
|
||||
systemctl disable --now salt-master.service 2>/dev/null || true
|
||||
|
||||
# Drop a clean unit, same pattern as Debian/Ubuntu onedir
|
||||
cat >/etc/systemd/system/salt-minion.service <<'EOF'
|
||||
[Unit]
|
||||
Description=Salt Minion (onedir)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/saltstack/salt/salt-minion -c /etc/salt
|
||||
Restart=always
|
||||
LimitNOFILE=100000
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
# Add onedir paths system-wide
|
||||
cat >/etc/profile.d/saltstack.sh <<'EOF'
|
||||
export PATH=/opt/saltstack/salt:/opt/saltstack/salt/bin:$PATH
|
||||
EOF
|
||||
|
||||
chmod 644 /etc/profile.d/saltstack.sh
|
||||
|
||||
if [ "$_START_DAEMONS" -eq $BS_TRUE ]; then
|
||||
systemctl enable --now salt-minion.service
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# Ended Arch Install Functions
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user