From b6e58bac2686d1883f14325871b13655e3ebc728 Mon Sep 17 00:00:00 2001 From: Hugh Esco Date: Mon, 10 Nov 2014 13:31:48 -0500 Subject: [PATCH] MODULES-1469 MODULES-1470 Support alias (eth0:0), negation for iniface, outiface --- README.markdown | 14 ++++++--- lib/puppet/type/firewall.rb | 16 +++++++--- spec/acceptance/rules_spec.rb | 26 ++++++++++++++-- spec/acceptance/standard_usage_spec.rb | 7 ++++- spec/fixtures/iptables/conversion_hash.rb | 36 +++++++++++++++++++++++ spec/unit/puppet/type/firewall_spec.rb | 8 +++++ 6 files changed, 96 insertions(+), 11 deletions(-) diff --git a/README.markdown b/README.markdown index d347232..be5db82 100644 --- a/README.markdown +++ b/README.markdown @@ -86,7 +86,13 @@ The rules in the `pre` and `post` classes are fairly general. These two classes iniface => 'lo', action => 'accept', }-> - firewall { '002 accept related established rules': + firewall { "002 reject local traffic not on loopback interface": + iniface => '! lo', + proto => 'all', + destination => '127.0.0.1/8', + action => 'reject', + }-> + firewall { '003 accept related established rules': proto => 'all', state => ['RELATED', 'ESTABLISHED'], action => 'accept', @@ -201,7 +207,7 @@ class profile::apache { ###Rule inversion Firewall rules may be inverted by prefixing the value of a parameter by "! ". If the value is an array, then every item in the array must be prefixed as iptables does not understand inverting a single value. -Parameters that understand inversion are: connmark, ctstate, destination, dport, dst\_range, dst\_type, port, proto, source, sport, src\_range, src\_type, and state. +Parameters that understand inversion are: connmark, ctstate, destination, dport, dst\_range, dst\_type, iniface, outiface, port, proto, source, sport, src\_range, src\_type, and state. Examples: @@ -440,7 +446,7 @@ If Puppet is managing the iptables or iptables-persistent packages, and the prov * `icmp`: When matching ICMP packets, this indicates the type of ICMP packet to match. A value of 'any' is not supported. To match any type of ICMP packet, the parameter should be omitted or undefined. Requires the `icmp_match` feature. -* `iniface`: Input interface to filter on. Values must match '/^[a-zA-Z0-9\-\._\+]+$/'. Requires the `interface_match` feature. +* `iniface`: Input interface to filter on. Values must match '/^!?\s?[a-zA-Z0-9\-\._\+\:]+$/'. Requires the `interface_match` feature. Supports interface alias (eth0:0) and negation. * `ipsec_dir`: Sets the ipsec policy direction. Valid values are 'in', 'out'. Requires the `ipsec_dir` feature. @@ -485,7 +491,7 @@ firewall { '999 this runs last': Depending on the provider, the name of the rule can be stored using the comment feature of the underlying firewall subsystem. Values must match '/^\d+[[:alpha:][:digit:][:punct:][:space:]]+$/'. -* `outiface`: Output interface to filter on. Values must match '/^[a-zA-Z0-9\-\._\+]+$/'. Requires the `interface_match` feature. +* `outiface`: Output interface to filter on. Values must match '/^!?\s?[a-zA-Z0-9\-\._\+\:]+$/'. Requires the `interface_match` feature. Supports interface alias (eth0:0) and negation. * `pkttype`: Sets the packet type to match. Valid values are: 'unicast', 'broadcast', and'multicast'. Requires the `pkttype` feature. diff --git a/lib/puppet/type/firewall.rb b/lib/puppet/type/firewall.rb index ce699da..170b451 100644 --- a/lib/puppet/type/firewall.rb +++ b/lib/puppet/type/firewall.rb @@ -428,16 +428,24 @@ Puppet::Type.newtype(:firewall) do # Interface specific matching properties newproperty(:iniface, :required_features => :interface_match) do desc <<-EOS - Input interface to filter on. + Input interface to filter on. Supports interface alias like eth0:0. + To negate the match try this: + + iniface => '! lo', + EOS - newvalues(/^[a-zA-Z0-9\-\._\+]+$/) + newvalues(/^!?\s?[a-zA-Z0-9\-\._\+\:]+$/) end newproperty(:outiface, :required_features => :interface_match) do desc <<-EOS - Output interface to filter on. + Output interface to filter on. Supports interface alias like eth0:0. + To negate the match try this: + + outiface => '! lo', + EOS - newvalues(/^[a-zA-Z0-9\-\._\+]+$/) + newvalues(/^!?\s?[a-zA-Z0-9\-\._\+\:]+$/) end # NAT specific properties diff --git a/spec/acceptance/rules_spec.rb b/spec/acceptance/rules_spec.rb index c44b853..6c099c7 100644 --- a/spec/acceptance/rules_spec.rb +++ b/spec/acceptance/rules_spec.rb @@ -146,6 +146,12 @@ describe 'complex ruleset 2' do action => 'accept', before => Firewallchain['INPUT:filter:IPv4'], } + firewall { "011 reject local traffic not on loopback interface": + iniface => '! lo', + proto => 'all', + destination => '127.0.0.1/8', + action => 'reject', + } firewall { '012 accept loopback': iniface => 'lo', action => 'accept', @@ -158,7 +164,14 @@ describe 'complex ruleset 2' do action => 'accept', before => Firewallchain['INPUT:filter:IPv4'], } - + firewall { '025 smtp': + outiface => '! eth0:2', + chain => 'OUTPUT', + proto => 'tcp', + dport => '25', + state => 'NEW', + action => 'accept', + } firewall { '013 icmp echo-request': proto => 'icmp', icmp => 'echo-request', @@ -175,12 +188,18 @@ describe 'complex ruleset 2' do icmp => 'time-exceeded', action => 'accept', } + firewall { '443 ssl on aliased interface': + proto => 'tcp', + dport => '443', + state => 'NEW', + action => 'accept', + iniface => 'eth0:3', + } firewall { '999 reject': action => 'reject', reject => 'icmp-host-prohibited', } - firewallchain { 'LOCAL_INPUT_PRE:filter:IPv4': } firewall { '001 LOCAL_INPUT_PRE': jump => 'LOCAL_INPUT_PRE', @@ -238,11 +257,14 @@ describe 'complex ruleset 2' do /LOCAL_INPUT_PRE/, /-A INPUT -m comment --comment \"001 LOCAL_INPUT_PRE\" -j LOCAL_INPUT_PRE/, /-A INPUT -m comment --comment \"010 INPUT allow established and related\" -m state --state RELATED,ESTABLISHED -j ACCEPT/, + /-A INPUT -d 127.0.0.0\/8 ! -i lo -m comment --comment \"011 reject local traffic not on loopback interface\" -j REJECT --reject-with icmp-port-unreachable/, /-A INPUT -i lo -m comment --comment \"012 accept loopback\" -j ACCEPT/, /-A INPUT -p icmp -m comment --comment \"013 icmp destination-unreachable\" -m icmp --icmp-type 3 -j ACCEPT/, /-A INPUT -s 10.0.0.0\/(8|255\.0\.0\.0) -p icmp -m comment --comment \"013 icmp echo-request\" -m icmp --icmp-type 8 -j ACCEPT/, /-A INPUT -p icmp -m comment --comment \"013 icmp time-exceeded\" -m icmp --icmp-type 11 -j ACCEPT/, /-A INPUT -p tcp -m multiport --dports 22 -m comment --comment \"020 ssh\" -m state --state NEW -j ACCEPT/, + /-A OUTPUT ! -o eth0:2 -p tcp -m multiport --dports 25 -m comment --comment \"025 smtp\" -m state --state NEW -j ACCEPT/, + /-A INPUT -i eth0:3 -p tcp -m multiport --dports 443 -m comment --comment \"443 ssl on aliased interface\" -m state --state NEW -j ACCEPT/, /-A INPUT -m comment --comment \"900 LOCAL_INPUT\" -j LOCAL_INPUT/, /-A INPUT -m comment --comment \"999 reject\" -j REJECT --reject-with icmp-host-prohibited/, /-A FORWARD -m comment --comment \"010 allow established and related\" -m state --state RELATED,ESTABLISHED -j ACCEPT/ diff --git a/spec/acceptance/standard_usage_spec.rb b/spec/acceptance/standard_usage_spec.rb index 7585bc1..753f6e1 100644 --- a/spec/acceptance/standard_usage_spec.rb +++ b/spec/acceptance/standard_usage_spec.rb @@ -19,7 +19,12 @@ describe 'standard usage tests:', :unless => UNSUPPORTED_PLATFORMS.include?(fact iniface => 'lo', action => 'accept', }-> - firewall { '002 accept related established rules': + firewall { "0002 reject local traffic not on loopback interface": + iniface => '! lo', + destination => '127.0.0.1/8', + action => 'reject', + }-> + firewall { '003 accept related established rules': proto => 'all', ctstate => ['RELATED', 'ESTABLISHED'], action => 'accept', diff --git a/spec/fixtures/iptables/conversion_hash.rb b/spec/fixtures/iptables/conversion_hash.rb index 3024e80..e33a2e1 100644 --- a/spec/fixtures/iptables/conversion_hash.rb +++ b/spec/fixtures/iptables/conversion_hash.rb @@ -328,6 +328,24 @@ ARGS_TO_HASH = { :iniface => 'eth0', }, }, + 'iniface_1_negated' => { + :line => '-A INPUT ! -i eth0 -m comment --comment "060 iniface" -j DROP', + :table => 'filter', + :params => { + :action => 'drop', + :chain => 'INPUT', + :iniface => '! eth0', + }, + }, + 'iniface_1_aliased' => { + :line => '-A INPUT -i eth0:1 -m comment --comment "060 iniface" -j DROP', + :table => 'filter', + :params => { + :action => 'drop', + :chain => 'INPUT', + :iniface => 'eth0:1', + }, + }, 'iniface_with_vlans_1' => { :line => '-A INPUT -i eth0.234 -m comment --comment "060 iniface" -j DROP', :table => 'filter', @@ -355,6 +373,24 @@ ARGS_TO_HASH = { :outiface => 'eth0', }, }, + 'outiface_1_negated' => { + :line => '-A OUTPUT ! -o eth0 -m comment --comment "060 outiface" -j DROP', + :table => 'filter', + :params => { + :action => 'drop', + :chain => 'OUTPUT', + :outiface => '! eth0', + }, + }, + 'outiface_1_aliased' => { + :line => '-A OUTPUT -o eth0:2 -m comment --comment "060 outiface" -j DROP', + :table => 'filter', + :params => { + :action => 'drop', + :chain => 'OUTPUT', + :outiface => 'eth0:2', + }, + }, 'outiface_with_vlans_1' => { :line => '-A OUTPUT -o eth0.234 -m comment --comment "060 outiface" -j DROP', :table => 'filter', diff --git a/spec/unit/puppet/type/firewall_spec.rb b/spec/unit/puppet/type/firewall_spec.rb index 8e9ef56..3df6a89 100755 --- a/spec/unit/puppet/type/firewall_spec.rb +++ b/spec/unit/puppet/type/firewall_spec.rb @@ -208,6 +208,14 @@ describe firewall do @resource[iface] = 'eth1' @resource[iface].should == 'eth1' end + it "should accept a negated #{iface} value as a string" do + @resource[iface] = '! eth1' + @resource[iface].should == '! eth1' + end + it "should accept an interface alias for the #{iface} value as a string" do + @resource[iface] = 'eth1:2' + @resource[iface].should == 'eth1:2' + end end end -- 2.45.2