Use zap cookbook for garbage collection in /etc/iptables.d
patcon opened this issue · comments
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)
@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).
@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...)