From: Eimhin Laverty Date: Thu, 14 Mar 2019 13:02:36 +0000 (+0000) Subject: [WIP] (FM-7785) Additional test cleanup (#823) X-Git-Tag: 1.15.2~5 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=50f019603fafd53d29db27f61789c506c306fa37;p=puppet-modules%2Fpuppetlabs-firewall.git [WIP] (FM-7785) Additional test cleanup (#823) move ipv6 tests into their own test files. one for happy path testing(checking parameters work), and one for exceptions or tests that check error output. move missed ipv4 tests into appropriate test files. --- diff --git a/spec/acceptance/bytecode_spec.rb b/spec/acceptance/bytecode_spec.rb deleted file mode 100644 index 3593fc1..0000000 --- a/spec/acceptance/bytecode_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'spec_helper_acceptance' - -# --bytecode is only supported by operatingsystems using nftables (in general Linux kernel 3.13, RedHat 7 (and derivates) with 3.10) -# Skipping those from which we know they would fail. -describe 'bytecode property', unless: (os[:family] == 'redhat' && os[:release][0] <= '6') || - (os[:family] == 'sles' && os[:release][0..1] <= '11') || - (host_inventory['facter']['os']['name'].casecmp('oraclelinux').zero? && os[:release][0] <= '7') do - describe 'bytecode' do - context '4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0' do - pp = <<-PUPPETCODE - class { '::firewall': } - firewall { '102 - test': - action => 'accept', - bytecode => '4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0', - chain => 'OUTPUT', - proto => 'all', - table => 'filter', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -m bpf --bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0" -m comment --comment "102 - test" -j ACCEPT}) - end - end - end - end -end diff --git a/spec/acceptance/change_source_spec.rb b/spec/acceptance/change_source_spec.rb deleted file mode 100644 index 34e119c..0000000 --- a/spec/acceptance/change_source_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'changing the source' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - describe 'when unmanaged rules exist' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '101 test source changes': - proto => tcp, - port => '101', - action => accept, - source => '8.0.0.1', - } - firewall { '100 test source static': - proto => tcp, - port => '100', - action => accept, - source => '8.0.0.2', - } - PUPPETCODE - it 'applies with 8.0.0.1 first' do - apply_manifest(pp1, catch_failures: true) - end - - it 'adds a unmanaged rule without a comment' do - shell('iptables -A INPUT -t filter -s 8.0.0.3/32 -p tcp -m multiport --ports 102 -j ACCEPT') - expect(shell('iptables-save').stdout).to match(%r{-A INPUT -s 8\.0\.0\.3(\/32)? -p tcp -m multiport --ports 102 -j ACCEPT}) - end - - it 'contains the changable 8.0.0.1 rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.1(\/32)? -p tcp -m multiport --ports 101 -m comment --comment "101 test source changes" -j ACCEPT}) - end - end - it 'contains the static 8.0.0.2 rule' do # rubocop:disable RSpec/RepeatedExample : The values being matched differ - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.2(\/32)? -p tcp -m multiport --ports 100 -m comment --comment "100 test source static" -j ACCEPT}) - end - end - - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '101 test source changes': - proto => tcp, - port => '101', - action => accept, - source => '8.0.0.4', - } - PUPPETCODE - it 'changes to 8.0.0.4 second' do - expect(apply_manifest(pp2, catch_failures: true).stdout) - .to match(%r{Notice: \/Stage\[main\]\/Main\/Firewall\[101 test source changes\]\/source: source changed '8\.0\.0\.1\/32' to '8\.0\.0\.4\/32'}) - end - - it 'does not contain the old changing 8.0.0.1 rule' do - shell('iptables-save') do |r| - expect(r.stdout).not_to match(%r{8\.0\.0\.1}) - end - end - it 'contains the staic 8.0.0.2 rule' do # rubocop:disable RSpec/RepeatedExample : The values being matched differ - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.2(\/32)? -p tcp -m multiport --ports 100 -m comment --comment "100 test source static" -j ACCEPT}) - end - end - it 'contains the changing new 8.0.0.4 rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.4(\/32)? -p tcp -m multiport --ports 101 -m comment --comment "101 test source changes" -j ACCEPT}) - end - end - end -end diff --git a/spec/acceptance/firewall_attributes_exceptions_spec.rb b/spec/acceptance/firewall_attributes_exceptions_spec.rb index f85e031..f3be135 100644 --- a/spec/acceptance/firewall_attributes_exceptions_spec.rb +++ b/spec/acceptance/firewall_attributes_exceptions_spec.rb @@ -6,16 +6,55 @@ describe 'firewall basics', docker: true do ip6tables_flush_all_tables end - describe 'name' do - context 'when invalid ordering range specified' do - pp = <<-PUPPETCODE + # --bytecode is only supported by operatingsystems using nftables (in general Linux kernel 3.13, RedHat 7 (and derivates) with 3.10) + # Skipping those from which we know they would fail. + describe 'bytecode property', unless: (os[:family] == 'redhat' && os[:release][0] <= '6') || + (os[:family] == 'sles' && os[:release][0..1] <= '11') || + (host_inventory['facter']['os']['name'].casecmp('oraclelinux').zero? && os[:release][0] <= '7') do + describe 'bytecode' do + context '4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0' do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '102 - test': + action => 'accept', + bytecode => '4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0', + chain => 'OUTPUT', + proto => 'all', + table => 'filter', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A OUTPUT -m bpf --bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0" -m comment --comment "102 - test" -j ACCEPT}) + end + end + end + end + end + + describe 'dport' do + context 'when invalid ports' do + pp22 = <<-PUPPETCODE class { '::firewall': } - firewall { '001 - test': ensure => present } - firewall { '9946 test': ensure => present } + firewall { '561 - test': + proto => tcp, + dport => '9999561-562', + action => accept, + } PUPPETCODE - it 'fails' do - apply_manifest(pp, expect_failures: true) do |r| - expect(r.stderr).to match(%r{Rule sorting error}) + it 'applies' do + apply_manifest(pp22, expect_failures: true) do |r| + expect(r.stderr).to match(%r{invalid port\/service `9999561' specified}) + end + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m multiport --dports 9999561-562 -m comment --comment "560 - test" -j ACCEPT}) end end end @@ -65,54 +104,354 @@ describe 'firewall basics', docker: true do end end - describe 'sport' do - context 'when invalid ports' do - pp19 = <<-PUPPETCODE + describe 'firewall inverting' do + context 'when inverting partial array rules' do + pp2 = <<-PUPPETCODE class { '::firewall': } - firewall { '560 - test': - proto => tcp, - sport => '9999560-561', - action => accept, + firewall { '603 drop 80,443 traffic': + chain => 'INPUT', + action => 'drop', + proto => 'tcp', + sport => ['! http', '443'], } PUPPETCODE - it 'applies' do - apply_manifest(pp19, expect_failures: true) do |r| - expect(r.stderr).to match(%r{invalid port\/service `9999560' specified}) + it 'raises a failure' do + apply_manifest(pp2, expect_failures: true) do |r| + expect(r.stderr).to match(%r{is not prefixed}) end end + end + end + + describe 'isfragment' do + describe 'adding a rule' do + before(:all) do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '803 - test': + ensure => present, + proto => 'tcp', + } + firewall { '804 - test': + ensure => present, + proto => 'tcp', + isfragment => true, + } + firewall { '805 - test': + ensure => present, + proto => 'tcp', + isfragment => false, + } + PUPPETCODE + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: do_catch_changes) + end + + let(:result) { shell('iptables-save') } + + it 'when unset' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m comment --comment "803 - test"}) + end + it 'when set to true' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -f -m comment --comment "804 - test"}) + end + it 'when set to false' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m comment --comment "805 - test"}) + end + end + describe 'editing a rule and current value is false' do + before(:all) do + pp_idempotent = <<-PUPPETCODE + class { '::firewall': } + firewall { '807 - test': + ensure => present, + proto => 'tcp', + isfragment => true, + } + firewall { '808 - test': + ensure => present, + proto => 'tcp', + isfragment => false, + } + PUPPETCODE + + pp_does_not_change = <<-PUPPETCODE + class { '::firewall': } + firewall { '806 - test': + ensure => present, + proto => 'tcp', + isfragment => false, + } + firewall { '809 - test': + ensure => present, + proto => 'tcp', + isfragment => true, + } + PUPPETCODE + shell('iptables -A INPUT -p tcp -m comment --comment "806 - test"') + shell('iptables -A INPUT -p tcp -m comment --comment "807 - test"') + shell('iptables -A INPUT -p tcp -f -m comment --comment "808 - test"') + shell('iptables -A INPUT -p tcp -f -m comment --comment "809 - test"') + + apply_manifest(pp_idempotent, catch_failures: true) + apply_manifest(pp_idempotent, catch_changes: do_catch_changes) + + apply_manifest(pp_does_not_change, catch_changes: do_catch_changes) + end + + let(:result) { shell('iptables-save') } + + it 'when unset or false' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m comment --comment "806 - test"}) + end + it 'when unset or false and current value is true' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -f -m comment --comment "807 - test"}) + end + it 'when set to true and current value is false' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m comment --comment "808 - test"}) + end + it 'when set to true and current value is true' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -f -m comment --comment "809 - test"}) + end + end + end + + # describe 'firewall isfragment property' do + # before :all do + # iptables_flush_all_tables + # ip6tables_flush_all_tables + # end + + # shared_examples 'is idempotent' do |value, line_match| + # pp1 = <<-PUPPETCODE + # class { '::firewall': } + # firewall { '597 - test': + # ensure => present, + # proto => 'tcp', + # #{value} + # } + # PUPPETCODE + # it "changes the value to #{value}" do + # apply_manifest(pp1, catch_failures: true) + # apply_manifest(pp1, catch_changes: do_catch_changes) + + # shell('iptables-save') do |r| + # expect(r.stdout).to match(%r{#{line_match}}) + # end + # end + # end + + # shared_examples "doesn't change" do |value, line_match| + # pp2 = <<-PUPPETCODE + # class { '::firewall': } + # firewall { '597 - test': + # ensure => present, + # proto => 'tcp', + # #{value} + # } + # PUPPETCODE + # it "doesn't change the value to #{value}" do + # apply_manifest(pp2, catch_changes: do_catch_changes) + + # shell('iptables-save') do |r| + # expect(r.stdout).to match(%r{#{line_match}}) + # end + # end + # end + + # describe 'adding a rule' do + # context 'when unset' do + # before :all do + # iptables_flush_all_tables + # end + # it_behaves_like 'is idempotent', '', %r{-A INPUT -p tcp -m comment --comment "597 - test"} + # end + # context 'when set to true' do + # before :all do + # iptables_flush_all_tables + # end + # it_behaves_like 'is idempotent', 'isfragment => true,', %r{-A INPUT -p tcp -f -m comment --comment "597 - test"} + # end + # context 'when set to false' do + # before :all do + # iptables_flush_all_tables + # end + # it_behaves_like 'is idempotent', 'isfragment => false,', %r{-A INPUT -p tcp -m comment --comment "597 - test"} + # end + # end + + # describe 'editing a rule and current value is false' do + # context 'when unset or false' do + # before :each do + # iptables_flush_all_tables + # shell('iptables -A INPUT -p tcp -m comment --comment "597 - test"') + # end + # it_behaves_like "doesn't change", 'isfragment => false,', %r{-A INPUT -p tcp -m comment --comment "597 - test"} + # end + # context 'when unset or false and current value is true' do + # before :each do + # iptables_flush_all_tables + # shell('iptables -A INPUT -p tcp -m comment --comment "597 - test"') + # end + # it_behaves_like 'is idempotent', 'isfragment => true,', %r{-A INPUT -p tcp -f -m comment --comment "597 - test"} + # end + + # context 'when set to true and current value is false' do + # before :each do + # iptables_flush_all_tables + # shell('iptables -A INPUT -p tcp -f -m comment --comment "597 - test"') + # end + # it_behaves_like 'is idempotent', 'isfragment => false,', %r{-A INPUT -p tcp -m comment --comment "597 - test"} + # end + # context 'when set to trueand current value is true' do + # before :each do + # iptables_flush_all_tables + # shell('iptables -A INPUT -p tcp -f -m comment --comment "597 - test"') + # end + # it_behaves_like "doesn't change", 'isfragment => true,', %r{-A INPUT -p tcp -f -m comment --comment "597 - test"} + # end + # end + # end + + describe 'mac_source' do + context 'when 0A:1B:3C:4D:5E:6F' do + pp88 = <<-PUPPETCODE + class { '::firewall': } + firewall { '610 - test': + ensure => present, + source => '10.1.5.28/32', + mac_source => '0A:1B:3C:4D:5E:6F', + chain => 'INPUT', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp88, catch_failures: true) + end it 'contains the rule' do shell('iptables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m multiport --sports 9999560-561 -m comment --comment "560 - test" -j ACCEPT}) + if os[:family] == 'redhat' && os[:release].start_with?('5') + expect(r.stdout).to match(%r{-A INPUT -s 10.1.5.28 -p tcp -m mac --mac-source 0A:1B:3C:4D:5E:6F -m comment --comment "610 - test"}) + else + expect(r.stdout).to match(%r{-A INPUT -s 10.1.5.28\/(32|255\.255\.255\.255) -p tcp -m mac --mac-source 0A:1B:3C:4D:5E:6F -m comment --comment "610 - test"}) + end end end + # rubocop:enable RSpec/ExampleLength : Cannot reduce lines to required size end end - describe 'dport' do - context 'when invalid ports' do - pp22 = <<-PUPPETCODE + describe 'name' do + context 'when invalid ordering range specified' do + pp = <<-PUPPETCODE class { '::firewall': } - firewall { '561 - test': - proto => tcp, - dport => '9999561-562', - action => accept, - } + firewall { '001 - test': ensure => present } + firewall { '9946 test': ensure => present } PUPPETCODE + it 'fails' do + apply_manifest(pp, expect_failures: true) do |r| + expect(r.stderr).to match(%r{Rule sorting error}) + end + end + end + end + + describe 'nflog', unless: fact('iptables_version') < '1.3.7' do + describe 'nflog_group' do it 'applies' do - apply_manifest(pp22, expect_failures: true) do |r| - expect(r.stderr).to match(%r{invalid port\/service `9999561' specified}) + pp2 = <<-PUPPETCODE + class {'::firewall': } + firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_group => 3} + PUPPETCODE + apply_manifest(pp2, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{NFLOG --nflog-group 3}) + end + end + end + + describe 'nflog_prefix' do + it 'applies' do + pp3 = <<-PUPPETCODE + class {'::firewall': } + firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_prefix => 'TEST PREFIX'} + PUPPETCODE + apply_manifest(pp3, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{NFLOG --nflog-prefix +"TEST PREFIX"}) end end + end + + describe 'nflog_range' do + it 'applies' do + pp4 = <<-PUPPETCODE + class {'::firewall': } + firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_range => 16} + PUPPETCODE + apply_manifest(pp4, catch_failures: true) + end it 'contains the rule' do shell('iptables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m multiport --dports 9999561-562 -m comment --comment "560 - test" -j ACCEPT}) + expect(r.stdout).to match(%r{NFLOG --nflog-range 16}) + end + end + end + + describe 'nflog_threshold' do + it 'applies' do + pp5 = <<-PUPPETCODE + class {'::firewall': } + firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_threshold => 2} + PUPPETCODE + apply_manifest(pp5, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{NFLOG --nflog-threshold 2}) + end + end + end + + describe 'multiple rules' do + it 'applies' do + pp6 = <<-PUPPETCODE + class {'::firewall': } + firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_threshold => 2, nflog_group => 3} + PUPPETCODE + apply_manifest(pp6, catch_failures: true) + end + + it 'contains the rules' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{NFLOG --nflog-group 2 --nflog-threshold 3}) end end end end + describe 'nflog on older OSes', if: fact('iptables_version') < '1.3.7' do + pp1 = <<-PUPPETCODE + class {'::firewall': } + firewall { '503 - test': + jump => 'NFLOG', + proto => 'all', + nflog_group => 3, + } + PUPPETCODE + it 'throws an error' do + apply_manifest(pp1, acceptable_error_codes: [0]) + end + end + describe 'port' do context 'when invalid ports' do pp25 = <<-PUPPETCODE @@ -137,76 +476,302 @@ describe 'firewall basics', docker: true do end end - ['dst_type', 'src_type'].each do |type| - describe type.to_s do - context 'when LOCAL --limit-iface-in', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do - pp97 = <<-PUPPETCODE - class { '::firewall': } - firewall { '613 - test': - proto => tcp, - action => accept, - #{type} => 'LOCAL --limit-iface-in', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp97, catch_failures: true) - end + describe 'purge tests' do + before :all do + iptables_flush_all_tables + ip6tables_flush_all_tables + end - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "613 - test" -j ACCEPT}) - end - end + context 'when resources purge' do + before(:all) do + iptables_flush_all_tables + + shell('iptables -A INPUT -s 1.2.1.2') + shell('iptables -A INPUT -s 1.2.1.2') end - context 'when LOCAL --limit-iface-in fail', if: (os[:family] == 'redhat' && os[:release].start_with?('5')) do - pp98 = <<-PUPPETCODE - class { '::firewall': } - firewall { '614 - test': - proto => tcp, - action => accept, - #{type} => 'LOCAL --limit-iface-in', - } - PUPPETCODE - it 'fails' do - apply_manifest(pp98, expect_failures: true) do |r| - expect(r.stderr).to match(%r{--limit-iface-in and --limit-iface-out are available from iptables version}) - end - end + pp1 = <<-PUPPETCODE + class { 'firewall': } + resources { 'firewall': + purge => true, + } + PUPPETCODE + it 'make sure duplicate existing rules get purged' do + apply_manifest(pp1, expect_changes: true) + end - it 'does not contain the rule' do - shell('iptables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "614 - test" -j ACCEPT}) - end + it 'saves' do + shell('iptables-save') do |r| + expect(r.stdout).not_to match(%r{1\.2\.1\.2}) + expect(r.stderr).to eq('') end end + end - context 'when duplicated LOCAL', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do - pp99 = <<-PUPPETCODE - class { '::firewall': } - firewall { '615 - test': - proto => tcp, - action => accept, - #{type} => ['LOCAL', 'LOCAL'], - } - PUPPETCODE - it 'fails' do - apply_manifest(pp99, expect_failures: true) do |r| - expect(r.stderr).to match(%r{#{type} elements must be unique}) - end - end + context 'when ipv4 chain purge' do + after(:all) do + iptables_flush_all_tables + end + before(:each) do + iptables_flush_all_tables - it 'does not contain the rule' do - shell('iptables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype --#{type.tr('_', '-')} LOCAL -m addrtype --#{type.tr('_', '-')} LOCAL -m comment --comment "615 - test" -j ACCEPT}) - end + shell('iptables -A INPUT -p tcp -s 1.2.1.1') + shell('iptables -A INPUT -p udp -s 1.2.1.1') + shell('iptables -A OUTPUT -s 1.2.1.2 -m comment --comment "010 output-1.2.1.2"') + end + + pp2 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'INPUT:filter:IPv4': + purge => true, + } + PUPPETCODE + it 'purges only the specified chain' do + apply_manifest(pp2, expect_changes: true) + + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{010 output-1\.2\.1\.2}) + expect(r.stdout).not_to match(%r{1\.2\.1\.1}) + expect(r.stderr).to eq('') end end + # rubocop:enable RSpec/ExampleLength - context 'when multiple addrtype', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do - pp100 = <<-PUPPETCODE - class { '::firewall': } - firewall { '616 - test': + pp3 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'OUTPUT:filter:IPv4': + purge => true, + } + firewall { '010 output-1.2.1.2': + chain => 'OUTPUT', + proto => 'all', + source => '1.2.1.2', + } + PUPPETCODE + it 'ignores managed rules' do + apply_manifest(pp3, catch_changes: do_catch_changes) + end + + pp4 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'INPUT:filter:IPv4': + purge => true, + ignore => [ + '-s 1\.2\.1\.1', + ], + } + PUPPETCODE + it 'ignores specified rules' do + apply_manifest(pp4, catch_changes: do_catch_changes) + end + + pp5 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'INPUT:filter:IPv4': + purge => true, + ignore => [ + '-s 1\.2\.1\.1', + ], + } + firewall { '014 input-1.2.1.6': + chain => 'INPUT', + proto => 'all', + source => '1.2.1.6', + } + -> firewall { '013 input-1.2.1.5': + chain => 'INPUT', + proto => 'all', + source => '1.2.1.5', + } + -> firewall { '012 input-1.2.1.4': + chain => 'INPUT', + proto => 'all', + source => '1.2.1.4', + } + -> firewall { '011 input-1.2.1.3': + chain => 'INPUT', + proto => 'all', + source => '1.2.1.3', + } + PUPPETCODE + it 'adds managed rules with ignored rules' do + apply_manifest(pp5, catch_failures: true) + + expect(shell('iptables-save').stdout).to match(%r{-A INPUT -s 1\.2\.1\.1(\/32)? -p tcp\s?\n-A INPUT -s 1\.2\.1\.1(\/32)? -p udp}) + end + end + end + + describe 'reset' do + it 'deletes all rules' do + shell('ip6tables --flush') + shell('iptables --flush; iptables -t nat --flush; iptables -t mangle --flush') + end + end + + describe 'sport' do + context 'when invalid ports' do + pp19 = <<-PUPPETCODE + class { '::firewall': } + firewall { '560 - test': + proto => tcp, + sport => '9999560-561', + action => accept, + } + PUPPETCODE + it 'applies' do + apply_manifest(pp19, expect_failures: true) do |r| + expect(r.stderr).to match(%r{invalid port\/service `9999560' specified}) + end + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m multiport --sports 9999560-561 -m comment --comment "560 - test" -j ACCEPT}) + end + end + end + end + + describe 'source' do + describe 'when unmanaged rules exist' do + pp1 = <<-PUPPETCODE + class { '::firewall': } + firewall { '101 test source changes': + proto => tcp, + port => '101', + action => accept, + source => '8.0.0.1', + } + firewall { '100 test source static': + proto => tcp, + port => '100', + action => accept, + source => '8.0.0.2', + } + PUPPETCODE + it 'applies with 8.0.0.1 first' do + apply_manifest(pp1, catch_failures: true) + end + + it 'adds a unmanaged rule without a comment' do + shell('iptables -A INPUT -t filter -s 8.0.0.3/32 -p tcp -m multiport --ports 102 -j ACCEPT') + expect(shell('iptables-save').stdout).to match(%r{-A INPUT -s 8\.0\.0\.3(\/32)? -p tcp -m multiport --ports 102 -j ACCEPT}) + end + + it 'contains the changable 8.0.0.1 rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.1(\/32)? -p tcp -m multiport --ports 101 -m comment --comment "101 test source changes" -j ACCEPT}) + end + end + it 'contains the static 8.0.0.2 rule' do # rubocop:disable RSpec/RepeatedExample : The values being matched differ + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.2(\/32)? -p tcp -m multiport --ports 100 -m comment --comment "100 test source static" -j ACCEPT}) + end + end + + pp2 = <<-PUPPETCODE + class { '::firewall': } + firewall { '101 test source changes': + proto => tcp, + port => '101', + action => accept, + source => '8.0.0.4', + } + PUPPETCODE + it 'changes to 8.0.0.4 second' do + expect(apply_manifest(pp2, catch_failures: true).stdout) + .to match(%r{Notice: \/Stage\[main\]\/Main\/Firewall\[101 test source changes\]\/source: source changed '8\.0\.0\.1\/32' to '8\.0\.0\.4\/32'}) + end + + it 'does not contain the old changing 8.0.0.1 rule' do + shell('iptables-save') do |r| + expect(r.stdout).not_to match(%r{8\.0\.0\.1}) + end + end + it 'contains the staic 8.0.0.2 rule' do # rubocop:disable RSpec/RepeatedExample : The values being matched differ + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.2(\/32)? -p tcp -m multiport --ports 100 -m comment --comment "100 test source static" -j ACCEPT}) + end + end + it 'contains the changing new 8.0.0.4 rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -s 8\.0\.0\.4(\/32)? -p tcp -m multiport --ports 101 -m comment --comment "101 test source changes" -j ACCEPT}) + end + end + end + end + + ['dst_type', 'src_type'].each do |type| + describe type.to_s do + context 'when LOCAL --limit-iface-in', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do + pp97 = <<-PUPPETCODE + class { '::firewall': } + firewall { '613 - test': + proto => tcp, + action => accept, + #{type} => 'LOCAL --limit-iface-in', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp97, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "613 - test" -j ACCEPT}) + end + end + end + + context 'when LOCAL --limit-iface-in fail', if: (os[:family] == 'redhat' && os[:release].start_with?('5')) do + pp98 = <<-PUPPETCODE + class { '::firewall': } + firewall { '614 - test': + proto => tcp, + action => accept, + #{type} => 'LOCAL --limit-iface-in', + } + PUPPETCODE + it 'fails' do + apply_manifest(pp98, expect_failures: true) do |r| + expect(r.stderr).to match(%r{--limit-iface-in and --limit-iface-out are available from iptables version}) + end + end + + it 'does not contain the rule' do + shell('iptables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "614 - test" -j ACCEPT}) + end + end + end + + context 'when duplicated LOCAL', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do + pp99 = <<-PUPPETCODE + class { '::firewall': } + firewall { '615 - test': + proto => tcp, + action => accept, + #{type} => ['LOCAL', 'LOCAL'], + } + PUPPETCODE + it 'fails' do + apply_manifest(pp99, expect_failures: true) do |r| + expect(r.stderr).to match(%r{#{type} elements must be unique}) + end + end + + it 'does not contain the rule' do + shell('iptables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype --#{type.tr('_', '-')} LOCAL -m addrtype --#{type.tr('_', '-')} LOCAL -m comment --comment "615 - test" -j ACCEPT}) + end + end + end + + context 'when multiple addrtype', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do + pp100 = <<-PUPPETCODE + class { '::firewall': } + firewall { '616 - test': proto => tcp, action => accept, #{type} => ['LOCAL', '! LOCAL'], @@ -244,6 +809,50 @@ describe 'firewall basics', docker: true do end end end + + context 'when LOCAL --limit-iface-in', unless: (os[:family] == 'redhat' && os[:release].start_with?('5') + ) do + pp102 = <<-PUPPETCODE + class { '::firewall': } + firewall { '617 - test': + proto => tcp, + action => accept, + #{type} => 'LOCAL --limit-iface-in', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp102, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "617 - test" -j ACCEPT}) + end + end + end + + context 'when LOCAL --limit-iface-in fail', if: (os[:family] == 'redhat' && os[:release].start_with?('5') + ) do + pp103 = <<-PUPPETCODE + class { '::firewall': } + firewall { '618 - test': + proto => tcp, + action => accept, + #{type} => 'LOCAL --limit-iface-in', + } + PUPPETCODE + it 'fails' do + apply_manifest(pp103, expect_failures: true) do |r| + expect(r.stderr).to match(%r{--limit-iface-in and --limit-iface-out are available from iptables version}) + end + end + + it 'does not contain the rule' do + shell('iptables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "618 - test" -j ACCEPT}) + end + end + end end end @@ -289,906 +898,319 @@ describe 'firewall basics', docker: true do end end - describe 'jump' do - after :all do - iptables_flush_all_tables + describe 'to' do + context 'when Destination netmap 192.168.1.1' do + pp89 = <<-PUPPETCODE + class { '::firewall': } + firewall { '569 - test': + proto => tcp, + table => 'nat', + chain => 'PREROUTING', + jump => 'NETMAP', + source => '200.200.200.200', + to => '192.168.1.1', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp89, catch_failures: true) + end + + it 'contains the rule' do + shell('iptables-save -t nat') do |r| + expect(r.stdout).to match(%r{-A PREROUTING -s 200.200.200.200(\/32)? -p tcp -m comment --comment "569 - test" -j NETMAP --to 192.168.1.1}) + end + end + end + + describe 'reset' do + it 'deletes all rules' do + shell('ip6tables --flush') + shell('iptables --flush; iptables -t nat --flush; iptables -t mangle --flush') + end end - context 'when MARK' do - pp33 = <<-PUPPETCODE + context 'when Source netmap 192.168.1.1' do + pp90 = <<-PUPPETCODE class { '::firewall': } - firewallchain { 'TEST:filter:IPv4': - ensure => present, - } - firewall { '567 - test': + firewall { '569 - test': proto => tcp, - chain => 'INPUT', - jump => 'TEST', + table => 'nat', + chain => 'POSTROUTING', + jump => 'NETMAP', + destination => '200.200.200.200', + to => '192.168.1.1', } PUPPETCODE it 'applies' do - apply_manifest(pp33, catch_failures: true) + apply_manifest(pp90, catch_failures: true) end it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m comment --comment "567 - test" -j TEST}) + shell('iptables-save -t nat') do |r| + expect(r.stdout).to match(%r{-A POSTROUTING -d 200.200.200.200(\/32)? -p tcp -m comment --comment "569 - test" -j NETMAP --to 192.168.1.1}) end end end end - unless (os[:family] == 'redhat' && os[:release].start_with?('5')) || os[:family] == 'sles' - describe 'checksum_fill' do - context 'when virbr' do - pp38 = <<-PUPPETCODE + unless (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') + describe 'tee_gateway' do + context 'when 10.0.0.2' do + pp1 = <<-PUPPETCODE class { '::firewall': } - firewall { '576 - test': - proto => udp, - table => 'mangle', - outiface => 'virbr0', - chain => 'POSTROUTING', - dport => '68', - jump => 'CHECKSUM', - checksum_fill => true, - provider => iptables, + firewall { + '810 - tee_gateway': + chain => 'PREROUTING', + table => 'mangle', + jump => 'TEE', + gateway => '10.0.0.2', + proto => all, } PUPPETCODE it 'applies' do - apply_manifest(pp38, catch_failures: true) + apply_manifest(pp1, catch_failures: true) end it 'contains the rule' do shell('iptables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A POSTROUTING -o virbr0 -p udp -m multiport --dports 68 -m comment --comment "576 - test" -j CHECKSUM --checksum-fill}) + expect(r.stdout).to match(%r{-A PREROUTING -m comment --comment "810 - tee_gateway" -j TEE --gateway 10.0.0.2}) end end end end - describe 'checksum_fill6' do - context 'when virbr' do - pp39 = <<-PUPPETCODE + describe 'time tests' do + context 'when set all time parameters' do + pp1 = <<-PUPPETCODE class { '::firewall': } - firewall { '576 - test': - proto => udp, - table => 'mangle', - outiface => 'virbr0', - chain => 'POSTROUTING', - dport => '68', - jump => 'CHECKSUM', - checksum_fill => true, - provider => ip6tables, + firewall { '805 - test': + proto => tcp, + dport => '8080', + action => accept, + chain => 'OUTPUT', + date_start => '2016-01-19T04:17:07', + date_stop => '2038-01-19T04:17:07', + time_start => '6:00', + time_stop => '17:00:00', + month_days => '7', + week_days => 'Tue', + kernel_timezone => true, } PUPPETCODE it 'applies' do - apply_manifest(pp39, catch_failures: true) + apply_manifest(pp1, catch_failures: true) + apply_manifest(pp1, catch_changes: do_catch_changes) end it 'contains the rule' do - shell('ip6tables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A POSTROUTING -o virbr0 -p udp -m multiport --dports 68 -m comment --comment "576 - test" -j CHECKSUM --checksum-fill}) + shell('iptables-save') do |r| + expect(r.stdout).to match( + %r{-A OUTPUT -p tcp -m multiport --dports 8080 -m time --timestart 06:00:00 --timestop 17:00:00 --monthdays 7 --weekdays Tue --datestart 2016-01-19T04:17:07 --datestop 2038-01-19T04:17:07 --kerneltz -m comment --comment "805 - test" -j ACCEPT}, # rubocop:disable Metrics/LineLength + ) end end end end end - # RHEL5 does not support --random - unless os[:family] == 'redhat' && os[:release].start_with?('5') - describe 'random' do - context 'when 192.168.1.1' do - pp40 = <<-PUPPETCODE + unless (os[:family] == 'redhat' && os[:release].start_with?('5')) || os[:family] == 'sles' + describe 'checksum_fill' do + context 'when virbr' do + pp38 = <<-PUPPETCODE class { '::firewall': } - firewall { '570 - test 2': - proto => all, - table => 'nat', + firewall { '576 - test': + proto => udp, + table => 'mangle', + outiface => 'virbr0', chain => 'POSTROUTING', - jump => 'MASQUERADE', - source => '172.30.0.0/16', - random => true - } - PUPPETCODE - it 'applies' do - apply_manifest(pp40, catch_failures: true) - apply_manifest(pp40, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('iptables-save -t nat') do |r| - expect(r.stdout).to match(%r{-A POSTROUTING -s 172\.30\.0\.0\/16 -m comment --comment "570 - test 2" -j MASQUERADE --random}) - end - end - end - end - end - - # iptables version 1.3.5 is not suppored by the ip6tables provider - # iptables version 1.4.7 fails for multiple hl entries - describe 'testing ipv6', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') do - describe 'hop_limit' do - context 'when 5' do - pp42 = <<-PUPPETCODE - class { '::firewall': } - firewall { '571 - test': - ensure => present, - proto => tcp, - port => '571', - action => accept, - hop_limit => '5', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp42, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 571 -m hl --hl-eq 5 -m comment --comment "571 - test" -j ACCEPT}) - end - end - end - - context 'when invalid' do - pp43 = <<-PUPPETCODE - class { '::firewall': } - firewall { '571 - test': - ensure => present, - proto => tcp, - port => '571', - action => accept, - hop_limit => 'invalid', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp43, expect_failures: true) do |r| - expect(r.stderr).to match(%r{Invalid value "invalid".}) - end - end - - it 'does not contain the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m multiport --ports 571 -m comment --comment "571 - test" -m hl --hl-eq invalid -j ACCEPT}) - end - end - end - end - - describe 'ishasmorefrags' do - context 'when true' do - pp44 = <<-PUPPETCODE - class { '::firewall': } - firewall { '587 - test': - ensure => present, - proto => tcp, - port => '587', - action => accept, - ishasmorefrags => true, - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp44, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{A INPUT -p tcp -m frag --fragid 0 --fragmore -m multiport --ports 587 -m comment --comment "587 - test" -j ACCEPT}) - end - end - end - - context 'when false' do - pp45 = <<-PUPPETCODE - class { '::firewall': } - firewall { '588 - test': - ensure => present, - proto => tcp, - port => '588', - action => accept, - ishasmorefrags => false, - provider => 'ip6tables', + dport => '68', + jump => 'CHECKSUM', + checksum_fill => true, + provider => iptables, } PUPPETCODE it 'applies' do - apply_manifest(pp45, catch_failures: true) + apply_manifest(pp38, catch_failures: true) end it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 588 -m comment --comment "588 - test" -j ACCEPT}) + shell('iptables-save -t mangle') do |r| + expect(r.stdout).to match(%r{-A POSTROUTING -o virbr0 -p udp -m multiport --dports 68 -m comment --comment "576 - test" -j CHECKSUM --checksum-fill}) end end end end - describe 'islastfrag' do + # RHEL5/SLES does not support -m socket + describe 'socket' do context 'when true' do - pp46 = <<-PUPPETCODE + pp78 = <<-PUPPETCODE class { '::firewall': } - firewall { '589 - test': + firewall { '585 - test': ensure => present, proto => tcp, - port => '589', + port => '585', action => accept, - islastfrag => true, - provider => 'ip6tables', + chain => 'PREROUTING', + table => 'nat', + socket => true, } PUPPETCODE it 'applies' do - apply_manifest(pp46, catch_failures: true) + apply_manifest(pp78, catch_failures: true) end it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m frag --fragid 0 --fraglast -m multiport --ports 589 -m comment --comment "589 - test" -j ACCEPT}) + shell('iptables-save -t nat') do |r| + expect(r.stdout).to match(%r{-A PREROUTING -p tcp -m multiport --ports 585 -m socket -m comment --comment "585 - test" -j ACCEPT}) end end end context 'when false' do - pp47 = <<-PUPPETCODE + pp79 = <<-PUPPETCODE class { '::firewall': } - firewall { '590 - test': + firewall { '586 - test': ensure => present, proto => tcp, - port => '590', + port => '586', action => accept, - islastfrag => false, - provider => 'ip6tables', + chain => 'PREROUTING', + table => 'nat', + socket => false, } PUPPETCODE it 'applies' do - apply_manifest(pp47, catch_failures: true) + apply_manifest(pp79, catch_failures: true) end it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 590 -m comment --comment "590 - test" -j ACCEPT}) + shell('iptables-save -t nat') do |r| + expect(r.stdout).to match(%r{-A PREROUTING -p tcp -m multiport --ports 586 -m comment --comment "586 - test" -j ACCEPT}) end end end - end - describe 'isfirstfrag' do - context 'when true' do - pp48 = <<-PUPPETCODE - class { '::firewall': } - firewall { '591 - test': - ensure => present, - proto => tcp, - port => '591', - action => accept, - isfirstfrag => true, - provider => 'ip6tables', - } + shared_examples 'is idempotent' do |value, line_match| + pp1 = <<-PUPPETCODE + class { '::firewall': } + firewall { '598 - test': + ensure => present, + proto => 'tcp', + chain => 'PREROUTING', + table => 'raw', + #{value} + } PUPPETCODE - it 'applies' do - apply_manifest(pp48, catch_failures: true) - end + it "changes the value to #{value}" do + apply_manifest(pp1, catch_failures: true) + apply_manifest(pp1, catch_changes: true) - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m frag --fragid 0 --fragfirst -m multiport --ports 591 -m comment --comment "591 - test" -j ACCEPT}) + shell('iptables-save -t raw') do |r| + expect(r.stdout).to match(%r{#{line_match}}) end end end - context 'when false' do - pp49 = <<-PUPPETCODE - class { '::firewall': } - firewall { '592 - test': - ensure => present, - proto => tcp, - port => '592', - action => accept, - isfirstfrag => false, - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp49, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 592 -m comment --comment "592 - test" -j ACCEPT}) - end - end - end - end - - describe 'tcp_flags' do - context 'when FIN,SYN ACK' do - pp50 = <<-PUPPETCODE - class { '::firewall': } - firewall { '593 - test': - proto => tcp, - action => accept, - tcp_flags => 'FIN,SYN ACK', - provider => 'ip6tables', - } + shared_examples "doesn't change" do |value, line_match| + pp2 = <<-PUPPETCODE + class { '::firewall': } + firewall { '598 - test': + ensure => present, + proto => 'tcp', + chain => 'PREROUTING', + table => 'raw', + #{value} + } PUPPETCODE - it 'applies' do - apply_manifest(pp50, catch_failures: true) - end + it "doesn't change the value to #{value}" do + apply_manifest(pp2, catch_changes: true) - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN ACK -m comment --comment "593 - test" -j ACCEPT}) + shell('iptables-save -t raw') do |r| + expect(r.stdout).to match(%r{#{line_match}}) end end end - end - - describe 'src_range' do - context 'when 2001:db8::1-2001:db8::ff' do - pp51 = <<-PUPPETCODE - class { '::firewall': } - firewall { '601 - test': - proto => tcp, - port => '601', - action => accept, - src_range => '2001:db8::1-2001:db8::ff', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp51, catch_failures: true) - apply_manifest(pp51, catch_changes: do_catch_changes) - end - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m iprange --src-range 2001:db8::1-2001:db8::ff -m multiport --ports 601 -m comment --comment "601 - test" -j ACCEPT}) + describe 'adding a rule' do + context 'when unset' do + before :all do + iptables_flush_all_tables end + it_behaves_like 'is idempotent', '', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} end - end - - # Invalid IP - context 'when 2001::db8::1-2001:db8::ff' do - pp52 = <<-PUPPETCODE - class { '::firewall': } - firewall { '601 - test': - proto => tcp, - port => '601', - action => accept, - provider => 'ip6tables', - src_range => '2001::db8::1-2001:db8::ff', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp52, expect_failures: true) do |r| - expect(r.stderr).to match(%r{Invalid IP address "2001::db8::1" in range "2001::db8::1-2001:db8::ff"}) + context 'when set to true' do + before :all do + iptables_flush_all_tables end + it_behaves_like 'is idempotent', 'socket => true,', %r{-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"} end - - it 'does not contain the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m iprange --src-range 2001::db8::1-2001:db8::ff -m multiport --ports 601 -m comment --comment "601 - test" -j ACCEPT}) + context 'when set to false' do + before :all do + iptables_flush_all_tables end + it_behaves_like 'is idempotent', 'socket => false,', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} end end - end - - describe 'dst_range' do - context 'when 2001:db8::1-2001:db8::ff' do - pp53 = <<-PUPPETCODE - class { '::firewall': } - firewall { '602 - test': - proto => tcp, - port => '602', - action => accept, - dst_range => '2001:db8::1-2001:db8::ff', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp53, catch_failures: true) - apply_manifest(pp53, catch_changes: do_catch_changes) - end - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m iprange --dst-range 2001:db8::1-2001:db8::ff -m multiport --ports 602 -m comment --comment "602 - test" -j ACCEPT}) + describe 'editing a rule' do + context 'when unset or false and current value is false' do + before :each do + iptables_flush_all_tables + shell('iptables -t raw -A PREROUTING -p tcp -m comment --comment "598 - test"') end + it_behaves_like "doesn't change", 'socket => false,', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} end - end - - # Invalid IP - context 'when 2001::db8::1-2001:db8::ff' do - pp54 = <<-PUPPETCODE - class { '::firewall': } - firewall { '602 - test': - proto => tcp, - port => '602', - action => accept, - provider => 'ip6tables', - dst_range => '2001::db8::1-2001:db8::ff', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp54, expect_failures: true) do |r| - expect(r.stderr).to match(%r{Invalid IP address "2001::db8::1" in range "2001::db8::1-2001:db8::ff"}) + context 'when unset or false and current value is true' do + before :each do + iptables_flush_all_tables + shell('iptables -t raw -A PREROUTING -p tcp -m comment --comment "598 - test"') end + it_behaves_like 'is idempotent', 'socket => true,', %r{-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"} end - - it 'does not contain the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m iprange --dst-range 2001::db8::1-2001:db8::ff -m multiport --ports 602 -m comment --comment "602 - test" -j ACCEPT}) + context 'when set to true and current value is false' do + before :each do + iptables_flush_all_tables + shell('iptables -t raw -A PREROUTING -p tcp -m socket -m comment --comment "598 - test"') end + it_behaves_like 'is idempotent', 'socket => false,', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} end - end - end - - describe 'mac_source' do - context 'when 0A:1B:3C:4D:5E:6F' do - pp55 = <<-PUPPETCODE - class { '::firewall': } - firewall { '604 - test': - ensure => present, - source => '2001:db8::1/128', - mac_source => '0A:1B:3C:4D:5E:6F', - chain => 'INPUT', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp55, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -s 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -p tcp -m mac --mac-source 0A:1B:3C:4D:5E:6F -m comment --comment "604 - test"}) + context 'when set to true and current value is true' do + before :each do + iptables_flush_all_tables + shell('iptables -t raw -A PREROUTING -p tcp -m socket -m comment --comment "598 - test"') end + it_behaves_like "doesn't change", 'socket => true,', %r{-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"} end end end + end - # ip6tables has limited `-m socket` support - unless (os[:family] == 'redhat' && os[:release].start_with?('5')) || os[:family] == 'sles' - describe 'socket' do - context 'when true' do - pp56 = <<-PUPPETCODE - class { '::firewall': } - firewall { '605 - test': - ensure => present, - proto => tcp, - port => '605', - action => accept, - chain => 'INPUT', - socket => true, - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp56, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 605 -m socket -m comment --comment "605 - test" -j ACCEPT}) - end - end - end - - context 'when false' do - pp57 = <<-PUPPETCODE + # RHEL5 does not support --random + unless os[:family] == 'redhat' && os[:release].start_with?('5') + describe 'match_mark' do + context 'when 0x1' do + pp1 = <<-PUPPETCODE class { '::firewall': } - firewall { '606 - test': - ensure => present, - proto => tcp, - port => '606', - action => accept, - chain => 'INPUT', - socket => false, - provider => 'ip6tables', + firewall { '503 match_mark - test': + proto => 'all', + match_mark => '0x1', + action => reject, } PUPPETCODE - it 'applies' do - apply_manifest(pp57, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 606 -m comment --comment "606 - test" -j ACCEPT}) - end - end - end - end - end - - describe 'ipsec_policy' do - context 'when ipsec' do - pp58 = <<-PUPPETCODE - class { '::firewall': } - firewall { '607 - test': - ensure => 'present', - action => 'reject', - chain => 'OUTPUT', - destination => '2001:db8::1/128', - ipsec_dir => 'out', - ipsec_policy => 'ipsec', - proto => 'all', - reject => 'icmp6-adm-prohibited', - table => 'filter', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp58, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match( - %r{-A OUTPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir out --pol ipsec -m comment --comment "607 - test" -j REJECT --reject-with icmp6-adm-prohibited}, # rubocop:disable Metrics/LineLength - ) - end - end - end - - context 'when none' do - pp59 = <<-PUPPETCODE - class { '::firewall': } - firewall { '608 - test': - ensure => 'present', - action => 'reject', - chain => 'OUTPUT', - destination => '2001:db8::1/128', - ipsec_dir => 'out', - ipsec_policy => 'none', - proto => 'all', - reject => 'icmp6-adm-prohibited', - table => 'filter', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp59, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match( - %r{-A OUTPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir out --pol none -m comment --comment "608 - test" -j REJECT --reject-with icmp6-adm-prohibited}, - ) - end - end - end - end - - describe 'ipsec_dir' do - context 'when out' do - pp60 = <<-PUPPETCODE - class { '::firewall': } - firewall { '609 - test': - ensure => 'present', - action => 'reject', - chain => 'OUTPUT', - destination => '2001:db8::1/128', - ipsec_dir => 'out', - ipsec_policy => 'ipsec', - proto => 'all', - reject => 'icmp6-adm-prohibited', - table => 'filter', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp60, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match( - %r{-A OUTPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir out --pol ipsec -m comment --comment "609 - test" -j REJECT --reject-with icmp6-adm-prohibited}, # rubocop:disable Metrics/LineLength - ) - end - end - end - - context 'when in' do - pp61 = <<-PUPPETCODE - class { '::firewall': } - firewall { '610 - test': - ensure => 'present', - action => 'reject', - chain => 'INPUT', - destination => '2001:db8::1/128', - ipsec_dir => 'in', - ipsec_policy => 'none', - proto => 'all', - reject => 'icmp6-adm-prohibited', - table => 'filter', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp61, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match( - %r{-A INPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir in --pol none -m comment --comment "610 - test" -j REJECT --reject-with icmp6-adm-prohibited}, - ) - end - end - end - end - - describe 'set_mark' do - context 'when 0x3e8/0xffffffff' do - pp62 = <<-PUPPETCODE - class { '::firewall': } - firewall { '611 - test': - ensure => present, - chain => 'OUTPUT', - proto => tcp, - port => '611', - jump => 'MARK', - table => 'mangle', - set_mark => '0x3e8/0xffffffff', - provider => 'ip6tables', - } - PUPPETCODE it 'applies' do - apply_manifest(pp62, catch_failures: true) + apply_manifest(pp1, catch_failures: true) end it 'contains the rule' do - shell('ip6tables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 611 -m comment --comment "611 - test" -j MARK --set-xmark 0x3e8\/0xffffffff}) - end - end - end - end - - # ipset is hard to test, only testing on ubuntu 14 - describe 'ipset', if: (host_inventory['facter']['os']['name'] == 'ubuntu' && os[:release].start_with?('14')) do - pp63 = <<-PUPPETCODE - exec { 'hackery pt 1': - command => 'service iptables-persistent flush', - path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', - } - package { 'ipset': - ensure => present, - require => Exec['hackery pt 1'], - } - exec { 'hackery pt 2': - command => 'service iptables-persistent start', - path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', - require => Package['ipset'], - } - class { '::firewall': } - exec { 'create ipset blacklist': - command => 'ipset create blacklist hash:ip,port family inet6 maxelem 1024 hashsize 65535 timeout 120', - path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', - require => Package['ipset'], - } - -> exec { 'create ipset honeypot': - command => 'ipset create honeypot hash:ip family inet6 maxelem 1024 hashsize 65535 timeout 120', - path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', - } - -> exec { 'add blacklist': - command => 'ipset add blacklist 2001:db8::1,80', - path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', - } - -> exec { 'add honeypot': - command => 'ipset add honeypot 2001:db8::5', - path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', - } - firewall { '612 - test': - ensure => present, - chain => 'INPUT', - proto => tcp, - action => drop, - ipset => ['blacklist src,dst', '! honeypot dst'], - provider => 'ip6tables', - require => Exec['add honeypot'], - } - PUPPETCODE - it 'applies' do - apply_manifest(pp63, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m set --match-set blacklist src,dst -m set ! --match-set honeypot dst -m comment --comment "612 - test" -j DROP}) - end - end - end - - ['dst_type', 'src_type'].each do |type| - describe type.to_s do - context 'when MULTICAST' do - pp65 = <<-PUPPETCODE - class { '::firewall': } - firewall { '603 - test': - proto => tcp, - action => accept, - #{type} => 'MULTICAST', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp65, catch_failures: true) - apply_manifest(pp65, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m addrtype\s.*\sMULTICAST -m comment --comment "603 - test" -j ACCEPT}) - end - end - end - - context 'when ! MULTICAST' do - pp66 = <<-PUPPETCODE - class { '::firewall': } - firewall { '603 - test inversion': - proto => tcp, - action => accept, - #{type} => '! MULTICAST', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp66, catch_failures: true) - apply_manifest(pp66, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m addrtype( !\s.*\sMULTICAST|\s.*\s! MULTICAST) -m comment --comment "603 - test inversion" -j ACCEPT}) - end - end - end - - context 'when BROKEN' do - pp67 = <<-PUPPETCODE - class { '::firewall': } - firewall { '603 - test': - proto => tcp, - action => accept, - #{type} => 'BROKEN', - provider => 'ip6tables', - } - PUPPETCODE - it 'fails' do - apply_manifest(pp67, expect_failures: true) do |r| - expect(r.stderr).to match(%r{Invalid value "BROKEN".}) - end - end - - it 'does not contain the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sBROKEN -m comment --comment "603 - test" -j ACCEPT}) - end - end - end - - context 'when LOCAL --limit-iface-in', unless: (os[:family] == 'redhat' && os[:release].start_with?('5') - ) do - pp102 = <<-PUPPETCODE - class { '::firewall': } - firewall { '617 - test': - proto => tcp, - action => accept, - #{type} => 'LOCAL --limit-iface-in', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp102, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "617 - test" -j ACCEPT}) - end - end - end - - context 'when LOCAL --limit-iface-in fail', if: (os[:family] == 'redhat' && os[:release].start_with?('5') - ) do - pp103 = <<-PUPPETCODE - class { '::firewall': } - firewall { '618 - test': - proto => tcp, - action => accept, - #{type} => 'LOCAL --limit-iface-in', - } - PUPPETCODE - it 'fails' do - apply_manifest(pp103, expect_failures: true) do |r| - expect(r.stderr).to match(%r{--limit-iface-in and --limit-iface-out are available from iptables version}) - end - end - - it 'does not contain the rule' do - shell('iptables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL --limit-iface-in -m comment --comment "618 - test" -j ACCEPT}) - end - end - end - - context 'when duplicated LOCAL', unless: (os[:family] == 'redhat' && os[:release].start_with?('5') - ) do - pp104 = <<-PUPPETCODE - class { '::firewall': } - firewall { '619 - test': - proto => tcp, - action => accept, - #{type} => ['LOCAL', 'LOCAL'], - provider => 'ip6tables', - } - PUPPETCODE - it 'fails' do - apply_manifest(pp104, expect_failures: true) do |r| - expect(r.stderr).to match(%r{#{type} elements must be unique}) - end - end - - it 'does not contain the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL -m addrtype\s.*\sLOCAL -m comment --comment "619 - test" -j ACCEPT}) - end - end - end - - context 'when multiple addrtype', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) do - pp105 = <<-PUPPETCODE - class { '::firewall': } - firewall { '620 - test': - proto => tcp, - action => accept, - #{type} => ['LOCAL', '! LOCAL'], - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp105, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m addrtype --#{type.tr('_', '-')} LOCAL -m addrtype ! --#{type.tr('_', '-')} LOCAL -m comment --comment "620 - test" -j ACCEPT}) - end - end - end - - context 'when multiple addrtype fail', if: (os[:family] == 'redhat' && os[:release].start_with?('5') - ) do - pp106 = <<-PUPPETCODE - class { '::firewall': } - firewall { '616 - test': - proto => tcp, - action => accept, - #{type} => ['LOCAL', '! LOCAL'], - provider => 'ip6tables', - } - PUPPETCODE - it 'fails' do - apply_manifest(pp106, expect_failures: true) do |r| - expect(r.stderr).to match(%r{Multiple #{type} elements are available from iptables version}) - end - end - - it 'does not contain the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype --#{type.tr('_', '-')} LOCAL -m addrtype ! --#{type.tr('_', '-')} LOCAL -m comment --comment "616 - test" -j ACCEPT}) - end + shell('iptables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -m mark --mark 0x1 -m comment --comment "503 match_mark - test" -j REJECT --reject-with icmp-port-unreachable}) end end end end - end - # iptables version 1.3.5 does not support masks on MARK rules - unless os[:family] == 'redhat' && os[:release].start_with?('5') + # iptables version 1.3.5 does not support masks on MARK rules describe 'set_mark' do context 'when 0x3e8/0xffffffff' do pp73 = <<-PUPPETCODE @@ -1214,249 +1236,72 @@ describe 'firewall basics', docker: true do end end end - end - - # RHEL5/SLES does not support -m socket - describe 'socket', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) || (os[:family] == 'sles') do - context 'when true' do - pp78 = <<-PUPPETCODE - class { '::firewall': } - firewall { '585 - test': - ensure => present, - proto => tcp, - port => '585', - action => accept, - chain => 'PREROUTING', - table => 'nat', - socket => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp78, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save -t nat') do |r| - expect(r.stdout).to match(%r{-A PREROUTING -p tcp -m multiport --ports 585 -m socket -m comment --comment "585 - test" -j ACCEPT}) - end - end - end - - context 'when false' do - pp79 = <<-PUPPETCODE - class { '::firewall': } - firewall { '586 - test': - ensure => present, - proto => tcp, - port => '586', - action => accept, - chain => 'PREROUTING', - table => 'nat', - socket => false, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp79, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save -t nat') do |r| - expect(r.stdout).to match(%r{-A PREROUTING -p tcp -m multiport --ports 586 -m comment --comment "586 - test" -j ACCEPT}) - end - end - end - end - - describe 'recent' do - context 'when set' do - pp84 = <<-PUPPETCODE - class { '::firewall': } - firewall { '597 - test': - ensure => 'present', - chain => 'INPUT', - destination => '30.0.0.0/8', - proto => 'all', - table => 'filter', - recent => 'set', - rdest => true, - rname => 'list1', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp84, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - # Mask added as of Ubuntu 14.04. - expect(r.stdout).to match(%r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --set --name list1 (--mask 255.255.255.255 )?--rdest -m comment --comment "597 - test"}) - end - end - end - context 'when rcheck' do - pp85 = <<-PUPPETCODE - class { '::firewall': } - firewall { '598 - test': - ensure => 'present', - chain => 'INPUT', - destination => '30.0.0.0/8', - proto => 'all', - table => 'filter', - recent => 'rcheck', - rsource => true, - rname => 'list1', - rseconds => 60, - rhitcount => 5, - rttl => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp85, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match( - %r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --rcheck --seconds 60 --hitcount 5 --rttl --name list1 (--mask 255.255.255.255 )?--rsource -m comment --comment "598 - test"}, - ) - end - end - end - - context 'when update' do - pp86 = <<-PUPPETCODE - class { '::firewall': } - firewall { '599 - test': - ensure => 'present', - chain => 'INPUT', - destination => '30.0.0.0/8', - proto => 'all', - table => 'filter', - recent => 'update', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp86, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --update --name DEFAULT (--mask 255.255.255.255 )?--rsource -m comment --comment "599 - test"}) - end - end - end - - context 'when remove' do - pp87 = <<-PUPPETCODE - class { '::firewall': } - firewall { '600 - test': - ensure => 'present', - chain => 'INPUT', - destination => '30.0.0.0/8', - proto => 'all', - table => 'filter', - recent => 'remove', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp87, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --remove --name DEFAULT (--mask 255.255.255.255 )?--rsource -m comment --comment "600 - test"}) + describe 'random' do + context 'when 192.168.1.1' do + pp40 = <<-PUPPETCODE + class { '::firewall': } + firewall { '570 - random': + proto => all, + table => 'nat', + chain => 'POSTROUTING', + jump => 'MASQUERADE', + source => '172.30.0.0/16', + random => true + } + PUPPETCODE + it 'applies' do + apply_manifest(pp40, catch_failures: true) + apply_manifest(pp40, catch_changes: do_catch_changes) end - end - end - end - describe 'mac_source' do - context 'when 0A:1B:3C:4D:5E:6F' do - pp88 = <<-PUPPETCODE - class { '::firewall': } - firewall { '610 - test': - ensure => present, - source => '10.1.5.28/32', - mac_source => '0A:1B:3C:4D:5E:6F', - chain => 'INPUT', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp88, catch_failures: true) - end - it 'contains the rule' do - shell('iptables-save') do |r| - if os[:family] == 'redhat' && os[:release].start_with?('5') - expect(r.stdout).to match(%r{-A INPUT -s 10.1.5.28 -p tcp -m mac --mac-source 0A:1B:3C:4D:5E:6F -m comment --comment "610 - test"}) - else - expect(r.stdout).to match(%r{-A INPUT -s 10.1.5.28\/(32|255\.255\.255\.255) -p tcp -m mac --mac-source 0A:1B:3C:4D:5E:6F -m comment --comment "610 - test"}) + it 'contains the rule' do + shell('iptables-save -t nat') do |r| + expect(r.stdout).to match(%r{-A POSTROUTING -s 172\.30\.0\.0\/16 -m comment --comment "570 - random" -j MASQUERADE --random}) end end end - # rubocop:enable RSpec/ExampleLength : Cannot reduce lines to required size end end - describe 'reset' do - it 'deletes all rules' do - shell('ip6tables --flush') - shell('iptables --flush; iptables -t nat --flush; iptables -t mangle --flush') - end - end - - describe 'to' do - context 'when Destination netmap 192.168.1.1' do - pp89 = <<-PUPPETCODE - class { '::firewall': } - firewall { '569 - test': - proto => tcp, - table => 'nat', - chain => 'PREROUTING', - jump => 'NETMAP', - source => '200.200.200.200', - to => '192.168.1.1', - } + describe 'hashlimit', unless: ((os[:family] == 'redhat' && os[:release][0] <= '5')) do + before(:all) do + pp = <<-PUPPETCODE + firewall { '805 - hashlimit_above test': + chain => 'INPUT', + proto => 'tcp', + hashlimit_name => 'above', + hashlimit_above => '526/sec', + hashlimit_htable_gcinterval => '10', + hashlimit_mode => 'srcip,dstip', + action => accept, + } + firewall { '806 - hashlimit_upto test': + chain => 'INPUT', + hashlimit_name => 'upto', + hashlimit_upto => '16/sec', + hashlimit_burst => '640', + hashlimit_htable_size => '1310000', + hashlimit_htable_max => '320000', + hashlimit_htable_expire => '36000000', + action => accept, + } PUPPETCODE - it 'applies' do - apply_manifest(pp89, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save -t nat') do |r| - expect(r.stdout).to match(%r{-A PREROUTING -s 200.200.200.200(\/32)? -p tcp -m comment --comment "569 - test" -j NETMAP --to 192.168.1.1}) - end - end + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: do_catch_changes) end - describe 'reset' do - it 'deletes all rules' do - shell('ip6tables --flush') - shell('iptables --flush; iptables -t nat --flush; iptables -t mangle --flush') - end - end + let(:result) { shell('iptables-save') } - context 'when Source netmap 192.168.1.1' do - pp90 = <<-PUPPETCODE - class { '::firewall': } - firewall { '569 - test': - proto => tcp, - table => 'nat', - chain => 'POSTROUTING', - jump => 'NETMAP', - destination => '200.200.200.200', - to => '192.168.1.1', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp90, catch_failures: true) - end + it 'hashlimit_above is set' do + regex_array = [%r{-A INPUT}, %r{-p tcp}, %r{--hashlimit-above 526\/sec}, %r{--hashlimit-mode srcip,dstip}, %r{--hashlimit-name above}, %r{--hashlimit-htable-gcinterval 10}, %r{-j ACCEPT}] - it 'contains the rule' do - shell('iptables-save -t nat') do |r| - expect(r.stdout).to match(%r{-A POSTROUTING -d 200.200.200.200(\/32)? -p tcp -m comment --comment "569 - test" -j NETMAP --to 192.168.1.1}) - end + regex_array.each do |regex| + expect(result.stdout).to match(regex) end end + it 'hashlimit_upto is set' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m hashlimit --hashlimit-upto 16\/sec --hashlimit-burst 640 --hashlimit-name upto --hashlimit-htable-size 1310000 --hashlimit-htable-max 320000 --hashlimit-htable-expire 36000000 -m comment --comment "806 - hashlimit_upto test" -j ACCEPT}) # rubocop:disable Metrics/LineLength : Cannot reduce line to required length + end end end diff --git a/spec/acceptance/firewall_attributes_happy_path_spec.rb b/spec/acceptance/firewall_attributes_happy_path_spec.rb index 89b8760..e6947d1 100644 --- a/spec/acceptance/firewall_attributes_happy_path_spec.rb +++ b/spec/acceptance/firewall_attributes_happy_path_spec.rb @@ -102,6 +102,14 @@ describe 'firewall attribute testing, happy path' do action => accept, chain => 'FORWARD', } + firewallchain { 'TEST:filter:IPv4': + ensure => present, + } + firewall { '567 - jump': + proto => tcp, + chain => 'INPUT', + jump => 'TEST', + } firewall { '568 - tosource': proto => tcp, table => 'nat', @@ -117,13 +125,6 @@ describe 'firewall attribute testing, happy path' do source => '200.200.200.200', todest => '192.168.1.1', } - firewall { '570 - toports': - proto => icmp, - table => 'nat', - chain => 'PREROUTING', - jump => 'REDIRECT', - toports => '2222', - } firewall { '572 - limit': ensure => present, proto => tcp, @@ -139,6 +140,13 @@ describe 'firewall attribute testing, happy path' do limit => '500/sec', burst => '1500', } + firewall { '574 - toports': + proto => icmp, + table => 'nat', + chain => 'PREROUTING', + jump => 'REDIRECT', + toports => '2222', + } firewall { '581 - pkttype': ensure => present, proto => tcp, @@ -175,23 +183,73 @@ describe 'firewall attribute testing, happy path' do reject => 'icmp-net-unreachable', table => 'filter', } - firewall { - '600 - set_mss': - proto => 'tcp', - tcp_flags => 'SYN,RST SYN', - jump => 'TCPMSS', - set_mss => '1360', - mss => '1361:1541', - chain => 'FORWARD', - table => 'mangle', - } - firewall { - '601 - clamp_mss_to_pmtu': - proto => 'tcp', - chain => 'FORWARD', - tcp_flags => 'SYN,RST SYN', - jump => 'TCPMSS', - clamp_mss_to_pmtu => true, + firewall { '597 - recent set': + ensure => 'present', + chain => 'INPUT', + destination => '30.0.0.0/8', + proto => 'all', + table => 'filter', + recent => 'set', + rdest => true, + rname => 'list1', + } + firewall { '598 - recent rcheck': + ensure => 'present', + chain => 'INPUT', + destination => '30.0.0.0/8', + proto => 'all', + table => 'filter', + recent => 'rcheck', + rsource => true, + rname => 'list1', + rseconds => 60, + rhitcount => 5, + rttl => true, + } + firewall { '599 - recent update': + ensure => 'present', + chain => 'INPUT', + destination => '30.0.0.0/8', + proto => 'all', + table => 'filter', + recent => 'update', + } + firewall { '600 - recent remove': + ensure => 'present', + chain => 'INPUT', + destination => '30.0.0.0/8', + proto => 'all', + table => 'filter', + recent => 'remove', + } + firewall { '601 - clamp_mss_to_pmtu': + proto => 'tcp', + chain => 'FORWARD', + tcp_flags => 'SYN,RST SYN', + jump => 'TCPMSS', + clamp_mss_to_pmtu => true, + } + firewall { '602 - drop NEW external website packets with FIN/RST/ACK set and SYN unset': + chain => 'INPUT', + ctstate => 'NEW', + action => 'drop', + proto => 'tcp', + sport => ['! http', '! 443'], + source => '! 10.0.0.0/8', + tcp_flags => '! FIN,SYN,RST,ACK SYN', + } + firewall { '603 - disallow esp protocol': + action => 'accept', + proto => '! esp', + } + firewall { '604 - set_mss': + proto => 'tcp', + tcp_flags => 'SYN,RST SYN', + jump => 'TCPMSS', + set_mss => '1360', + mss => '1361:1541', + chain => 'FORWARD', + table => 'mangle', } firewall { '700 - blah-A Test Rule': jump => 'LOG', @@ -249,10 +307,54 @@ describe 'firewall attribute testing, happy path' do uid => '!0', proto => 'all', } + + firewall { '807 - ipt_modules tests': + proto => tcp, + dport => '8080', + action => reject, + chain => 'OUTPUT', + uid => 0, + gid => 404, + src_range => "90.0.0.1-90.0.0.2", + dst_range => "100.0.0.1-100.0.0.2", + src_type => 'LOCAL', + dst_type => 'UNICAST', + physdev_in => "eth0", + physdev_out => "eth1", + physdev_is_bridged => true, + } + firewall { '808 - ipt_modules tests': + proto => tcp, + dport => '8080', + action => reject, + chain => 'OUTPUT', + gid => 404, + dst_range => "100.0.0.1-100.0.0.2", + dst_type => 'UNICAST', + physdev_out => "eth1", + physdev_is_bridged => true, + } + firewall { '1000 - set_dscp': + proto => 'tcp', + jump => 'DSCP', + set_dscp => '0x01', + port => '997', + chain => 'OUTPUT', + table => 'mangle', + } + firewall { '1001 EF - set_dscp_class': + proto => 'tcp', + jump => 'DSCP', + port => '997', + set_dscp_class => 'EF', + chain => 'OUTPUT', + table => 'mangle', + } PUPPETCODE apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: do_catch_changes) end + let(:result) { shell('iptables-save') } it 'log_level and log_prefix' do @@ -312,7 +414,7 @@ describe 'firewall attribute testing, happy path' do expect(result.stdout).to match(%r{-A PREROUTING -s 200.200.200.200(\/32)? -p tcp -m comment --comment "569 - todest" -j DNAT --to-destination 192.168.1.1}) end it 'toports is set' do - expect(result.stdout).to match(%r{-A PREROUTING -p icmp -m comment --comment "570 - toports" -j REDIRECT --to-ports 2222}) + expect(result.stdout).to match(%r{-A PREROUTING -p icmp -m comment --comment "574 - toports" -j REDIRECT --to-ports 2222}) end it 'limit is set' do expect(result.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 572 -m limit --limit 500\/sec -m comment --comment "572 - limit" -j ACCEPT}) @@ -333,7 +435,7 @@ describe 'firewall attribute testing, happy path' do expect(result.stdout).to match(%r{-A INPUT -d 20.0.0.0\/(8|255\.0\.0\.0) -m policy --dir in --pol none -m comment --comment "596 - ipsec_policy none and in" -j REJECT --reject-with icmp-net-unreachable}) # rubocop:disable Metrics/LineLength end it 'set_mss is set' do - expect(result.stdout).to match(%r{-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1541 -m comment --comment "600 - set_mss" -j TCPMSS --set-mss 1360}) + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1541 -m comment --comment "604 - set_mss" -j TCPMSS --set-mss 1360}) end it 'clamp_mss_to_pmtu is set' do expect(result.stdout).to match(%r{-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m comment --comment "601 - clamp_mss_to_pmtu" -j TCPMSS --clamp-mss-to-pmtu}) @@ -365,5 +467,41 @@ describe 'firewall attribute testing, happy path' do it 'uid set to 0 negated' do expect(result.stdout).to match(%r{-A OUTPUT -m owner ! --uid-owner (0|root) -m comment --comment "804 - uid 0 negated" -j ACCEPT}) end + it 'set_dscp is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1000 - set_dscp" -j DSCP --set-dscp 0x01}) + end + it 'set_dscp_class is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1001 EF - set_dscp_class" -j DSCP --set-dscp 0x2e}) + end + it 'all the modules with multiple args is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m iprange --src-range 90.0.0.1-90.0.0.2\s+--dst-range 100.0.0.1-100.0.0.2 -m owner --uid-owner (0|root) --gid-owner 404 -m multiport --dports 8080 -m addrtype --src-type LOCAL --dst-type UNICAST -m comment --comment "807 - ipt_modules tests" -j REJECT --reject-with icmp-port-unreachable}) # rubocop:disable Metrics/LineLength + end + it 'all the modules with single args is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m iprange --dst-range 100.0.0.1-100.0.0.2 -m owner --gid-owner 404 -m multiport --dports 8080 -m addrtype --dst-type UNICAST -m comment --comment "808 - ipt_modules tests" -j REJECT --reject-with icmp-port-unreachable}) # rubocop:disable Metrics/LineLength + end + it 'inverting rules' do + regex_array = [%r{-A INPUT (-s !|! -s) (10\.0\.0\.0\/8|10\.0\.0\.0\/255\.0\.0\.0).*}, %r{-A INPUT.*(--sports !|! --sports) 80,443.*}, + %r{-A INPUT.*-m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN.*}, %r{-A INPUT.*-j DROP}, + %r{-A INPUT (! -p|-p !) esp -m comment --comment "603 - disallow esp protocol" -j ACCEPT}] + + regex_array.each do |regex| + expect(result.stdout).to match(regex) + end + end + it 'recent set to set' do + expect(result.stdout).to match(%r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --set --name list1 (--mask 255.255.255.255 )?--rdest -m comment --comment "597 - recent set"}) + end + it 'recent set to rcheck' do + expect(result.stdout).to match(%r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --rcheck --seconds 60 --hitcount 5 --rttl --name list1 (--mask 255.255.255.255 )?--rsource -m comment --comment "598 - recent rcheck"}) # rubocop:disable Metrics/LineLength + end + it 'recent set to update' do + expect(result.stdout).to match(%r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --update --name DEFAULT (--mask 255.255.255.255 )?--rsource -m comment --comment "599 - recent update"}) + end + it 'recent set to remove' do + expect(result.stdout).to match(%r{-A INPUT -d 30.0.0.0\/(8|255\.0\.0\.0) -m recent --remove --name DEFAULT (--mask 255.255.255.255 )?--rsource -m comment --comment "600 - recent remove"}) + end + it 'jump is set' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m comment --comment "567 - jump" -j TEST}) + end end end diff --git a/spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb b/spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb new file mode 100644 index 0000000..c796c4f --- /dev/null +++ b/spec/acceptance/firewall_attributes_ipv6_exceptions_spec.rb @@ -0,0 +1,594 @@ +require 'spec_helper_acceptance' + +describe 'firewall ipv6 attribute testing, exceptions' do + before(:all) do + iptables_flush_all_tables + ip6tables_flush_all_tables + end + + describe 'standard attributes', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') do + describe 'dst_range' do + context 'when 2001::db8::1-2001:db8::ff' do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '602 - test': + proto => tcp, + port => '602', + action => accept, + provider => 'ip6tables', + dst_range => '2001::db8::1-2001:db8::ff', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp, expect_failures: true) do |r| + expect(r.stderr).to match(%r{Invalid IP address "2001::db8::1" in range "2001::db8::1-2001:db8::ff"}) + end + end + + it 'does not contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m iprange --dst-range 2001::db8::1-2001:db8::ff -m multiport --ports 602 -m comment --comment "602 - test" -j ACCEPT}) + end + end + end + end + + ['dst_type', 'src_type'].each do |type| + describe type.to_s do + context 'when BROKEN' do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '603 - test': + proto => tcp, + action => accept, + #{type} => 'BROKEN', + provider => 'ip6tables', + } + PUPPETCODE + it 'fails' do + apply_manifest(pp, expect_failures: true) do |r| + expect(r.stderr).to match(%r{Invalid value "BROKEN".}) + end + end + + it 'does not contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sBROKEN -m comment --comment "603 - test" -j ACCEPT}) + end + end + end + + context 'when duplicated LOCAL' do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '619 - test': + proto => tcp, + action => accept, + #{type} => ['LOCAL', 'LOCAL'], + provider => 'ip6tables', + } + PUPPETCODE + it 'fails' do + apply_manifest(pp, expect_failures: true) do |r| + expect(r.stderr).to match(%r{#{type} elements must be unique}) + end + end + + it 'does not contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype\s.*\sLOCAL -m addrtype\s.*\sLOCAL -m comment --comment "619 - test" -j ACCEPT}) + end + end + end + + context 'when multiple addrtype fail', if: (os[:family] == 'redhat' && os[:release].start_with?('5')) do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '616 - test': + proto => tcp, + action => accept, + #{type} => ['LOCAL', '! LOCAL'], + provider => 'ip6tables', + } + PUPPETCODE + it 'fails' do + apply_manifest(pp, expect_failures: true) do |r| + expect(r.stderr).to match(%r{Multiple #{type} elements are available from iptables version}) + end + end + + it 'does not contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m addrtype --#{type.tr('_', '-')} LOCAL -m addrtype ! --#{type.tr('_', '-')} LOCAL -m comment --comment "616 - test" -j ACCEPT}) + end + end + end + end + end + + describe 'hop_limit' do + context 'when invalid' do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '571 - test': + ensure => present, + proto => tcp, + port => '571', + action => accept, + hop_limit => 'invalid', + provider => 'ip6tables', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp, expect_failures: true) do |r| + expect(r.stderr).to match(%r{Invalid value "invalid".}) + end + end + + it 'does not contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m multiport --ports 571 -m comment --comment "571 - test" -m hl --hl-eq invalid -j ACCEPT}) + end + end + end + end + + # ipset is hard to test, only testing on ubuntu 14 + describe 'ipset', if: (host_inventory['facter']['os']['name'] == 'Ubuntu' && os[:release].start_with?('14')) do + before(:all) do + pp = <<-PUPPETCODE + exec { 'hackery pt 1': + command => 'service iptables-persistent flush', + path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + package { 'ipset': + ensure => present, + require => Exec['hackery pt 1'], + } + exec { 'hackery pt 2': + command => 'service iptables-persistent start', + path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + require => Package['ipset'], + } + class { '::firewall': } + exec { 'create ipset blacklist': + command => 'ipset create blacklist hash:ip,port family inet6 maxelem 1024 hashsize 65535 timeout 120', + path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + require => Package['ipset'], + } + -> exec { 'create ipset honeypot': + command => 'ipset create honeypot hash:ip family inet6 maxelem 1024 hashsize 65535 timeout 120', + path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + -> exec { 'add blacklist': + command => 'ipset add blacklist 2001:db8::1,80', + path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + -> exec { 'add honeypot': + command => 'ipset add honeypot 2001:db8::5', + path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', + } + firewall { '612 - test': + ensure => present, + chain => 'INPUT', + proto => tcp, + action => drop, + ipset => ['blacklist src,dst', '! honeypot dst'], + provider => 'ip6tables', + require => Exec['add honeypot'], + } + PUPPETCODE + apply_manifest(pp, catch_failures: true) + end + + it 'contains the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).to match(%r{-A INPUT -p tcp -m set --match-set blacklist src,dst -m set ! --match-set honeypot dst -m comment --comment "612 - test" -j DROP}) + end + end + end + + describe 'src_range' do + context 'when 2001::db8::1-2001:db8::ff' do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '601 - test': + proto => tcp, + port => '601', + action => accept, + provider => 'ip6tables', + src_range => '2001::db8::1-2001:db8::ff', + } + PUPPETCODE + it 'applies' do + apply_manifest(pp, expect_failures: true) do |r| + expect(r.stderr).to match(%r{Invalid IP address "2001::db8::1" in range "2001::db8::1-2001:db8::ff"}) + end + end + + it 'does not contain the rule' do + shell('ip6tables-save') do |r| + expect(r.stdout).not_to match(%r{-A INPUT -p tcp -m iprange --src-range 2001::db8::1-2001:db8::ff -m multiport --ports 601 -m comment --comment "601 - test" -j ACCEPT}) + end + end + end + end + end + + describe 'unless redhat 5 happy path', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do + before(:all) do + pp = <<-PUPPETCODE + firewall { '701 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '701', + action => accept, + physdev_in => 'eth0', + } + firewall { '702 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '702', + action => accept, + physdev_out => 'eth1', + } + firewall { '703 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '703', + action => accept, + physdev_in => 'eth0', + physdev_out => 'eth1', + } + firewall { '704 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '704', + action => accept, + physdev_is_bridged => true, + } + firewall { '705 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '705', + action => accept, + physdev_in => 'eth0', + physdev_is_bridged => true, + } + firewall { '706 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '706', + action => accept, + physdev_out => 'eth1', + physdev_is_bridged => true, + } + firewall { '707 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '707', + action => accept, + physdev_in => 'eth0', + physdev_out => 'eth1', + physdev_is_bridged => true, + } + firewall { '708 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '708', + action => accept, + physdev_is_in => true, + } + firewall { '709 - test': + provider => 'ip6tables', + chain => 'FORWARD', + proto => tcp, + port => '709', + action => accept, + physdev_is_out => true, + } + firewall { '1002 - set_dscp': + proto => 'tcp', + jump => 'DSCP', + set_dscp => '0x01', + port => '997', + chain => 'OUTPUT', + table => 'mangle', + provider => 'ip6tables', + } + firewall { '1003 EF - set_dscp_class': + proto => 'tcp', + jump => 'DSCP', + port => '997', + set_dscp_class => 'EF', + chain => 'OUTPUT', + table => 'mangle', + provider => 'ip6tables', + } + firewall { '502 - set_mss': + proto => 'tcp', + tcp_flags => 'SYN,RST SYN', + jump => 'TCPMSS', + set_mss => '1360', + mss => '1361:1541', + chain => 'FORWARD', + table => 'mangle', + provider => 'ip6tables', + } + firewall { '503 - clamp_mss_to_pmtu': + proto => 'tcp', + chain => 'FORWARD', + tcp_flags => 'SYN,RST SYN', + jump => 'TCPMSS', + clamp_mss_to_pmtu => true, + provider => 'ip6tables', + } + firewall { '803 - hashlimit_upto test ip6': + chain => 'INPUT', + provider => 'ip6tables', + hashlimit_name => 'upto-ip6', + hashlimit_upto => '16/sec', + hashlimit_burst => '640', + hashlimit_htable_size => '1310000', + hashlimit_htable_max => '320000', + hashlimit_htable_expire => '36000000', + action => accept, + } + firewall { '503 match_mark ip6tables - test': + proto => 'all', + match_mark => '0x1', + action => reject, + provider => 'ip6tables', + } + + PUPPETCODE + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: do_catch_changes) + end + + let(:result) { shell('ip6tables-save') } + + it 'physdev_in is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 -m multiport --ports 701 -m comment --comment "701 - test" -j ACCEPT}) + end + it 'physdev_out is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 -m multiport --ports 702 -m comment --comment "702 - test" -j ACCEPT}) + end + it 'physdev_in and physdev_out is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 -m multiport --ports 703 -m comment --comment "703 - test" -j ACCEPT}) + end + it 'physdev_is_bridged is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-is-bridged -m multiport --ports 704 -m comment --comment "704 - test" -j ACCEPT}) + end + it 'physdev_in and physdev_is_bridged is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-is-bridged -m multiport --ports 705 -m comment --comment "705 - test" -j ACCEPT}) + end + it 'physdev_out and physdev_is_bridged is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m multiport --ports 706 -m comment --comment "706 - test" -j ACCEPT}) + end + it 'physdev_in and physdev_out and physdev_is_bridged is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m multiport --ports 707 -m comment --comment "707 - test" -j ACCEPT}) + end + it 'physdev_is_in is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-is-in -m multiport --ports 708 -m comment --comment "708 - test" -j ACCEPT}) + end + it 'physdev_is_out is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-is-out -m multiport --ports 709 -m comment --comment "709 - test" -j ACCEPT}) + end + it 'set_dscp is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1002 - set_dscp" -j DSCP --set-dscp 0x01}) + end + it 'set_dscp_class is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1003 EF - set_dscp_class" -j DSCP --set-dscp 0x2e}) + end + it 'set_mss and mss is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1541 -m comment --comment "502 - set_mss" -j TCPMSS --set-mss 1360}) + end + it 'clamp_mss_to_pmtu is set' do + expect(result.stdout).to match(%r{-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m comment --comment "503 - clamp_mss_to_pmtu" -j TCPMSS --clamp-mss-to-pmtu}) + end + it 'hashlimit_name set to "upto-ip6"' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m hashlimit --hashlimit-upto 16\/sec --hashlimit-burst 640 --hashlimit-name upto-ip6 --hashlimit-htable-size 1310000 --hashlimit-htable-max 320000 --hashlimit-htable-expire 36000000 -m comment --comment "803 - hashlimit_upto test ip6" -j ACCEPT}) # rubocop:disable Metrics/LineLength : Cannot reduce line to required length + end + it 'match_mark is set' do + expect(result.stdout).to match(%r{-A INPUT -m mark --mark 0x1 -m comment --comment "503 match_mark ip6tables - test" -j REJECT --reject-with icmp6-port-unreachable}) + end + end + + describe 'ishasmorefrags/islastfrag/isfirstfrag', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') do + shared_examples 'is idempotent' do |values, line_match| + pp2 = <<-PUPPETCODE + class { '::firewall': } + firewall { '599 - test': + ensure => present, + proto => 'tcp', + provider => 'ip6tables', + #{values} + } + PUPPETCODE + it "changes the values to #{values}" do + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: do_catch_changes) + + shell('ip6tables-save') do |r| + expect(r.stdout).to match(%r{#{line_match}}) + end + end + end + shared_examples "doesn't change" do |values, line_match| + pp3 = <<-PUPPETCODE + class { '::firewall': } + firewall { '599 - test': + ensure => present, + proto => 'tcp', + provider => 'ip6tables', + #{values} + } + PUPPETCODE + it "doesn't change the values to #{values}" do + apply_manifest(pp3, catch_changes: do_catch_changes) + + shell('ip6tables-save') do |r| + expect(r.stdout).to match(%r{#{line_match}}) + end + end + end + + describe 'adding a rule' do + context 'when unset' do + before :all do + ip6tables_flush_all_tables + end + it_behaves_like 'is idempotent', '', %r{-A INPUT -p tcp -m comment --comment "599 - test"} + end + context 'when set to true' do + before :all do + ip6tables_flush_all_tables + end + it_behaves_like 'is idempotent', 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', + %r{-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"} + end + context 'when set to false' do + before :all do + ip6tables_flush_all_tables + end + it_behaves_like 'is idempotent', 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', %r{-A INPUT -p tcp -m comment --comment "599 - test"} + end + end + describe 'editing a rule' do + context 'when unset or false' do + before :each do + ip6tables_flush_all_tables + shell('ip6tables -A INPUT -p tcp -m comment --comment "599 - test"') + end + context 'when current value is false' do + it_behaves_like "doesn't change", 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', %r{-A INPUT -p tcp -m comment --comment "599 - test"} + end + context 'when current value is true' do + it_behaves_like 'is idempotent', 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', + %r{-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"} + end + end + context 'when set to true' do + before :each do + ip6tables_flush_all_tables + shell('ip6tables -A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"') + end + context 'when current value is false' do + it_behaves_like 'is idempotent', 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', %r{-A INPUT -p tcp -m comment --comment "599 - test"} + end + context 'when current value is true' do + it_behaves_like "doesn't change", 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', + %r{-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"} + end + end + end + end + + describe 'purge' do + context 'when ipv6 chain purge', unless: os[:family] == 'redhat' && os[:release].start_with?('5') do + after(:all) do + ip6tables_flush_all_tables + end + before(:each) do + ip6tables_flush_all_tables + + shell('ip6tables -A INPUT -p tcp -s 1::42') + shell('ip6tables -A INPUT -p udp -s 1::42') + shell('ip6tables -A OUTPUT -s 1::50 -m comment --comment "010 output-1::50"') + end + + let(:result) { shell('ip6tables-save') } + + pp1 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'INPUT:filter:IPv6': + purge => true, + } + PUPPETCODE + it 'purges only the specified chain' do + apply_manifest(pp1, expect_changes: true) + + expect(result.stdout).to match(%r{010 output-1::50}) + expect(result.stdout).not_to match(%r{1::42}) + expect(result.stderr).to eq('') + end + + pp2 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'OUTPUT:filter:IPv6': + purge => true, + } + firewall { '010 output-1::50': + chain => 'OUTPUT', + proto => 'all', + source => '1::50', + provider => 'ip6tables', + } + PUPPETCODE + it 'ignores managed rules' do + apply_manifest(pp2, catch_changes: do_catch_changes) + end + + pp3 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'INPUT:filter:IPv6': + purge => true, + ignore => [ + '-s 1::42', + ], + } + PUPPETCODE + it 'ignores specified rules' do + apply_manifest(pp3, catch_changes: do_catch_changes) + end + + pp4 = <<-PUPPETCODE + class { 'firewall': } + firewallchain { 'INPUT:filter:IPv6': + purge => true, + ignore => [ + '-s 1::42', + ], + } + firewall { '014 input-1::46': + chain => 'INPUT', + proto => 'all', + source => '1::46', + provider => 'ip6tables', + } + -> firewall { '013 input-1::45': + chain => 'INPUT', + proto => 'all', + source => '1::45', + provider => 'ip6tables', + } + -> firewall { '012 input-1::44': + chain => 'INPUT', + proto => 'all', + source => '1::44', + provider => 'ip6tables', + } + -> firewall { '011 input-1::43': + chain => 'INPUT', + proto => 'all', + source => '1::43', + provider => 'ip6tables', + } + PUPPETCODE + it 'adds managed rules with ignored rules' do + apply_manifest(pp4, catch_failures: true) + + expect(result.stdout).to match(%r{-A INPUT -s 1::42(\/128)? -p tcp\s?\n-A INPUT -s 1::42(\/128)? -p udp}) + end + end + end +end diff --git a/spec/acceptance/firewall_attributes_ipv6_happy_path_spec.rb b/spec/acceptance/firewall_attributes_ipv6_happy_path_spec.rb new file mode 100644 index 0000000..69c88d0 --- /dev/null +++ b/spec/acceptance/firewall_attributes_ipv6_happy_path_spec.rb @@ -0,0 +1,390 @@ +require 'spec_helper_acceptance' + +describe 'firewall attribute testing, happy path', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') do + before :all do + iptables_flush_all_tables + ip6tables_flush_all_tables + end + + describe 'attributes test' do + before(:all) do + pp = <<-PUPPETCODE + class { '::firewall': } + firewall { '571 - hop_limit': + ensure => present, + proto => tcp, + port => '571', + action => accept, + hop_limit => '5', + provider => 'ip6tables', + } + firewall { '576 - checksum_fill': + proto => udp, + table => 'mangle', + outiface => 'virbr0', + chain => 'POSTROUTING', + dport => '68', + jump => 'CHECKSUM', + checksum_fill => true, + provider => ip6tables, + } + firewall { '587 - ishasmorefrags true': + ensure => present, + proto => tcp, + port => '587', + action => accept, + ishasmorefrags => true, + provider => 'ip6tables', + } + firewall { '588 - ishasmorefrags false': + ensure => present, + proto => tcp, + port => '588', + action => accept, + ishasmorefrags => false, + provider => 'ip6tables', + } + firewall { '589 - islastfrag true': + ensure => present, + proto => tcp, + port => '589', + action => accept, + islastfrag => true, + provider => 'ip6tables', + } + firewall { '590 - islastfrag false': + ensure => present, + proto => tcp, + port => '590', + action => accept, + islastfrag => false, + provider => 'ip6tables', + } + firewall { '591 - isfirstfrag true': + ensure => present, + proto => tcp, + port => '591', + action => accept, + isfirstfrag => true, + provider => 'ip6tables', + } + firewall { '592 - isfirstfrag false': + ensure => present, + proto => tcp, + port => '592', + action => accept, + isfirstfrag => false, + provider => 'ip6tables', + } + firewall { '593 - tcpfrags': + proto => tcp, + action => accept, + tcp_flags => 'FIN,SYN ACK', + provider => 'ip6tables', + } + firewall { '601 - src_range': + proto => tcp, + port => '601', + action => accept, + src_range => '2001:db8::1-2001:db8::ff', + provider => 'ip6tables', + } + firewall { '602 - dst_range': + proto => tcp, + port => '602', + action => accept, + dst_range => '2001:db8::1-2001:db8::ff', + provider => 'ip6tables', + } + firewall { '604 - mac_source': + ensure => present, + source => '2001:db8::1/128', + mac_source => '0A:1B:3C:4D:5E:6F', + chain => 'INPUT', + provider => 'ip6tables', + } + firewall { '605 - socket true': + ensure => present, + proto => tcp, + port => '605', + action => accept, + chain => 'INPUT', + socket => true, + provider => 'ip6tables', + } + firewall { '606 - socket false': + ensure => present, + proto => tcp, + port => '606', + action => accept, + chain => 'INPUT', + socket => false, + provider => 'ip6tables', + } + firewall { '607 - ipsec_policy ipsec': + ensure => 'present', + action => 'reject', + chain => 'OUTPUT', + destination => '2001:db8::1/128', + ipsec_dir => 'out', + ipsec_policy => 'ipsec', + proto => 'all', + reject => 'icmp6-adm-prohibited', + table => 'filter', + provider => 'ip6tables', + } + firewall { '608 - ipsec_policy none': + ensure => 'present', + action => 'reject', + chain => 'OUTPUT', + destination => '2001:db8::1/128', + ipsec_dir => 'out', + ipsec_policy => 'none', + proto => 'all', + reject => 'icmp6-adm-prohibited', + table => 'filter', + provider => 'ip6tables', + } + firewall { '609 - ipsec_dir out': + ensure => 'present', + action => 'reject', + chain => 'OUTPUT', + destination => '2001:db8::1/128', + ipsec_dir => 'out', + ipsec_policy => 'ipsec', + proto => 'all', + reject => 'icmp6-adm-prohibited', + table => 'filter', + provider => 'ip6tables', + } + firewall { '610 - ipsec_dir in': + ensure => 'present', + action => 'reject', + chain => 'INPUT', + destination => '2001:db8::1/128', + ipsec_dir => 'in', + ipsec_policy => 'none', + proto => 'all', + reject => 'icmp6-adm-prohibited', + table => 'filter', + provider => 'ip6tables', + } + firewall { '611 - set_mark': + ensure => present, + chain => 'OUTPUT', + proto => tcp, + port => '611', + jump => 'MARK', + table => 'mangle', + set_mark => '0x3e8/0xffffffff', + provider => 'ip6tables', + } + firewall { '613 - dst_type MULTICAST': + proto => tcp, + action => accept, + dst_type => 'MULTICAST', + provider => 'ip6tables', + } + firewall { '614 - src_type MULTICAST': + proto => tcp, + action => accept, + src_type => 'MULTICAST', + provider => 'ip6tables', + } + firewall { '615 - dst_type ! MULTICAST': + proto => tcp, + action => accept, + dst_type => '! MULTICAST', + provider => 'ip6tables', + } + firewall { '616 - src_type ! MULTICAST': + proto => tcp, + action => accept, + src_type => '! MULTICAST', + provider => 'ip6tables', + } + firewall { '619 - dst_type multiple values': + proto => tcp, + action => accept, + dst_type => ['LOCAL', '! LOCAL'], + provider => 'ip6tables', + } + firewall { '620 - src_type multiple values': + proto => tcp, + action => accept, + src_type => ['LOCAL', '! LOCAL'], + provider => 'ip6tables', + } + firewall { '801 - ipt_modules tests': + proto => tcp, + dport => '8080', + action => reject, + chain => 'OUTPUT', + provider => 'ip6tables', + uid => 0, + gid => 404, + src_range => "2001::-2002::", + dst_range => "2003::-2004::", + src_type => 'LOCAL', + dst_type => 'UNICAST', + physdev_in => "eth0", + physdev_out => "eth1", + physdev_is_bridged => true, + } + firewall { '802 - ipt_modules tests': + proto => tcp, + dport => '8080', + action => reject, + chain => 'OUTPUT', + provider => 'ip6tables', + gid => 404, + dst_range => "2003::-2004::", + dst_type => 'UNICAST', + physdev_out => "eth1", + physdev_is_bridged => true, + } + firewall { '805 - time': + proto => tcp, + dport => '8080', + action => accept, + chain => 'OUTPUT', + date_start => '2016-01-19T04:17:07', + date_stop => '2038-01-19T04:17:07', + time_start => '6:00', + time_stop => '17:00:00', + month_days => '7', + week_days => 'Tue', + kernel_timezone => true, + provider => 'ip6tables', + } + firewall { '806 - hashlimit_above test ipv6': + chain => 'INPUT', + provider => 'ip6tables', + proto => 'tcp', + hashlimit_name => 'above-ip6', + hashlimit_above => '526/sec', + hashlimit_htable_gcinterval => '10', + hashlimit_mode => 'srcip,dstip', + action => accept, + } + firewall { '811 - tee_gateway6': + chain => 'PREROUTING', + table => 'mangle', + jump => 'TEE', + gateway => '2001:db8::1', + proto => all, + provider => 'ip6tables', + } + + PUPPETCODE + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: do_catch_changes) + end + let(:result) { shell('ip6tables-save') } + + it 'hop_limit is set' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 571 -m hl --hl-eq 5 -m comment --comment "571 - hop_limit" -j ACCEPT}) + end + it 'checksum_fill is set' do + expect(result.stdout).to match(%r{-A POSTROUTING -o virbr0 -p udp -m multiport --dports 68 -m comment --comment "576 - checksum_fill" -j CHECKSUM --checksum-fill}) + end + it 'ishasmorefrags when true' do + expect(result.stdout).to match(%r{A INPUT -p tcp -m frag --fragid 0 --fragmore -m multiport --ports 587 -m comment --comment "587 - ishasmorefrags true" -j ACCEPT}) + end + it 'ishasmorefrags when false' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 588 -m comment --comment "588 - ishasmorefrags false" -j ACCEPT}) + end + it 'islastfrag when true' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m frag --fragid 0 --fraglast -m multiport --ports 589 -m comment --comment "589 - islastfrag true" -j ACCEPT}) + end + it 'islastfrag when false' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 590 -m comment --comment "590 - islastfrag false" -j ACCEPT}) + end + it 'isfirstfrag when true' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m frag --fragid 0 --fragfirst -m multiport --ports 591 -m comment --comment "591 - isfirstfrag true" -j ACCEPT}) + end + it 'isfirstfrag when false' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 592 -m comment --comment "592 - isfirstfrag false" -j ACCEPT}) + end + it 'tcp_flags is set' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN ACK -m comment --comment "593 - tcpfrags" -j ACCEPT}) + end + it 'src_range is set' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m iprange --src-range 2001:db8::1-2001:db8::ff -m multiport --ports 601 -m comment --comment "601 - src_range" -j ACCEPT}) + end + it 'dst_range is set' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m iprange --dst-range 2001:db8::1-2001:db8::ff -m multiport --ports 602 -m comment --comment "602 - dst_range" -j ACCEPT}) + end + it 'mac_source is set' do + expect(result.stdout).to match(%r{-A INPUT -s 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -p tcp -m mac --mac-source 0A:1B:3C:4D:5E:6F -m comment --comment "604 - mac_source"}) + end + it 'socket when true' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 605 -m socket -m comment --comment "605 - socket true" -j ACCEPT}) + end + it 'socket when false' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m multiport --ports 606 -m comment --comment "606 - socket false" -j ACCEPT}) + end + it 'ipsec_policy when ipsec' do + expect(result.stdout).to match( + %r{-A OUTPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir out --pol ipsec -m comment --comment "607 - ipsec_policy ipsec" -j REJECT --reject-with icmp6-adm-prohibited}, # rubocop:disable Metrics/LineLength + ) + end + it 'ipsec_policy when none' do + expect(result.stdout).to match( + %r{-A OUTPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir out --pol none -m comment --comment "608 - ipsec_policy none" -j REJECT --reject-with icmp6-adm-prohibited}, # rubocop:disable Metrics/LineLength + ) + end + it 'ipsec_dir when out' do + expect(result.stdout).to match( + %r{-A OUTPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir out --pol ipsec -m comment --comment "609 - ipsec_dir out" -j REJECT --reject-with icmp6-adm-prohibited}, # rubocop:disable Metrics/LineLength + ) + end + it 'ipsec_dir when in' do + expect(result.stdout).to match( + %r{-A INPUT -d 2001:db8::1\/(128|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) -m policy --dir in --pol none -m comment --comment "610 - ipsec_dir in" -j REJECT --reject-with icmp6-adm-prohibited}, + ) + end + it 'set_mark is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 611 -m comment --comment "611 - set_mark" -j MARK --set-xmark 0x3e8\/0xffffffff}) + end + it 'dst_type when MULTICAST' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m addrtype\s--dst-type\sMULTICAST -m comment --comment "613 - dst_type MULTICAST" -j ACCEPT}) + end + it 'src_type when MULTICAST' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m addrtype\s--src-type\sMULTICAST -m comment --comment "614 - src_type MULTICAST" -j ACCEPT}) + end + it 'dst_type when ! MULTICAST' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m addrtype( !\s--dst-type\sMULTICAST|\s--dst-type\s! MULTICAST) -m comment --comment "615 - dst_type ! MULTICAST" -j ACCEPT}) + end + it 'src_type when ! MULTICAST' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m addrtype( !\s--src-type\sMULTICAST|\s--src-type\s! MULTICAST) -m comment --comment "616 - src_type ! MULTICAST" -j ACCEPT}) + end + it 'dst_type when multiple values' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m addrtype --dst-type LOCAL -m addrtype ! --dst-type LOCAL -m comment --comment "619 - dst_type multiple values" -j ACCEPT}) + end + it 'src_type when multiple values' do + expect(result.stdout).to match(%r{-A INPUT -p tcp -m addrtype --src-type LOCAL -m addrtype ! --src-type LOCAL -m comment --comment "620 - src_type multiple values" -j ACCEPT}) + end + it 'all the modules with multiple args is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m iprange --src-range 2001::-2002::\s+--dst-range 2003::-2004:: -m owner --uid-owner (0|root) --gid-owner 404 -m multiport --dports 8080 -m addrtype --src-type LOCAL --dst-type UNICAST -m comment --comment "801 - ipt_modules tests" -j REJECT --reject-with icmp6-port-unreachable}) # rubocop:disable Metrics/LineLength + end + it 'all the modules with single args is set' do + expect(result.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m iprange --dst-range 2003::-2004:: -m owner --gid-owner 404 -m multiport --dports 8080 -m addrtype --dst-type UNICAST -m comment --comment "802 - ipt_modules tests" -j REJECT --reject-with icmp6-port-unreachable}) # rubocop:disable Metrics/LineLength + end + it 'tee_gateway is set' do + expect(result.stdout).to match(%r{-A PREROUTING -m comment --comment "811 - tee_gateway6" -j TEE --gateway 2001:db8::1}) + end + it 'when set all time parameters' do + expect(result.stdout).to match( + %r{-A OUTPUT -p tcp -m multiport --dports 8080 -m time --timestart 06:00:00 --timestop 17:00:00 --monthdays 7 --weekdays Tue --datestart 2016-01-19T04:17:07 --datestop 2038-01-19T04:17:07 --kerneltz -m comment --comment "805 - time" -j ACCEPT}, # rubocop:disable Metrics/LineLength + ) + end + it 'hashlimit_above is set' do + regex_array = [%r{-A INPUT}, %r{-p tcp}, %r{--hashlimit-above 526\/sec}, %r{--hashlimit-mode srcip,dstip}, + %r{--hashlimit-name above-ip6}, %r{--hashlimit-htable-gcinterval 10}, %r{-j ACCEPT}] + regex_array.each do |regex| + expect(result.stdout).to match(regex) + end + end + end +end diff --git a/spec/acceptance/firewall_bridging_spec.rb b/spec/acceptance/firewall_bridging_spec.rb deleted file mode 100644 index 5d6625e..0000000 --- a/spec/acceptance/firewall_bridging_spec.rb +++ /dev/null @@ -1,231 +0,0 @@ -require 'spec_helper_acceptance' - -# iptables version 1.3.5 is not suppored by the ip6tables provider -describe 'firewall bridging', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - describe 'ip6tables physdev tests' do - context 'when physdev_in eth0' do - pp8 = <<-PUPPETCODE - class { '::firewall': } - firewall { '701 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '701', - action => accept, - physdev_in => 'eth0', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp8, catch_failures: true) - apply_manifest(pp8, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 -m multiport --ports 701 -m comment --comment "701 - test" -j ACCEPT}) - end - end - end - - context 'when physdev_out eth1' do - pp9 = <<-PUPPETCODE - class { '::firewall': } - firewall { '702 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '702', - action => accept, - physdev_out => 'eth1', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp9, catch_failures: true) - apply_manifest(pp9, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 -m multiport --ports 702 -m comment --comment "702 - test" -j ACCEPT}) - end - end - end - - context 'when physdev_in eth0 and physdev_out eth1' do - pp10 = <<-PUPPETCODE - class { '::firewall': } - firewall { '703 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '703', - action => accept, - physdev_in => 'eth0', - physdev_out => 'eth1', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp10, catch_failures: true) - apply_manifest(pp10, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 -m multiport --ports 703 -m comment --comment "703 - test" -j ACCEPT}) - end - end - end - - context 'when physdev_is_bridged' do - pp11 = <<-PUPPETCODE - class { '::firewall': } - firewall { '704 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '704', - action => accept, - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp11, catch_failures: true) - apply_manifest(pp11, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-is-bridged -m multiport --ports 704 -m comment --comment "704 - test" -j ACCEPT}) - end - end - end - - context 'when physdev_in eth0 and physdev_is_bridged' do - pp12 = <<-PUPPETCODE - class { '::firewall': } - firewall { '705 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '705', - action => accept, - physdev_in => 'eth0', - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp12, catch_failures: true) - apply_manifest(pp12, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-is-bridged -m multiport --ports 705 -m comment --comment "705 - test" -j ACCEPT}) - end - end - end - - context 'when physdev_out eth1 and physdev_is_bridged' do - pp13 = <<-PUPPETCODE - class { '::firewall': } - firewall { '706 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '706', - action => accept, - physdev_out => 'eth1', - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp13, catch_failures: true) - apply_manifest(pp13, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m multiport --ports 706 -m comment --comment "706 - test" -j ACCEPT}) - end - end - end - - context 'when physdev_in eth0 and physdev_out eth1 and physdev_is_bridged' do - pp14 = <<-PUPPETCODE - class { '::firewall': } - firewall { '707 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '707', - action => accept, - physdev_in => 'eth0', - physdev_out => 'eth1', - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp14, catch_failures: true) - apply_manifest(pp14, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m multiport --ports 707 -m comment --comment "707 - test" -j ACCEPT}) - end - end - end - - context 'when physdev_is_in' do - pp15 = <<-PUPPETCODE - class { '::firewall': } - firewall { '708 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '708', - action => accept, - physdev_is_in => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp15, catch_failures: true) - apply_manifest(pp15, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-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 'when physdev_is_out' do - pp16 = <<-PUPPETCODE - class { '::firewall': } - firewall { '709 - test': - provider => 'ip6tables', - chain => 'FORWARD', - proto => tcp, - port => '709', - action => accept, - physdev_is_out => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp16, catch_failures: true) - apply_manifest(pp16, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-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 -end diff --git a/spec/acceptance/firewall_dscp_spec.rb b/spec/acceptance/firewall_dscp_spec.rb deleted file mode 100644 index 7501991..0000000 --- a/spec/acceptance/firewall_dscp_spec.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall DSCP' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - describe 'dscp ipv4 tests' do - context 'when set_dscp 0x01' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '1000 - set_dscp': - proto => 'tcp', - jump => 'DSCP', - set_dscp => '0x01', - port => '997', - chain => 'OUTPUT', - table => 'mangle', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp1, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1000 - set_dscp" -j DSCP --set-dscp 0x01}) - end - end - end - - context 'when set_dscp_class EF' do - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '1001 EF - set_dscp_class': - proto => 'tcp', - jump => 'DSCP', - port => '997', - set_dscp_class => 'EF', - chain => 'OUTPUT', - table => 'mangle', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp2, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1001 EF - set_dscp_class" -j DSCP --set-dscp 0x2e}) - end - end - end - end - - describe 'dscp ipv6 tests', unless: os[:family] == 'redhat' && os[:release].start_with?('5') do - context 'when set_dscp 0x01' do - pp3 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '1002 - set_dscp': - proto => 'tcp', - jump => 'DSCP', - set_dscp => '0x01', - port => '997', - chain => 'OUTPUT', - table => 'mangle', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp3, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1002 - set_dscp" -j DSCP --set-dscp 0x01}) - end - end - end - - context 'when set_dscp_class EF' do - pp4 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '1003 EF - set_dscp_class': - proto => 'tcp', - jump => 'DSCP', - port => '997', - set_dscp_class => 'EF', - chain => 'OUTPUT', - table => 'mangle', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp4, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m multiport --ports 997 -m comment --comment "1003 EF - set_dscp_class" -j DSCP --set-dscp 0x2e}) - end - end - end - end -end diff --git a/spec/acceptance/firewall_iptmodules_spec.rb b/spec/acceptance/firewall_iptmodules_spec.rb deleted file mode 100644 index 52baf23..0000000 --- a/spec/acceptance/firewall_iptmodules_spec.rb +++ /dev/null @@ -1,130 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall iptmodules' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - describe 'iptables ipt_modules tests' do - context 'when all the modules with multiple args' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '801 - ipt_modules tests': - proto => tcp, - dport => '8080', - action => reject, - chain => 'OUTPUT', - uid => 0, - gid => 404, - src_range => "90.0.0.1-90.0.0.2", - dst_range => "100.0.0.1-100.0.0.2", - src_type => 'LOCAL', - dst_type => 'UNICAST', - physdev_in => "eth0", - physdev_out => "eth1", - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp1, catch_failures: true) - apply_manifest(pp1, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m iprange --src-range 90.0.0.1-90.0.0.2\s+--dst-range 100.0.0.1-100.0.0.2 -m owner --uid-owner (0|root) --gid-owner 404 -m multiport --dports 8080 -m addrtype --src-type LOCAL --dst-type UNICAST -m comment --comment "801 - ipt_modules tests" -j REJECT --reject-with icmp-port-unreachable}) # rubocop:disable Metrics/LineLength - end - end - end - - context 'when all the modules with single args' do - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '802 - ipt_modules tests': - proto => tcp, - dport => '8080', - action => reject, - chain => 'OUTPUT', - gid => 404, - dst_range => "100.0.0.1-100.0.0.2", - dst_type => 'UNICAST', - physdev_out => "eth1", - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp2, catch_failures: true) - apply_manifest(pp2, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m iprange --dst-range 100.0.0.1-100.0.0.2 -m owner --gid-owner 404 -m multiport --dports 8080 -m addrtype --dst-type UNICAST -m comment --comment "802 - ipt_modules tests" -j REJECT --reject-with icmp-port-unreachable}) # rubocop:disable Metrics/LineLength - end - end - end - end - - describe 'ip6tables ipt_modules tests', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') do - context 'when all the modules with multiple args' do - pp3 = <<-PUPPETCODE - class { '::firewall': } - firewall { '801 - ipt_modules tests': - proto => tcp, - dport => '8080', - action => reject, - chain => 'OUTPUT', - provider => 'ip6tables', - uid => 0, - gid => 404, - src_range => "2001::-2002::", - dst_range => "2003::-2004::", - src_type => 'LOCAL', - dst_type => 'UNICAST', - physdev_in => "eth0", - physdev_out => "eth1", - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp3, catch_failures: true) - apply_manifest(pp3, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-in eth0 --physdev-out eth1 --physdev-is-bridged -m iprange --src-range 2001::-2002::\s+--dst-range 2003::-2004:: -m owner --uid-owner (0|root) --gid-owner 404 -m multiport --dports 8080 -m addrtype --src-type LOCAL --dst-type UNICAST -m comment --comment "801 - ipt_modules tests" -j REJECT --reject-with icmp6-port-unreachable}) # rubocop:disable Metrics/LineLength - end - end - end - - context 'when all the modules with single args' do - pp4 = <<-PUPPETCODE - class { '::firewall': } - firewall { '802 - ipt_modules tests': - proto => tcp, - dport => '8080', - action => reject, - chain => 'OUTPUT', - provider => 'ip6tables', - gid => 404, - dst_range => "2003::-2004::", - dst_type => 'UNICAST', - physdev_out => "eth1", - physdev_is_bridged => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp4, catch_failures: true) - apply_manifest(pp4, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A OUTPUT -p tcp -m physdev\s+--physdev-out eth1 --physdev-is-bridged -m iprange --dst-range 2003::-2004:: -m owner --gid-owner 404 -m multiport --dports 8080 -m addrtype --dst-type UNICAST -m comment --comment "802 - ipt_modules tests" -j REJECT --reject-with icmp6-port-unreachable}) # rubocop:disable Metrics/LineLength - end - end - end - end -end diff --git a/spec/acceptance/firewall_mss_spec.rb b/spec/acceptance/firewall_mss_spec.rb deleted file mode 100644 index cd91c96..0000000 --- a/spec/acceptance/firewall_mss_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall MSS', unless: os[:family] == 'redhat' && os[:release].start_with?('5') do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - describe 'mss ipv6 tests' do - context 'when 1360' do - pp3 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '502 - set_mss': - proto => 'tcp', - tcp_flags => 'SYN,RST SYN', - jump => 'TCPMSS', - set_mss => '1360', - mss => '1361:1541', - chain => 'FORWARD', - table => 'mangle', - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp3, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1541 -m comment --comment "502 - set_mss" -j TCPMSS --set-mss 1360}) - end - end - end - - context 'when clamp_mss_to_pmtu' do - pp4 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '503 - clamp_mss_to_pmtu': - proto => 'tcp', - chain => 'FORWARD', - tcp_flags => 'SYN,RST SYN', - jump => 'TCPMSS', - clamp_mss_to_pmtu => true, - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp4, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m comment --comment "503 - clamp_mss_to_pmtu" -j TCPMSS --clamp-mss-to-pmtu}) - end - end - end - end -end diff --git a/spec/acceptance/firewall_tee_spec.rb b/spec/acceptance/firewall_tee_spec.rb deleted file mode 100644 index 29b00b4..0000000 --- a/spec/acceptance/firewall_tee_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall tee', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - describe 'tee_gateway' do - context 'when 10.0.0.2' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '810 - tee_gateway': - chain => 'PREROUTING', - table => 'mangle', - jump => 'TEE', - gateway => '10.0.0.2', - proto => all, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp1, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A PREROUTING -m comment --comment "810 - tee_gateway" -j TEE --gateway 10.0.0.2}) - end - end - end - end - - describe 'tee_gateway6' do - context 'when 2001:db8::1' do - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { - '811 - tee_gateway6': - chain => 'PREROUTING', - table => 'mangle', - jump => 'TEE', - gateway => '2001:db8::1', - proto => all, - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp2, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save -t mangle') do |r| - expect(r.stdout).to match(%r{-A PREROUTING -m comment --comment "811 - tee_gateway6" -j TEE --gateway 2001:db8::1}) - end - end - end - end -end diff --git a/spec/acceptance/firewall_time_spec.rb b/spec/acceptance/firewall_time_spec.rb deleted file mode 100644 index 89fcef7..0000000 --- a/spec/acceptance/firewall_time_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall time', unless: (os[:family] == 'redhat' && os[:release].start_with?('5', '6')) || (os[:family] == 'sles') do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - describe 'time tests ipv4' do - context 'when set all time parameters' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '805 - test': - proto => tcp, - dport => '8080', - action => accept, - chain => 'OUTPUT', - date_start => '2016-01-19T04:17:07', - date_stop => '2038-01-19T04:17:07', - time_start => '6:00', - time_stop => '17:00:00', - month_days => '7', - week_days => 'Tue', - kernel_timezone => true, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp1, catch_failures: true) - apply_manifest(pp1, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match( - %r{-A OUTPUT -p tcp -m multiport --dports 8080 -m time --timestart 06:00:00 --timestop 17:00:00 --monthdays 7 --weekdays Tue --datestart 2016-01-19T04:17:07 --datestop 2038-01-19T04:17:07 --kerneltz -m comment --comment "805 - test" -j ACCEPT}, # rubocop:disable Metrics/LineLength - ) - end - end - end - end - - describe 'time tests ipv6' do - context 'when when set all time parameters' do - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '805 - test': - proto => tcp, - dport => '8080', - action => accept, - chain => 'OUTPUT', - date_start => '2016-01-19T04:17:07', - date_stop => '2038-01-19T04:17:07', - time_start => '6:00', - time_stop => '17:00:00', - month_days => '7', - week_days => 'Tue', - kernel_timezone => true, - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp2, catch_failures: true) - apply_manifest(pp2, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match( - %r{-A OUTPUT -p tcp -m multiport --dports 8080 -m time --timestart 06:00:00 --timestop 17:00:00 --monthdays 7 --weekdays Tue --datestart 2016-01-19T04:17:07 --datestop 2038-01-19T04:17:07 --kerneltz -m comment --comment "805 - test" -j ACCEPT}, # rubocop:disable Metrics/LineLength - ) - end - end - end - end -end diff --git a/spec/acceptance/hashlimit_spec.rb b/spec/acceptance/hashlimit_spec.rb deleted file mode 100644 index f380bba..0000000 --- a/spec/acceptance/hashlimit_spec.rb +++ /dev/null @@ -1,123 +0,0 @@ - -require 'spec_helper_acceptance' - -describe 'hashlimit property', unless: ((os[:family] == 'redhat' && os[:release][0] <= '5')) do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - describe 'hashlimit_tests' do - context 'when hashlimit_above' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '800 - hashlimit_above test': - chain => 'INPUT', - proto => 'tcp', - hashlimit_name => 'above', - hashlimit_above => '526/sec', - hashlimit_htable_gcinterval => '10', - hashlimit_mode => 'srcip,dstip', - action => accept, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp1, catch_failures: true) - apply_manifest(pp1, catch_changes: do_catch_changes) - end - - regex_array = [%r{-A INPUT}, %r{-p tcp}, %r{--hashlimit-above 526\/sec}, %r{--hashlimit-mode srcip,dstip}, - %r{--hashlimit-name above}, %r{--hashlimit-htable-gcinterval 10}, %r{-j ACCEPT}] - it 'contains the rule' do - shell('iptables-save') do |r| - regex_array.each do |regex| - expect(r.stdout).to match(regex) - end - end - end - end - - context 'when hashlimit_above_ip6' do - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '801 - hashlimit_above test ipv6': - chain => 'INPUT', - provider => 'ip6tables', - proto => 'tcp', - hashlimit_name => 'above-ip6', - hashlimit_above => '526/sec', - hashlimit_htable_gcinterval => '10', - hashlimit_mode => 'srcip,dstip', - action => accept, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp2, catch_failures: true) - apply_manifest(pp2, catch_changes: do_catch_changes) - end - - regex_array = [%r{-A INPUT}, %r{-p tcp}, %r{--hashlimit-above 526\/sec}, %r{--hashlimit-mode srcip,dstip}, - %r{--hashlimit-name above-ip6}, %r{--hashlimit-htable-gcinterval 10}, %r{-j ACCEPT}] - it 'contains the rule' do - shell('ip6tables-save') do |r| - regex_array.each do |regex| - expect(r.stdout).to match(regex) - end - end - end - end - - context 'when hashlimit_upto' do - pp3 = <<-PUPPETCODE - class { '::firewall': } - firewall { '802 - hashlimit_upto test': - chain => 'INPUT', - hashlimit_name => 'upto', - hashlimit_upto => '16/sec', - hashlimit_burst => '640', - hashlimit_htable_size => '1310000', - hashlimit_htable_max => '320000', - hashlimit_htable_expire => '36000000', - action => accept, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp3, catch_failures: true) - apply_manifest(pp3, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m hashlimit --hashlimit-upto 16\/sec --hashlimit-burst 640 --hashlimit-name upto --hashlimit-htable-size 1310000 --hashlimit-htable-max 320000 --hashlimit-htable-expire 36000000 -m comment --comment "802 - hashlimit_upto test" -j ACCEPT}) # rubocop:disable Metrics/LineLength : Cannot reduce line to required length - end - end - end - - context 'when hashlimit_upto_ip6' do - pp4 = <<-PUPPETCODE - class { '::firewall': } - firewall { '803 - hashlimit_upto test ip6': - chain => 'INPUT', - provider => 'ip6tables', - hashlimit_name => 'upto-ip6', - hashlimit_upto => '16/sec', - hashlimit_burst => '640', - hashlimit_htable_size => '1310000', - hashlimit_htable_max => '320000', - hashlimit_htable_expire => '36000000', - action => accept, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp4, catch_failures: true) - apply_manifest(pp4, catch_changes: do_catch_changes) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -p tcp -m hashlimit --hashlimit-upto 16\/sec --hashlimit-burst 640 --hashlimit-name upto-ip6 --hashlimit-htable-size 1310000 --hashlimit-htable-max 320000 --hashlimit-htable-expire 36000000 -m comment --comment "803 - hashlimit_upto test ip6" -j ACCEPT}) # rubocop:disable Metrics/LineLength : Cannot reduce line to required length - end - end - end - end -end diff --git a/spec/acceptance/invert_spec.rb b/spec/acceptance/invert_spec.rb deleted file mode 100644 index 0050102..0000000 --- a/spec/acceptance/invert_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall inverting' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - context 'when inverting rules' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '601 disallow esp protocol': - action => 'accept', - proto => '! esp', - } - firewall { '602 drop NEW external website packets with FIN/RST/ACK set and SYN unset': - chain => 'INPUT', - ctstate => 'NEW', - action => 'drop', - proto => 'tcp', - sport => ['! http', '! 443'], - source => '! 10.0.0.0/8', - tcp_flags => '! FIN,SYN,RST,ACK SYN', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp1, catch_failures: true) - apply_manifest(pp1, catch_changes: do_catch_changes) - end - - regex_array = [%r{-A INPUT (-s !|! -s) (10\.0\.0\.0\/8|10\.0\.0\.0\/255\.0\.0\.0).*}, %r{-A INPUT.*(--sports !|! --sports) 80,443.*}, - %r{-A INPUT.*-m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN.*}, %r{-A INPUT.*-j DROP}, - %r{-A INPUT (! -p|-p !) esp -m comment --comment "601 disallow esp protocol" -j ACCEPT}] - it 'contains the rules' do - shell('iptables-save') do |r| - regex_array.each do |regex| - expect(r.stdout).to match(regex) - end - end - end - end - context 'when inverting partial array rules' do - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '603 drop 80,443 traffic': - chain => 'INPUT', - action => 'drop', - proto => 'tcp', - sport => ['! http', '443'], - } - PUPPETCODE - it 'raises a failure' do - apply_manifest(pp2, expect_failures: true) do |r| - expect(r.stderr).to match(%r{is not prefixed}) - end - end - end -end diff --git a/spec/acceptance/ip6_fragment_spec.rb b/spec/acceptance/ip6_fragment_spec.rb deleted file mode 100644 index 9499a86..0000000 --- a/spec/acceptance/ip6_fragment_spec.rb +++ /dev/null @@ -1,117 +0,0 @@ -require 'spec_helper_acceptance' - -if os[:family] == 'redhat' && os[:release].start_with?('5') - describe "firewall ip6tables doesn't work on 1.3.5 because --comment is missing" do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '599 - test': - ensure => present, - proto => 'tcp', - provider => 'ip6tables', - } - PUPPETCODE - it "can't use ip6tables" do - expect(apply_manifest(pp1, expect_failures: true).stderr).to match(%r{ip6tables provider is not supported}) - end - end -else - describe 'firewall ishasmorefrags/islastfrag/isfirstfrag properties' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - shared_examples 'is idempotent' do |values, line_match| - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '599 - test': - ensure => present, - proto => 'tcp', - provider => 'ip6tables', - #{values} - } - PUPPETCODE - it "changes the values to #{values}" do - apply_manifest(pp2, catch_failures: true) - apply_manifest(pp2, catch_changes: do_catch_changes) - - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{#{line_match}}) - end - end - end - shared_examples "doesn't change" do |values, line_match| - pp3 = <<-PUPPETCODE - class { '::firewall': } - firewall { '599 - test': - ensure => present, - proto => 'tcp', - provider => 'ip6tables', - #{values} - } - PUPPETCODE - it "doesn't change the values to #{values}" do - apply_manifest(pp3, catch_changes: do_catch_changes) - - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{#{line_match}}) - end - end - end - - describe 'adding a rule' do - context 'when unset' do - before :all do - ip6tables_flush_all_tables - end - it_behaves_like 'is idempotent', '', %r{-A INPUT -p tcp -m comment --comment "599 - test"} - end - context 'when set to true' do - before :all do - ip6tables_flush_all_tables - end - it_behaves_like 'is idempotent', 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', - %r{-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"} - end - context 'when set to false' do - before :all do - ip6tables_flush_all_tables - end - it_behaves_like 'is idempotent', 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', %r{-A INPUT -p tcp -m comment --comment "599 - test"} - end - end - describe 'editing a rule' do - context 'when unset or false' do - before :each do - ip6tables_flush_all_tables - shell('ip6tables -A INPUT -p tcp -m comment --comment "599 - test"') - end - context 'when current value is false' do - it_behaves_like "doesn't change", 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', %r{-A INPUT -p tcp -m comment --comment "599 - test"} - end - context 'when current value is true' do - it_behaves_like 'is idempotent', 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', - %r{-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"} - end - end - context 'when set to true' do - before :each do - ip6tables_flush_all_tables - shell('ip6tables -A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"') - end - context 'when current value is false' do - it_behaves_like 'is idempotent', 'ishasmorefrags => false, islastfrag => false, isfirstfrag => false', %r{-A INPUT -p tcp -m comment --comment "599 - test"} - end - context 'when current value is true' do - it_behaves_like "doesn't change", 'ishasmorefrags => true, islastfrag => true, isfirstfrag => true', - %r{-A INPUT -p tcp -m frag --fragid 0 --fragmore -m frag --fragid 0 --fraglast -m frag --fragid 0 --fragfirst -m comment --comment "599 - test"} - end - end - end - end -end diff --git a/spec/acceptance/isfragment_spec.rb b/spec/acceptance/isfragment_spec.rb deleted file mode 100644 index c11262f..0000000 --- a/spec/acceptance/isfragment_spec.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall isfragment property' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - shared_examples 'is idempotent' do |value, line_match| - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '597 - test': - ensure => present, - proto => 'tcp', - #{value} - } - PUPPETCODE - it "changes the value to #{value}" do - apply_manifest(pp1, catch_failures: true) - apply_manifest(pp1, catch_changes: do_catch_changes) - - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{#{line_match}}) - end - end - end - - shared_examples "doesn't change" do |value, line_match| - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '597 - test': - ensure => present, - proto => 'tcp', - #{value} - } - PUPPETCODE - it "doesn't change the value to #{value}" do - apply_manifest(pp2, catch_changes: do_catch_changes) - - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{#{line_match}}) - end - end - end - - describe 'adding a rule' do - context 'when unset' do - before :all do - iptables_flush_all_tables - end - it_behaves_like 'is idempotent', '', %r{-A INPUT -p tcp -m comment --comment "597 - test"} - end - context 'when set to true' do - before :all do - iptables_flush_all_tables - end - it_behaves_like 'is idempotent', 'isfragment => true,', %r{-A INPUT -p tcp -f -m comment --comment "597 - test"} - end - context 'when set to false' do - before :all do - iptables_flush_all_tables - end - it_behaves_like 'is idempotent', 'isfragment => false,', %r{-A INPUT -p tcp -m comment --comment "597 - test"} - end - end - - describe 'editing a rule and current value is false' do - context 'when unset or false' do - before :each do - iptables_flush_all_tables - shell('iptables -A INPUT -p tcp -m comment --comment "597 - test"') - end - it_behaves_like "doesn't change", 'isfragment => false,', %r{-A INPUT -p tcp -m comment --comment "597 - test"} - end - context 'when unset or false and current value is true' do - before :each do - iptables_flush_all_tables - shell('iptables -A INPUT -p tcp -m comment --comment "597 - test"') - end - it_behaves_like 'is idempotent', 'isfragment => true,', %r{-A INPUT -p tcp -f -m comment --comment "597 - test"} - end - - context 'when set to true and current value is false' do - before :each do - iptables_flush_all_tables - shell('iptables -A INPUT -p tcp -f -m comment --comment "597 - test"') - end - it_behaves_like 'is idempotent', 'isfragment => false,', %r{-A INPUT -p tcp -m comment --comment "597 - test"} - end - context 'when set to trueand current value is true' do - before :each do - iptables_flush_all_tables - shell('iptables -A INPUT -p tcp -f -m comment --comment "597 - test"') - end - it_behaves_like "doesn't change", 'isfragment => true,', %r{-A INPUT -p tcp -f -m comment --comment "597 - test"} - end - end -end diff --git a/spec/acceptance/match_mark_spec.rb b/spec/acceptance/match_mark_spec.rb deleted file mode 100644 index 25e00a5..0000000 --- a/spec/acceptance/match_mark_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'firewall match marks', unless: os[:family] == 'redhat' && os[:release].start_with?('5') do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - describe 'match_mark' do - context 'when 0x1' do - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '503 match_mark - test': - proto => 'all', - match_mark => '0x1', - action => reject, - } - PUPPETCODE - it 'applies' do - apply_manifest(pp1, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -m mark --mark 0x1 -m comment --comment "503 match_mark - test" -j REJECT --reject-with icmp-port-unreachable}) - end - end - end - end - - describe 'match_mark_ip6' do - context 'when 0x1' do - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '503 match_mark ip6tables - test': - proto => 'all', - match_mark => '0x1', - action => reject, - provider => 'ip6tables', - } - PUPPETCODE - it 'applies' do - apply_manifest(pp2, catch_failures: true) - end - - it 'contains the rule' do - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{-A INPUT -m mark --mark 0x1 -m comment --comment "503 match_mark ip6tables - test" -j REJECT --reject-with icmp6-port-unreachable}) - end - end - end - end -end diff --git a/spec/acceptance/nflog_spec.rb b/spec/acceptance/nflog_spec.rb deleted file mode 100644 index f0311be..0000000 --- a/spec/acceptance/nflog_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'nflog on older OSes', if: fact('iptables_version') < '1.3.7' do # rubocop:disable RSpec/MultipleDescribes : Describes are clearly seperate - pp1 = <<-PUPPETCODE - class {'::firewall': } - firewall { '503 - test': - jump => 'NFLOG', - proto => 'all', - nflog_group => 3, - } - PUPPETCODE - it 'throws an error' do - apply_manifest(pp1, acceptable_error_codes: [0]) - end -end - -describe 'nflog', unless: fact('iptables_version') < '1.3.7' do - describe 'nflog_group' do - let(:group) { 3 } - - it 'applies' do - pp2 = <<-PUPPETCODE - class {'::firewall': } - firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_group => #{group}} - PUPPETCODE - apply_manifest(pp2, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{NFLOG --nflog-group #{group}}) - end - end - end - - describe 'nflog_prefix' do - let(:prefix) { 'TEST PREFIX' } - - it 'applies' do - pp3 = <<-PUPPETCODE - class {'::firewall': } - firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_prefix => '#{prefix}'} - PUPPETCODE - apply_manifest(pp3, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{NFLOG --nflog-prefix +"#{prefix}"}) - end - end - end - - describe 'nflog_range' do - let(:range) { 16 } - - it 'applies' do - pp4 = <<-PUPPETCODE - class {'::firewall': } - firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_range => #{range}} - PUPPETCODE - apply_manifest(pp4, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{NFLOG --nflog-range #{range}}) - end - end - end - - describe 'nflog_threshold' do - let(:threshold) { 2 } - - it 'applies' do - pp5 = <<-PUPPETCODE - class {'::firewall': } - firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_threshold => #{threshold}} - PUPPETCODE - apply_manifest(pp5, catch_failures: true) - end - - it 'contains the rule' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{NFLOG --nflog-threshold #{threshold}}) - end - end - end - - describe 'multiple rules' do - let(:threshold) { 2 } - let(:group) { 3 } - - it 'applies' do - pp6 = <<-PUPPETCODE - class {'::firewall': } - firewall { '503 - test': jump => 'NFLOG', proto => 'all', nflog_threshold => #{threshold}, nflog_group => #{group}} - PUPPETCODE - apply_manifest(pp6, catch_failures: true) - end - - it 'contains the rules' do - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{NFLOG --nflog-group #{group} --nflog-threshold #{threshold}}) - end - end - end -end diff --git a/spec/acceptance/purge_spec.rb b/spec/acceptance/purge_spec.rb deleted file mode 100644 index 084d203..0000000 --- a/spec/acceptance/purge_spec.rb +++ /dev/null @@ -1,225 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'purge tests' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - context('when resources purge') do - before(:all) do - iptables_flush_all_tables - - shell('iptables -A INPUT -s 1.2.1.2') - shell('iptables -A INPUT -s 1.2.1.2') - end - - pp1 = <<-PUPPETCODE - class { 'firewall': } - resources { 'firewall': - purge => true, - } - PUPPETCODE - it 'make sure duplicate existing rules get purged' do - apply_manifest(pp1, expect_changes: true) - end - - it 'saves' do - shell('iptables-save') do |r| - expect(r.stdout).not_to match(%r{1\.2\.1\.2}) - expect(r.stderr).to eq('') - end - end - end - - context('when ipv4 chain purge') do - after(:all) do - iptables_flush_all_tables - end - before(:each) do - iptables_flush_all_tables - - shell('iptables -A INPUT -p tcp -s 1.2.1.1') - shell('iptables -A INPUT -p udp -s 1.2.1.1') - shell('iptables -A OUTPUT -s 1.2.1.2 -m comment --comment "010 output-1.2.1.2"') - end - - pp2 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'INPUT:filter:IPv4': - purge => true, - } - PUPPETCODE - it 'purges only the specified chain' do - apply_manifest(pp2, expect_changes: true) - - shell('iptables-save') do |r| - expect(r.stdout).to match(%r{010 output-1\.2\.1\.2}) - expect(r.stdout).not_to match(%r{1\.2\.1\.1}) - expect(r.stderr).to eq('') - end - end - # rubocop:enable RSpec/ExampleLength - - pp3 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'OUTPUT:filter:IPv4': - purge => true, - } - firewall { '010 output-1.2.1.2': - chain => 'OUTPUT', - proto => 'all', - source => '1.2.1.2', - } - PUPPETCODE - it 'ignores managed rules' do - apply_manifest(pp3, catch_changes: do_catch_changes) - end - - pp4 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'INPUT:filter:IPv4': - purge => true, - ignore => [ - '-s 1\.2\.1\.1', - ], - } - PUPPETCODE - it 'ignores specified rules' do - apply_manifest(pp4, catch_changes: do_catch_changes) - end - - pp5 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'INPUT:filter:IPv4': - purge => true, - ignore => [ - '-s 1\.2\.1\.1', - ], - } - firewall { '014 input-1.2.1.6': - chain => 'INPUT', - proto => 'all', - source => '1.2.1.6', - } - -> firewall { '013 input-1.2.1.5': - chain => 'INPUT', - proto => 'all', - source => '1.2.1.5', - } - -> firewall { '012 input-1.2.1.4': - chain => 'INPUT', - proto => 'all', - source => '1.2.1.4', - } - -> firewall { '011 input-1.2.1.3': - chain => 'INPUT', - proto => 'all', - source => '1.2.1.3', - } - PUPPETCODE - it 'adds managed rules with ignored rules' do - apply_manifest(pp5, catch_failures: true) - - expect(shell('iptables-save').stdout).to match(%r{-A INPUT -s 1\.2\.1\.1(\/32)? -p tcp\s?\n-A INPUT -s 1\.2\.1\.1(\/32)? -p udp}) - end - end - - context 'when ipv6 chain purge', unless: os[:family] == 'redhat' && os[:release].start_with?('5') do - after(:all) do - ip6tables_flush_all_tables - end - before(:each) do - ip6tables_flush_all_tables - - shell('ip6tables -A INPUT -p tcp -s 1::42') - shell('ip6tables -A INPUT -p udp -s 1::42') - shell('ip6tables -A OUTPUT -s 1::50 -m comment --comment "010 output-1::50"') - end - - pp6 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'INPUT:filter:IPv6': - purge => true, - } - PUPPETCODE - it 'purges only the specified chain' do - apply_manifest(pp6, expect_changes: true) - - shell('ip6tables-save') do |r| - expect(r.stdout).to match(%r{010 output-1::50}) - expect(r.stdout).not_to match(%r{1::42}) - expect(r.stderr).to eq('') - end - end - # rubocop:enable RSpec/ExampleLength - - pp7 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'OUTPUT:filter:IPv6': - purge => true, - } - firewall { '010 output-1::50': - chain => 'OUTPUT', - proto => 'all', - source => '1::50', - provider => 'ip6tables', - } - PUPPETCODE - it 'ignores managed rules' do - apply_manifest(pp7, catch_changes: do_catch_changes) - end - - pp8 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'INPUT:filter:IPv6': - purge => true, - ignore => [ - '-s 1::42', - ], - } - PUPPETCODE - it 'ignores specified rules' do - apply_manifest(pp8, catch_changes: do_catch_changes) - end - - pp9 = <<-PUPPETCODE - class { 'firewall': } - firewallchain { 'INPUT:filter:IPv6': - purge => true, - ignore => [ - '-s 1::42', - ], - } - firewall { '014 input-1::46': - chain => 'INPUT', - proto => 'all', - source => '1::46', - provider => 'ip6tables', - } - -> firewall { '013 input-1::45': - chain => 'INPUT', - proto => 'all', - source => '1::45', - provider => 'ip6tables', - } - -> firewall { '012 input-1::44': - chain => 'INPUT', - proto => 'all', - source => '1::44', - provider => 'ip6tables', - } - -> firewall { '011 input-1::43': - chain => 'INPUT', - proto => 'all', - source => '1::43', - provider => 'ip6tables', - } - PUPPETCODE - it 'adds managed rules with ignored rules' do - apply_manifest(pp9, catch_failures: true) - - expect(shell('ip6tables-save').stdout).to match(%r{-A INPUT -s 1::42(\/128)? -p tcp\s?\n-A INPUT -s 1::42(\/128)? -p udp}) - end - end -end diff --git a/spec/acceptance/resource_cmd_spec.rb b/spec/acceptance/resource_cmd_spec.rb index 12a6845..1093df8 100644 --- a/spec/acceptance/resource_cmd_spec.rb +++ b/spec/acceptance/resource_cmd_spec.rb @@ -23,6 +23,7 @@ describe 'puppet resource firewall command' do context 'when flush iptables and make sure it returns nothing afterwards' do before(:all) do iptables_flush_all_tables + ip6tables_flush_all_tables end # No rules, means no output thanks. And no errors as well. diff --git a/spec/acceptance/socket_spec.rb b/spec/acceptance/socket_spec.rb deleted file mode 100644 index 47cea59..0000000 --- a/spec/acceptance/socket_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'spec_helper_acceptance' - -# RHEL5 does not support -m socket -describe 'firewall socket property', unless: (os[:family] == 'redhat' && os[:release].start_with?('5')) || os[:family] == 'sles' do - before :all do - iptables_flush_all_tables - ip6tables_flush_all_tables - end - - shared_examples 'is idempotent' do |value, line_match| - pp1 = <<-PUPPETCODE - class { '::firewall': } - firewall { '598 - test': - ensure => present, - proto => 'tcp', - chain => 'PREROUTING', - table => 'raw', - #{value} - } - PUPPETCODE - it "changes the value to #{value}" do - apply_manifest(pp1, catch_failures: true) - apply_manifest(pp1, catch_changes: true) - - shell('iptables-save -t raw') do |r| - expect(r.stdout).to match(%r{#{line_match}}) - end - end - end - - shared_examples "doesn't change" do |value, line_match| - pp2 = <<-PUPPETCODE - class { '::firewall': } - firewall { '598 - test': - ensure => present, - proto => 'tcp', - chain => 'PREROUTING', - table => 'raw', - #{value} - } - PUPPETCODE - it "doesn't change the value to #{value}" do - apply_manifest(pp2, catch_changes: true) - - shell('iptables-save -t raw') do |r| - expect(r.stdout).to match(%r{#{line_match}}) - end - end - end - - describe 'adding a rule' do - context 'when unset' do - before :all do - iptables_flush_all_tables - end - it_behaves_like 'is idempotent', '', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} - end - context 'when set to true' do - before :all do - iptables_flush_all_tables - end - it_behaves_like 'is idempotent', 'socket => true,', %r{-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"} - end - context 'when set to false' do - before :all do - iptables_flush_all_tables - end - it_behaves_like 'is idempotent', 'socket => false,', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} - end - end - - describe 'editing a rule' do - context 'when unset or false and current value is false' do - before :each do - iptables_flush_all_tables - shell('iptables -t raw -A PREROUTING -p tcp -m comment --comment "598 - test"') - end - it_behaves_like "doesn't change", 'socket => false,', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} - end - context 'when unset or false and current value is true' do - before :each do - iptables_flush_all_tables - shell('iptables -t raw -A PREROUTING -p tcp -m comment --comment "598 - test"') - end - it_behaves_like 'is idempotent', 'socket => true,', %r{-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"} - end - context 'when set to true and current value is false' do - before :each do - iptables_flush_all_tables - shell('iptables -t raw -A PREROUTING -p tcp -m socket -m comment --comment "598 - test"') - end - it_behaves_like 'is idempotent', 'socket => false,', %r{-A PREROUTING -p tcp -m comment --comment "598 - test"} - end - context 'when set to true and current value is true' do - before :each do - iptables_flush_all_tables - shell('iptables -t raw -A PREROUTING -p tcp -m socket -m comment --comment "598 - test"') - end - it_behaves_like "doesn't change", 'socket => true,', %r{-A PREROUTING -p tcp -m socket -m comment --comment "598 - test"} - end - end -end