Commit Graph
18634 Commits
Author SHA1 Message Date
Josh Patterson e42f7cd6fc add restart policy to so-postgres 2026-07-14 13:33:57 -04:00
Jorge Reyes 8167ae3282 Merge pull request #16062 from Security-Onion-Solutions/reyesj2/es937
ES 9.3.7
2026-07-13 14:35:35 -05:00
reyesj2 2cd889782d soup es check for 9.3.7 2026-07-13 13:16:12 -05:00
reyesj2 87a5639643 pipeline updates 2026-07-13 13:05:25 -05:00
Josh Patterson ed533efb7b so-salt-minion-check: tag and clarify log lines per check
With two independent checks now writing to the same log, messages like
"system uptime only N seconds does not meet 1800 second requirement" were
ambiguous about which check they came from. Prefix every line with a
[minion-restart-check] or [boot-highstate-check] tag and reword the uptime,
threshold, and healthy messages to say what was evaluated and why it was
skipped.

Restructure the boot-highstate check from a nested if into an if/elif chain so
each outcome (restart already queued, uptime too low, healthy, already running,
forcing) logs its own reason instead of silently doing nothing.
2026-07-10 15:53:49 -04:00
Josh Patterson 5af6c56996 so-salt-minion-check: force highstate if none has completed since boot
Add a second, independent trigger to the every-5-minute health check: if the
host has been up >= 15 minutes (HIGHSTATE_UPTIME_REQ) and no highstate has
completed since this boot (lasthighstate mtime older than boot time), run
salt-call state.highstate. This recovers a host whose boot highstate
(so-boot-highstate.service) failed or was skipped, even while the minion is
otherwise healthy and touching state-apply-test.

The new path deliberately does not enable highstate, so a soup-disabled
highstate is respected and never forced mid-upgrade. A saltutil.running guard
plus queue=True prevents stacking across successive cron runs, and a RESTARTED
flag suppresses the new block when the existing minion-restart path already
queued a highstate.
2026-07-10 14:54:20 -04:00
reyesj2 99e9fc1c3b ES 9.3.7 2026-07-10 13:50:55 -05:00
Jorge Reyes e5de499bcc Merge pull request #16059 from Security-Onion-Solutions/reyesj2-patch-4 2026-07-10 13:02:18 -05:00
reyesj2 7d17784e96 status messages for so-elastic-fleet-setup 2026-07-10 12:50:21 -05:00
Jason Ertel f0bbbf37d8 Merge pull request #16058 from Security-Onion-Solutions/jertel/wip
toggle pg metrics
2026-07-10 10:48:07 -04:00
Jason Ertel 6fc0fd954c clarify output annotation 2026-07-10 10:35:37 -04:00
Jason Ertel 566f90a0c0 toggle pg metrics 2026-07-10 10:32:25 -04:00
Josh Patterson 89e6a746c8 so-salt-minion-wait: wait for the restart job before reading MainPID
Live testing on a standalone node found the previous commit still reported
ready on the OUTGOING daemon. Reproduced by running the production sequence:

  systemctl restart --no-block salt-minion   # what service.restart issues
  /usr/sbin/so-salt-minion-wait              # what cmd.run then runs

  so-salt-minion-wait: gating on pid-tagged ready line ... plus master sockets
  salt-minion (pid 2750297) ready after 3s   # 2750297 is the OLD child

salt restarts this unit with --no-block -- _no_block_default() in
salt/modules/systemd_service.py returns True when the unit is the salt-minion
service -- so service.restart returns as soon as the job is enqueued. Measured
on the host, systemd does not swap MainPID until ~7.3s later. Throughout that
window the old daemon is still running, still holds its master sockets, and
its own ready line is already in the log, so every gate passes on the instance
that is about to be torn down. INITIAL_SLEEP=3 expired inside that window.

Wait for systemd's job queue for the unit to drain before resolving MainPID.
That is deterministic rather than a timing guess: the job exists from the
moment --no-block returns until the new instance signals READY, and MainPID is
new by the time it clears. Measured transition:

  t=0.0s   job pending, child=OLD, sockets up, ready line present
  t=7.9s   job drained, child=NEW, sockets up, ready line ABSENT
  t=10.7s  ready line for NEW child appears   <- script returns here

The same run also confirms empirically why the log line is required in
addition to the sockets: for 2.8s the new child has both master connections
while _post_master_init() is still loading modules and compiling pillar, so a
socket-only gate would return that much too early.

Correct the comment claim from the previous commit. The --no-block restart is
real; it lives in salt's systemd_service module, not in this repo, which is
why searching the repo for it turned up nothing.
2026-07-10 09:35:21 -04:00
Mike Reeves 52885e28c5 Name the reposync-side kernel repo securityonionkernelsync
The reposync section in repodownload.conf and the client repo assigned in
repo/client/oracle.sls both used the bare name securityonionkernel, colliding
across the two roles. Rename the reposync-side section (and its --repoid, the
so-repo-sync guard, and the so-kernel-upgrade presence check) to
securityonionkernelsync, mirroring the existing securityonion/securityonionsync
split for the main repo. The client repo stays securityonionkernel. Also give
the section its own name=Security Onion Kernel Repo repo.
2026-07-09 17:02:47 -04:00
Josh Patterson fbeac25ee9 so-salt-minion-check: highstate after minion restart
When the minion is deemed hung and restarted, wait for it to become
ready via so-salt-minion-wait, then kick off salt-call state.highstate
(queued, backgrounded) so the box re-applies its states and recovers on
its own rather than waiting for the next scheduled highstate.
2026-07-09 16:57:19 -04:00
Josh Patterson 8a3f5d0f81 Gate so-salt-minion-wait on real minion readiness
The previous gate did not detect whether the restarted minion was back:

  systemctl is-active --quiet salt-minion \
    && salt-call --local --timeout=5 --out=quiet test.ping

Both halves are near-vacuous. `--local` sets file_client=local, so test.ping
runs in a throwaway minion that never contacts the master and never inspects
the running daemon; it only proves python and the module loader work. And the
shipped unit is Type=notify with notify_systemd() called before the daemon
imports salt.cli.daemons, so is-active goes true at process launch, not at
connection. The script could return ready while the minion was still
authenticating, which is the race it exists to prevent.

Gate instead on the condition salt itself uses to log "Minion is ready to
receive requests!", requiring both signals of the current daemon instance:

  1. the pid-tagged ready line in the minion log. tune_in() emits it only
     after sync_connect_master() returns, i.e. the pub channel authenticated,
     the req channel connected, and _post_master_init() finished loading
     modules and compiling pillar.
  2. that same pid holding an ESTABLISHED req connection to a master on 4506
     plus a second (publish) connection to the same master IP. The publish
     port is absent from minion config -- the minion learns it from the
     master's auth reply -- so it is derived from the connection.

Resolve the daemon pid from systemd (MainPID -> pgrep -P), never from
/var/run/salt-minion.pid. salt_minion() runs the minion in a multiprocessing
child; that child writes the pidfile, owns the sockets and logs the ready
line, while MainPID is the parent. During a restart the pidfile still names
the old child, whose own ready line is already in the log, so keying off it
reports ready instantly. Children of the current MainPID exclude the old
instance structurally, with no timing assumptions.

Degrade deterministically rather than spinning to the timeout: if
log_level_logfile does not emit INFO records the ready line can never appear,
so detect that up front from the merged config and fall back to the socket
check. log_level_logfile defaults to None (inherit log_level), so resolve the
inheritance before deciding. If ss is unavailable, fall back to the log gate.
If neither signal is usable, fail immediately with a clear message.

Requiring master connectivity adds no new dependency: every path that applies
salt.minion or a highstate does so without --local, so file_client=remote
already required a reachable master to fetch salt:// files. No salt-call
master round-trip is added; the daemon's own successful auth already proves
the key is accepted.

Also fix the comment above wait_for_salt_minion_ready, which attributed the
script to common_sbin/common/tools/sbin (it is deployed by salt_sbin from
salt/tools/sbin) and asserted a --no-block restart that appears nowhere in
the repo. No state logic changed.
2026-07-09 16:55:30 -04:00
Jorge Reyes 4e856f02da Merge pull request #16055 from Security-Onion-Solutions/reyesj2-patch-3
exit so-setup early for issues with so-elastic-fleet-setup
2026-07-09 14:53:52 -05:00
reyesj2 f6a2758321 add so-elastic-agent-install script to minions 2026-07-09 14:44:42 -05:00
reyesj2 0b078c4804 give the elasticfleet state a few chances to complete successfully before exiting 1 causing so-setup to fail 2026-07-09 14:23:45 -05:00
reyesj2 2959dc9564 keep logs for all 3 attempts 2026-07-09 14:18:08 -05:00
reyesj2 8b0759866e verify installers are generated 2026-07-09 14:15:22 -05:00
reyesj2 6fa0d327cb cause so-setup to fail if there are issues setting up fleet 2026-07-09 14:14:58 -05:00
Mike Reeves 9a71f64a35 Branch so-kernel-upgrade on the running kernel flavor
Only the RHCK->UEK flavor cross needs grubby --set-default; a UEK7->UEK8
update stays in the kernel-uek lineage and auto-promotes on its own. Detect
the running kernel and act accordingly:

- UEK8: already on target, no-op.
- UEK7: populate the repo and install UEK8, then verify it auto-promoted
  (warn with the manual grubby command if it did not) -- no grubby change.
- RHCK: install UEK8 and set the boot default explicitly, as before.

Also make an already-installed UEK8 skip the repo entirely so a disabled or
empty kernel repo can't block flipping the default, and correct the header
comment that claimed every transition needs grubby.
2026-07-09 15:10:13 -04:00
Mike Reeves 40c02b3149 Make so-kernel-upgrade populate the kernel repo and fail loudly
Three stages of the UEK8 path fail silently, and the script only handled
the last one:

1. Populate. so-repo-sync runs before the highstate deploys the
   [securityonionkernel] section into repodownload.conf, so the first
   kernel-aware soup skips the kernel sync. kernelrepo_init_empty then
   seeds valid-but-empty repodata, leaving an enabled repo with zero
   packages. dnf resolves it happily and installs nothing, no error.

2. Install. `dnf install kernel-uek` on a UEK7 node sees kernel-uek 5.15
   already installed, prints "Nothing to do" and exits 0 -- so the script
   sailed past the install and died later with a misleading grubby error.

3. Boot. Already handled: grubby only auto-promotes within the running
   kernel's flavor lineage, so 5.x -> 6.x UEK never promotes on its own.

Add ensure_kernel_repo(), which verifies the repo is enabled (necessary
because skip_if_unavailable=1 hides a broken repo) and that it can serve a
6.x kernel-uek. When it cannot, a manager runs so-repo-sync to populate
/nsm/kernelrepo and re-checks; a minion cannot fix it and exits non-zero
pointing the admin at the manager. Airgap managers bail, since their repo
comes from the ISO rather than a sync.

Install the explicit UEK8 NEVRA instead of the bare package name so the
"Nothing to do" exit-0 case cannot mask a no-op, and pin the repoquery to
securityonionkernel so a UEK7 kernel-uek in the main repo is never picked.

Still idempotent and still never reboots.
2026-07-09 14:21:08 -04:00
Mike Reeves 5fd5df54b4 Install UEK8 in so-kernel-upgrade when no UEK kernel is present
The script assumed the UEK8 kernel was already installed and only switched
the boot default to it. On a node running the EL9 stock kernel (RHCK 5.14)
there is no kernel-uek* package at all, so `dnf update` has nothing to
upgrade and UEK8 never lands -- the script just logged "nothing to do" and
exited 0.

When no 6.x UEK boot entry exists, install the kernel-uek metapackage (it
pulls kernel-uek-core plus the module subpackages, including
kernel-uek-modules-extra-netfilter) and then proceed with the grubby
switch. Fail loudly if securityonionkernel is not an enabled repo, since
that assignment is gated on the NIC-pin marker and the salt version match
and a silent no-op there is hard to diagnose.

Also point DEFAULTKERNEL at kernel-uek-core so later kernel updates stay on
the UEK line rather than falling back to RHCK.

Still idempotent and still never reboots.
2026-07-09 13:47:50 -04:00
reyesj2 3394e9aab7 increase agent health timeout and add logging for elastic agent status output 2026-07-09 11:29:43 -05:00
Jorge Reyes 3766f74102 Merge pull request #16052 from Security-Onion-Solutions/reyesj2-patch-2
elastic fleet server persistence
2026-07-08 16:40:45 -05:00
reyesj2 c04a30785f make elastic agent state persistent to prevent re-enrollment during soup / reboots 2026-07-08 16:15:02 -05:00
Jason Ertel ca4d22a5fe Merge pull request #16050 from Security-Onion-Solutions/jertel/wip
restart soc after re-initing db
2026-07-08 16:07:13 -04:00
Jorge Reyes ea199aee55 Merge pull request #16049 from Security-Onion-Solutions/reyesj2-patch-1
add missing so-logs-soc annotation
2026-07-08 14:09:17 -05:00
reyesj2 5a57bbe4de add missing so-logs-soc annotation 2026-07-08 14:03:31 -05:00
Jason Ertel 1f44e98681 restart soc after re-initing db 2026-07-08 14:34:27 -04:00
Jorge Reyes 9a313d1966 Merge pull request #16045 from Security-Onion-Solutions/reyesj2/eahealth
verify elastic-agent reports healthy status before completing install…
2026-07-08 11:45:54 -05:00
reyesj2 85d7f6bebc independently download so-elastic-agent installer 2026-07-08 08:19:15 -05:00
reyesj2 2a4a7307f7 uninstall agent after downloading new one and getting gridtoken 2026-07-08 07:51:13 -05:00
reyesj2 f8de176f4b uninstall agent on final failed attempt 2026-07-08 07:47:47 -05:00
Jason Ertel dffe0d3780 Merge pull request #16046 from Security-Onion-Solutions/jertel/wip
recollate databases
2026-07-08 07:05:37 -04:00
Jason Ertel d131d167de provide explanation text 2026-07-08 07:00:38 -04:00
Jason Ertel 8a8f2c4a33 change order to recollate first 2026-07-07 22:22:00 -04:00
Jason Ertel 7f6014096b recollate db 2026-07-07 22:01:27 -04:00
reyesj2 70af3cec53 avoid using 'failure' until all loops are done so so-verify doesn't flag it 2026-07-07 16:48:10 -05:00
reyesj2 57b7d59387 verify elastic-agent reports healthy status before completing installation 2026-07-07 16:42:47 -05:00
Jason Ertel ef83450107 recollate 2026-07-07 16:54:06 -04:00
coreyogburn 032d792331 Merge pull request #16030 from Security-Onion-Solutions/feature/agentic
Feature/agentic
2026-07-07 14:37:52 -06:00
Josh Patterson 66a1141b84 Merge remote-tracking branch 'origin/3/dev' into saltthangs 2026-07-07 09:02:15 -04:00
Josh Brower 0cac761edc Merge pull request #16041 from Security-Onion-Solutions/playbook-reponames
Add repo names
2026-07-07 13:53:16 +02:00
Josh Brower db91ce981d Add repo names 2026-07-07 07:49:11 -04:00
Mike Reeves bd8e5a63db Merge pull request #16039 from Security-Onion-Solutions/TOoSmOotH-patch-1
Add cluster_health option to telegraf.conf
2026-07-06 17:29:04 -04:00
Mike Reeves 18212cad0d Add cluster_health option to telegraf.conf
Enable cluster health monitoring in Telegraf configuration.
2026-07-06 17:27:37 -04:00
Josh Brower 9975d36b4f Merge pull request #16019 from Security-Onion-Solutions/feature/sigma-playbooks
support sigma playbooks
2026-07-06 13:17:54 +02:00