chef-cookbooks / iptables

Development repository for Chef Cookbook iptables

Home Page:https://supermarket.chef.io/cookbooks/iptables

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use zap cookbook for garbage collection in /etc/iptables.d

patcon opened this issue · comments

commented

Figured I'd provide a working example using zap for anyone who wants the config dir purged of old/manual files.

Cleanup recipe listed last in my node's run_list, but I believe it can be placed anywhere in the run list (EDIT: it can)

# cleanup iptables config files
include_recipe 'iptables'
zap '/etc/iptables.d' do
  immediately false
  klass ['Chef::Resource::File', 'Chef::Resource::Template', 'Chef::Resource::IptablesRule']
  collect { ::Dir.glob("/etc/iptables.d/*") }
  select do |r|
    case r.class.to_s
    when 'Chef::Resource::File', 'Chef::Resource::Template'
      r.name
    when 'Chef::Resource::IptablesRule'
      "/etc/iptables.d/#{r.name}"
    end
  end
  notifies :run, 'execute[rebuild-iptables]', :delayed
end

Version information
Chef: 12.3.0
Ohai: 8.3.0
Iptables Cookbook: 2.0.1 (hash 7c20a79)
Zap Cookbook: 0.11.2 (hash nvwls/zap@8382fe2)

It seems this doesn't work for me. The class reported for the iptables_rules is:
"Custom resource iptables_rule from cookbook iptables"

Any idea why this is?
Version information
Chef: 12.13.37
Iptables Cookbook: 2.2.0
Zap Cookbook: 0.11.4 (hash nvwls/zap@8382fe2)

commented

@daften That was changed in Chef 12.5. My current code using the iptables 2.0.1 cookbook is

# clean up /etc/iptables.d directory of files not longer managed by chef
include_recipe 'iptables'
zap '/etc/iptables.d' do
  immediately false
  klass ['Chef::Resource::File', 'Chef::Resource::Template', 'Chef::Resource::IptablesRule']
  collect { ::Dir.glob('/etc/iptables.d/*') }
  select do |r|
    case r.class.to_s
    when 'Chef::Resource::File', 'Chef::Resource::Template'
      r.name
    when 'Chef::Resource::IptablesRule', 'Custom resource iptables_rule from cookbook iptables'
      "/etc/iptables.d/#{r.name}"
    end
  end
  notifies :run, 'execute[rebuild-iptables]', :delayed
end

zap won't find iptables rules in sub-resource collections created by use_inline_resources/custom resources, it probably shouldn't be used here until that is fixed.

the "nested" suite added to TK in #62 will most likely break if you try to combine this with the zap cookbook

Yeah, @devsibwarra your snippet fails like this on the nested-ubuntu-1604 test:

[...]
       Recipe: iptables_test::nested
         * iptables_rule[sshd] action enable
           * file[/etc/iptables.d/sshd] action create
             - create new file /etc/iptables.d/sshd
             - update content in file /etc/iptables.d/sshd from none to fc9157
             --- /etc/iptables.d/sshd   2016-10-11 16:28:17.434143334 +0000
             +++ /etc/iptables.d/.chef-sshd20161011-2367-1wbyaz6    2016-10-11 16:28:17.434143334 +0000
             @@ -1 +1,2 @@
             +-A FWR -p tcp -m tcp --dport 22 -j ACCEPT
             - change mode from '' to '0644'

         * nested[httpd] action doit
           * iptables_rule[httpd] action enable
             * file[/etc/iptables.d/httpd] action create
        - create new file /etc/iptables.d/httpd
        - update content in file /etc/iptables.d/httpd from none to 71626a
        --- /etc/iptables.d/httpd   2016-10-11 16:28:17.446149334 +0000
        +++ /etc/iptables.d/.chef-httpd20161011-2367-1gay4ws    2016-10-11 16:28:17.446149334 +0000
        @@ -1 +1,2 @@
        +-A FWR -p tcp -m tcp --dport 80 -j ACCEPT
        - change mode from '' to '0644'


         * doubly_nested[https] action doit
           * nested[https] action doit
             * iptables_rule[https] action enable
        * file[/etc/iptables.d/https] action create
          - create new file /etc/iptables.d/https
          - update content in file /etc/iptables.d/https from none to b9c7a1
          --- /etc/iptables.d/https 2016-10-11 16:28:17.462157333 +0000
          +++ /etc/iptables.d/.chef-https20161011-2367-1jqcspl  2016-10-11 16:28:17.462157333 +0000
          @@ -1 +1,2 @@
          +-A FWR -p tcp -m tcp --dport 443 -j ACCEPT
          - change mode from '' to '0644'



         * zap[/etc/iptables.d] action delete (up to date)
         * zap[/etc/iptables.d] action delete
           - zap[/etc/iptables.d]
         * file[/etc/iptables.d/httpd] action delete
           - delete file /etc/iptables.d/httpd
         * file[/etc/iptables.d/https] action delete
           - delete file /etc/iptables.d/https
       Recipe: iptables::default
         * execute[rebuild-iptables] action run
           - execute /usr/sbin/rebuild-iptables

       Running handlers:
       Running handlers complete
       Chef Client finished, 22/31 resources updated in 04 seconds
[...]
       File "/etc/iptables.d"
         should be directory

       File "/usr/sbin/rebuild-iptables"
         should exist

       File "/etc/network/if-pre-up.d/iptables_load"
         should exist

       iptables
         should have rule "-A FWR -p tcp -m tcp --dport 22 -j ACCEPT"
         should have rule "-A FWR -p tcp -m tcp --dport 80 -j ACCEPT" (FAILED - 1)
         should have rule "-A FWR -p tcp -m tcp --dport 443 -j ACCEPT" (FAILED - 2)

       File "/etc/iptables.d/sshd"
         should exist

       File "/etc/iptables.d/httpd"
         should exist (FAILED - 3)

       File "/etc/iptables.d/https"
         should exist (FAILED - 4)

       Failures:

         1) iptables should have rule "-A FWR -p tcp -m tcp --dport 80 -j ACCEPT"
            Failure/Error: it { should have_rule('-A FWR -p tcp -m tcp --dport 80 -j ACCEPT') }
              expected iptables to have rule "-A FWR -p tcp -m tcp --dport 80 -j ACCEPT"
              /bin/sh -c iptables\ -S\ \|\ grep\ --\ -A\\\ FWR\\\ -p\\\ tcp\\\ -m\\\ tcp\\\ --dport\\\ 80\\\ -j\\\ ACCEPT

            # /tmp/verifier/suites/serverspec/rules_spec.rb:7:in `block (2 levels) in <top (required)>'

         2) iptables should have rule "-A FWR -p tcp -m tcp --dport 443 -j ACCEPT"
            Failure/Error: it { should have_rule('-A FWR -p tcp -m tcp --dport 443 -j ACCEPT') }
              expected iptables to have rule "-A FWR -p tcp -m tcp --dport 443 -j ACCEPT"
              /bin/sh -c iptables\ -S\ \|\ grep\ --\ -A\\\ FWR\\\ -p\\\ tcp\\\ -m\\\ tcp\\\ --dport\\\ 443\\\ -j\\\ ACCEPT

            # /tmp/verifier/suites/serverspec/rules_spec.rb:8:in `block (2 levels) in <top (required)>'

         3) File "/etc/iptables.d/httpd" should exist
            Failure/Error: it { should exist }
              expected File "/etc/iptables.d/httpd" to exist
              /bin/sh -c test\ -e\ /etc/iptables.d/httpd

            # /tmp/verifier/suites/serverspec/rules_spec.rb:13:in `block (3 levels) in <top (required)>'

         4) File "/etc/iptables.d/https" should exist
            Failure/Error: it { should exist }
              expected File "/etc/iptables.d/https" to exist
              /bin/sh -c test\ -e\ /etc/iptables.d/https

            # /tmp/verifier/suites/serverspec/rules_spec.rb:13:in `block (3 levels) in <top (required)>'

       Finished in 0.04612 seconds (files took 0.29726 seconds to load)
       9 examples, 4 failures

       Failed examples:

       rspec /tmp/verifier/suites/serverspec/rules_spec.rb:7 # iptables should have rule "-A FWR -p tcp -m tcp --dport 80 -j ACCEPT"
       rspec /tmp/verifier/suites/serverspec/rules_spec.rb:8 # iptables should have rule "-A FWR -p tcp -m tcp --dport 443 -j ACCEPT"
       rspec /tmp/verifier/suites/serverspec/rules_spec.rb[3:1] # File "/etc/iptables.d/httpd" should exist
       rspec /tmp/verifier/suites/serverspec/rules_spec.rb[4:1] # File "/etc/iptables.d/https" should exist

see also the issues in chef/chef#3956

if zap gets fixed we could take it, but i think it would break too much to use it in its current form (and breaking iptables could be very bad for users).

commented

@lamont-granquist Thanks for the update. Wonder if the use_inline_resources/custom resources have a different class name than what we've encountered so far. I'm fine with keeping this out of the iptables cookbook and leaving it up to the admins to test the cleanup steps in their wrappers

well yeah the point is that you wrap it with a resource that has a new class name, you could add that, but its not guaranteed that the wrapping resource wraps exactly one file -- you could have a custom application resource that deployed your app and setup four firewall rules for every one of them. what you want to be able to do is step into the sub-resource collection created by your application resource and then pick out the individual files and templates that drop into /etc/iptables.d. unfortunately we don't hold onto sub-resource collection pointers and they're typically garbage collected by the time that zap would be looking for resources to see what it needs to clean up. it probably needs to use an event handler in order to register file or template resources that are updated similar to the existing resource reporter in chef, or something like that (or else we need to patch core chef to hold around all the old sub-resource collections...)