From e5d31f140c1e8883dc5a7307b0e09f0005193cdc Mon Sep 17 00:00:00 2001 From: Georg Koester Date: Wed, 10 Apr 2013 05:47:56 -0700 Subject: [PATCH] Add match rule for fragments. Via isfragment true/false property, toggles '-f'. Same implementation as socket property, same bug where the property is always recognized as changed. --- lib/puppet/provider/firewall/iptables.rb | 20 ++++++++++++++++---- lib/puppet/type/firewall.rb | 9 +++++++++ spec/fixtures/iptables/conversion_hash.rb | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/puppet/provider/firewall/iptables.rb b/lib/puppet/provider/firewall/iptables.rb index 545b748..978654c 100644 --- a/lib/puppet/provider/firewall/iptables.rb +++ b/lib/puppet/provider/firewall/iptables.rb @@ -20,6 +20,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir has_feature :mark has_feature :tcp_flags has_feature :pkttype + has_feature :isfragment has_feature :socket optional_commands({ @@ -65,7 +66,8 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir :toports => "--to-ports", :tosource => "--to-source", :uid => "-m owner --uid-owner", - :pkttype => "-m pkttype --pkt-type" + :pkttype => "-m pkttype --pkt-type", + :isfragment => "-f", } # Create property methods dynamically @@ -84,7 +86,7 @@ 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, - :proto, :tcp_flags, :gid, :uid, :sport, :dport, :port, :socket, :pkttype, :name, :state, :icmp, :limit, :burst, + :proto, :isfragment, :tcp_flags, :gid, :uid, :sport, :dport, :port, :socket, :pkttype, :name, :state, :icmp, :limit, :burst, :jump, :todest, :tosource, :toports, :log_level, :log_prefix, :reject, :set_mark] def insert @@ -146,7 +148,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir # These are known booleans that do not take a value, but we want to munge # to true if they exist. - known_booleans = [:socket] + known_booleans = [:socket, :isfragment] #################### # PRE-PARSE CLUDGING @@ -158,7 +160,14 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir # Trick the system for booleans known_booleans.each do |bool| - values = values.sub(/#{@resource_map[bool]}/, '-m socket true') + if bool == :socket then + values = values.sub(/#{@resource_map[bool]}/, '-m socket true') + end + if bool == :isfragment then + # only replace those -f that are not followed by an l to + # distinguish between -f and the '-f' inside of --tcp-flags. + values = values.sub(/-f(?=[^l])/, '-f true') + end end ############ @@ -312,6 +321,9 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir if res == :socket then resource_value = nil end + if res == :isfragment then + resource_value = nil + end elsif res == :jump and resource[:action] then # In this case, we are substituting jump for action resource_value = resource[:action].to_s.upcase diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index cbfc4b3..e451699 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -42,6 +42,7 @@ Puppet::Type.newtype(:firewall) do feature :tcp_flags, "The ability to match on particular TCP flag settings" feature :pkttype, "Match a packet type" feature :socket, "Match open sockets" + feature :isfragment, "Match fragments" # provider specific features feature :iptables, "The provider provides iptables features." @@ -551,6 +552,14 @@ Puppet::Type.newtype(:firewall) do newvalues(:unicast, :broadcast, :multicast) end + newproperty(:isfragment, :required_features => :isfragment) do + desc <<-EOS + Set to true to match tcp fragments (requires type to be set to tcp) + EOS + + newvalues(:true, :false) + end + newproperty(:socket, :required_features => :socket) do desc <<-EOS If true, matches if an open socket can be found by doing a coket lookup diff --git a/spec/fixtures/iptables/conversion_hash.rb b/spec/fixtures/iptables/conversion_hash.rb index e12e482..7c509d8 100644 --- a/spec/fixtures/iptables/conversion_hash.rb +++ b/spec/fixtures/iptables/conversion_hash.rb @@ -298,6 +298,14 @@ ARGS_TO_HASH = { :socket => true, }, }, + 'isfragment_option' => { + :line => '-A INPUT -f -j ACCEPT', + :table => 'filter', + :params => { + :action => 'accept', + :isfragment => true, + }, + }, 'single_tcp_sport' => { :line => '-A OUTPUT -s 10.94.100.46/32 -p tcp -m tcp --sport 20443 -j ACCEPT', :table => 'mangle', @@ -706,4 +714,14 @@ HASH_TO_ARGS = { }, :args => ['-t', :mangle, '-p', :tcp, '-m', 'socket', '-m', 'comment', '--comment', '050 socket option', '-j', 'ACCEPT'], }, + 'isfragment_option' => { + :params => { + :name => '050 isfragment option', + :table => 'filter', + :proto => :all, + :action => 'accept', + :isfragment => true, + }, + :args => ['-t', :filter, '-p', :all, '-f', '-m', 'comment', '--comment', '050 isfragment option', '-j', 'ACCEPT'], + }, } -- 2.45.2