From 83382bb509ecde5818ff9b68c176ef080648e879 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 10:33:27 +0100 Subject: [PATCH 01/25] Add nftables::simplerule --- manifests/simplerule.pp | 39 +++++++++++++++++++++++++++++ spec/defines/simplerule_spec.rb | 44 +++++++++++++++++++++++++++++++++ templates/simplerule.epp | 16 ++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 manifests/simplerule.pp create mode 100644 spec/defines/simplerule_spec.rb create mode 100644 templates/simplerule.epp diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp new file mode 100644 index 00000000..8e4b5c66 --- /dev/null +++ b/manifests/simplerule.pp @@ -0,0 +1,39 @@ +# This class is meant to be useful to ease the migration from the Firewall type +# for simple use cases. The coverage of all the casuistry is rather low so for +# any case not covered by nftables::simplerule please just use nftables::rule. +define nftables::simplerule( + Enum['present','absent'] + $ensure = 'present', + Pattern[/^[-a-zA-Z0-9_]+$/] + $setname = $title, + Pattern[/^\d\d$/] + $order = '50', + String + $chain = 'default_in', + Optional[String] + $table = 'inet-filter', + Enum['accept', 'drop'] + $action = 'accept', + Optional[String] + $comment = undef, + Optional[Integer[1, 65535]] + $dport = undef, + Optional[Enum['tcp', 'udp']] + $proto = undef, +){ + + if $ensure == 'present' { + nftables::rule{"${chain}-${title}": + content => epp('nftables/simplerule.epp', + { + 'action' => $action, + 'comment' => $comment, + 'dport' => $dport, + 'proto' => $proto, + } + ), + order => $order, + table => $table, + } + } +} diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb new file mode 100644 index 00000000..0e4563fb --- /dev/null +++ b/spec/defines/simplerule_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe 'nftables::simplerule' do + let(:pre_condition) { 'include nftables' } + + let(:title) { 'my_default_rule_name' } + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + describe 'minimum instantiation' do + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'accept', + order: 50, + ) + } + end + + describe 'all parameters provided' do + let(:title) { 'my_big_rule' } + let(:params) do + { + action: 'accept', + comment: 'this is my rule', + dport: 333, + proto: 'udp', + chain: 'default_out', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_out-my_big_rule').with( + content: 'udp dport 333 comment "this is my rule" accept', + order: 50, + ) + } + end + end + end +end diff --git a/templates/simplerule.epp b/templates/simplerule.epp new file mode 100644 index 00000000..e5787b8a --- /dev/null +++ b/templates/simplerule.epp @@ -0,0 +1,16 @@ +<%- | String $action, + Optional[String] $comment, + Optional[Integer] $dport, + Optional[String] $proto, +| -%> +<%- if $proto and $dport { + $_destination = "${proto} dport ${dport}" +} else { + $_destination = undef +} -%> +<%- if $comment { + $_comment = "comment \"${comment}\"" +} else { + $_comment = undef +} -%> +<%= strip([$_destination, $_comment, $action].join(' ')) -%> From fb65734ddb5f6bff284d024a587cd5b85111a923 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 11:22:54 +0100 Subject: [PATCH 02/25] s/setname/rulename --- manifests/simplerule.pp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 8e4b5c66..d0dca034 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -5,7 +5,7 @@ Enum['present','absent'] $ensure = 'present', Pattern[/^[-a-zA-Z0-9_]+$/] - $setname = $title, + $rulename = $title, Pattern[/^\d\d$/] $order = '50', String @@ -23,7 +23,7 @@ ){ if $ensure == 'present' { - nftables::rule{"${chain}-${title}": + nftables::rule{"${chain}-${rulename}": content => epp('nftables/simplerule.epp', { 'action' => $action, From 3a52fb41aeb0adc8ad5680ea88bc2b8d4ccfc173 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 14:40:49 +0100 Subject: [PATCH 03/25] Richer dport --- manifests/simplerule.pp | 6 +++++- spec/defines/simplerule_spec.rb | 36 +++++++++++++++++++++++++++++++-- templates/simplerule.epp | 12 +++++++---- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index d0dca034..fd4547a8 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -16,12 +16,16 @@ $action = 'accept', Optional[String] $comment = undef, - Optional[Integer[1, 65535]] + Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $dport = undef, Optional[Enum['tcp', 'udp']] $proto = undef, ){ + if $dport and !$proto { + fail('Specifying a transport protocol via $proto is mandatory when passing a port') + } + if $ensure == 'present' { nftables::rule{"${chain}-${rulename}": content => epp('nftables/simplerule.epp', diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 0e4563fb..8cf0ebf4 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -14,7 +14,7 @@ it { is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( content: 'accept', - order: 50, + order: '50', ) } end @@ -35,7 +35,39 @@ it { is_expected.to contain_nftables__rule('default_out-my_big_rule').with( content: 'udp dport 333 comment "this is my rule" accept', - order: 50, + order: '50', + ) + } + end + + describe 'port range' do + let(:params) do + { + dport: '333-334', + proto: 'tcp', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'tcp dport 333-334 accept', + ) + } + end + + describe 'port array' do + let(:params) do + { + dport: [333, 335], + proto: 'tcp', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'tcp dport {333, 335} accept', ) } end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index e5787b8a..e6137786 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -1,10 +1,14 @@ <%- | String $action, Optional[String] $comment, - Optional[Integer] $dport, + Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $dport, Optional[String] $proto, | -%> -<%- if $proto and $dport { - $_destination = "${proto} dport ${dport}" +<%- if $proto and $dport { + if $dport =~ Array { + $_destination = "${proto} dport {${dport.join(', ')}}" + } else { + $_destination = "${proto} dport $dport" + } } else { $_destination = undef } -%> @@ -13,4 +17,4 @@ } else { $_comment = undef } -%> -<%= strip([$_destination, $_comment, $action].join(' ')) -%> +<%= regsubst(strip([$_destination, $_comment, $action].join(' ')), '\s+', ' ', 'G') -%> From 316bc3f87e381b4eeea4533f81b939af70ea27b1 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 16:07:54 +0100 Subject: [PATCH 04/25] Allow IPv4 and IPv6 only rules --- manifests/simplerule.pp | 2 +- spec/defines/simplerule_spec.rb | 32 ++++++++++++++++++++++++++++++++ templates/simplerule.epp | 19 ++++++++++++++++--- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index fd4547a8..a3d06f73 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -18,7 +18,7 @@ $comment = undef, Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $dport = undef, - Optional[Enum['tcp', 'udp']] + Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, ){ diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 8cf0ebf4..45440fa7 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -71,6 +71,38 @@ ) } end + + describe 'only IPv4 TCP traffic' do + let(:params) do + { + dport: 333, + proto: 'tcp4', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'ip version 4 tcp dport 333 accept', + ) + } + end + + describe 'only IPv6 UDP traffic' do + let(:params) do + { + dport: 33, + proto: 'udp6', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'ip version 6 udp dport 33 accept', + ) + } + end end end end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index e6137786..5b797388 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -3,11 +3,24 @@ Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $dport, Optional[String] $proto, | -%> +<%- if $proto { + $_proto = $proto ? { + /tcp(4|6)?/ => 'tcp', + /udp(4|6)?/ => 'udp', + } + $_ip_version_filter = $proto ? { + /(tcp4|udp4)/ => 'ip version 4', + /(tcp6|udp6)/ => 'ip version 6', + default => undef, + } +} else { + $_ip_version_filter = undef +} -%> <%- if $proto and $dport { if $dport =~ Array { - $_destination = "${proto} dport {${dport.join(', ')}}" + $_destination = "${_proto} dport {${dport.join(', ')}}" } else { - $_destination = "${proto} dport $dport" + $_destination = "${_proto} dport $dport" } } else { $_destination = undef @@ -17,4 +30,4 @@ } else { $_comment = undef } -%> -<%= regsubst(strip([$_destination, $_comment, $action].join(' ')), '\s+', ' ', 'G') -%> +<%= regsubst(strip([$_ip_version_filter, $_destination, $_comment, $action].join(' ')), '\s+', ' ', 'G') -%> From d38aab5b6584063fd844377fbf4aaf54c05337c0 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 16:14:32 +0100 Subject: [PATCH 05/25] Test passing a port without protocol --- spec/defines/simplerule_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 45440fa7..3e6d3da9 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -19,6 +19,16 @@ } end + describe 'port without protocol' do + let(:params) do + { + dport: 333, + } + end + + it { is_expected.not_to compile } + end + describe 'all parameters provided' do let(:title) { 'my_big_rule' } let(:params) do From aaa3717227e47c22195f2cf7e95d96bc01179cd8 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 17:09:32 +0100 Subject: [PATCH 06/25] Implement nftables:;simplerule::daddr --- manifests/simplerule.pp | 14 +++++-- spec/defines/simplerule_spec.rb | 67 ++++++++++++++++++++++++++++++++- templates/simplerule.epp | 24 ++++++++++-- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index a3d06f73..77a8035f 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -20,6 +20,10 @@ $dport = undef, Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, + Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] + $daddr = undef, + Enum['ip', 'ip6'] + $set_type = 'ip6', ){ if $dport and !$proto { @@ -30,10 +34,12 @@ nftables::rule{"${chain}-${rulename}": content => epp('nftables/simplerule.epp', { - 'action' => $action, - 'comment' => $comment, - 'dport' => $dport, - 'proto' => $proto, + 'action' => $action, + 'comment' => $comment, + 'dport' => $dport, + 'proto' => $proto, + 'daddr' => $daddr, + 'set_type' => $set_type, } ), order => $order, diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 3e6d3da9..828d9dc9 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -38,13 +38,14 @@ dport: 333, proto: 'udp', chain: 'default_out', + daddr: '2001:1458::/32', } end it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_out-my_big_rule').with( - content: 'udp dport 333 comment "this is my rule" accept', + content: 'udp dport 333 ip6 daddr 2001:1458::/32 accept comment "this is my rule"', order: '50', ) } @@ -113,6 +114,70 @@ ) } end + + describe 'with an IPv4 CIDR as daddr' do + let(:params) do + { + daddr: '192.168.0.1/24', + dport: 33, + proto: 'tcp', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'tcp dport 33 ip daddr 192.168.0.1/24 accept', + ) + } + end + + describe 'with an IPv6 address as daddr' do + let(:params) do + { + daddr: '2001:1458::1', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'ip6 daddr 2001:1458::1 accept', + ) + } + end + + describe 'with an IPv6 set as daddr, default set_type' do + let(:params) do + { + daddr: '@my6_set', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'ip6 daddr @my6_set accept', + ) + } + end + + describe 'with a IPv4 set as daddr' do + let(:params) do + { + daddr: '@my4_set', + set_type: 'ip', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'ip daddr @my4_set accept', + ) + } + end + end end end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 5b797388..a66c2806 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -2,6 +2,8 @@ Optional[String] $comment, Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $dport, Optional[String] $proto, + Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, + Enum['ip', 'ip6'] $set_type, | -%> <%- if $proto { $_proto = $proto ? { @@ -16,18 +18,32 @@ } else { $_ip_version_filter = undef } -%> +<%- if $daddr { + if $daddr =~ Stdlib::IP::Address::V6 { + $_dst_hosts = "ip6 daddr ${daddr}" + } elsif $daddr =~ Stdlib::IP::Address::V4 { + $_dst_hosts = "ip daddr ${daddr}" + } else { + $_dst_hosts = $set_type ? { + 'ip' => "ip daddr ${daddr}", + 'ip6' => "ip6 daddr ${daddr}", + } + } +} else { + $_dst_hosts = undef +} -%> <%- if $proto and $dport { if $dport =~ Array { - $_destination = "${_proto} dport {${dport.join(', ')}}" + $_dst_port = "${_proto} dport {${dport.join(', ')}}" } else { - $_destination = "${_proto} dport $dport" + $_dst_port = "${_proto} dport $dport" } } else { - $_destination = undef + $_dst_port = undef } -%> <%- if $comment { $_comment = "comment \"${comment}\"" } else { $_comment = undef } -%> -<%= regsubst(strip([$_ip_version_filter, $_destination, $_comment, $action].join(' ')), '\s+', ' ', 'G') -%> +<%= regsubst(strip([$_ip_version_filter, $_dst_port, $_dst_hosts, $action, $_comment].join(' ')), '\s+', ' ', 'G') -%> From d43ced4d2d33980dea91c19eb73f8e99f8f71565 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 17:18:46 +0100 Subject: [PATCH 07/25] Implement nftables:;simplerule::counter --- manifests/simplerule.pp | 3 +++ spec/defines/simplerule_spec.rb | 17 ++++++++++++++++- templates/simplerule.epp | 8 +++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 77a8035f..dc1613c5 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -24,6 +24,8 @@ $daddr = undef, Enum['ip', 'ip6'] $set_type = 'ip6', + Boolean + $counter = false, ){ if $dport and !$proto { @@ -36,6 +38,7 @@ { 'action' => $action, 'comment' => $comment, + 'counter' => $counter, 'dport' => $dport, 'proto' => $proto, 'daddr' => $daddr, diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 828d9dc9..685e7f39 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -35,6 +35,7 @@ { action: 'accept', comment: 'this is my rule', + counter: true, dport: 333, proto: 'udp', chain: 'default_out', @@ -45,7 +46,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_out-my_big_rule').with( - content: 'udp dport 333 ip6 daddr 2001:1458::/32 accept comment "this is my rule"', + content: 'udp dport 333 ip6 daddr 2001:1458::/32 counter accept comment "this is my rule"', order: '50', ) } @@ -178,6 +179,20 @@ } end + describe 'with counter enabled' do + let(:params) do + { + counter: true, + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'counter accept', + ) + } + end end end end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index a66c2806..9692b918 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -4,6 +4,7 @@ Optional[String] $proto, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, Enum['ip', 'ip6'] $set_type, + Boolean $counter, | -%> <%- if $proto { $_proto = $proto ? { @@ -46,4 +47,9 @@ } else { $_comment = undef } -%> -<%= regsubst(strip([$_ip_version_filter, $_dst_port, $_dst_hosts, $action, $_comment].join(' ')), '\s+', ' ', 'G') -%> +<%- if $counter { + $_counter = "counter" +} else { + $_counter = undef +} -%> +<%= regsubst(strip([$_ip_version_filter, $_dst_port, $_dst_hosts, $_counter, $action, $_comment].join(' ')), '\s+', ' ', 'G') -%> From 4ec94616d3df3dbcc07bb44d1ef00d0af3ef74ee Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 17:27:54 +0100 Subject: [PATCH 08/25] Re-document and add example --- manifests/simplerule.pp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index dc1613c5..c458f38c 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -1,6 +1,15 @@ -# This class is meant to be useful to ease the migration from the Firewall type -# for simple use cases. The coverage of all the casuistry is rather low so for -# any case not covered by nftables::simplerule please just use nftables::rule. +# @summary Provides a simplified interface to nftables::rule for basic use cases +# +# @example allow incoming traffic on port 543 TCP to a given IP range and count packets +# nftables::simplerule{'my_service_in': +# action => 'accept', +# comment => 'allow traffic to port 543', +# counter => true, +# proto => 'tcp', +# dport => 543, +# daddr => '2001:1458::/32', +# } + define nftables::simplerule( Enum['present','absent'] $ensure = 'present', From 2489f932b9e4988805cf768c7db2edf8a0732781 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 17:31:56 +0100 Subject: [PATCH 09/25] Correct error message --- manifests/simplerule.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index c458f38c..4f0b1dea 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -38,7 +38,7 @@ ){ if $dport and !$proto { - fail('Specifying a transport protocol via $proto is mandatory when passing a port') + fail('Specifying a transport protocol via $proto is mandatory when passing a $dport') } if $ensure == 'present' { From 2cc543087a3aa2e1eba68b83e45a43a4fcb9b07e Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Thu, 3 Dec 2020 17:33:29 +0100 Subject: [PATCH 10/25] Remove optional modifier on $table It does not really make sense to pass undef to nftables::rule --- manifests/simplerule.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 4f0b1dea..55909948 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -19,7 +19,7 @@ $order = '50', String $chain = 'default_in', - Optional[String] + String $table = 'inet-filter', Enum['accept', 'drop'] $action = 'accept', From 467ea4e227f00b4d510b3153bb71d871edb5a63f Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Tue, 8 Dec 2020 12:12:37 +0100 Subject: [PATCH 11/25] Lint fixes --- manifests/simplerule.pp | 43 ++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 55909948..a1cc97d8 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -10,39 +10,26 @@ # daddr => '2001:1458::/32', # } -define nftables::simplerule( - Enum['present','absent'] - $ensure = 'present', - Pattern[/^[-a-zA-Z0-9_]+$/] - $rulename = $title, - Pattern[/^\d\d$/] - $order = '50', - String - $chain = 'default_in', - String - $table = 'inet-filter', - Enum['accept', 'drop'] - $action = 'accept', - Optional[String] - $comment = undef, - Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] - $dport = undef, - Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] - $proto = undef, - Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] - $daddr = undef, - Enum['ip', 'ip6'] - $set_type = 'ip6', - Boolean - $counter = false, -){ - +define nftables::simplerule ( + Enum['present','absent'] $ensure = 'present', + Pattern[/^[-a-zA-Z0-9_]+$/] $rulename = $title, + Pattern[/^\d\d$/] $order = '50', + String $chain = 'default_in', + String $table = 'inet-filter', + Enum['accept', 'drop'] $action = 'accept', + Optional[String] $comment = undef, + Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $dport = undef, + Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, + Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr = undef, + Enum['ip', 'ip6'] $set_type = 'ip6', + Boolean $counter = false, +) { if $dport and !$proto { fail('Specifying a transport protocol via $proto is mandatory when passing a $dport') } if $ensure == 'present' { - nftables::rule{"${chain}-${rulename}": + nftables::rule { "${chain}-${rulename}": content => epp('nftables/simplerule.epp', { 'action' => $action, From 6793d28675445d3b6d3785c4f1d1f9a12edf6b78 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 12:15:16 +0100 Subject: [PATCH 12/25] Handle dport internally always as an array --- spec/defines/simplerule_spec.rb | 10 +++++----- templates/simplerule.epp | 6 +----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 685e7f39..b848ed90 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -46,7 +46,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_out-my_big_rule').with( - content: 'udp dport 333 ip6 daddr 2001:1458::/32 counter accept comment "this is my rule"', + content: 'udp dport {333} ip6 daddr 2001:1458::/32 counter accept comment "this is my rule"', order: '50', ) } @@ -63,7 +63,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( - content: 'tcp dport 333-334 accept', + content: 'tcp dport {333-334} accept', ) } end @@ -95,7 +95,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( - content: 'ip version 4 tcp dport 333 accept', + content: 'ip version 4 tcp dport {333} accept', ) } end @@ -111,7 +111,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( - content: 'ip version 6 udp dport 33 accept', + content: 'ip version 6 udp dport {33} accept', ) } end @@ -128,7 +128,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( - content: 'tcp dport 33 ip daddr 192.168.0.1/24 accept', + content: 'tcp dport {33} ip daddr 192.168.0.1/24 accept', ) } end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 9692b918..03584925 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -34,11 +34,7 @@ $_dst_hosts = undef } -%> <%- if $proto and $dport { - if $dport =~ Array { - $_dst_port = "${_proto} dport {${dport.join(', ')}}" - } else { - $_dst_port = "${_proto} dport $dport" - } + $_dst_port = "${_proto} dport {${Array($dport, true).join(', ')}}" } else { $_dst_port = undef } -%> From fb58f7b3892991df721dac34e47a69d113af02ad Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 11:18:24 +0000 Subject: [PATCH 13/25] Remove double spacing --- manifests/simplerule.pp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index a1cc97d8..95c4d4c7 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -18,8 +18,8 @@ String $table = 'inet-filter', Enum['accept', 'drop'] $action = 'accept', Optional[String] $comment = undef, - Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $dport = undef, - Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, + Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $dport = undef, + Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr = undef, Enum['ip', 'ip6'] $set_type = 'ip6', Boolean $counter = false, From 77abc10b1080ee450cc6080bdcee28f0ddb6b622 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 12:27:48 +0100 Subject: [PATCH 14/25] Implement nftables::simplerule::sport --- manifests/simplerule.pp | 9 +++++++- spec/defines/simplerule_spec.rb | 37 +++++++++++++++++++++++++++++---- templates/simplerule.epp | 8 ++++++- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 95c4d4c7..2784fc31 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -1,6 +1,6 @@ # @summary Provides a simplified interface to nftables::rule for basic use cases # -# @example allow incoming traffic on port 543 TCP to a given IP range and count packets +# @example allow incoming traffic from port 541 on port 543 TCP to a given IP range and count packets # nftables::simplerule{'my_service_in': # action => 'accept', # comment => 'allow traffic to port 543', @@ -8,6 +8,7 @@ # proto => 'tcp', # dport => 543, # daddr => '2001:1458::/32', +# sport => 541, # } define nftables::simplerule ( @@ -22,12 +23,17 @@ Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr = undef, Enum['ip', 'ip6'] $set_type = 'ip6', + Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $sport = undef, Boolean $counter = false, ) { if $dport and !$proto { fail('Specifying a transport protocol via $proto is mandatory when passing a $dport') } + if $sport and !$proto { + fail('Specifying a transport protocol via $proto is mandatory when passing a $sport') + } + if $ensure == 'present' { nftables::rule { "${chain}-${rulename}": content => epp('nftables/simplerule.epp', @@ -39,6 +45,7 @@ 'proto' => $proto, 'daddr' => $daddr, 'set_type' => $set_type, + 'sport' => $sport, } ), order => $order, diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index b848ed90..4ef96006 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -19,7 +19,7 @@ } end - describe 'port without protocol' do + describe 'dport without protocol' do let(:params) do { dport: 333, @@ -29,6 +29,16 @@ it { is_expected.not_to compile } end + describe 'sport without protocol' do + let(:params) do + { + sport: 333, + } + end + + it { is_expected.not_to compile } + end + describe 'all parameters provided' do let(:title) { 'my_big_rule' } let(:params) do @@ -37,6 +47,7 @@ comment: 'this is my rule', counter: true, dport: 333, + sport: 444, proto: 'udp', chain: 'default_out', daddr: '2001:1458::/32', @@ -46,7 +57,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_out-my_big_rule').with( - content: 'udp dport {333} ip6 daddr 2001:1458::/32 counter accept comment "this is my rule"', + content: 'udp sport {444} udp dport {333} ip6 daddr 2001:1458::/32 counter accept comment "this is my rule"', order: '50', ) } @@ -56,6 +67,7 @@ let(:params) do { dport: '333-334', + sport: '1-2', proto: 'tcp', } end @@ -63,7 +75,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( - content: 'tcp dport {333-334} accept', + content: 'tcp sport {1-2} tcp dport {333-334} accept', ) } end @@ -72,6 +84,23 @@ let(:params) do { dport: [333, 335], + sport: [433, 435], + proto: 'tcp', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'tcp sport {433, 435} tcp dport {333, 335} accept', + ) + } + end + + describe 'only sport TCP traffic' do + let(:params) do + { + sport: 555, proto: 'tcp', } end @@ -79,7 +108,7 @@ it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( - content: 'tcp dport {333, 335} accept', + content: 'tcp sport {555} accept', ) } end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 03584925..9d434539 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -4,6 +4,7 @@ Optional[String] $proto, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, Enum['ip', 'ip6'] $set_type, + Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $sport, Boolean $counter, | -%> <%- if $proto { @@ -43,9 +44,14 @@ } else { $_comment = undef } -%> +<%- if $proto and $sport { + $_src_port = "${_proto} sport {${Array($sport, true).join(', ')}}" +} else { + $_src_port = undef +} -%> <%- if $counter { $_counter = "counter" } else { $_counter = undef } -%> -<%= regsubst(strip([$_ip_version_filter, $_dst_port, $_dst_hosts, $_counter, $action, $_comment].join(' ')), '\s+', ' ', 'G') -%> +<%= regsubst(strip([$_ip_version_filter, $_src_port, $_dst_port, $_dst_hosts, $_counter, $action, $_comment].join(' ')), '\s+', ' ', 'G') -%> From af15de488efaf1de89c29580109c9f395451fac1 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 12:28:39 +0100 Subject: [PATCH 15/25] Recommend using nftables::rule --- manifests/simplerule.pp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 2784fc31..6c7373b5 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -1,4 +1,6 @@ -# @summary Provides a simplified interface to nftables::rule for basic use cases +# @summary Provides a simplified interface to nftables::rule for basic use cases. +# It's recommended to use nftables::rule directly if you feel comfortable with +# nft's syntax. # # @example allow incoming traffic from port 541 on port 543 TCP to a given IP range and count packets # nftables::simplerule{'my_service_in': From 2f28cced1708bb4da8d9308c2711d6be94bf8e80 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 12:40:52 +0100 Subject: [PATCH 16/25] Document nftables::simplerule's parameters --- manifests/simplerule.pp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 6c7373b5..6f595d86 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -12,6 +12,43 @@ # daddr => '2001:1458::/32', # sport => 541, # } +# +# @param rulename +# The symbolic name for the rule to add. Defaults to the resource's title. +# +# @param order +# A number representing the order of the rule. +# +# @param chain +# The name of the chain to add this rule to. +# +# @param table +# The name of the table to add this rule to. +# +# @param action +# The verdict for the matched traffic. +# +# @param comment +# A typically human-readable comment for the rule. +# +# @param dport +# The destination port, ports or port range. +# +# @param proto +# The transport-layer protocol to match. +# +# @param daddr +# The destination address, CIDR or set to match. +# +# @param set_type +# When using sets as saddr or daddr, the type of the set. +# Use `ip` for sets of type `ipv4_addr`. +# +# @param sport +# The source port, ports or port range. +# +# @param counter +# Enable traffic counters for the matched traffic. define nftables::simplerule ( Enum['present','absent'] $ensure = 'present', From 5944b9cb9fd69c4031e138b03f90c9bb7f36ffc5 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 12:41:03 +0100 Subject: [PATCH 17/25] Allow some other types of verdicts --- manifests/simplerule.pp | 2 +- spec/defines/simplerule_spec.rb | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 6f595d86..2f889a97 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -56,7 +56,7 @@ Pattern[/^\d\d$/] $order = '50', String $chain = 'default_in', String $table = 'inet-filter', - Enum['accept', 'drop'] $action = 'accept', + Enum['accept', 'continue', 'drop', 'queue', 'return'] $action = 'accept', Optional[String] $comment = undef, Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $dport = undef, Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 4ef96006..42f8d2f3 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -222,6 +222,24 @@ ) } end + + describe 'counter and continue sport' do + let(:params) do + { + proto: 'tcp', + sport: 80, + counter: true, + action: 'continue', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'tcp sport {80} counter continue', + ) + } + end end end end From abb04c9516ab347758ab19f523f87593085d6d95 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 12:53:35 +0100 Subject: [PATCH 18/25] Mention nftables::simplerule in the README --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 6bc9019d..e8a718b6 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,10 @@ You can define the order by using the `order` param. Adds a named set to a given table. It allows composing the set using individual parameters but also takes raw input via the content and source parameters. + +## nftables::simplerule + +Allows expressing firewall rules without having to use nftables's language by +adding an abstraction layer a-la-Firewall. It's rather limited how far you can +go so if you need rather complex rules or you can speak nftables it's +recommended to use `nftables::rule` directly. From 3a469f2b35f19d7e91fe2f745a124faf8271b45b Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 13:02:25 +0100 Subject: [PATCH 19/25] Implement nftables::simplerule::saddr --- manifests/simplerule.pp | 5 +++++ spec/defines/simplerule_spec.rb | 34 ++++++++++++++++++++++++++++++++- templates/simplerule.epp | 17 ++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 2f889a97..6ef963b9 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -47,6 +47,9 @@ # @param sport # The source port, ports or port range. # +# @param saddr +# The source address, CIDR or set to match. +# # @param counter # Enable traffic counters for the matched traffic. @@ -63,6 +66,7 @@ Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr = undef, Enum['ip', 'ip6'] $set_type = 'ip6', Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $sport = undef, + Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr = undef, Boolean $counter = false, ) { if $dport and !$proto { @@ -84,6 +88,7 @@ 'proto' => $proto, 'daddr' => $daddr, 'set_type' => $set_type, + 'saddr' => $saddr, 'sport' => $sport, } ), diff --git a/spec/defines/simplerule_spec.rb b/spec/defines/simplerule_spec.rb index 42f8d2f3..413e8a7c 100644 --- a/spec/defines/simplerule_spec.rb +++ b/spec/defines/simplerule_spec.rb @@ -51,13 +51,14 @@ proto: 'udp', chain: 'default_out', daddr: '2001:1458::/32', + saddr: '2001:145c::/32', } end it { is_expected.to compile } it { is_expected.to contain_nftables__rule('default_out-my_big_rule').with( - content: 'udp sport {444} udp dport {333} ip6 daddr 2001:1458::/32 counter accept comment "this is my rule"', + content: 'udp sport {444} udp dport {333} ip6 saddr 2001:145c::/32 ip6 daddr 2001:1458::/32 counter accept comment "this is my rule"', order: '50', ) } @@ -177,6 +178,21 @@ } end + describe 'with an IPv6 address as saddr' do + let(:params) do + { + saddr: '2001:1458:0000:0000:0000:0000:0000:0003', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'ip6 saddr 2001:1458:0000:0000:0000:0000:0000:0003 accept', + ) + } + end + describe 'with an IPv6 set as daddr, default set_type' do let(:params) do { @@ -208,6 +224,22 @@ } end + describe 'with a IPv6 set as saddr' do + let(:params) do + { + saddr: '@my6_set', + set_type: 'ip6', + } + end + + it { is_expected.to compile } + it { + is_expected.to contain_nftables__rule('default_in-my_default_rule_name').with( + content: 'ip6 saddr @my6_set accept', + ) + } + end + describe 'with counter enabled' do let(:params) do { diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 9d434539..46cf9288 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -5,6 +5,7 @@ Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, Enum['ip', 'ip6'] $set_type, Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $sport, + Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr, Boolean $counter, | -%> <%- if $proto { @@ -34,6 +35,20 @@ } else { $_dst_hosts = undef } -%> +<%- if $saddr { + if $saddr =~ Stdlib::IP::Address::V6 { + $_src_hosts = "ip6 saddr ${saddr}" + } elsif $daddr =~ Stdlib::IP::Address::V4 { + $_src_hosts = "ip saddr ${saddr}" + } else { + $_src_hosts = $set_type ? { + 'ip' => "ip saddr ${saddr}", + 'ip6' => "ip6 saddr ${saddr}", + } + } +} else { + $_src_hosts = undef +} -%> <%- if $proto and $dport { $_dst_port = "${_proto} dport {${Array($dport, true).join(', ')}}" } else { @@ -54,4 +69,4 @@ } else { $_counter = undef } -%> -<%= regsubst(strip([$_ip_version_filter, $_src_port, $_dst_port, $_dst_hosts, $_counter, $action, $_comment].join(' ')), '\s+', ' ', 'G') -%> +<%= regsubst(strip([$_ip_version_filter, $_src_port, $_dst_port, $_src_hosts, $_dst_hosts, $_counter, $action, $_comment].join(' ')), '\s+', ' ', 'G') -%> From 6739966c8787c6a0b653fe4cd03547724aa59ce6 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 13:05:50 +0100 Subject: [PATCH 20/25] Sort template parameters alphabetically --- manifests/simplerule.pp | 4 ++-- templates/simplerule.epp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index 6ef963b9..f617827b 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -84,11 +84,11 @@ 'action' => $action, 'comment' => $comment, 'counter' => $counter, + 'daddr' => $daddr, 'dport' => $dport, 'proto' => $proto, - 'daddr' => $daddr, - 'set_type' => $set_type, 'saddr' => $saddr, + 'set_type' => $set_type, 'sport' => $sport, } ), diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 46cf9288..5c495b21 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -1,12 +1,12 @@ <%- | String $action, Optional[String] $comment, + Boolean $counter, + Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $dport, Optional[String] $proto, - Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, + Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr, Enum['ip', 'ip6'] $set_type, Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $sport, - Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr, - Boolean $counter, | -%> <%- if $proto { $_proto = $proto ? { From 09b07e569da1dbb61d09b3d35ca668ca82830c6e Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 14:11:29 +0100 Subject: [PATCH 21/25] Encapsulate port-related exprs in Nftables::Port --- manifests/simplerule.pp | 4 ++-- spec/type_aliases/nftables_port_spec.rb | 9 +++++++++ templates/simplerule.epp | 4 ++-- types/port.pp | 7 +++++++ types/port/range.pp | 3 +++ 5 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 spec/type_aliases/nftables_port_spec.rb create mode 100644 types/port.pp create mode 100644 types/port/range.pp diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index f617827b..ffc90b74 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -61,11 +61,11 @@ String $table = 'inet-filter', Enum['accept', 'continue', 'drop', 'queue', 'return'] $action = 'accept', Optional[String] $comment = undef, - Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $dport = undef, + Optional[Nftables::Port] $dport = undef, Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr = undef, Enum['ip', 'ip6'] $set_type = 'ip6', - Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, Pattern[/\d+-\d+/]]] $sport = undef, + Optional[Nftables::Port] $sport = undef, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr = undef, Boolean $counter = false, ) { diff --git a/spec/type_aliases/nftables_port_spec.rb b/spec/type_aliases/nftables_port_spec.rb new file mode 100644 index 00000000..ccd649a5 --- /dev/null +++ b/spec/type_aliases/nftables_port_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe 'Nftables::Port' do + it { is_expected.to allow_value(53) } + it { is_expected.to allow_value([1, 1985, 65_535]) } + it { is_expected.to allow_value('53-55') } + it { is_expected.not_to allow_value('53') } + it { is_expected.not_to allow_value([]) } +end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 5c495b21..0d384918 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -2,11 +2,11 @@ Optional[String] $comment, Boolean $counter, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, - Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $dport, + Optional[Nftables::Port] $dport, Optional[String] $proto, Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr, Enum['ip', 'ip6'] $set_type, - Optional[Variant[Array[Stdlib::Port, 1], Stdlib::Port, String]] $sport, + Optional[Nftables::Port] $sport, | -%> <%- if $proto { $_proto = $proto ? { diff --git a/types/port.pp b/types/port.pp new file mode 100644 index 00000000..15847a70 --- /dev/null +++ b/types/port.pp @@ -0,0 +1,7 @@ +# @summary +# Represents a port expression to be used within a rule. +type Nftables::Port = Variant[ + Array[Stdlib::Port, 1], + Stdlib::Port, + Nftables::Port::Range, +] diff --git a/types/port/range.pp b/types/port/range.pp new file mode 100644 index 00000000..6c1de559 --- /dev/null +++ b/types/port/range.pp @@ -0,0 +1,3 @@ +# @summary +# Represents a port range expression to be used within a rule. +type Nftables::Port::Range = Pattern[/^\d+-\d+$/] From f1ef02c555f09187f9a1877d8198b5c582687fe0 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 14:17:01 +0100 Subject: [PATCH 22/25] Encapsulate addr-related exprs in Nftables::Addr --- manifests/simplerule.pp | 4 ++-- spec/type_aliases/nftables_addr_spec.rb | 12 ++++++++++++ templates/simplerule.epp | 4 ++-- types/addr.pp | 7 +++++++ types/addr/set.pp | 3 +++ 5 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 spec/type_aliases/nftables_addr_spec.rb create mode 100644 types/addr.pp create mode 100644 types/addr/set.pp diff --git a/manifests/simplerule.pp b/manifests/simplerule.pp index ffc90b74..b3965c69 100644 --- a/manifests/simplerule.pp +++ b/manifests/simplerule.pp @@ -63,10 +63,10 @@ Optional[String] $comment = undef, Optional[Nftables::Port] $dport = undef, Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']] $proto = undef, - Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr = undef, + Optional[Nftables::Addr] $daddr = undef, Enum['ip', 'ip6'] $set_type = 'ip6', Optional[Nftables::Port] $sport = undef, - Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr = undef, + Optional[Nftables::Addr] $saddr = undef, Boolean $counter = false, ) { if $dport and !$proto { diff --git a/spec/type_aliases/nftables_addr_spec.rb b/spec/type_aliases/nftables_addr_spec.rb new file mode 100644 index 00000000..3e1d6104 --- /dev/null +++ b/spec/type_aliases/nftables_addr_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe 'Nftables::Addr' do + it { is_expected.to allow_value('127.0.0.1') } + it { is_expected.to allow_value('172.16.1.0/24') } + it { is_expected.to allow_value('2001:1458::/32') } + it { is_expected.to allow_value('2001:1458::3') } + it { is_expected.to allow_value('@set_name') } + it { is_expected.not_to allow_value('anything') } + it { is_expected.not_to allow_value(43) } + it { is_expected.not_to allow_value(['127.0.0.1']) } +end diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 0d384918..88672d6b 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -1,10 +1,10 @@ <%- | String $action, Optional[String] $comment, Boolean $counter, - Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $daddr, + Optional[Nftables::Addr] $daddr, Optional[Nftables::Port] $dport, Optional[String] $proto, - Optional[Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Pattern[/^@[-a-zA-Z0-9_]+$/]]] $saddr, + Optional[Nftables::Addr] $saddr, Enum['ip', 'ip6'] $set_type, Optional[Nftables::Port] $sport, | -%> diff --git a/types/addr.pp b/types/addr.pp new file mode 100644 index 00000000..f7f7cdbc --- /dev/null +++ b/types/addr.pp @@ -0,0 +1,7 @@ +# @summary +# Represents an address expression to be used within a rule. +type Nftables::Addr = Variant[ + Stdlib::IP::Address::V6, + Stdlib::IP::Address::V4, + Nftables::Addr::Set +] diff --git a/types/addr/set.pp b/types/addr/set.pp new file mode 100644 index 00000000..f05b2391 --- /dev/null +++ b/types/addr/set.pp @@ -0,0 +1,3 @@ +# @summary +# Represents a set expression to be used within a rule. +type Nftables::Addr::Set = Pattern[/^@[-a-zA-Z0-9_]+$/] From 55277023cb19494e556d58267c4bbad637558f77 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 14:21:52 +0100 Subject: [PATCH 23/25] Align template parameters --- templates/simplerule.epp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/simplerule.epp b/templates/simplerule.epp index 88672d6b..f69eff33 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -1,11 +1,11 @@ -<%- | String $action, - Optional[String] $comment, - Boolean $counter, +<%- | String $action, + Optional[String] $comment, + Boolean $counter, Optional[Nftables::Addr] $daddr, Optional[Nftables::Port] $dport, - Optional[String] $proto, + Optional[String] $proto, Optional[Nftables::Addr] $saddr, - Enum['ip', 'ip6'] $set_type, + Enum['ip', 'ip6'] $set_type, Optional[Nftables::Port] $sport, | -%> <%- if $proto { From 42e7f3eaa06a08238ec0a1ab781f16bc17adc698 Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 14:22:14 +0100 Subject: [PATCH 24/25] Relax type validation in template It comes already validated from the calling class. --- templates/simplerule.epp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/simplerule.epp b/templates/simplerule.epp index f69eff33..bacb8ffe 100644 --- a/templates/simplerule.epp +++ b/templates/simplerule.epp @@ -5,7 +5,7 @@ Optional[Nftables::Port] $dport, Optional[String] $proto, Optional[Nftables::Addr] $saddr, - Enum['ip', 'ip6'] $set_type, + String $set_type, Optional[Nftables::Port] $sport, | -%> <%- if $proto { From 4d63adda417349bd0617ca0feaf3a0c9a3d8c4bd Mon Sep 17 00:00:00 2001 From: Nacho Barrientos Date: Wed, 9 Dec 2020 17:45:04 +0100 Subject: [PATCH 25/25] Refresh REFERENCE --- REFERENCE.md | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/REFERENCE.md b/REFERENCE.md index a4bcb8fb..7225fac4 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -66,6 +66,14 @@ * [`nftables::rules::masquerade`](#nftablesrulesmasquerade): masquerade all outgoing traffic * [`nftables::rules::snat4`](#nftablesrulessnat4): manage a ipv4 snat rule * [`nftables::set`](#nftablesset): manage a named set +* [`nftables::simplerule`](#nftablessimplerule) + +### Data types + +* [`Nftables::Addr`](#nftablesaddr): Represents an address expression to be used within a rule. +* [`Nftables::Addr::Set`](#nftablesaddrset): Represents a set expression to be used within a rule. +* [`Nftables::Port`](#nftablesport): Represents a port expression to be used within a rule. +* [`Nftables::Port::Range`](#nftablesportrange): Represents a port range expression to be used within a rule. ## Classes @@ -1215,3 +1223,149 @@ Data type: `Optional[Variant[String,Array[String,1]]]` Default value: ``undef`` +### `nftables::simplerule` + +The nftables::simplerule class. + +#### Parameters + +The following parameters are available in the `nftables::simplerule` defined type. + +##### `ensure` + +Data type: `Enum['present','absent']` + + + +Default value: `'present'` + +##### `rulename` + +Data type: `Pattern[/^[-a-zA-Z0-9_]+$/]` + + + +Default value: `$title` + +##### `order` + +Data type: `Pattern[/^\d\d$/]` + + + +Default value: `'50'` + +##### `chain` + +Data type: `String` + + + +Default value: `'default_in'` + +##### `table` + +Data type: `String` + + + +Default value: `'inet-filter'` + +##### `action` + +Data type: `Enum['accept', 'continue', 'drop', 'queue', 'return']` + + + +Default value: `'accept'` + +##### `comment` + +Data type: `Optional[String]` + + + +Default value: ``undef`` + +##### `dport` + +Data type: `Optional[Nftables::Port]` + + + +Default value: ``undef`` + +##### `proto` + +Data type: `Optional[Enum['tcp', 'tcp4', 'tcp6', 'udp', 'udp4', 'udp6']]` + + + +Default value: ``undef`` + +##### `daddr` + +Data type: `Optional[Nftables::Addr]` + + + +Default value: ``undef`` + +##### `set_type` + +Data type: `Enum['ip', 'ip6']` + + + +Default value: `'ip6'` + +##### `sport` + +Data type: `Optional[Nftables::Port]` + + + +Default value: ``undef`` + +##### `saddr` + +Data type: `Optional[Nftables::Addr]` + + + +Default value: ``undef`` + +##### `counter` + +Data type: `Boolean` + + + +Default value: ``false`` + +## Data types + +### `Nftables::Addr` + +Represents an address expression to be used within a rule. + +Alias of `Variant[Stdlib::IP::Address::V6, Stdlib::IP::Address::V4, Nftables::Addr::Set]` + +### `Nftables::Addr::Set` + +Represents a set expression to be used within a rule. + +Alias of `Pattern[/^@[-a-zA-Z0-9_]+$/]` + +### `Nftables::Port` + +Represents a port expression to be used within a rule. + +Alias of `Variant[Array[Stdlib::Port, 1], Stdlib::Port, Nftables::Port::Range]` + +### `Nftables::Port::Range` + +Represents a port range expression to be used within a rule. + +Alias of `Pattern[/^\d+-\d+$/]` +