From 79407f7f44403e3a86585bffb2caea1d5a6b6029 Mon Sep 17 00:00:00 2001 From: Jon-Paul Lindquist Date: Tue, 31 Dec 2019 09:57:47 -0700 Subject: [PATCH] Add template variables and parameters for ModSecurity Audit Logs --- manifests/mod/security.pp | 10 ++++++++++ manifests/params.pp | 1 + spec/classes/mod/security_spec.rb | 9 +++++++++ templates/mod/security.conf.erb | 5 ++++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/manifests/mod/security.pp b/manifests/mod/security.pp index 683fad0be5..1bc3edfd83 100644 --- a/manifests/mod/security.pp +++ b/manifests/mod/security.pp @@ -27,6 +27,12 @@ # Defines which parts of each transaction are going to be recorded in the audit log. Each part is assigned a single letter; when a # letter appears in the list then the equivalent part will be recorded. # +# @param audit_log_type +# Defines the type of audit logging mechanism to be used. +# +# @param audit_log_storage_dir +# Defines the directory where concurrent audit log entries are to be stored. This directive is only needed when concurrent audit logging is used. +# # @param secpcrematchlimit # Sets the match limit in the PCRE library. # @@ -96,6 +102,8 @@ $modsec_secruleengine = $::apache::params::modsec_secruleengine, $audit_log_relevant_status = '^(?:5|4(?!04))', $audit_log_parts = $::apache::params::modsec_audit_log_parts, + $audit_log_type = $::apache::params::modsec_audit_log_type, + $audit_log_storage_dir = undef, $secpcrematchlimit = $::apache::params::secpcrematchlimit, $secpcrematchlimitrecursion = $::apache::params::secpcrematchlimitrecursion, $allowed_methods = 'GET HEAD POST OPTIONS', @@ -169,6 +177,8 @@ # - logroot # - $modsec_dir # - $audit_log_parts + # - $audit_log_type + # - $audit_log_storage_dir # - secpcrematchlimit # - secpcrematchlimitrecursion # - secrequestbodylimit diff --git a/manifests/params.pp b/manifests/params.pp index 5e89fc4d28..e54bbeb426 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -35,6 +35,7 @@ $vhost_include_pattern = '*' $modsec_audit_log_parts = 'ABIJDEFHZ' + $modsec_audit_log_type = 'Serial' # no client certs should be trusted for auth by default. $ssl_certs_dir = undef diff --git a/spec/classes/mod/security_spec.rb b/spec/classes/mod/security_spec.rb index 042bf4d668..ad7d9644a1 100644 --- a/spec/classes/mod/security_spec.rb +++ b/spec/classes/mod/security_spec.rb @@ -42,6 +42,7 @@ is_expected.to contain_file('security.conf') .with_content(%r{^\s+SecAuditLogRelevantStatus "\^\(\?:5\|4\(\?!04\)\)"$}) .with_content(%r{^\s+SecAuditLogParts ABIJDEFHZ$}) + .with_content(%r{^\s+SecAuditLogType Serial$}) .with_content(%r{^\s+SecDebugLog /var/log/httpd/modsec_debug.log$}) .with_content(%r{^\s+SecAuditLog /var/log/httpd/modsec_audit.log$}) } @@ -78,12 +79,16 @@ ], audit_log_relevant_status: '^(?:5|4(?!01|04))', audit_log_parts: 'ABCDZ', + audit_log_type: 'Concurrent', + audit_log_storage_dir: '/var/log/httpd/audit', secdefaultaction: 'deny,status:406,nolog,auditlog', } end it { is_expected.to contain_file('security.conf').with_content %r{^\s+SecAuditLogRelevantStatus "\^\(\?:5\|4\(\?!01\|04\)\)"$} } it { is_expected.to contain_file('security.conf').with_content %r{^\s+SecAuditLogParts ABCDZ$} } + it { is_expected.to contain_file('security.conf').with_content %r{^\s+SecAuditLogType Concurrent$} } + it { is_expected.to contain_file('security.conf').with_content %r{^\s+SecAuditLogStorageDir /var/log/httpd/audit$} } it { is_expected.to contain_file('/etc/httpd/modsecurity.d/security_crs.conf').with_content %r{^\s*SecDefaultAction "phase:2,deny,status:406,nolog,auditlog"$} } it { is_expected.to contain_file('bar.conf').with( @@ -126,6 +131,7 @@ is_expected.to contain_file('security.conf') .with_content(%r{^\s+SecAuditLogRelevantStatus "\^\(\?:5\|4\(\?!04\)\)"$}) .with_content(%r{^\s+SecAuditLogParts ABIJDEFHZ$}) + .with_content(%r{^\s+SecAuditLogType Serial$}) .with_content(%r{^\s+SecDebugLog /var/log/apache2/modsec_debug.log$}) .with_content(%r{^\s+SecAuditLog /var/log/apache2/modsec_audit.log$}) } @@ -165,6 +171,8 @@ ], audit_log_relevant_status: '^(?:5|4(?!01|04))', audit_log_parts: 'ABCDZ', + audit_log_type: 'Concurrent', + audit_log_storage_dir: '/var/log/httpd/audit', secdefaultaction: 'deny,status:406,nolog,auditlog', } end @@ -173,6 +181,7 @@ (facts[:os]['release']['major'].to_i < 9 && facts[:os]['name'] == 'Debian') it { is_expected.to contain_file('security.conf').with_content %r{^\s+SecAuditLogRelevantStatus "\^\(\?:5\|4\(\?!01\|04\)\)"$} } it { is_expected.to contain_file('security.conf').with_content %r{^\s+SecAuditLogParts ABCDZ$} } + it { is_expected.to contain_file('security.conf').with_content %r{^\s+SecAuditLogStorageDir /var/log/httpd/audit$} } it { is_expected.to contain_file('/etc/modsecurity/security_crs.conf').with_content %r{^\s*SecDefaultAction "phase:2,deny,status:406,nolog,auditlog"$} } it { is_expected.to contain_file('bar.conf').with( diff --git a/templates/mod/security.conf.erb b/templates/mod/security.conf.erb index 638332e52e..5392bae3a5 100644 --- a/templates/mod/security.conf.erb +++ b/templates/mod/security.conf.erb @@ -45,7 +45,10 @@ SecAuditEngine RelevantOnly SecAuditLogRelevantStatus "<%= @audit_log_relevant_status %>" SecAuditLogParts <%= @audit_log_parts %> - SecAuditLogType Serial + SecAuditLogType <%= @audit_log_type %> + <%- if @audit_log_storage_dir -%> + SecAuditLogStorageDir <%= @audit_log_storage_dir %> + <%- end -%> SecArgumentSeparator & SecCookieFormat 0 <%- if scope.lookupvar('::osfamily') == 'Debian' -%>