From 4dd9caa3b42d473fae1f1e029cc858066dad16ef Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Fri, 9 Oct 2020 11:27:06 +0100 Subject: [PATCH] (IAC-1190) add `ignore_foreign` when purging firewallchains This stops `firewallchains` from purging rules that do not look like rules the module puts into place. This capability can be used to co-exist with other firewall management solutions on the same machine. Improved flow in the README around setting up purging, make it a user decision to enable, and add a pointer to `ignore_foreign`. --- README.md | 46 +++++++++++++++++--------------- lib/puppet/type/firewallchain.rb | 12 +++++++++ 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index f4f8d85..573f121 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,28 @@ The rules you create here are helpful if you don’t have any existing rules; th Rules are persisted automatically between reboots, although there are known issues with ip6tables on older Debian/Ubuntu distributions. There are also known issues with ebtables. -1. In site.pp or another top-scope file, add the following code to set up a metatype to purge unmanaged firewall resources. This will clear any existing rules and make sure that only rules defined in Puppet exist on the machine. +1. Use the following code to set up the default parameters for all of the firewall rules that you will establish later. These defaults will ensure that the `pre` and `post` classes are run in the correct order and avoid locking you out of your box during the first Puppet run. + +```puppet +Firewall { + before => Class['my_fw::post'], + require => Class['my_fw::pre'], +} +``` + +2. Declare the `my_fw::pre` and `my_fw::post` classes to satisfy dependencies. You can declare these classes using an external node classifier or the following code: + +```puppet +class { ['my_fw::pre', 'my_fw::post']: } +``` + +3. Include the `firewall` class to ensure the correct packages are installed: + +```puppet +class { 'firewall': } +``` + +4. If you want to remove unmanaged firewall rules, add the following code to set up a metatype to purge unmanaged firewall resources in your site.pp or another top-scope file. This will clear any existing rules and make sure that only rules defined in Puppet exist on the machine. ```puppet resources { 'firewall': @@ -168,28 +189,9 @@ resources { 'firewallchain': } ``` - **Note** - If there are unmanaged rules in unmanaged chains, it will take two Puppet runs for the firewall chain to be purged. This is different than the `purge` parameter available in `firewallchain`. +> **Note:** If there are unmanaged rules in unmanaged chains, it will take a second Puppet run for the firewall chain to be purged. -2. Use the following code to set up the default parameters for all of the firewall rules that you will establish later. These defaults will ensure that the `pre` and `post` classes are run in the correct order and avoid locking you out of your box during the first Puppet run. - -```puppet -Firewall { - before => Class['my_fw::post'], - require => Class['my_fw::pre'], -} -``` - -3. Declare the `my_fw::pre` and `my_fw::post` classes to satisfy dependencies. You can declare these classes using an external node classifier or the following code: - -```puppet -class { ['my_fw::pre', 'my_fw::post']: } -``` - -4. Include the `firewall` class to ensure the correct packages are installed: - -```puppet -class { 'firewall': } -``` +> **Note:** If you need more fine-grained control about which unmananged rules get removed, investigate the `purge` and `ignore_foreign` parameters available in `firewallchain`. ### Upgrading diff --git a/lib/puppet/type/firewallchain.rb b/lib/puppet/type/firewallchain.rb index e0147b5..3a38b7f 100644 --- a/lib/puppet/type/firewallchain.rb +++ b/lib/puppet/type/firewallchain.rb @@ -163,6 +163,15 @@ Puppet::Type.newtype(:firewallchain) do end end + newparam(:ignore_foreign, boolean: true) do + desc <<-PUPPETCODE + Ignore rules that do not match the puppet title pattern "^\d+[[:graph:][:space:]]" when purging unmanaged firewall rules in this chain. + This can be used to ignore rules that were not put in by puppet. Beware that nothing keeps other systems from configuring firewall rules with a comment that starts with digits, and is indistinguishable from puppet-configured rules. + PUPPETCODE + newvalues(false, true) + defaultto false + end + # Classes would be a better abstraction, pending: # http://projects.puppetlabs.com/issues/19001 autorequire(:package) do @@ -240,6 +249,9 @@ Puppet::Type.newtype(:firewallchain) do # Remove rules which match our ignore filter rules_resources.delete_if { |res| value(:ignore).find_index { |f| res.provider.properties[:line].match(f) } } if value(:ignore) + # Remove rules that were (presumably) not put in by puppet + rules_resources.delete_if { |res| res.provider.properties[:name].match(%r{^(\d+)[[:graph:][:space:]]})[1].to_i >= 9000 } if value(:ignore_foreign) == :true + # We mark all remaining rules for deletion, and then let the catalog override us on rules which should be present rules_resources.each { |res| res[:ensure] = :absent } -- 2.45.2