Skip to content

Stage 1b: arm64, more test VMs, Lynis 85, remaining guard checks - #19

Draft
VectoDE wants to merge 17 commits into
feat/lss-2-corefrom
feat/lss-1b
Draft

VectoDE wants to merge 17 commits into
feat/lss-2-corefrom
feat/lss-1b

Conversation

@VectoDE

@VectoDE VectoDE commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Stage 1b (#12), based on #2. Retargeted to main once #2 is merged.

Refs #12

🤖 Generated with Claude Code

VectoDE and others added 2 commits October 13, 2026 18:40
Every container job also runs on the free arm64 runners, and the kernel
modules on an arm64 VM. The minimal-secure profile runs on an Ubuntu 26.04
runner VM besides 24.04. The x86_64 job names stay, so the required checks
keep matching.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
…s found

AIDE, rkhunter and clamscan report findings through their exit status,
which their units accept as success, so a changed file or an infected one
only reached the journal. guard now reads the last run of each unit and
reports its findings, and a scanner that stopped running.

It also reports high-urgency vulnerabilities with a fix (debsecan on
Debian, installed by the module) or critical and important advisories
(dnf updateinfo), and failed SSH logins above LSS_GUARD_LOGIN_THRESHOLD
with their main sources. Successful logins and active fail2ban or CrowdSec
bans are notes in the summary.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
Comment thread libexec/lss-guard Fixed
VectoDE and others added 2 commits October 13, 2026 18:50
A syslog identifier can be set by any local user (logger -t sshd), so the
login check reads sshd lines by _COMM and _UID, which journald sets itself.
Findings quote file names and log text that users control: control
characters are replaced, so such text cannot add lines to the summary or
forge journal entries, and sendmail runs with -i, so a lone dot cannot end
the mail early.

Found by a security review of the previous commit.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
… RHEL family

The runner VM only covers Ubuntu. tests/integration/vm.sh boots the
vendors' cloud images (Debian 12 and 13, Rocky Linux 9, AlmaLinux 10)
with KVM, checked against the checksum file each vendor publishes, and
reaches them over SSH with a fresh key for a test user in the
administrator group, so the SSH hardening keeps it in. run.sh accepts
vm-NAME as a system; the workflow runs the kernel modules and the
minimal-secure profile with a Lynis audit on each.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
Comment thread tests/unit/guard.bats Fixed
VectoDE and others added 13 commits October 13, 2026 18:56
From the Lynis suggestions after minimal-secure:
- ssh-hardening also writes the banner to /etc/issue and /etc/issue.net
  (BANN-7126/7130); the default text names enough legal terms for Lynis.
- password-policy sets the hash cost (AUTH-9230) and installs
  libpam-tmpdir (DEB-0280).
- auditd turns on process accounting (ACCT-9622).
- aide installs debsums (PKGS-7370), tools apt-show-versions (PKGS-7394).
The profile job prints the remaining Lynis details (sysctl, SSH options,
file permissions), the input for the next steps.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
…abel

- lss-guard declares its arrays global: sourced inside the bats setup
  function, declare -a made them local, so they were unset in the test
  and set -u stopped the empty-array checks.
- An explicit if instead of A && B || continue (SC2015).
- The journalctl stub is called indirectly (SC2329).
- actionlint does not know the ubuntu-26.04 runner label yet.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
Ubuntu 26.04 ships sudo-rs, whose visudo rejects Defaults logfile; the
module now leaves it out there (sudo-rs logs to the journal). On the RHEL
family sudo's secure_path lacks /usr/local/sbin, so sudo lss failed; the
sudoers file adds it, the README says how to call lss before that, and
the VM harness sets PATH itself.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
Lynis details after minimal-secure named the cron files (SCHD-7704, CIS
5.1.2-5.1.7) and sshd_config (FILE-7524). The system module makes the
crontab 600 and the cron directories 700, ssh-hardening makes
sshd_config 600.

Measured hardening index: Debian 12 87, Debian 13 85, Ubuntu runner 78
(the runner image brings Docker, PostgreSQL and its own sudoers file).
CI now requires 82 on the Debian VMs and 75 on the runner.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
AIDE, rkhunter, ClamAV and Lynis ran as root without any sandbox (Lynis
BOOT-5264 rated their units unsafe). svc_scanner_sandbox gives them a
read-only system and read-only home directories, no new privileges and
write access only to their state and logs; AIDE and ClamAV get no
network. The real /tmp, /proc/kallsyms, the kernel modules and the
kernel log stay visible, because the scanners check them.

The profile test starts every scanner unit once inside its sandbox and
prints its systemd exposure score.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
The Debian cloud VM has no USB controller, so usbguard-daemon exited at
once (no /sys/bus/usb/devices) and systemd restarted it until it gave
up. The module now loads usbcore when it is missing; where the kernel
still shows no USB bus, a drop-in makes systemd start usbguard on the
first boot that has one, and the empty policy blocks every device until
it is allowed. verify checks the matching state.

The test VMs get an xHCI controller with a keyboard, so usbguard is
also tested with a real device.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
The apt-get installs of QEMU and shfmt printed the man-db trigger note
(Not building database ...) and the needrestart summary (No services
need to be restarted ...); zizmor printed No findings to report. apt
now runs with -qq, NEEDRESTART_SUSPEND and stdout discarded (errors stay
in the log), and zizmor reports findings as annotations only.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
The first runs in Rocky Linux and AlmaLinux VMs found two RHEL issues:
- mkswap --quiet needs util-linux 2.38; Rocky 9 has 2.37. mkswap
  reports on stdout, which is discarded anyway.
- firewall-offline-cmd reads --remove-service as a lokkit option and
  refuses it together with --zone; offline it is
  --remove-service-from-zone.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
firewall-cmd --get-target only works with --permanent, so verify got
an empty answer and reported an open zone on Rocky and AlmaLinux. The
resource figures now drop the page cache before measuring and report
zero instead of a negative difference on shared runners.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
RHEL 10 ships augenrules in the separate audit-rules package, so the auditd module failed on AlmaLinux 10. When a second install is not idempotent, the integration test now prints the change notes and the difference of every rewritten file, to find why AIDE and rkhunter rebuilt their databases on Rocky 9.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
…lld start

On RHEL /sbin and /bin are symlinks, so command -v returned different paths
depending on PATH and a second run rewrote the aide and rkhunter units.
augenrules output and firewalld's dbus notice now go to the log only.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
(cherry picked from commit 73bb165)
NoNewPrivileges blocks the transition from init_t into aide_t, so the AIDE
check on RHEL ran as init_t and could not write /var/log/aide/aide.log.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
(cherry picked from commit d185701)
Rocky Linux 9 reached 85 and AlmaLinux 10 84 after minimal-secure.

Refs #12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: VectoDE <system.bot.discord.utility@gmail.com>
(cherry picked from commit 1c6700d)
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants