f3a058d2184c474fca6774c4db0c10cca0748e10
[mirror/dsa-puppet.git] / modules / ferm / manifests / rule / simple.pp
1 # a plain, simple ferm rule
2 #
3 # @param proto  tcp or udp or both.
4 # @param port   one or more ports or port ranges.
5 # @param saddr  one or more source addresses/networks.
6 # @param daddr  one or more destination addresses/networks.
7 # @param domain netfilter domain: ip (IPv4), ip6 (IPv6), or both.
8 # @param table  netfilter table
9 # @param chain  netfilter chain
10 # @param target netfilter target
11 # @param description a description of the rule
12 # @param prio   Priority/Order of the rule
13 define ferm::rule::simple (
14   String $description = '',
15   Variant[Enum['tcp', 'udp'], Array[Enum['tcp', 'udp']]] $proto = 'tcp',
16   Optional[Variant[Integer, Array[Integer], String, Array[String]]] $port = undef,
17   Optional[Variant[Stdlib::IP::Address, Array[Stdlib::IP::Address]]] $saddr = undef,
18   Optional[Variant[Stdlib::IP::Address, Array[Stdlib::IP::Address]]] $daddr = undef,
19   Variant[Enum['ip', 'ip6'], Array[Enum['ip', 'ip6']]] $domain = ['ip', 'ip6'],
20   String $table = 'filter',
21   String $chain = 'INPUT',
22   String $target = 'ACCEPT',
23   String $prio = '10',
24 ) {
25   include ferm
26
27   $filter_port  = $port  != undef
28   $filter_saddr = $saddr != undef
29   $filter_daddr = $daddr != undef
30
31   $real_domain = Array($domain, true)
32   $real_proto  = Array($proto, true)
33   $real_port   = Array($port, true)
34   $real_saddr  = Array($saddr, true)
35   $real_daddr  = Array($daddr, true)
36
37   file {
38     "/etc/ferm/dsa.d/${prio}_${name}":
39       ensure  => 'present',
40       mode    => '0400',
41       notify  => Exec['ferm reload'],
42       content => inline_template( @(EOF) ),
43                     domain (<%= @real_domain.join(' ') %>) {
44                       table <%= @table %> {
45                         <%-
46                         # netfilter chain names are limited to 28 characters, so if name is too long, we'll have to do something about that
47                         name = @name
48                         if name.size > 20 then
49                           require 'digest'
50                           name = 'dgst-' + Digest::SHA256.hexdigest(name)[0,15]
51                         end
52                         tail = "jump #{@target}"
53                         -%>
54                         <%=
55                           out = []
56                           [ [@filter_daddr, 'daddr', @real_daddr],
57                             [@filter_saddr, 'saddr', @real_saddr],
58                             [@filter_port , 'dport', @real_port ] ].each do |do_filter, filter_name, arr|
59                             next unless do_filter
60                             filter = "#{filter_name} (#{ arr.join(' ') })"
61                             if (arr.size > 2) then
62                               target = "#{name}-#{filter_name}"; prev_tail = tail; tail = "jump #{target}"
63                               out << "chain #{target} { #{filter} #{prev_tail}; }"
64                             else
65                               tail = "#{filter} #{tail}"
66                             end
67                           end
68                           out << "chain #{@chain} proto (#{ @real_proto.join(' ') }) #{tail};"
69                           out.join("\n")
70                         %>
71                       }
72                     }
73                     | EOF
74   }
75 }