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':
}
```
- **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
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
# 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 }