_Public Classes_
-* [`ferm`](#ferm): Class: ferm This class manages ferm installation and rule generation on modern linux systems class{'ferm': manage_service => true, ip_v
+* [`ferm`](#ferm): This class manages ferm installation and rule generation on modern linux systems
_Private Classes_
Class: ferm
-This class manages ferm installation and rule generation on modern linux systems
+#### Examples
-class{'ferm':
- manage_service => true,
- ip_versions => ['ip6'],
-}
+##### deploy ferm without any configured rules, but also don't start the service or modify existing config files
-#### Examples
+```puppet
+include ferm
+```
-##### deploy ferm and start it, on node with only ipv6 enabled
+##### deploy ferm and start it, on nodes with only ipv6 enabled
```puppet
+class{'ferm':
+ manage_service => true,
+ ip_versions => ['ip6'],
+}
+```
+##### deploy ferm and don't touch chains from other software, like fail2ban and docker
+
+```puppet
+class{'ferm':
+ manage_service => true,
+ preserve_chains_in_tables => {
+ 'filter' => [
+ 'f2b-sshd',
+ 'DOCKER',
+ 'DOCKER-ISOLATION-STAGE-1',
+ 'DOCKER-ISOLATION-STAGE-2',
+ 'DOCKER-USER',
+ ]
+ }
+}
```
#### Parameters
Set list of versions of ip we want ot use.
Default value: ['ip', 'ip6']
+##### `preserve_chains_in_tables`
+
+Data type: `Hash[String[1],Array[String[1]]]`
+
+Hash with table:chains[] to use ferm @preserve for
+Default value: Empty Hash
+Allowed values: Hash with a list of tables and chains in it to preserve
+Example: {'nat' => ['PREROUTING', 'POSTROUTING']}
+
## Defined types
### ferm::chain
ferm::input_policy: DROP
ferm::forward_policy: DROP
ferm::output_policy: ACCEPT
+ferm::preserve_chains_in_tables: {}
ferm::rules: {}
ferm::input_log_dropped_packets: false
ferm::forward_log_dropped_packets: false
target => $ferm::configfile,
content => epp(
"${module_name}/ferm.conf.epp", {
- 'ip' => $_ip,
- 'configdirectory' => $ferm::configdirectory,
+ 'ip' => $_ip,
+ 'configdirectory' => $ferm::configdirectory,
+ 'preserve_chains_in_tables' => $ferm::preserve_chains_in_tables,
}
),
order => '50',
# Class: ferm
#
-# This class manages ferm installation and rule generation on modern linux systems
+# @summary This class manages ferm installation and rule generation on modern linux systems
#
-# @example deploy ferm and start it, on node with only ipv6 enabled
-# class{'ferm':
-# manage_service => true,
-# ip_versions => ['ip6'],
-# }
+# @example deploy ferm without any configured rules, but also don't start the service or modify existing config files
+# include ferm
+#
+# @example deploy ferm and start it, on nodes with only ipv6 enabled
+# class{'ferm':
+# manage_service => true,
+# ip_versions => ['ip6'],
+# }
+#
+# @example deploy ferm and don't touch chains from other software, like fail2ban and docker
+# class{'ferm':
+# manage_service => true,
+# preserve_chains_in_tables => {
+# 'filter' => [
+# 'f2b-sshd',
+# 'DOCKER',
+# 'DOCKER-ISOLATION-STAGE-1',
+# 'DOCKER-ISOLATION-STAGE-2',
+# 'DOCKER-USER',
+# ]
+# }
+# }
#
# @param manage_service Disable/Enable the management of the ferm daemon
# Default value: false
# Allowed values: (true|false)
# @param ip_versions Set list of versions of ip we want ot use.
# Default value: ['ip', 'ip6']
+# @param preserve_chains_in_tables Hash with table:chains[] to use ferm @preserve for
+# Default value: Empty Hash
+# Allowed values: Hash with a list of tables and chains in it to preserve
+# Example: {'nat' => ['PREROUTING', 'POSTROUTING']}
class ferm (
Boolean $manage_service,
Boolean $manage_configfile,
Boolean $input_log_dropped_packets,
Hash $rules,
Array[Enum['ip','ip6']] $ip_versions,
+ Hash[String[1],Array[String[1]]] $preserve_chains_in_tables,
) {
contain ferm::install
contain ferm::config
it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_concat__fragment('ferm_header.conf') }
it { is_expected.to contain_concat__fragment('ferm.conf') }
+ # the following string exists only if we preserve chains
+ it do
+ is_expected.to contain_concat__fragment('ferm.conf'). \
+ without_content(%r{@preserve;})
+ end
end
context 'with managed initfile' do
let :params do
it { is_expected.to contain_ferm__chain('OUTPUT') }
it { is_expected.to contain_ferm__chain('INPUT') }
end
+
+ context 'it preserves chains' do
+ let :params do
+ {
+ manage_configfile: true,
+ preserve_chains_in_tables: { 'nat' => %w[PREROUTING POSTROUTING] }
+ }
+ end
+
+ it { is_expected.to compile.with_all_deps }
+ it do
+ is_expected.to contain_concat__fragment('ferm.conf'). \
+ with_content(%r{domain \(ip ip6\) table nat \{})
+ end
+ it do
+ is_expected.to contain_concat__fragment('ferm.conf'). \
+ with_content(%r{chain PREROUTING @preserve;})
+ end
+ it do
+ is_expected.to contain_concat__fragment('ferm.conf'). \
+ with_content(%r{chain POSTROUTING @preserve;})
+ end
+ end
end
end
end
<%- | String[1] $ip,
Stdlib::Absolutepath $configdirectory,
+Hash[String[1], Array[String[1]]] $preserve_chains_in_tables,
| -%>
# End custom section
+<%- $preserve_chains_in_tables.each |$table, $chains| { -%>
+domain (<%= $ip %>) table <%= $table %> {
+ <%- $chains.each |$chain| { -%>
+ chain <%= $chain %> @preserve;
+ <%- } -%>
+}
+<%- } -%>
+
domain (<%= $ip %>) table filter {
chain INPUT {
interface lo ACCEPT;