aboutsummaryrefslogtreecommitdiff
path: root/manifests/chain.pp
blob: cfa4f803749e1640648756b40fb6d99ddf34d3ef (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
94
95
96
97
98
99
100
101
102
103
104
105
106
# @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. By default, we enable conntrack only for the filter INPUT chain
# @param drop_invalid_packets_with_conntrack Enable/Disable the `mod conntrack ctstate INVALID DROP` statement. Only works if `$disable_conntrack` is `false` in this chain. You can set this to false if your policy is DROP.
# @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)
#   Allowed values: (ACCEPT|DROP) (see Ferm::Policies type)
# @param chain Name of the chain that should be managed
#   Allowed values: String[1]
# @param table Select the target table (filter/raw/mangle/nat)
#   Allowed values: (filter|raw|mangle|nat) (see Ferm::Tables type)
# @param ip_versions Set list of versions of ip we want ot use.
# @param content custom string that will be written into th chain file
#
define ferm::chain (
  Boolean $log_dropped_packets                 = false,
  Boolean $drop_invalid_packets_with_conntrack = false,
  Boolean $disable_conntrack                   = true,
  String[1] $chain                             = $name,
  Optional[Ferm::Policies] $policy             = undef,
  Ferm::Tables $table                          = 'filter',
  Array[Enum['ip', 'ip6']] $ip_versions        = $ferm::ip_versions,
  Optional[String[1]] $content                 = undef,
) {
  # 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',
  }

  if $content {
    concat::fragment { "${table}-${chain}-custom-content":
      target  => $filename,
      content => epp(
        "${module_name}/ferm_chain_custom.conf.epp", {
          'content' => $content,
        },
      ),
    }
  } else {
    concat::fragment { "${table}-${chain}-policy":
      target  => $filename,
      content => epp(
        "${module_name}/ferm_chain_header.conf.epp", {
          'policy'                              => $policy,
          'disable_conntrack'                   => $disable_conntrack,
          'drop_invalid_packets_with_conntrack' => $drop_invalid_packets_with_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],
  }
}