Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion manifests/mod/security.pp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@
# @see https://github.com/SpiderLabs/ModSecurity/wiki for additional documentation.
# @see https://coreruleset.org/docs/ for addional documentation
#
# @note Unsupported platforms: RedHat: 10
# @note On RHEL/EL 10 the ModSecurity engine is provided by EPEL (enable EPEL
# yourself; this module does not manage it). The OWASP CRS package
# (`mod_security_crs`) is not available on EL10, so the class manages the
# engine only there and does not install or activate CRS rules.
class apache::mod::security (
Stdlib::Absolutepath $logroot = $apache::params::logroot,
Integer $version = $apache::params::modsec_version,
Expand Down
30 changes: 26 additions & 4 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,23 @@
$mellon_cache_size = 100
$mellon_post_directory = undef
$modsec_version = 1
$modsec_crs_package = 'mod_security_crs'
# EL10 base/EPEL ships the ModSecurity engine but not the mod_security_crs
# package, so install the engine only and leave CRS unmanaged there.
$modsec_crs_package = $facts['os']['release']['major'] ? {
'10' => undef, # RedHat 10 doesn't ship mod_security_crs (CRS tracked separately)
default => 'mod_security_crs',
}
$modsec_dir = '/etc/httpd/modsecurity.d'
$secpcrematchlimit = 1500
$secpcrematchlimitrecursion = 1500
$modsec_secruleengine = 'On'
if $facts['os']['family'] == 'RedHat' and versioncmp($facts['os']['release']['major'], '7') <= 0 {
if $facts['os']['family'] == 'RedHat' and versioncmp($facts['os']['release']['major'], '10') >= 0 {
# Engine-only on EL10: no CRS package, so no rules are activated. The path
# is kept at the EL8+ default since it is only referenced when rules are
# activated (none here).
$modsec_crs_path = '/usr/share/mod_modsecurity_crs'
$modsec_default_rules = []
} elsif $facts['os']['family'] == 'RedHat' and versioncmp($facts['os']['release']['major'], '7') <= 0 {
$modsec_crs_path = '/usr/lib/modsecurity.d'
$modsec_default_rules = [
'base_rules/modsecurity_35_bad_robots.data',
Expand Down Expand Up @@ -260,12 +271,23 @@
$mellon_cache_size = 100
$mellon_post_directory = undef
$modsec_version = 1
$modsec_crs_package = 'mod_security_crs'
# EL10 base/EPEL ships the ModSecurity engine but not the mod_security_crs
# package, so install the engine only and leave CRS unmanaged there.
$modsec_crs_package = $facts['os']['release']['major'] ? {
'10' => undef, # RedHat 10 doesn't ship mod_security_crs (CRS tracked separately)
default => 'mod_security_crs',
}
$modsec_dir = '/etc/httpd/modsecurity.d'
$secpcrematchlimit = 1500
$secpcrematchlimitrecursion = 1500
$modsec_secruleengine = 'On'
if $facts['os']['family'] == 'RedHat' and versioncmp($facts['os']['release']['major'], '7') <= 0 {
if $facts['os']['family'] == 'RedHat' and versioncmp($facts['os']['release']['major'], '10') >= 0 {
# Engine-only on EL10: no CRS package, so no rules are activated. The path
# is kept at the EL8+ default since it is only referenced when rules are
# activated (none here).
$modsec_crs_path = '/usr/share/mod_modsecurity_crs'
$modsec_default_rules = []
} elsif $facts['os']['family'] == 'RedHat' and versioncmp($facts['os']['release']['major'], '7') <= 0 {
$modsec_crs_path = '/usr/lib/modsecurity.d'
$modsec_default_rules = [
'base_rules/modsecurity_35_bad_robots.data',
Expand Down
58 changes: 56 additions & 2 deletions spec/classes/mod/security_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@
)
}

it { is_expected.to contain_package('mod_security_crs') }
if facts[:os]['release']['major'].to_i >= 10
# EL10 ships the engine via EPEL but not the mod_security_crs package.
it { is_expected.not_to contain_package('mod_security_crs') }
else
it { is_expected.to contain_package('mod_security_crs') }
end
Comment on lines +36 to +41

if (facts[:os]['release']['major'].to_i > 6 && facts[:os]['release']['major'].to_i <= 7) || (facts[:os]['release']['major'].to_i >= 8)
it {
Expand Down Expand Up @@ -73,7 +78,10 @@
)
}

if facts[:os]['release']['major'].to_i <= 7
if facts[:os]['release']['major'].to_i >= 10
# EL10 is engine-only (no CRS package), so no rules are activated.
it { is_expected.not_to contain_apache__security__rule_link('rules/crawlers-user-agents.data') }
elsif facts[:os]['release']['major'].to_i <= 7
it { is_expected.to contain_apache__security__rule_link('base_rules/modsecurity_35_bad_robots.data') }
Comment on lines +81 to 85

it {
Expand Down Expand Up @@ -384,4 +392,50 @@
end
end
end

# FacterDB does not yet ship a RedHat-named EL10 factset, so on_supported_os
# cannot generate a redhat-10 context. Exercise the engine-only EL10 path
# explicitly with hardcoded facts.
context 'on RedHat 10 (engine-only via EPEL)' do
let :facts do
{
os: {
'architecture' => 'x86_64',
'family' => 'RedHat',
'hardware' => 'x86_64',
'name' => 'RedHat',
'release' => { 'full' => '10.0', 'major' => '10' },
'selinux' => { 'enabled' => false },
},
}
end

it { is_expected.to compile.with_all_deps }

it {
expect(subject).to contain_apache__mod('security').with(
id: 'security2_module',
lib: 'mod_security2.so',
)
}

it {
expect(subject).to contain_apache__mod('unique_id').with(
id: 'unique_id_module',
lib: 'mod_unique_id.so',
)
}

# EL10 ships the engine via EPEL but not the mod_security_crs package, so
# the CRS package must not be managed and no rules are activated.
it { is_expected.not_to contain_package('mod_security_crs') }
it { is_expected.not_to contain_apache__security__rule_link('rules/crawlers-user-agents.data') }

# The engine config is still written.
it {
expect(subject).to contain_file('security.conf').with(
path: '/etc/httpd/conf.modules.d/security.conf',
)
}
end
end
Loading