]> review.fuel-infra Code Review - puppet-modules/puppetlabs-firewall.git/commitdiff
MODULES-1469 MODULES-1470 Support alias (eth0:0), negation for iniface, outiface
authorHugh Esco <hesco@campaignfoundations.com>
Mon, 10 Nov 2014 18:31:48 +0000 (13:31 -0500)
committerMorgan Haskel <morgan@puppetlabs.com>
Wed, 3 Dec 2014 17:28:41 +0000 (12:28 -0500)
README.markdown
lib/puppet/type/firewall.rb
spec/acceptance/rules_spec.rb
spec/acceptance/standard_usage_spec.rb
spec/fixtures/iptables/conversion_hash.rb
spec/unit/puppet/type/firewall_spec.rb

index d347232173c4687f134d25c5891a816b5eed81a6..be5db82bbabe170c3614ff7daef62e6ff73522f9 100644 (file)
@@ -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.
 
index ce699da0ebb63db0f8eb8669df4663303c60b633..170b4510b6f9ef02d016aacbaa3c276a3564c37d 100644 (file)
@@ -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
index c44b8535ed40164cb3030bcd45ccc2efe7b91845..6c099c793c96974b482df31b80c31ada99b32c00 100644 (file)
@@ -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/
index 7585bc15bbf7a30b17472349ef3d0b6919932b89..753f6e1e55a21e25d36b7829db56d834d73405e7 100644 (file)
@@ -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',
index 3024e80d5e4e02c51e457a07a946aa9778f005dd..e33a2e13c5e9255fc8385f2dbe380145d31ae67c 100644 (file)
@@ -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',
index 8e9ef5663c3d5240cbbad14a642921286a6a3ead..3df6a89f904abd969c74c74cac5b8d2d48b15745 100755 (executable)
@@ -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