aboutsummaryrefslogtreecommitdiff
path: root/manifests/rule.pp
blob: 68e88a2025014a173a0567d42aa692627dcfc98f (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
# defined resource which creates a single rule in a specific chain
# @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 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
# @param daddr The destination address we want to match
# @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
define ferm::rule (
  String[1] $chain,
  Ferm::Policies $policy,
  Ferm::Protocols $proto,
  String $comment = $name,
  Optional[Variant[Stdlib::Port,String[1]]] $dport = undef,
  Optional[Variant[Stdlib::Port,String[1]]] $sport = undef,
  Optional[Variant[Array, String[1]]] $saddr = undef,
  Optional[Variant[Array, String[1]]] $daddr = undef,
  Optional[String[1]] $proto_options = undef,
  Optional[String[1]] $interface = undef,
  Enum['absent','present'] $ensure = 'present',
){
  $proto_real = "proto ${proto}"

  $dport_real = $dport ? {
    undef   => '',
    default => "dport ${dport}",
  }
  $sport_real = $sport ? {
    undef   => '',
    default => "sport ${sport}",
  }
  if $saddr =~ Array {
    assert_type(Array[Stdlib::IP::Address], flatten($saddr)) |$expected, $actual| {
      fail( "The data type should be \'${expected}\', not \'${actual}\'. The data is ${flatten($saddr)}." )
        ''
    }
  }
  $saddr_real = $saddr ? {
    undef   => '',
    Array   => "saddr @ipfilter((${join(flatten($saddr).unique, ' ')}))",
    String  => "saddr @ipfilter((${saddr}))",
    default => '',
  }
  if $daddr =~ Array {
    assert_type(Array[Stdlib::IP::Address], flatten($daddr)) |$expected, $actual| {
      fail( "The data type should be \'${expected}\', not \'${actual}\'. The data is ${flatten($daddr)}." )
        ''
    }
  }
  $daddr_real = $daddr ? {
    undef   => '',
    Array   => "daddr @ipfilter((${join(flatten($daddr).unique, ' ')}))",
    String  => "daddr @ipfilter((${daddr}))",
    default => '',
  }
  $proto_options_real = $proto_options ? {
    undef   =>  '',
    default => $proto_options
  }
  $comment_real = "mod comment comment '${comment}'"

  $rule = squeeze("${comment_real} ${proto_real} ${proto_options_real} ${dport_real} ${sport_real} ${daddr_real} ${saddr_real} ${policy};", ' ')
  if $ensure == 'present' {
    if $interface {
      unless defined(Concat::Fragment["${chain}-${interface}-aaa"]) {
        concat::fragment{"${chain}-${interface}-aaa":
          target  => "${ferm::configdirectory}/chains/${chain}.conf",
          content => "interface ${interface} {\n",
          order   => $interface,
        }
      }

      concat::fragment{"${chain}-${interface}-${name}":
        target  => "${ferm::configdirectory}/chains/${chain}.conf",
        content => "  ${rule}\n",
        order   => $interface,
      }

      unless defined(Concat::Fragment["${chain}-${interface}-zzz"]) {
        concat::fragment{"${chain}-${interface}-zzz":
          target  => "${ferm::configdirectory}/chains/${chain}.conf",
          content => "}\n",
          order   => $interface,
        }
      }
    } else {
      concat::fragment{"${chain}-${name}":
        target  => "${ferm::configdirectory}/chains/${chain}.conf",
        content => "${rule}\n",
      }
    }
  }
}