Skip to content

Releases: doccaz/scap2salt

v1.0.14 — MLM container-volume deploy + nftables masking

Choose a tag to compare

@doccaz doccaz released this 08 Jun 13:33
9d9576f

PCI-DSS v4 hardening Salt formulas for SUSE, generated by scap2salt and packaged as MLM/Uyuni formulas with form. Two per-OS RPMs are attached — assign one per system-group.

Coverage (pci-dss-4 profile)

SLE 15 (AppArmor) SLE 16 (SELinux)
Native mapping 209/238 remediable (87%) 197/230 (85%)
Live OpenSCAP compliance 92.9% (223/17) 91.6% (207/19)

What's new in 1.0.14

  • service_*_disabled now passes — the OVAL requires LoadState=masked, not just disabled. Disabled-service rules now also service.masked (e.g. service_nftables_disabled → pass).
  • Formula RPM now deploys into the live MLM container volumes on SL Micro. The Uyuni Salt master reads /srv/salt + /srv/formula_metadata, which on a containerised server are podman volumes under /var/lib/containers/storage. Because SL Micro installs RPMs via transactional-update (whose %post runs in a chroot where that storage is shadowed), deployment is now done on first boot by a bundled deploy-<formula>.service oneshot (vendor-enabled via a packaged multi-user.target.wants symlink), with a /usr/libexec/deploy-<formula>.sh helper for immediate deploy.
  • Per-OS formula names PCI_DSS_v4_SLE15 / PCI_DSS_v4_SLE16 for clean, case-correct labels in the MLM Formulas list.
  • Looked into and documented the residual fails: sysctl_fs_suid_dumpable (runtime hardened to 0; static check left untouched to avoid an rpm_verify_hashes violation) and the pam-file hashing rules (oscap 1.4.1 can't credit them on SUSE; the effective control set_password_hashing_algorithm_logindefs passes).

Install (containerised MLM on SL Micro)

sudo transactional-update pkg install --allow-unsigned-rpm ./PCI_DSS_v4_SLE16-hardening-formula-1.0.14-0.noarch.rpm
sudo reboot     # required to activate the transactional install; the formula auto-deploys on boot

Then assign PCI DSS V4 SLE16 (or …SLE15) to a system/group in the Formulas tab, toggle categories, and apply the highstate. See each RPM's bundled README for the writable-root and traditional-server paths.

v1.0.13 — Fix broken formula after sub-group revert

Choose a tag to compare

@doccaz doccaz released this 05 Jun 15:15
5f0afd1

Reverts the v1.0.12 sub-group form.yml change that broke MLM formula assignment.

What broke in v1.0.12: Changing category toggles from flat booleans (pci_dss.sysctl: True) to sub-groups (pci_dss.sysctl.enabled: True) is a schema-breaking change. MLM stores saved form values in its database and can't render the pillar when the schema changes, causing highstate to fail with a Jinja error.

What's fixed: emit_formula() reverts to flat boolean categories. Jinja guards revert from p.get(cat, {}).get('enabled', True) back to p.get(cat, True).

Kept from v1.0.12:

  • Group-level $help text clarifying AppArmor/SELinux runtime detection
  • Short clean category labels in CAT_LABELS
  • PCI-DSS section references in CAT_HELP (tooltip/$help fields)
  • metadata.yml name field update

Note on form layout: MLM renders boolean fields as checkboxes with tooltip-only $help. The visible inline description per-category (and indentation under the master switch) would require the sub-group schema, which breaks existing assignments — not feasible without a migration path.

v1.0.11

Choose a tag to compare

@doccaz doccaz released this 05 Jun 14:43
8735f99

v1.0.11 — Fix auditd/audit-rules.service immutable-flag loop

Root cause

The zz-pci-immutable.rules fragment sets -e 2 (immutable mode) after the first successful highstate. On subsequent systemctl start audit-rules.service calls (e.g. when Salt tries to start auditd), augenrules --load calls auditctl -R which hits «Rule exists» because:

  1. auditctl -D silently exits 0 but does nothing (rules are locked)
  2. Existing kernel rules can't be replaced without a reboot

Fix

Install a systemd drop-in at /etc/systemd/system/audit-rules.service.d/pci-immutable.conf that wraps augenrules with an immutability check:

[Service]
ExecStart=
ExecStart=/bin/sh -c 'if auditctl -s 2>/dev/null | grep -q "enabled 2"; then echo "Audit rules immutable (-e 2), skipping reload"; exit 0; fi; /sbin/augenrules --load'

When audit rules are immutable (already correctly loaded from the previous boot run), the wrapper exits 0 so audit-rules.service succeeds and auditd can start.

Included from v1.0.10

  • Formula UI: each category label shows its PCI-DSS requirement refs inline
  • metadata.yml: name: field fixes «Pci Dss» → «PCI-DSS v4 Hardening» tab label
  • Master-switch $help tooltip explains the enable toggle

v1.0.10

Choose a tag to compare

@doccaz doccaz released this 05 Jun 14:35
09e04ef

v1.0.10 — auditd boot-failure fix + formula UI improvements

Fixes

  • services.sls: audit_prereq_reset now also runs auditctl -D before resetting the failed audit-rules.service, clearing any partially-loaded kernel audit rules that would cause «Rule exists» on the next reload attempt.

Formula UI improvements

  • form.yml: each category checkbox label now shows its PCI-DSS requirement section inline (e.g. SSH server hardening — PCI-DSS §2.2.4, §2.2.7, §8.3.1) — always visible, not just as a tooltip.
  • form.yml: "Enable PCI-DSS hardening" toggle gets a tooltip explaining it is the master on/off switch; when unchecked, all categories are skipped without removing the formula assignment.
  • metadata.yml: added name: PCI-DSS v4 Hardening so the MLM Formulas tab shows the correct title instead of the auto-formatted "Pci Dss".
  • Capitalisation: "Sudo defaults" and "Systemd core dump policy" now start with a capital letter; all category descriptions lead with their PCI-DSS section reference.

v1.0.9

Choose a tag to compare

@doccaz doccaz released this 05 Jun 14:19
9931ed4

v1.0.9 — AppArmor/SLE 16 compatibility + auditd service fix

Fixes

  • mac.sls: AppArmor states are now guarded by a Jinja runtime check for /sys/kernel/security/apparmor. On SELinux systems (SLE 16) these states are silently skipped instead of failing with package-not-found errors.
  • services.sls: Added audit_prereq_reset state that resets audit-rules.service if it is stuck in a failed state from boot-time duplicate-rule errors, before Salt attempts to start auditd.

v1.0.8

Choose a tag to compare

@doccaz doccaz released this 05 Jun 14:08
402e395

Fix: keep deduplicated audit fragment files as comment-only rather than omitting them, so stale on-disk .rules files from previous runs are overwritten instead of left in place.

v1.0.7

Choose a tag to compare

@doccaz doccaz released this 05 Jun 14:05
7e9da87

Changes in v1.0.7

Bug fixes

  • augenrules --load "Rule exists" errors: CaC time-related audit rules (audit_rules_time_adjtimex, audit_rules_time_settimeofday, audit_rules_time_stime) all generate the same combined -a always,exit -F arch=... -S adjtimex -S settimeofday line. Each rule got its own fragment file, so augenrules would concatenate three copies of the same rule into audit.rules. The kernel rejects duplicates with "Rule exists", causing augenrules to exit non-zero, which fails audit-rules.service and cascades to auditd.service. The fix: emit_tree now globally deduplicates rule lines across all audit fragments before rendering. The first fragment in sort order (adjtimex) keeps the combined rule; settimeofday and stime fragments become empty and are omitted entirely.

v1.0.6

Choose a tag to compare

@doccaz doccaz released this 05 Jun 14:01
28d445a

Changes in v1.0.6

Bug fixes

  • stime syscall in b64 audit rules: augenrules --load (and therefore audit-rules.service and auditd.service) was failing on modern kernels because stime (syscall nr 25) was removed from x86_64 in Linux 5.x. The audit mapper now strips -S stime from b64 rules; b32 rules keep it for 32-bit compatibility. If stripping leaves a b64 rule with no syscalls and no other filters, that line is dropped entirely.
  • /etc/ssh and /tmp are directories: file_permissions_sshd_pub_key and file_permissions_unauthorized_world_writable were generating file.managed states targeting /etc/ssh and /tmp, which Salt rejects for directory paths. Both are now added to the known-directory set and emit file.directory states.

v1.0.5

Choose a tag to compare

@doccaz doccaz released this 05 Jun 13:55
00faeac

Changes in v1.0.5

Bug fixes (found during SLE 16 highstate test run)

  • sysctl values unresolved: m_sysctl now calls shell_resolve() on the extracted value, so shell variable references like $SYSCTL_SETTING_VALUE expand to their actual numeric defaults instead of being passed literally to the kernel (fixed 7 failing sysctl states)
  • chronyd_or_ntpd service not found: normalise the combined service name from the SCAP rule to chronyd, which is the actual NTP daemon on SUSE systems
  • Directories in file.managed: cron directories (/etc/cron.d, /etc/cron.daily, /etc/cron.hourly, /etc/cron.monthly, /etc/cron.weekly) now use file.directory instead of file.managed; Salt rejects file.managed when the target is a directory
  • Missing files on minimal installs: lineinfile category now emits a file.managed preamble (with makedirs: True and replace: False) for /etc/login.defs, /etc/default/useradd, and /etc/ssh/sshd_config.d/01-complianceascode-reinforce-os-defaults.conf before any file.replace states touch them
  • Optional app config files: /etc/postfix/main.cf and /etc/libuser.conf states now carry onlyif: test -f <path> so the state is skipped cleanly when the package is not installed
  • /etc/security/limits.d/ missing: limits_disable_coredumps state now includes makedirs: True
  • rpm_verify_* exits non-zero: appended 2>/dev/null || true so xargs rpm --setperms/--setugids returning non-zero does not fail the state

v1.0.4

Choose a tag to compare

@doccaz doccaz released this 05 Jun 13:21
dd8407b

Changes in v1.0.4

Bug fixes

  • SLE 16 compatibility: Remove create_if_not_found from all file.replace states — this keyword is not a valid Salt parameter and is strictly rejected on SLE 16's Salt version. Affected mappers: m_auditd_conf, m_chronyd_user (two remaining occurrences after previous 1.0.3 partial fix).
  • sshd drop-in file: Add a file.managed preamble state (sshd_dropin_create) in sshd.sls that creates /etc/ssh/sshd_config.d/00-pci-hardening.conf with makedirs: True and replace: False, so subsequent file.replace states do not fail on a missing file.