From 4eaa7df9bf526b45f62184b9d4caf38550356894 Mon Sep 17 00:00:00 2001 From: Manuel Hutter Date: Thu, 16 Feb 2017 09:44:31 +0100 Subject: [PATCH] (MODULES-4234) Add support for physdev-is-{in,out} --- Gemfile | 8 ++-- README.markdown | 4 ++ lib/puppet/provider/firewall/ip6tables.rb | 11 +++-- lib/puppet/provider/firewall/iptables.rb | 11 +++-- lib/puppet/type/firewall.rb | 14 +++++++ spec/acceptance/firewall_bridging_spec.rb | 50 +++++++++++++++++++++++ 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index 5d86325..cda523d 100644 --- a/Gemfile +++ b/Gemfile @@ -35,7 +35,7 @@ group :development do gem 'metadata-json-lint', :require => false, :platforms => 'ruby' gem 'puppet_facts', :require => false gem 'puppet-blacksmith', '>= 3.4.0', :require => false, :platforms => 'ruby' - gem 'puppetlabs_spec_helper', '>= 1.2.1', :require => false + gem 'puppetlabs_spec_helper', '~> 1.2', :require => false gem 'rspec-puppet', '>= 2.3.2', :require => false gem 'rspec-puppet-facts', :require => false, :platforms => 'ruby' gem 'mocha', '< 1.2.0', :require => false @@ -53,14 +53,14 @@ group :development do end group :system_tests do - gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '>= 3') + gem 'beaker', *location_for(ENV['BEAKER_VERSION'] || '>= 3') gem 'beaker-pe', :require => false - gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION']) + gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION']) gem 'beaker-puppet_install_helper', :require => false gem 'beaker-module_install_helper', :require => false gem 'master_manipulator', :require => false gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION']) - gem 'beaker-abs', *location_for(ENV['BEAKER_ABS_VERSION'] || '~> 0.1') + gem 'beaker-abs', *location_for(ENV['BEAKER_ABS_VERSION'] || '~> 0.1') end gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) diff --git a/README.markdown b/README.markdown index a06d423..a207425 100644 --- a/README.markdown +++ b/README.markdown @@ -639,6 +639,10 @@ firewall { '999 this runs last': * `physdev_is_bridged`: Match if the packet is transversing a bridge. Valid values are true or false. +* `physdev_is_in`: Match if the packet has entered through a bridge interface. Valid values are true or false. + +* `physdev_is_bridged`: Match if the packet will leave through a bridge interface. Valid values are true or false. + * `pkttype`: Sets the packet type to match. Valid values are: 'unicast', 'broadcast', and'multicast'. Requires the `pkttype` feature. * `port`: *DEPRECATED* Using the unspecific 'port' parameter can lead to firewall rules that are unexpectedly too lax. It is recommended to always use the specific dport and sport parameters to avoid this ambiguity. The destination or source port to match for this filter (if the protocol supports ports). Will accept a single element or an array. For some firewall providers you can pass a range of ports in the format: 'start number-end number'. For example, '1-1024' would cover ports 1 to 1024. diff --git a/lib/puppet/provider/firewall/ip6tables.rb b/lib/puppet/provider/firewall/ip6tables.rb index c6a381d..edcb8e3 100644 --- a/lib/puppet/provider/firewall/ip6tables.rb +++ b/lib/puppet/provider/firewall/ip6tables.rb @@ -145,6 +145,8 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source = :physdev_in => "--physdev-in", :physdev_out => "--physdev-out", :physdev_is_bridged => "--physdev-is-bridged", + :physdev_is_in => "--physdev-is-in", + :physdev_is_out => "--physdev-is-out", :date_start => "--datestart", :date_stop => "--datestop", :time_start => "--timestart", @@ -172,12 +174,14 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source = :rttl, :socket, :physdev_is_bridged, + :physdev_is_in, + :physdev_is_out, :time_contiguous, :kernel_timezone, :queue_bypass, ] - # Properties that use "-m " (with the potential to have multiple + # Properties that use "-m " (with the potential to have multiple # arguments against the same IPT module) must be in this hash. The keys in this # hash are the IPT module names, with the values being an array of the respective # supported arguments for this IPT module. @@ -190,7 +194,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source = # ones. # @module_to_argument_mapping = { - :physdev => [:physdev_in, :physdev_out, :physdev_is_bridged], + :physdev => [:physdev_in, :physdev_out, :physdev_is_bridged, :physdev_is_in, :physdev_is_out], :addrtype => [:src_type, :dst_type], :iprange => [:src_range, :dst_range], :owner => [:uid, :gid], @@ -233,7 +237,8 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source = # I put it when calling the command. So compability with manual changes # not provided with current parser [georg.koester]) @resource_list = [:table, :source, :destination, :iniface, :outiface, :physdev_in, - :physdev_out, :physdev_is_bridged, :proto, :ishasmorefrags, :islastfrag, :isfirstfrag, :src_range, :dst_range, + :physdev_out, :physdev_is_bridged, :physdev_is_in, :physdev_is_out, + :proto, :ishasmorefrags, :islastfrag, :isfirstfrag, :src_range, :dst_range, :tcp_flags, :uid, :gid, :mac_source, :sport, :dport, :port, :src_type, :dst_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy, :state, :ctstate, :icmp, :hop_limit, :limit, :burst, :length, :recent, :rseconds, :reap, diff --git a/lib/puppet/provider/firewall/iptables.rb b/lib/puppet/provider/firewall/iptables.rb index dd0a72c..5b2c3e5 100644 --- a/lib/puppet/provider/firewall/iptables.rb +++ b/lib/puppet/provider/firewall/iptables.rb @@ -132,6 +132,8 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir :physdev_in => "--physdev-in", :physdev_out => "--physdev-out", :physdev_is_bridged => "--physdev-is-bridged", + :physdev_is_in => "--physdev-is-in", + :physdev_is_out => "--physdev-is-out", :date_start => "--datestart", :date_stop => "--datestop", :time_start => "--timestart", @@ -164,6 +166,8 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir :rttl, :socket, :physdev_is_bridged, + :physdev_is_in, + :physdev_is_out, :time_contiguous, :kernel_timezone, :clusterip_new, @@ -183,7 +187,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir # ones. # @module_to_argument_mapping = { - :physdev => [:physdev_in, :physdev_out, :physdev_is_bridged], + :physdev => [:physdev_in, :physdev_out, :physdev_is_bridged, :physdev_is_in, :physdev_is_out], :addrtype => [:src_type, :dst_type], :iprange => [:src_range, :dst_range], :owner => [:uid, :gid], @@ -266,8 +270,9 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir # changes between puppet runs, the changed rules will be re-applied again. # This order can be determined by going through iptables source code or just tweaking and trying manually @resource_list = [ - :table, :source, :destination, :iniface, :outiface, :physdev_in, :physdev_out, :physdev_is_bridged, :proto, :isfragment, - :stat_mode, :stat_every, :stat_packet, :stat_probability, + :table, :source, :destination, :iniface, :outiface, + :physdev_in, :physdev_out, :physdev_is_bridged, :physdev_is_in, :physdev_is_out, + :proto, :isfragment, :stat_mode, :stat_every, :stat_packet, :stat_probability, :src_range, :dst_range, :tcp_flags, :uid, :gid, :mac_source, :sport, :dport, :port, :src_type, :dst_type, :socket, :pkttype, :name, :ipsec_dir, :ipsec_policy, :state, :ctstate, :icmp, :limit, :burst, :length, :recent, :rseconds, :reap, diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index a0de965..2493447 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -1253,6 +1253,20 @@ Puppet::Type.newtype(:firewall) do newvalues(:true, :false) end + newproperty(:physdev_is_in, :required_features => :iptables) do + desc <<-EOS + Matches if the packet has entered through a bridge interface. + EOS + newvalues(:true, :false) + end + + newproperty(:physdev_is_out, :required_features => :iptables) do + desc <<-EOS + Matches if the packet will leave through a bridge interface. + EOS + newvalues(:true, :false) + end + newproperty(:date_start, :required_features => :iptables) do desc <<-EOS Only match during the given time, which must be in ISO 8601 "T" notation. diff --git a/spec/acceptance/firewall_bridging_spec.rb b/spec/acceptance/firewall_bridging_spec.rb index 568d64c..608e0e9 100644 --- a/spec/acceptance/firewall_bridging_spec.rb +++ b/spec/acceptance/firewall_bridging_spec.rb @@ -366,4 +366,54 @@ describe 'firewall bridging' do end end end + + context 'physdev_is_in' do + it 'applies' do + pp = <<-EOS + class { '::firewall': } + firewall { '708 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '708', + action => accept, + physdev_is_in => true, + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => do_catch_changes) + end + + it 'should contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-is-in -m multiport --ports 708 -m comment --comment "708 - test" -j ACCEPT/) + end + end + end + + context 'physdev_is_out' do + it 'applies' do + pp = <<-EOS + class { '::firewall': } + firewall { '709 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '709', + action => accept, + physdev_is_out => true, + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => do_catch_changes) + end + + it 'should contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).to match(/-A FORWARD -p tcp -m physdev\s+--physdev-is-out -m multiport --ports 709 -m comment --comment "709 - test" -j ACCEPT/) + end + end + end end -- 2.45.2