aboutsummaryrefslogtreecommitdiff
path: root/manifests/chain.pp
blob: 1be7e832ffacbcbfb2ec3c37043ae65bc2a6dc06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# @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 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)
# @param ip_versions Set list of versions of ip we want ot use.
#   Default value: $ferm::ip_versions
define ferm::chain (
  Boolean $disable_conntrack,
  Boolean $log_dropped_packets,
  String[1] $chain                     = $name,
  Optional[Ferm::Policies] $policy     = undef,
  Ferm::Tables $table                  = 'filter',
  Array[Enum['ip','ip6']] $ip_versions = $ferm::ip_versions,
) {
  # 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
  concat{$filename:
    ensure  => 'present',
  }

  concat::fragment{"${table}-${chain}-policy":
    target  => $filename,
    content => epp(
      "${module_name}/ferm_chain_header.conf.epp", {
        'policy'            => $policy,
        'disable_conntrack' => $disable_conntrack,
      }
    ),
    order   => '01',
  }

  if $log_dropped_packets {
    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
  # the ordering here is hacked. We might end up with multiple blocks for the same filter+chain.
  # This happens if we add ipset matches. We suffix this ordering with `bbb`. This allows us to
  # insert ipset matches before other rules by adding `-aaa` or
  # insert them at the end by ordering them with `-ccc`.
  concat::fragment{"${table}-${chain}-config-include":
    target  => $ferm::configfile,
    content => epp(
      "${module_name}/ferm-table-chain-config-include.epp", {
        'ip'       => join($ip_versions, ' '),
        'table'    => $table,
        'chain'    => $chain,
        'filename' => $filename,
      }
    ),
    order   => "${table}-${chain}-bbb",
    require => Concat[$filename],
  }
}