From 98a92134aa6ff0983b6eef5c307221fb6f3b7cd0 Mon Sep 17 00:00:00 2001 From: Jonathan Davies Date: Sun, 22 Feb 2015 21:45:45 +0000 Subject: [PATCH] TEE Feature --- README.markdown | 15 ++++++ lib/puppet/provider/firewall/ip6tables.rb | 3 +- lib/puppet/provider/firewall/iptables.rb | 3 +- lib/puppet/type/firewall.rb | 13 +++++ spec/acceptance/firewall_tee_spec.rb | 65 +++++++++++++++++++++++ 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 spec/acceptance/firewall_tee_spec.rb diff --git a/README.markdown b/README.markdown index 0712f00..e4d11a3 100644 --- a/README.markdown +++ b/README.markdown @@ -292,6 +292,7 @@ firewall { '100 snat for network foo2': } ``` + You can also change the TCP MSS value for VPN client traffic: ```puppet @@ -307,6 +308,18 @@ firewall { '110 TCPMSS for VPN clients': } ``` +The following will mirror all traffic sent to the server to a secondary host on the LAN with the TEE target: + +```puppet +firewall { '503 Mirror traffic to IDS': + proto => all, + jump => 'TEE', + gateway => '10.0.0.2', + chain => 'PREROUTING', + table => 'mangle', +} +``` + The following example creates a new chain and forwards any port 5000 access to it. ```puppet firewall { '100 forward to MY_CHAIN': @@ -518,6 +531,8 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov * `ensure`: Ensures that the resource is present. Valid values are 'present', 'absent'. The default is 'present'. +* `gateway`: Used with TEE target to mirror traffic of a machine to a secondary host on the LAN. + * `gid`: GID or Group owner matching rule. Accepts a string argument only, as iptables does not accept multiple gid in a single statement. Requires the `owner` feature. * `hop_limit`: Hop limiting value for matched packets. Values must match '/^\d+$/'. Requires the `hop_limiting` feature. diff --git a/lib/puppet/provider/firewall/ip6tables.rb b/lib/puppet/provider/firewall/ip6tables.rb index d0a020e..196af39 100644 --- a/lib/puppet/provider/firewall/ip6tables.rb +++ b/lib/puppet/provider/firewall/ip6tables.rb @@ -75,6 +75,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source = :dport => ["-m multiport --dports", "--dport"], :dst_range => '--dst-range', :dst_type => "--dst-type", + :gateway => "--gateway", :gid => "--gid-owner", :hop_limit => "-m hl --hl-eq", :icmp => "-m icmp6 --icmpv6-type", @@ -213,7 +214,7 @@ Puppet::Type.type(:firewall).provide :ip6tables, :parent => :iptables, :source = :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, :recent, :rseconds, :reap, - :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :todest, + :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :gateway, :todest, :tosource, :toports, :checksum_fill, :log_level, :log_prefix, :reject, :set_mss, :mss, :set_mark, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone] diff --git a/lib/puppet/provider/firewall/iptables.rb b/lib/puppet/provider/firewall/iptables.rb index 5f614c0..30df7cf 100644 --- a/lib/puppet/provider/firewall/iptables.rb +++ b/lib/puppet/provider/firewall/iptables.rb @@ -61,6 +61,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir :dport => ["-m multiport --dports", "--dport"], :dst_range => "--dst-range", :dst_type => "--dst-type", + :gateway => "--gateway", :gid => "--gid-owner", :icmp => "-m icmp --icmp-type", :iniface => "-i", @@ -238,7 +239,7 @@ Puppet::Type.type(:firewall).provide :iptables, :parent => Puppet::Provider::Fir :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, :recent, :rseconds, :reap, - :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :set_mss, :todest, + :rhitcount, :rttl, :rname, :mask, :rsource, :rdest, :ipset, :jump, :gateway, :set_mss, :todest, :tosource, :toports, :to, :checksum_fill, :random, :log_prefix, :log_level, :reject, :set_mark, :mss, :connlimit_above, :connlimit_mask, :connmark, :time_start, :time_stop, :month_days, :week_days, :date_start, :date_stop, :time_contiguous, :kernel_timezone ] diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index 637c0c6..3b589fc 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -1064,6 +1064,13 @@ Puppet::Type.newtype(:firewall) do EOS end + newproperty(:gateway, :required_features => :iptables) do + desc <<-EOS + The TEE target will clone a packet and redirect this clone to another + machine on the local network segment. gateway is the target host's IP. + EOS + end + newproperty(:ipset, :required_features => :ipset) do desc <<-EOS Matches against the specified ipset list. @@ -1309,6 +1316,12 @@ Puppet::Type.newtype(:firewall) do end end + if value(:jump).to_s == "TEE" + unless value(:gateway) + self.fail "When using jump => TEE, the gateway property is required" + end + end + if value(:jump).to_s == "DNAT" unless value(:table).to_s =~ /nat/ self.fail "Parameter jump => DNAT only applies to table => nat" diff --git a/spec/acceptance/firewall_tee_spec.rb b/spec/acceptance/firewall_tee_spec.rb new file mode 100644 index 0000000..c64c80c --- /dev/null +++ b/spec/acceptance/firewall_tee_spec.rb @@ -0,0 +1,65 @@ +require 'spec_helper_acceptance' + +describe 'firewall type', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + + before(:all) do + shell('iptables --flush; iptables -t nat --flush; iptables -t mangle --flush') + shell('ip6tables --flush; ip6tables -t nat --flush; ip6tables -t mangle --flush') + end + + if default['platform'] =~ /ubuntu-1404/ or default['platform'] =~ /ubuntu-1204/ or default['platform'] =~ /debian-7/ or default['platform'] =~ /debian-8/ or default['platform'] =~ /el-7/ + describe 'tee_gateway' do + context '10.0.0.2' do + it 'applies' do + pp = <<-EOS + class { '::firewall': } + firewall { + '810 - tee_gateway': + chain => 'PREROUTING', + table => 'mangle', + jump => 'TEE', + gateway => '10.0.0.2', + proto => all, + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + it 'should contain the rule' do + shell('iptables-save -t mangle') do |r| + expect(r.stdout).to match(/-A PREROUTING -m comment --comment "810 - tee_gateway" -j TEE --gateway 10.0.0.2/) + end + end + end + end + + describe 'tee_gateway6' do + context '2001:db8::1' do + it 'applies' do + pp = <<-EOS + class { '::firewall': } + firewall { + '811 - tee_gateway6': + chain => 'PREROUTING', + table => 'mangle', + jump => 'TEE', + gateway => '2001:db8::1', + proto => all, + provider => 'ip6tables', + } + EOS + + apply_manifest(pp, :catch_failures => true) + end + + it 'should contain the rule' do + shell('ip6tables-save -t mangle') do |r| + expect(r.stdout).to match(/-A PREROUTING -m comment --comment "811 - tee_gateway6" -j TEE --gateway 2001:db8::1/) + end + end + end + end + end + +end -- 2.45.2