(MODULES-11857) Scaffold OWASP CRS v4 support on EL10 via crs_source enum#2637
(MODULES-11857) Scaffold OWASP CRS v4 support on EL10 via crs_source enum#2637SugatD wants to merge 6 commits into
Conversation
…enum Add a crs_source enum (package/archive/path/none) to apache::mod::security so CRS can be deployed on EL10, which has no mod_security_crs package, while preserving the package-based behaviour on EL7/8/9. - params.pp: crs_source defaults to none on EL10, package elsewhere; archive source/checksum default to undef (user-pinned, no version treadmill). - security.pp: case $crs_source selects acquisition (package install / puppet-archive fetch+extract / pre-staged path / none) and branches rule activation between legacy per-rule symlinks (package) and the v4 include layout (archive/path). Extract dir kept outside the purged modsec_dir. - templates/mod/security_crs_v4.conf.epp: emits the v4 crs-setup.conf + rules/*.conf includes, auto-loaded via modsec_dir/*.conf. - metadata.json/.fixtures.yml: add puppetlabs/archive dependency. - spec: cover none/archive/path modes and fail-fast validation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The puppet-archive module is published as puppet/archive (Vox Pupuli), not puppetlabs/archive, which does not exist on the Forge. The wrong name made dependency-checker crash in CI and the fixture clone fail. Point both metadata.json and .fixtures.yml at the correct module/repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Latest published puppet/archive is 8.1.0; the dependency-checker requires the current Forge version to satisfy the declared range. Bump the upper bound to < 9.0.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make crs_source => archive work end-to-end: - Add crs_version param (user-pinned). CRS tarballs unpack to a versioned coreruleset-<version>/ dir, so pinning the version makes the extract path and includes deterministic. Extract into a base dir (default /usr/share). - Create the active crs-setup.conf from the shipped crs-setup.conf.example via an exec guarded by creates (preserves later user edits). - Update unit specs for the versioned layout and the new fail-fast on missing crs_version. Resolves the extraction TODO from the initial scaffold. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Covers crs_source => path and archive on EL10 with a self-contained, internet-free CRS fixture (built on the target) that also stands in for an internal mirror. Asserts idempotent apply, the v4 include wiring, that crs-setup.conf is created from the example in archive mode, and that apachectl configtest passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Archive mode passed checksum_type unconditionally, so with no crs_archive_checksum
puppet/archive verified against an empty expected checksum and failed
("Download file checksum mismatch (expected: ...)"). A trusted internal mirror
may legitimately be used without a checksum. Set checksum_verify only when a
checksum is supplied. Caught by the new EL10 acceptance test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Acceptance tests now pass on all Enterprise Linux platforms (RedHat-7/8/9/10 + 10-arm, Rocky, CentOS), including the new @kenyon — as requested, holding until acceptance passed; it now does, so this is ready for review. The only red checks are Follow-up captured as MODULES-11895 (wiring the ModSecurity tuning params into the CRS v4 |
Summary
Scaffolds OWASP Core Rule Set (CRS) v4 support on EL10, where there is no
mod_security_crspackage, while preserving the existing package-based behaviour on EL7/8/9. Implements the design locked in the SPIKE MODULES-11852 (air-gapped customer with internal mirrors → mirror-first, no required internet call).Introduces a
crs_sourceenum onapache::mod::security:crs_sourcepackagemod_security_crs+ per-rule symlinks (v2/v3 layout) — unchangedarchivepuppet/archivefrom a configurablecrs_archive_source(e.g. an internal mirror) + checksum, extract, wire v4 includespathcrs_path), no downloadnoneChanges
manifests/params.pp—crs_sourcedefaults (noneon EL10,packageelsewhere); archive source/checksum default toundef(user-pinned, no module-shipped version → avoids the CRS version/CVE treadmill).manifests/mod/security.pp— new params +case $crs_sourcefor acquisition; rule activation branches between legacy per-rule symlinks (package) and the v4 include layout (archive/path); fail-fast validation when required inputs are missing. Extract dir is kept outside the purgedmodsec_dir.templates/mod/security_crs_v4.conf.epp— emitsIncludeOptional <dir>/crs-setup.conf+rules/*.conf, auto-loaded via the existingIncludeOptional ${modsec_dir}/*.conf.metadata.json/.fixtures.yml— addpuppetlabs/archivedependency.spec/classes/mod/security_spec.rb— cover none/archive/path modes + fail-fast cases.Validation
puppet parser validate,epp validate,puppet-lint,rubocop,metadata_lint: cleancrs_sourcevalues, with/without-checksum archive, fail-fast)spec/acceptance/mod_security_crs_v4_spec.rbexercises path + archive)configtest, SQLi/XSS/LFI → 403)Known limitation / follow-up
paranoia_level,*_anomaly_threshold,allowed_methods, DOS knobs, …) currently feed only the legacysecurity_crs.conf(package mode). Inarchive/path(v4) modes the CRS-shippedcrs-setup.confis used as-is, so those params are not applied. Operators can editcrs-setup.confdirectly (preserved by thecreatesguard). Tracked as follow-up MODULES-11895 — not a blocker for this PR.CI note
The only red checks are
Debian-13,SLES-12,SLES-15acceptance — pre-existing platform failures (Debian-13 systemd start; SLES missingapache2ctl), unrelated to this change (same set is red onmainnightly; this PR does not touch those code paths).Relates to MODULES-11852 (design SPIKE), MODULES-11851 (engine restore), MODULES-11739 (parent), MODULES-11895 (follow-up).
🤖 Generated with Claude Code