From e048afaec245b19ed8a94a8e2e893c9c9b4e47e6 Mon Sep 17 00:00:00 2001 From: Thore Bödecker Date: Mon, 22 Jun 2020 15:53:06 +0200 Subject: implement multiport support for dport/sport --- README.md | 6 ++++-- REFERENCE.md | 48 +++++++++----------------------------------- manifests/rule.pp | 36 ++++++++++++++++++++++----------- spec/acceptance/ferm_spec.rb | 4 ++-- spec/defines/rule_spec.rb | 20 +++++++++--------- 5 files changed, 50 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 64a9f84..f095ce7 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ You can easily define rules in Puppet (they don't need to be exported resources) chain => 'INPUT', policy => 'ACCEPT', proto => 'tcp', - dport => '(9092 9093)', + dport => [9092, 9093], saddr => "(${facts['networking']['ip6']}/128 ${facts['networking']['ip']}/32)", tag => 'allow_kafka_server2server', } @@ -97,7 +97,9 @@ ferm::rules: chain: 'INPUT' policy: 'ACCEPT' proto: 'tcp' - dport: '(80 443)' + dport: + - 80 + - 443 saddr: "%{alias('subnets')}" ``` diff --git a/REFERENCE.md b/REFERENCE.md index eef0dc5..821136b 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -267,34 +267,6 @@ ferm::chain{'check-ssh': } ``` -##### create a custom chain, e.g. for managing custom FORWARD chain rule for OpenVPN using custom ferm DSL. - -```puppet -$my_rules = @(EOT) -chain OPENVPN_FORWORD_RULES { - proto udp { - interface tun0 { - outerface enp4s0 { - mod conntrack ctstate (NEW) saddr @ipfilter((10.8.0.0/24)) ACCEPT; - } - } - } -} -| EOT - -ferm::chain{'OPENVPN_FORWORD_RULES': - chain => 'OPENVPN_FORWORD_RULES', - content => $my_rules, -} - -ferm::rule { "OpenVPN - FORWORD all udp traffic from network 10.8.0.0/24 to subchain OPENVPN_FORWORD_RULES": - chain => 'FORWARD', - action => 'OPENVPN_FORWORD_RULES', - saddr => '10.8.0.0/24', - proto => 'udp', -} -``` - #### Parameters The following parameters are available in the `ferm::chain` defined type. @@ -352,7 +324,7 @@ Default value: 'filter' ##### `ip_versions` -Data type: `Array[Enum['ip','ip6']]` +Data type: `Array[Enum['ip', 'ip6']]` Set list of versions of ip we want ot use. @@ -360,11 +332,11 @@ Default value: $ferm::ip_versions ##### `content` -Data type: `Optional[String]` +Data type: `Optional[String[1]]` -Can only be used for custom chains. It allows you to provide your own ferm rules for this chain. Sets the contents of this custom chain to provided value. -Default value: undef + +Default value: `undef` ### ferm::ipset @@ -454,7 +426,7 @@ ferm::rule{'incoming-ssh': chain => 'INPUT', action => 'SSH', proto => 'tcp', - dport => '22', + dport => 22, } ``` @@ -465,7 +437,7 @@ ferm::rule{'allow-ssh-localhost': chain => 'SSH', action => 'ACCEPT', proto => 'tcp', - dport => '22', + dport => 22, saddr => '127.0.0.1', } ``` @@ -538,17 +510,17 @@ Default value: `undef` ##### `dport` -Data type: `Optional[Variant[Stdlib::Port,String[1]]]` +Data type: `Optional[Variant[Stdlib::Port,Array[Stdlib::Port]]]` -The destination port, can be a range as string or a single port number as integer +The destination port, can be a single port number as integer or an Array of integers (which will then use the multiport matcher) Default value: `undef` ##### `sport` -Data type: `Optional[Variant[Stdlib::Port,String[1]]]` +Data type: `Optional[Variant[Stdlib::Port,Array[Stdlib::Port]]]` -The source port, can be a range as string or a single port number as integer +The source port, can be a single port number as integer or an Array of integers (which will then use the multiport matcher) Default value: `undef` diff --git a/manifests/rule.pp b/manifests/rule.pp index 1acbfd1..458bef6 100644 --- a/manifests/rule.pp +++ b/manifests/rule.pp @@ -5,7 +5,7 @@ # chain => 'INPUT', # action => 'SSH', # proto => 'tcp', -# dport => '22', +# dport => 22, # } # # @example Create a rule in the 'SSH' chain to allow connections from localhost @@ -13,7 +13,7 @@ # chain => 'SSH', # action => 'ACCEPT', # proto => 'tcp', -# dport => '22', +# dport => 22, # saddr => '127.0.0.1', # } # @@ -43,8 +43,8 @@ # @param policy Configure what we want to do with the packet (drop/accept/reject, can also be a target chain name) [DEPRECATED] # Default value: undef # Allowed values: (RETURN|ACCEPT|DROP|REJECT|NOTRACK|LOG|MARK|DNAT|SNAT|MASQUERADE|REDIRECT|String[1]) -# @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 dport The destination port, can be a single port number as integer or an Array of integers (which will then use the multiport matcher) +# @param sport The source port, can be a single port number as integer or an Array of integers (which will then use the multiport matcher) # @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) @@ -59,8 +59,8 @@ define ferm::rule ( String $comment = $name, Optional[Ferm::Actions] $action = undef, Optional[Ferm::Policies] $policy = undef, - Optional[Variant[Stdlib::Port,String[1]]] $dport = undef, - Optional[Variant[Stdlib::Port,String[1]]] $sport = undef, + Optional[Variant[Stdlib::Port,Array[Stdlib::Port]]] $dport = undef, + Optional[Variant[Stdlib::Port,Array[Stdlib::Port]]] $sport = undef, Optional[Variant[Array, String[1]]] $saddr = undef, Optional[Variant[Array, String[1]]] $daddr = undef, Optional[String[1]] $proto_options = undef, @@ -95,14 +95,26 @@ define ferm::rule ( String => "proto ${proto}", } - $dport_real = $dport ? { - undef => '', - default => "dport ${dport}", + # ferm supports implicit multiport using the "dports" shortcut + if $dport =~ Array { + $dports = join($dport, ' ') + $dport_real = "dports (${dports})" + } elsif $dport =~ Integer { + $dport_real = "dport ${dport}" + } else { + $dport_real = '' } - $sport_real = $sport ? { - undef => '', - default => "sport ${sport}", + + # ferm supports implicit multiport using the "sports" shortcut + if $sport =~ Array { + $sports = join($sport, ' ') + $sport_real = "sports (${sports})" + } elsif $sport =~ Integer { + $sport_real = "sport ${sport}" + } else { + $sport_real = '' } + 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)}." ) diff --git a/spec/acceptance/ferm_spec.rb b/spec/acceptance/ferm_spec.rb index f8f0ef4..eee01fa 100644 --- a/spec/acceptance/ferm_spec.rb +++ b/spec/acceptance/ferm_spec.rb @@ -126,14 +126,14 @@ describe 'ferm' do chain => 'INPUT', action => 'HTTP', proto => 'tcp', - dport => '80', + dport => 80, require => Ferm::Chain['check-http'], } ferm::rule { 'allow_http_localhost': chain => 'HTTP', action => 'ACCEPT', proto => 'tcp', - dport => '80', + dport => 80, saddr => '127.0.0.1', require => Ferm::Chain['check-http'], } diff --git a/spec/defines/rule_spec.rb b/spec/defines/rule_spec.rb index 5e4ad69..f1887b6 100644 --- a/spec/defines/rule_spec.rb +++ b/spec/defines/rule_spec.rb @@ -17,7 +17,7 @@ describe 'ferm::rule', type: :define do { chain: 'INPUT', proto: 'tcp', - dport: '22', + dport: 22, saddr: '127.0.0.1' } end @@ -33,7 +33,7 @@ describe 'ferm::rule', type: :define do policy: 'ACCEPT', action: 'ACCEPT', proto: 'tcp', - dport: '22', + dport: 22, saddr: '127.0.0.1' } end @@ -48,7 +48,7 @@ describe 'ferm::rule', type: :define do chain: 'INPUT', policy: 'ACCEPT', proto: 'tcp', - dport: '22', + dport: 22, saddr: '127.0.0.1' } end @@ -64,7 +64,7 @@ describe 'ferm::rule', type: :define do chain: 'INPUT', action: 'ACCEPT', proto: 'tcp', - dport: '22', + dport: 22, saddr: '127.0.0.1' } end @@ -83,7 +83,7 @@ describe 'ferm::rule', type: :define do chain: 'INPUT', action: 'ACCEPT', proto: 'tcp', - dport: '22', + dport: 22, saddr: '127.0.0.1', interface: 'eth0' } @@ -102,7 +102,7 @@ describe 'ferm::rule', type: :define do chain: 'INPUT', action: 'ACCEPT', proto: 'tcp', - dport: '22', + dport: 22, daddr: ['127.0.0.1', '123.123.123.123', ['10.0.0.1', '10.0.0.2']], interface: 'eth0' } @@ -121,13 +121,13 @@ describe 'ferm::rule', type: :define do chain: 'INPUT', action: 'ACCEPT', proto: %w[tcp udp], - dport: '(8301 8302)', + dport: [8301, 8302], saddr: '127.0.0.1' } end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_concat__fragment('INPUT-filter-consul').with_content("mod comment comment 'filter-consul' proto (tcp udp) dport (8301 8302) saddr @ipfilter((127.0.0.1)) ACCEPT;\n") } + it { is_expected.to contain_concat__fragment('INPUT-filter-consul').with_content("mod comment comment 'filter-consul' proto (tcp udp) dports (8301 8302) saddr @ipfilter((127.0.0.1)) ACCEPT;\n") } it { is_expected.to contain_concat__fragment('filter-INPUT-config-include') } it { is_expected.to contain_concat__fragment('filter-FORWARD-config-include') } it { is_expected.to contain_concat__fragment('filter-OUTPUT-config-include') } @@ -149,7 +149,7 @@ describe 'ferm::rule', type: :define do chain: 'INPUT', action: 'SSH', proto: 'tcp', - dport: '22' + dport: 22 } end @@ -184,7 +184,7 @@ describe 'ferm::rule', type: :define do chain: 'SSH', action: 'ACCEPT', proto: 'tcp', - dport: '22', + dport: 22, saddr: '127.0.0.1' } end -- cgit v1.2.3