aboutsummaryrefslogtreecommitdiff
path: root/manifests
diff options
context:
space:
mode:
Diffstat (limited to 'manifests')
-rw-r--r--manifests/chain.pp71
-rw-r--r--manifests/config.pp29
-rw-r--r--manifests/init.pp9
-rw-r--r--manifests/rule.pp76
4 files changed, 163 insertions, 22 deletions
diff --git a/manifests/chain.pp b/manifests/chain.pp
index 1198f62..a01b9b4 100644
--- a/manifests/chain.pp
+++ b/manifests/chain.pp
@@ -1,23 +1,57 @@
-# defined resource which creates all rules for one chain
-# @param policy Set the default policy for a CHAIN
+# @summary This defined resource manages ferm/iptables chains
+#
+# @example create a custom chain, e.g. for all incoming SSH connections
+# ferm::chain{'check-ssh':
+# chain => 'SSH',
+# disable_conntrack => true,
+# log_dropped_packets => true,
+# }
+#
# @param disable_conntrack Disable/Enable usage of conntrack
-# @param chain Name of the chain that should be managed
# @param log_dropped_packets Enable/Disable logging of packets to the kernel log, if no explicit chain matched
+# @param policy Set the default policy for CHAIN (works only for builtin chains)
+# Default value: undef
+# Allowed values: (ACCEPT|DROP) (see Ferm::Policies type)
+# @param chain Name of the chain that should be managed
+# Default value: $name (resource name)
+# Allowed values: String[1]
+# @param table Select the target table (filter/raw/mangle/nat)
+# Default value: 'filter'
+# Allowed values: (filter|raw|mangle|nat) (see Ferm::Tables type)
define ferm::chain (
- Ferm::Policies $policy,
Boolean $disable_conntrack,
Boolean $log_dropped_packets,
- String[1] $chain = $name,
+ String[1] $chain = $name,
+ Optional[Ferm::Policies] $policy = undef,
+ Ferm::Tables $table = 'filter',
) {
+ # prevent unmanaged files due to new naming schema
+ # keep the default "filter" chains in the original location
+ # only prefix chains in other tables with the table name
+ if $table == 'filter' and $chain in ['INPUT', 'FORWARD', 'OUTPUT'] {
+ $filename = "${ferm::configdirectory}/chains/${chain}.conf"
+ } else {
+ $filename = "${ferm::configdirectory}/chains/${table}-${chain}.conf"
+ }
+
+ $builtin_chains = {
+ 'raw' => ['PREROUTING', 'OUTPUT'],
+ 'nat' => ['PREROUTING', 'INPUT', 'OUTPUT', 'POSTROUTING'],
+ 'mangle' => ['PREROUTING', 'INPUT', 'FORWARD', 'OUTPUT', 'POSTROUTING'],
+ 'filter' => ['INPUT', 'FORWARD', 'OUTPUT'],
+ }
+
+ if $policy and ! ($chain in $builtin_chains[$table]) {
+ fail("Can only set a default policy for builtin chains. '${chain}' is not a builtin chain.")
+ }
# concat resource for the chain
- $filename = downcase($chain)
- concat{"${ferm::configdirectory}/chains/${chain}.conf":
+ concat{$filename:
ensure => 'present',
}
- concat::fragment{"${chain}-policy":
- target => "${ferm::configdirectory}/chains/${chain}.conf",
+ concat::fragment{"${table}-${chain}-policy":
+ target => $filename,
content => epp(
"${module_name}/ferm_chain_header.conf.epp", {
'policy' => $policy,
@@ -28,10 +62,25 @@ define ferm::chain (
}
if $log_dropped_packets {
- concat::fragment{"${chain}-footer":
- target => "${ferm::configdirectory}/chains/${chain}.conf",
+ concat::fragment{"${table}-${chain}-footer":
+ target => $filename,
content => epp("${module_name}/ferm_chain_footer.conf.epp", { 'chain' => $chain }),
order => 'zzzzzzzzzzzzzzzzzzzzz',
}
}
+
+ # make sure the generated snippet is actually included
+ concat::fragment{"${table}-${chain}-config-include":
+ target => $ferm::configfile,
+ content => epp(
+ "${module_name}/ferm-table-chain-config-include.epp", {
+ 'ip' => join($ferm::ip_versions, ' '),
+ 'table' => $table,
+ 'chain' => $chain,
+ 'filename' => $filename,
+ }
+ ),
+ order => "${table}-${chain}",
+ require => Concat[$filename],
+ }
}
diff --git a/manifests/config.pp b/manifests/config.pp
index 25607ad..efabe2b 100644
--- a/manifests/config.pp
+++ b/manifests/config.pp
@@ -57,4 +57,33 @@ class ferm::config {
disable_conntrack => $ferm::disable_conntrack,
log_dropped_packets => $ferm::output_log_dropped_packets,
}
+
+ # initialize default tables and chains
+ ['PREROUTING', 'OUTPUT'].each |$raw_chain| {
+ ferm::chain{"raw-${raw_chain}":
+ chain => $raw_chain,
+ policy => 'ACCEPT',
+ disable_conntrack => true,
+ log_dropped_packets => false,
+ table => 'raw',
+ }
+ }
+ ['PREROUTING', 'INPUT', 'OUTPUT', 'POSTROUTING'].each |$nat_chain| {
+ ferm::chain{"nat-${nat_chain}":
+ chain => $nat_chain,
+ policy => 'ACCEPT',
+ disable_conntrack => true,
+ log_dropped_packets => false,
+ table => 'nat',
+ }
+ }
+ ['PREROUTING', 'INPUT', 'FORWARD', 'OUTPUT', 'POSTROUTING'].each |$mangle_chain| {
+ ferm::chain{"mangle-${mangle_chain}":
+ chain => $mangle_chain,
+ policy => 'ACCEPT',
+ disable_conntrack => true,
+ log_dropped_packets => false,
+ table => 'mangle',
+ }
+ }
}
diff --git a/manifests/init.pp b/manifests/init.pp
index 221e148..d2251c9 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -45,13 +45,13 @@
# Allowed values: (true|false)
# @param forward_policy Default policy for the FORWARD chain
# Default value: DROP
-# Allowed values: (ACCEPT|DROP|REJECT)
+# Allowed values: (ACCEPT|DROP)
# @param output_policy Default policy for the OUTPUT chain
# Default value: ACCEPT
-# Allowed values: (ACCEPT|DROP|REJECT)
+# Allowed values: (ACCEPT|DROP)
# @param input_policy Default policy for the INPUT chain
# Default value: DROP
-# Allowed values: (ACCEPT|DROP|REJECT)
+# Allowed values: (ACCEPT|DROP)
# @param rules A hash that holds all data for ferm::rule
# Default value: Empty Hash
# Allowed value: Any Hash
@@ -95,6 +95,9 @@ class ferm (
-> Class['ferm::config']
~> Class['ferm::service']
+ Ferm::Chain <| |>
+ ~> Class['ferm::service']
+
$rules.each |$rulename, $attributes| {
ferm::rule{$rulename:
* => $attributes,
diff --git a/manifests/rule.pp b/manifests/rule.pp
index 68e88a2..4f2c985 100644
--- a/manifests/rule.pp
+++ b/manifests/rule.pp
@@ -1,8 +1,31 @@
-# defined resource which creates a single rule in a specific chain
+# @summary This defined resource manages a single rule in a specific chain
+#
+# @example Jump to the 'SSH' chain for all incoming SSH traffic (see chain.pp examples on how to create the chain)
+# ferm::rule{'incoming-ssh':
+# chain => 'INPUT',
+# action => 'SSH',
+# proto => 'tcp',
+# dport => '22',
+# }
+#
+# @example Create a rule in the 'SSH' chain to allow connections from localhost
+# ferm::rule{'allow-ssh-localhost':
+# chain => 'SSH',
+# action => 'ACCEPT',
+# proto => 'tcp',
+# dport => '22',
+# saddr => '127.0.0.1',
+# }
+#
# @param chain Configure the chain where we want to add the rule
-# @param policy Configure what we want to do with the packet (drop, accept, log...)
# @param proto Which protocol do we want to match, typically UDP or TCP
# @param comment A comment that will be added to the ferm config and to ip{,6}tables
+# @param action Configure what we want to do with the packet (drop/accept/reject, can also be a target chain name)
+# Default value: undef
+# Allowed values: (RETURN|ACCEPT|DROP|REJECT|NOTRACK|LOG|MARK|DNAT|SNAT|MASQUERADE|REDIRECT|String[1])
+# @param policy Configure what we want to do with the packet (drop/accept/reject, can also be a target chain name) [DEPRECATED]
+# Default value: undef
+# Allowed values: (RETURN|ACCEPT|DROP|REJECT|NOTRACK|LOG|MARK|DNAT|SNAT|MASQUERADE|REDIRECT|String[1])
# @param dport The destination port, can be a range as string or a single port number as integer
# @param sport The source port, can be a range as string or a single port number as integer
# @param saddr The source address we want to match
@@ -10,11 +33,15 @@
# @param proto_options Optional parameters that will be passed to the protocol (for example to match specific ICMP types)
# @param interface an Optional interface where this rule should be applied
# @param ensure Set the rule to present or absent
+# @param table Select the target table (filter/raw/mangle/nat)
+# Default value: filter
+# Allowed values: (filter|raw|mangle|nat) (see Ferm::Tables type)
define ferm::rule (
String[1] $chain,
- Ferm::Policies $policy,
Ferm::Protocols $proto,
String $comment = $name,
+ Optional[Ferm::Actions] $action = undef,
+ Optional[Ferm::Policies] $policy = undef,
Optional[Variant[Stdlib::Port,String[1]]] $dport = undef,
Optional[Variant[Stdlib::Port,String[1]]] $sport = undef,
Optional[Variant[Array, String[1]]] $saddr = undef,
@@ -22,7 +49,31 @@ define ferm::rule (
Optional[String[1]] $proto_options = undef,
Optional[String[1]] $interface = undef,
Enum['absent','present'] $ensure = 'present',
+ Ferm::Tables $table = 'filter',
){
+
+ if $policy and $action {
+ fail('Cannot specify both policy and action. Do not provide policy when using the new action param.')
+ } elsif $policy and ! $action {
+ warning('The param "policy" is deprecated (superseded by "action") and will be dropped in a future release.')
+ $action_temp = $policy
+ } elsif $action and ! $policy {
+ $action_temp = $action
+ } else {
+ fail('Exactly one of "action" or the deprecated "policy" param is required.')
+ }
+
+ if $action_temp in ['RETURN', 'ACCEPT', 'DROP', 'REJECT', 'NOTRACK', 'LOG',
+ 'MARK', 'DNAT', 'SNAT', 'MASQUERADE', 'REDIRECT'] {
+ $action_real = $action_temp
+ } else {
+ # assume the action contains a target chain, so prefix it with the "jump" statement
+ $action_real = "jump ${action_temp}"
+ # make sure the target chain is created before we try to add rules to it
+ Ferm::Chain <| chain == $action_temp and table == $table |> -> Ferm::Rule[$name]
+ }
+
+
$proto_real = "proto ${proto}"
$dport_real = $dport ? {
@@ -63,33 +114,42 @@ define ferm::rule (
}
$comment_real = "mod comment comment '${comment}'"
- $rule = squeeze("${comment_real} ${proto_real} ${proto_options_real} ${dport_real} ${sport_real} ${daddr_real} ${saddr_real} ${policy};", ' ')
+ # prevent unmanaged files due to new naming schema
+ # keep the default "filter" chains in the original location
+ # only prefix chains in other tables with the table name
+ if $table == 'filter' and $chain in ['INPUT', 'FORWARD', 'OUTPUT'] {
+ $filename = "${ferm::configdirectory}/chains/${chain}.conf"
+ } else {
+ $filename = "${ferm::configdirectory}/chains/${table}-${chain}.conf"
+ }
+
+ $rule = squeeze("${comment_real} ${proto_real} ${proto_options_real} ${dport_real} ${sport_real} ${daddr_real} ${saddr_real} ${action_real};", ' ')
if $ensure == 'present' {
if $interface {
unless defined(Concat::Fragment["${chain}-${interface}-aaa"]) {
concat::fragment{"${chain}-${interface}-aaa":
- target => "${ferm::configdirectory}/chains/${chain}.conf",
+ target => $filename,
content => "interface ${interface} {\n",
order => $interface,
}
}
concat::fragment{"${chain}-${interface}-${name}":
- target => "${ferm::configdirectory}/chains/${chain}.conf",
+ target => $filename,
content => " ${rule}\n",
order => $interface,
}
unless defined(Concat::Fragment["${chain}-${interface}-zzz"]) {
concat::fragment{"${chain}-${interface}-zzz":
- target => "${ferm::configdirectory}/chains/${chain}.conf",
+ target => $filename,
content => "}\n",
order => $interface,
}
}
} else {
concat::fragment{"${chain}-${name}":
- target => "${ferm::configdirectory}/chains/${chain}.conf",
+ target => $filename,
content => "${rule}\n",
}
}