I''m using puppetlabs/firewall with Puppet 2.7.2, and for the most part it''s working great. I have this in my sites.pp, which I took from this list sometime ago, to save firewall rules to disk when they''re changed: # Always persist firewall rules if ($kernel == ''Linux'') { exec { ''persist-firewall'': command => ''service iptables save'', refreshonly => true, } Firewall { notify => Exec[''persist-firewall''], before => Class[''firewall::post''], require => Class[''firewall::pre''], } Firewallchain { notify => Exec[''persist-firewall''], } resources {''firewall'': purge => true} } One issue I have run into, is that any node using a class that includes Firewall resources *must* also have the Firewall class, or there will be a missing dependency for Class[''firewall::pre'']. I would prefer that the firewall is orthogonal to a class: a node can be deployed without the firewall class, and if the firewall is ever enabled, it will be configured properly. This is very useful to me when incrementally bringing critical production infrastructure under puppet management. I''ve thought of a number of solutions. Most of them involve the use of ''if defined( class_name )'', which has its own repercussions: - Define a use_firewall guard parameter - Move all Firewall resources into the firewall module as sub-classes - Conditionally exec persist-firewall based on if the firewall class is loaded (how?) I would love to here about "the right way" to do something like this. Cheers, -David Arroyo -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
On Tuesday, March 12, 2013 3:19:31 PM UTC-5, dr...@aqwari.us wrote:> > I''m using puppetlabs/firewall with Puppet 2.7.2, and for the most part > it''s working great. I have this in my sites.pp, which I took from this list > sometime ago, to save firewall rules to disk when they''re changed: > > # Always persist firewall rules > if ($kernel == ''Linux'') { > exec { ''persist-firewall'': > command => ''service iptables save'', > refreshonly => true, > } > > Firewall { > notify => Exec[''persist-firewall''], > before => Class[''firewall::post''], > require => Class[''firewall::pre''], > } > Firewallchain { > notify => Exec[''persist-firewall''], > } > resources {''firewall'': purge => true} >Be very careful with that: it should remove the rules provided by your distro''s default firewall configuration, too, not just any additional rules you may have added.> } > > One issue I have run into, is that any node using a class that includes > Firewall resources *must* also have the Firewall class, or there will be a > missing dependency for Class[''firewall::pre'']. >I think you are mistaking the nature of the problem and solution. The ::firewall class provided by the puppetlabs-firewall module (as judged by its GitHub repository) does not do anything to cause class ::firewall::pre (or firewall::post) to be declared on your nodes, so adding it cannot be what resolves your missing dependencies. On the flip side, the Firewall resource type provided by that module does not have any inherent dependency on such classes -- that''s all coming from the global resource defaults you declare. Of course, the GH version of the module does not include classes firewall::pre or firewall::post, so either you are using a different (locally-modified?) version of the module, or those default relationships are just plain wrong.> I would prefer that the firewall is orthogonal to a class: a node can be > deployed without the firewall class, and if the firewall is ever enabled, > it will be configured properly. This is very useful to me when > incrementally bringing critical production infrastructure under puppet > management. >Are you saying that you want the firewall configured, but the firewall service unmanaged? I think you need a different module for that. The puppetlabs-firewall module''s Firewall and Firewallchain resources dynamically interact with the running firewall, and that doesn''t make sense if the firewall is not, in fact, running. Moreover, your Exec[''persist-firewall''] does not seem to be geared toward the case in which the service is not running.> > I''ve thought of a number of solutions. Most of them involve the use of ''if > defined( class_name )'', which has its own repercussions: >You do not need defined() for this problem (or any other). You are trying to solve the wrong problem. Nevertheless, you are right that any node that has a Firewall resource declared on it must also have classes ::firewall::pre and ::firewall::post. In the Puppet sense, you created those requirements by declaring resource defaults. In the module''s use context, however, those are intended to protect you from locking yourself out of your own boxes. Supposing that your versions are not parameterized, you can solve the missing dependency problem without declaring the ::firewall class itself by declaring the -pre and -post classes directly. In particular, each class that needs them can do this, if the classes are not parameterized: include ''::firewall::pre'' include ''::firewall::post'' That just avoids the issue, however, which is that the firewall needs to be running to be managed via the module you are trying to use.> - Define a use_firewall guard parameter >A parameter of what? The ::firewall class? It perhaps makes sense to add a separate class to the module that ensures the firewall down, since the module doesn''t actually have that capability right now. But that doesn''t solve the problem that the firewall needs to be up for the module''s resource types to work.> - Move all Firewall resources into the firewall module as sub-classes >That doesn''t even make sense. Resources are not classes, so they cannot be subclasses. In any case it doesn''t solve the problem that the firewall needs to be up to manage its rules and chains via the module you''re using. Supposing you wrap your resources in (new) subclasses of class ::firewall, all that you accomplish is to force class Firewall to be declared as a side effect of declaring rules. That''s counter-productive if your objective is to avoid running the firewall, and it is unnecessary otherwise (just declare class ::firewall on nodes where you in fact *do* want it running).> - Conditionally exec persist-firewall based on if the firewall class is > loaded (how?) >Wrap the two up so that you declare them together if you declare them at all: class mymodule::firewall_wrapper { if ($kernel == ''Linux'') { include ''::firewall'' exec { ''persist-firewall'': command => ''service iptables save'', refreshonly => true, } } else { fail(''Firewall configuration supported only on Linux'') } } Be sure not to declare class ::firewall any other way than via declaring that wrapper class. Note also that you will now not be able to declare rules without declaring the wrapper class, since it declares the Exec they notify by default.> > I would love to here about "the right way" to do something like this. > >I''m not sure I have correctly understood what the "this" is, so I''m not prepared to generalize to other things like it. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
droyo@aqwari.us
2013-Mar-13 21:30 UTC
[Puppet Users] Re: Optional loading of firewall rules
Hi John, On Wednesday, March 13, 2013 11:51:51 AM UTC-4, jcbollinger wrote:> > On the flip side, the Firewall resource type provided by that module does > not have any inherent dependency on such classes -- that''s all coming from > the global resource defaults you declare. >I understand that the ::pre and ::post dependencies are my own modifications to the resource defaults. If it helps to see where I got this from, I followed the "recommended" configuration from https://forge.puppetlabs.com/puppetlabs/firewall . The dependencies are a red herring and not my real problem. I will try stating what I want without any assumptions or postulation: - Any module can declare its own set of firewall rules - These rules are only enforced when a "switch" is flipped on the node That''s all. - Define a use_firewall guard parameter>> > A parameter of what? The ::firewall class? >A node parameter to effectively wrap any Firewall resources in, e.g.: define firewall::rule($proto, $port, $action) { # real one would have all parameters if $::use_firewall { firewall {$title: proto => $proto, port => $port, action => $action, } } } class my_server_class ( $listen_port ) { firewall::rule {''500 my_server_class'': proto => tcp, port => $listen_port, action => accept, } ... } Or even something like this? (untested): ##sites.pp Firewall { ensure => $::use_firewall ? { undef => absent, /(?i:no|false|off)/ => absent, /(?i:yes|true|on)/ => present, } }> - Move all Firewall resources into the firewall module as sub-classes >> > > That doesn''t even make sense. Resources are not classes, so they cannot > be subclasses. >Sorry, poor choice of words. I meant pulling Firewall definitions out of all classes and putting them under ::firewall, as you guessed. I thought perhaps once I did that, I could put logic in the firewall class to load sets of Firewall resouces contained in subclasses based on what classes the current node was using. I abandoned that idea, it''s too convoluted with too much magic, and I''d like to keep firewall definitions within the classes they concern. Upon further reflection and looking at the firewall type a little closer, I realize that disregarding any ::pre, ::post, or persist-firewall complications, the simple act of declaring a firewall resource will cause it to be loaded into iptables. So any solution would involve either preventing the resources'' declarations in the first place, or changing the behaviour of the type itself. Thanks for making me think about it :) Regards, David -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Hi John, On Wednesday, March 13, 2013 11:51:51 AM UTC-4, jcbollinger wrote:> On the flip side, the Firewall resource type provided by that module does not > have any inherent dependency on such classes -- that''s all coming from the > global resource defaults you declare.I understand that the ::pre and ::post dependencies are my own modifications to the resource defaults. If it helps to see where I got this from, I followed the "recommended" configuration from https://forge.puppetlabs.com/puppetlabs/firewall The dependencies are a red herring and not my real problem. I will try stating what I want without any assumptions or postulation: - Any module can declare its own set of firewall rules - These rules are only enforced when a "switch" is flipped on the node That''s all.> Define a use_firewall guard parameter A parameter of what? The ::firewall > class?A node parameter to effectively wrap any Firewall resources in, e.g.: define firewall::rule($proto, $port, $action) { if $::use_firewall { firewall {$title: proto => $proto, port => $port, action => $action, } } } class my_server_class ( $listen_port ) { firewall::rule {''500 my_server_class'': proto => tcp, port => $listen_port, action => accept, } ... } Or even something like this? (untested): ##sites.pp Firewall { ensure => $::use_firewall ? { undef => absent, /(?i:no|false|off)/ => absent, /(?i:yes|true|on)/ => present, } }> > - Move all Firewall resources into the firewall module as sub-classes > > > That doesn''t even make sense. Resources are not classes, so they cannot be > subclasses.Sorry, poor choice of words. I meant pulling Firewall definitions out of all classes and putting them under ::firewall, as you guessed. I thought perhaps once I did that, I could put logic in the firewall class to load sets of Firewall resouces contained in subclasses based on what classes the current node was using. I abandoned that idea, it''s too convoluted with too much magic, and I''d like to keep firewall definitions within the classes they concern. Upon further reflection and looking at the firewall type a little closer, I realize that disregarding any ::pre, ::post, or persist-firewall complications, the simple act of declaring a firewall resource will cause it to be loaded into iptables. So any solution would involve either preventing the resources'' existence in the first place, or changing the behaviour of the type itself. Thanks for making me think about it :) Cheers, David -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
On Wednesday, March 13, 2013 4:30:28 PM UTC-5, dr...@aqwari.us wrote:> > Hi John, > > On Wednesday, March 13, 2013 11:51:51 AM UTC-4, jcbollinger wrote: >> >> On the flip side, the Firewall resource type provided by that module does >> not have any inherent dependency on such classes -- that''s all coming from >> the global resource defaults you declare. >> > > I understand that the ::pre and ::post dependencies are my own > modifications to the resource defaults. If it helps to see where I got this > from, I followed the "recommended" configuration from > https://forge.puppetlabs.com/puppetlabs/firewall . The dependencies are a > red herring and not my real problem. > > I will try stating what I want without any assumptions or postulation: > - Any module can declare its own set of firewall rules > - These rules are only enforced when a "switch" is flipped on the node > > That''s all. >You are looking for virtual resources. Here''s one way to do it: # Example class that declares a firewall rule class my_server_class ( $listen_port ) { # Key point: resource is virtual @firewall {''500 my_server_class'': proto => tcp, port => $listen_port, action => accept, } } # Declare this class on nodes that should have the # FW managed. class site::firewall_enabled { include ''firewall'' include ''site::firewall_pre'' include ''site::firewall_post'' exec { ''persist-firewall'': command => ''service iptables save'', refreshonly => true, } Firewall<| |> { require => Class[''site::firewall_pre''], before => Class[''site::firewall_post''], notify => Exec[''persist-firewall''], } Firewallchain<| |> { notify => Exec[''persist-firewall''], } resources {''firewall'': purge => true} } node node1 { class { ''my_server_class'': listen_port => 12345 } # turn on the firewall and all configured firewall rules: include site::firewall_enabled } John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.