diff --git a/manifests/rule_group.pp b/manifests/rule_group.pp new file mode 100644 index 0000000..8d8ff4b --- /dev/null +++ b/manifests/rule_group.pp @@ -0,0 +1,45 @@ +# @summary Create a group of related rules with a comment header +# +# @example Creating 'watch' rules +# auditd::rule_group { 'Tools to change group identifiers': +# rules => [ +# { +# 'files' => ['/usr/sbin/groupadd','/usr/sbin/groupmod','/usr/sbin/addgroup'], +# 'permissions' => ['x'], +# 'keys' => ['group_modification'], +# } +# { +# 'files' => ['/usr/sbin/useradd','/usr/sbin/usermod','/usr/sbin/adduser'], +# 'permissions' => ['x'], +# 'keys' => ['user_modification'], +# } +# ], +# } +# +# @example Freeform syscall rules with default_keys set +# auditd::rule_group { 'Kernel module loading and unloading': +# rules => [ +# '-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/insmod', +# '-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/modprobe', +# '-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/rmmod', +# ], +# default_keys => ['modules'], +# } +# +# @param rules An array of rules to include. +# @param default_keys An array of keys you want added to every rule in this group +# @param comment The comment to use as a header for this group of rules. Defaults to the `rule_group` title. +# @param order Where in the audit rules file to place this group. +define auditd::rule_group( + Array[Variant[String[1],Auditd::WatchRule],1] $rules, + Array[String[1]] $default_keys = [], + String[1] $comment = $name, + $order = 10, +) +{ + concat::fragment{ "auditd_rule_group_fragment_${name}": + target => $auditd::rules_file, + order => $order, + content => epp('auditd/rule_group.epp',{'comment' => $comment, 'rules' => $rules, 'default_keys' => $default_keys, }), + } +} diff --git a/spec/defines/rule_group_spec.rb b/spec/defines/rule_group_spec.rb new file mode 100644 index 0000000..72a6463 --- /dev/null +++ b/spec/defines/rule_group_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe 'auditd::rule_group' do + let (:facts) {{ + :osfamily => 'RedHat', + :operatingsystem => 'RedHat', + :operatingsystemrelease => '7', + :concat_basedir => '/var/lib/puppet/concat', + }} + let :pre_condition do + 'class{"auditd": } ' + end + describe 'Reference example 1' do + let(:title) { 'Tools to change group identifiers' } + let(:params) {{ + rules: [ + { + 'files' => ['/usr/sbin/groupadd','/usr/sbin/groupmod','/usr/sbin/addgroup'], + 'permissions' => ['x'], + 'keys' => ['group_modification'], + }, + { + 'files' => ['/usr/sbin/useradd','/usr/sbin/usermod','/usr/sbin/adduser'], + 'permissions' => ['x'], + 'keys' => ['user_modification'], + } + ], + }} + expected_content=<<-HEREDOC +# Tools to change group identifiers +-w /usr/sbin/groupadd -p x -k group_modification +-w /usr/sbin/groupmod -p x -k group_modification +-w /usr/sbin/addgroup -p x -k group_modification +-w /usr/sbin/useradd -p x -k user_modification +-w /usr/sbin/usermod -p x -k user_modification +-w /usr/sbin/adduser -p x -k user_modification + +HEREDOC + it { is_expected.to contain_concat_fragment('auditd_rule_group_fragment_Tools to change group identifiers'). + with_target('/etc/audit/rules.d/puppet.rules'). + with_content(expected_content). + with_order(10) + } + end + describe 'Reference example 2' do + let(:title) { 'Kernel module loading and unloading' } + let(:params) {{ + rules: [ + '-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/insmod', + '-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/modprobe', + '-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/rmmod', + ], + default_keys: ['modules'], + }} + expected_content=<<-HEREDOC +# Kernel module loading and unloading +-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/insmod -k modules +-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/modprobe -k modules +-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/rmmod -k modules + +HEREDOC + it { is_expected.to contain_concat_fragment('auditd_rule_group_fragment_Kernel module loading and unloading'). + with_target('/etc/audit/rules.d/puppet.rules'). + with_content(expected_content). + with_order(10) + } + end +end diff --git a/templates/rule_group.epp b/templates/rule_group.epp new file mode 100644 index 0000000..70a9ab7 --- /dev/null +++ b/templates/rule_group.epp @@ -0,0 +1,19 @@ +<%- | + String $comment, + Array[Variant[String[1],Auditd::WatchRule],1] $rules, + Array[String] $default_keys = [], +| -%> +# <%= $comment %> +<% $rules.each |$rule| {-%> +<%- + case $rule { + String: { + $keys = $default_keys.map |$key| {" -k ${key}"}.join('') + $rule_content = "${rule}${keys}" + } + Auditd::WatchRule: { $rule_content = epp('auditd/watch_rule.epp', {rule => $rule, default_keys => $default_keys } ).chomp } + } +-%> +<%= $rule_content %> +<% } -%> + diff --git a/templates/watch_rule.epp b/templates/watch_rule.epp new file mode 100644 index 0000000..e6dbb6b --- /dev/null +++ b/templates/watch_rule.epp @@ -0,0 +1,7 @@ +<%- | + Auditd::WatchRule $rule, + Array[String] $default_keys, +| -%> +<% $rule['files'].each |$file| {-%> +-w <%= $file %> <% if 'permissions' in $rule {-%> -p <%= $rule['permissions'].join('') %><% } -%><%= (pick($rule['keys'], []) + $default_keys).map |$key| {" -k ${key}"}.join('') %> +<% } -%> diff --git a/types/watchrule.pp b/types/watchrule.pp new file mode 100644 index 0000000..08fcb15 --- /dev/null +++ b/types/watchrule.pp @@ -0,0 +1,5 @@ +type Auditd::WatchRule = Struct[{ + files => Array[Stdlib::Unixpath,1], + Optional[permissions] => Array[Enum['r','w','x','a'],1], + Optional[keys] => Array[String[1]], +}]