diff --git a/REFERENCE.md b/REFERENCE.md
index 76106a38a..d4d18cd99 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -6070,6 +6070,7 @@ The following parameters are available in the `apache::mod::security` class:
* [`activated_rules`](#-apache--mod--security--activated_rules)
* [`custom_rules`](#-apache--mod--security--custom_rules)
* [`custom_rules_set`](#-apache--mod--security--custom_rules_set)
+* [`custom_actions_set`](#-apache--mod--security--custom_actions_set)
* [`modsec_dir`](#-apache--mod--security--modsec_dir)
* [`modsec_secruleengine`](#-apache--mod--security--modsec_secruleengine)
* [`debug_log_level`](#-apache--mod--security--debug_log_level)
@@ -6151,10 +6152,18 @@ Default value: `$apache::params::modsec_custom_rules`
Data type: `Optional[Array[String]]`
-
+Custom `SecRule` rules to be included
Default value: `$apache::params::modsec_custom_rules_set`
+##### `custom_actions_set`
+
+Data type: `Optional[Array[String]]`
+
+Custom `SecAction` rules to be included
+
+Default value: `undef`
+
##### `modsec_dir`
Data type: `Stdlib::Absolutepath`
diff --git a/manifests/mod/security.pp b/manifests/mod/security.pp
index 27de2e8a4..4af17c93c 100644
--- a/manifests/mod/security.pp
+++ b/manifests/mod/security.pp
@@ -16,7 +16,9 @@
# @param custom_rules
#
# @param custom_rules_set
-#
+# Custom `SecRule` rules to be included
+# @param custom_actions_set
+# Custom `SecAction` rules to be included
# @param modsec_dir
# Defines the path where Puppet installs the modsec configuration and activated rules links.
#
@@ -144,6 +146,7 @@
Array[String] $activated_rules = $apache::params::modsec_default_rules,
Boolean $custom_rules = $apache::params::modsec_custom_rules,
Optional[Array[String]] $custom_rules_set = $apache::params::modsec_custom_rules_set,
+ Optional[Array[String]] $custom_actions_set = undef,
Stdlib::Absolutepath $modsec_dir = $apache::params::modsec_dir,
String $modsec_secruleengine = $apache::params::modsec_secruleengine,
Integer[0, 9] $debug_log_level = 0,
@@ -319,7 +322,7 @@
owner => $apache::params::user,
group => $apache::params::group,
mode => $apache::file_mode,
- content => epp('apache/mod/security_custom.conf.epp', { 'custom_rules_set' => $custom_rules_set, }),
+ content => epp('apache/mod/security_custom.conf.epp', { 'custom_rules_set' => $custom_rules_set, 'custom_actions_set' => $custom_actions_set, }),
require => File["${modsec_dir}/custom_rules"],
notify => Class['apache::service'],
}
@@ -373,7 +376,7 @@
notify => Class['apache::service'],
}
- unless $facts['os']['name'] == 'SLES' or $facts['os']['name'] == 'Debian' or $facts['os']['name'] == 'Ubuntu' {
+ unless $facts['os']['name'] == 'SLES' {
apache::security::rule_link { $activated_rules: }
}
}
diff --git a/manifests/params.pp b/manifests/params.pp
index 60318ef6a..d8287eaaa 100644
--- a/manifests/params.pp
+++ b/manifests/params.pp
@@ -486,25 +486,25 @@
$secpcrematchlimitrecursion = 1500
$modsec_secruleengine = 'On'
$modsec_default_rules = [
- 'crawlers-user-agents.data',
- 'iis-errors.data',
- 'java-code-leakages.data',
- 'java-errors.data',
- 'lfi-os-files.data',
- 'php-config-directives.data',
- 'php-errors.data',
- 'php-function-names-933150.data',
- 'php-function-names-933151.data',
- 'php-variables.data',
- 'restricted-files.data',
- 'scanners-headers.data',
- 'scanners-urls.data',
- 'scanners-user-agents.data',
- 'scripting-user-agents.data',
- 'sql-errors.data',
- 'sql-function-names.data',
- 'unix-shell.data',
- 'windows-powershell-commands.data',
+ 'rules/crawlers-user-agents.data',
+ 'rules/iis-errors.data',
+ 'rules/java-code-leakages.data',
+ 'rules/java-errors.data',
+ 'rules/lfi-os-files.data',
+ 'rules/php-config-directives.data',
+ 'rules/php-errors.data',
+ 'rules/php-function-names-933150.data',
+ 'rules/php-function-names-933151.data',
+ 'rules/php-variables.data',
+ 'rules/restricted-files.data',
+ 'rules/scanners-headers.data',
+ 'rules/scanners-urls.data',
+ 'rules/scanners-user-agents.data',
+ 'rules/scripting-user-agents.data',
+ 'rules/sql-errors.data',
+ 'rules/sql-function-names.data',
+ 'rules/unix-shell.data',
+ 'rules/windows-powershell-commands.data',
]
$alias_icons_path = '/usr/share/apache2/icons'
$error_documents_path = '/usr/share/apache2/error'
diff --git a/spec/classes/mod/security_spec.rb b/spec/classes/mod/security_spec.rb
index 126377767..6aef2efea 100644
--- a/spec/classes/mod/security_spec.rb
+++ b/spec/classes/mod/security_spec.rb
@@ -155,7 +155,7 @@
}
end
- describe 'with parameters' do
+ describe 'with custom rules' do
let :params do
{
custom_rules: true,
@@ -173,6 +173,24 @@
it { is_expected.to contain_file('/etc/httpd/modsecurity.d/custom_rules/custom_01_rules.conf').with_content %r{^\s*.*"id:199999,phase:1,nolog,allow,ctl:ruleEngine=off"$} }
end
+ describe 'with custom actions' do
+ let :params do
+ {
+ custom_rules: true,
+ custom_actions_set: ['id:199999,phase:1,pass,nolog,t:none,initcol:global=global']
+ }
+ end
+
+ it {
+ expect(subject).to contain_file('/etc/httpd/modsecurity.d/custom_rules').with(
+ ensure: 'directory', path: '/etc/httpd/modsecurity.d/custom_rules',
+ owner: 'apache', group: 'apache'
+ )
+ }
+
+ it { is_expected.to contain_file('/etc/httpd/modsecurity.d/custom_rules/custom_01_rules.conf').with_content %r{^\s*.*"id:199999,phase:1,pass,nolog,t:none,initcol:global=global"$} }
+ end
+
describe 'with CRS parameters' do
let :params do
{
@@ -284,6 +302,15 @@
)
}
+ it { is_expected.to contain_apache__security__rule_link('rules/crawlers-user-agents.data') }
+
+ it {
+ expect(subject).to contain_file('crawlers-user-agents.data').with(
+ path: '/etc/modsecurity/activated_rules/crawlers-user-agents.data',
+ target: '/usr/share/modsecurity-crs/rules/crawlers-user-agents.data',
+ )
+ }
+
it {
expect(subject).to contain_file('/etc/modsecurity/security_crs.conf').with(
path: '/etc/modsecurity/security_crs.conf',
@@ -302,7 +329,7 @@
}
end
- describe 'with parameters' do
+ describe 'with custom rules' do
let :params do
{
custom_rules: true,
@@ -320,6 +347,56 @@
it { is_expected.to contain_file('/etc/modsecurity/custom_rules/custom_01_rules.conf').with_content %r{\s*.*"id:199999,phase:1,nolog,allow,ctl:ruleEngine=off"$} }
end
+ describe 'with custom actions' do
+ let :params do
+ {
+ custom_rules: true,
+ custom_actions_set: ['id:199999,phase:1,pass,nolog,t:none,initcol:global=global']
+ }
+ end
+
+ it {
+ expect(subject).to contain_file('/etc/modsecurity/custom_rules').with(
+ ensure: 'directory', path: '/etc/modsecurity/custom_rules',
+ owner: 'www-data', group: 'www-data'
+ )
+ }
+
+ it { is_expected.to contain_file('/etc/modsecurity/custom_rules/custom_01_rules.conf').with_content %r{\s*.*"id:199999,phase:1,pass,nolog,t:none,initcol:global=global"$} }
+ end
+
+ describe 'with absolute path to activated rule' do
+ let :params do
+ {
+ activated_rules: ['/tmp/foo/bar.conf']
+ }
+ end
+
+ it { is_expected.to contain_apache__security__rule_link('/tmp/foo/bar.conf') }
+
+ it {
+ expect(subject).to contain_file('bar.conf').with(
+ path: '/etc/modsecurity/activated_rules/bar.conf',
+ target: '/tmp/foo/bar.conf',
+ )
+ }
+ end
+ describe 'with relative path to activated rule' do
+ let :params do
+ {
+ activated_rules: ['rules/bar.conf']
+ }
+ end
+
+ it { is_expected.to contain_apache__security__rule_link('rules/bar.conf') }
+ it {
+ expect(subject).to contain_file('bar.conf').with(
+ path: '/etc/modsecurity/activated_rules/bar.conf',
+ target: '/usr/share/modsecurity-crs/rules/bar.conf',
+ )
+ }
+ end
+
describe 'with mod security version' do
let :params do
{
diff --git a/templates/mod/security_custom.conf.epp b/templates/mod/security_custom.conf.epp
index e2570c44a..4c3ff6ace 100644
--- a/templates/mod/security_custom.conf.epp
+++ b/templates/mod/security_custom.conf.epp
@@ -1,6 +1,12 @@
# This file is managed by puppet, any direct modification will be overwritten.
+<% if $custom_actions_set and !($custom_actions_set.empty) { -%>
+<% $custom_actions_set.each |$secaction| { -%>
+SecAction "<%= $secaction %>"
+<% } -%>
+<% } -%>
+
<% if $custom_rules_set and !($custom_rules_set.empty) { -%>
<% $custom_rules_set.each |$secrule| { -%>
SecRule <%= $secrule %>
<% } -%>
-<% } -%>
\ No newline at end of file
+<% } -%>