3 # This rule will send IPv4 and/or IPv6 traffic using either TCP and/or UDP
4 # optionally going to a port, optionally from/to addresses/networks from
5 # one table (INPUT by default) to some target (ACCEPT by default).
9 # ferm::rule::simple { '01-dsa-bind':
10 # description => 'Allow nameserver access',
11 # proto => ['udp', 'tcp'],
17 # ferm::rule::simple { 'dsa-smtp':
18 # description => 'Allow smtp access from the world',
24 # @@ferm::rule::simple { "submission-from-${::fqdn}":
25 # tag => 'smtp::server::submission::to::mail-relay',
26 # chain => 'submission',
27 # saddr => $base::public_addresses,
30 # ferm::rule::simple { 'submission-from-satellites':
31 # target => 'submission',
32 # port => 'submission',
34 # Ferm::Rule::Simple <<| tag == 'smtp::server::submission::to::mail-relay' |>>
37 # @param proto tcp or udp or both.
38 # @param port one or more ports or port ranges.
39 # @param saddr one or more source addresses/networks.
40 # @param daddr one or more destination addresses/networks.
41 # @param domain netfilter domain: ip (IPv4), ip6 (IPv6), or both.
42 # @param table netfilter table
43 # @param chain netfilter chain
44 # @param target netfilter target
45 # @param description a description of the rule
46 # @param prio Priority/Order of the rule
47 define ferm::rule::simple (
48 String $description = '',
49 Variant[Enum['tcp', 'udp'], Array[Enum['tcp', 'udp']]] $proto = 'tcp',
50 Optional[Variant[Integer, Array[Integer], String, Array[String]]] $port = undef,
51 Optional[Variant[Stdlib::IP::Address, Array[Stdlib::IP::Address]]] $saddr = undef,
52 Optional[Variant[Stdlib::IP::Address, Array[Stdlib::IP::Address]]] $daddr = undef,
53 Variant[Enum['ip', 'ip6'], Array[Enum['ip', 'ip6']]] $domain = ['ip', 'ip6'],
54 String $table = 'filter',
55 String $chain = 'INPUT',
56 String $target = 'ACCEPT',
61 $filter_port = $port != undef
62 $filter_saddr = $saddr != undef
63 $filter_daddr = $daddr != undef
65 $real_domain = Array($domain, true)
66 $real_proto = Array($proto, true)
67 $real_port = Array($port, true)
68 $real_saddr = Array($saddr, true)
69 $real_daddr = Array($daddr, true)
72 "/etc/ferm/dsa.d/${prio}_${name}":
75 notify => Exec['ferm reload'],
76 content => inline_template( @(EOF) ),
77 domain (<%= @real_domain.join(' ') %>) {
80 # netfilter chain names are limited to 28 characters, so if name is too long, we'll have to do something about that
82 if name.size > 20 then
84 name = 'dgst-' + Digest::SHA256.hexdigest(name)[0,15]
86 tail = "jump #{@target}"
90 [ [@filter_daddr, 'daddr', @real_daddr],
91 [@filter_saddr, 'saddr', @real_saddr],
92 [@filter_port , 'dport', @real_port ] ].each do |do_filter, filter_name, arr|
94 filter = "#{filter_name} (#{ arr.join(' ') })"
95 if (arr.size > 2) then
96 target = "#{name}-#{filter_name}"; prev_tail = tail; tail = "jump #{target}"
97 out << "chain #{target} { #{filter} #{prev_tail}; }"
99 tail = "#{filter} #{tail}"
102 out << "chain #{@chain} proto (#{ @real_proto.join(' ') }) #{tail};"