On Tuesday, April 7, 2015 at 3:30:30 PM UTC-5, Scott Jaffa wrote: 


> On Friday, April 3, 2015 at 9:15:00 AM UTC-4, jcbollinger wrote:
>>
>>
>>
>> On Thursday, April 2, 2015 at 4:02:30 PM UTC-5, Scott Jaffa wrote:
>>>
>>> Hi,
>>>
>>> I'm working in an environment where certain parameters need to be 
>>> enforced per security requirements..  
>>>
>>> The ways we've identified to do this are:
>>>
>>> 1)  Put the specific settings in the profile:
>>> Advantages:  Utilize stock roles and profiles pattern, plenty of 
>>> documentation and guides online.
>>> Disadvantage:  The settings are part of the profile and thus two groups 
>>> need to share ownership of the same module.  Reduces flexibility or speed 
>>> due to additional enforcement needed by shared ownership.
>>>
>>> 2)  Modify the modules themselves.
>>> Advantages:  Configuration is part of the module.
>>> Disadvantages:  We are now maintaining all custom modules.  
>>>
>>> 3)  Extend roles and profiles to add an additional layer between 
>>> existing profiles and the modules.
>>> The workflow would be:
>>> Role (business layer) > Profile (technology layer) > Security (security 
>>> layer) > Module.  
>>> Advantages:  Engineering configuration and security configuration are 
>>> seperated, with security configuration enforced.
>>> Disadvantages:  Need a way to present most options up to the profiles 
>>> layer for parameterization, while enforcing a few options.
>>>
>>>
>>> We'd prefer to go with option 3.  Does this make sense?
>>>
>>
>>
>> I'm having trouble understanding how you propose to factor out security 
>> considerations from the technology to which they apply.  Is this just about 
>> ownership of data, or do there need to be *bona fide* security-specific 
>> resources?  If the former, then what do you need that you cannot achieve 
>> via a security-specific level in your Hiera hierarchy?  If the latter, then 
>> how would making the security classes responsible for declaring 
>> component-level classes (per option 3) achieve the separation of concerns 
>> you claim as an advantage?
>>
>>  
>>
>>>
>>> If so, some tips on how to go about this would be appreciated.  Does it 
>>> make sense for the security module to inherit the base module in this case? 
>>>  It would look something like this (but actually work :) )
>>> class sec_profile::ssh inherits ::ssh {  
>>> $server_options = { 'Protocol' => '2', 'Ciphers' => 
>>> 'aes128-ctr,aes192-ctr,aes256-ctr', 'PermitRootLogin' => 'no', 
>>> 'ClientAliveInterval' => '900', 'PermitEmptyPasswords' => 'no', 
>>> 'PasswordAuthentication' => 'no', 'Port' => [22], } }
>>>
>>>
>>
>> If you are contemplating class inheritance for the purpose of greater 
>> freedom in applying resource property overrides, then maybe they would be 
>> useful to you.  If you have an idea that they would do anything else for 
>> you, then put it out of your mind -- class inheritance doesn't work that 
>> way (whatever way that happens to be).  Note, however, that often you can 
>> perform resource overrides without class inheritance, that often it is 
>> better to modify the external data from which modules draw property values 
>> than to override property values after the fact, and that class inheritance 
>> creates a very tight coupling that is probably better avoided if it crosses 
>> module boundaries.
>>
>> Yes, the goal is strictly to provide flexibility in parameters.  I think 
> this is a case where inheritance can make sense, but, particularly as an 
> end goal is the public release of these modules, I'd like to make sure they 
> are designed correctly, or at least today's definition of correctly.
>
>>  
>>
>>> If not, can you suggest a good approach to present the base module 
>>> options to the profile?  We'd like to to allow parameterization / hiera 
>>> lookups at the profile layer, preferrably without having to reimplement 
>>> each option in the security layer.
>>>
>>>
>>
>> It would help if you presented a representative example of what you're 
>> trying to configure, and explained the challenge you face with respect to 
>> that.  What you've presented so far is too abstract for me to offer any 
>> specific advice.
>>
>>
>> John
>>
>> Certainly!
>
> The goal here is to build security hardening into the Puppet configuration 
> stack while still allowing flexibility for environment configuration, as, 
> for example, it is reasonable to turn off one or more hardening settings. 
>  Ideally, any module released would allow one to select their hardening 
> standard, whether CIS, STIG, or other.
>
> Conceptually this would extend the roles and profiles pattern.  In 
> particular, profiles exist to define technology stacks.  This likely will 
> result in multiple profiles calling the same module.   The idea is to 
> inject another layer above the modules, which have a 1:1 correlation with 
> the modules.
>


This is where your separation of concerns falls down.  Any change to the 
underlying profile requires at least a review of the security-layer 
wrapper, and possibly a change there, too.

 

>  This wrapper module would provide an expose the specific configuration 
> options required for security hardening, while allowing the calling profile 
> to pass through environment parameters, as is done today.
>


Huh?  What are "environment parameters"?

 

>   
> To continue with the SSH example (pardon the mix of pseudocode and bad 
> puppet code, my puppet code is very rusty):
>
> Today, the profile declares SSH as a needed class:
> class profile::base {
>
> class { '::ssh': }  
> }
> This uses the ssh class (saz-ssh in my instance) with default options. 
> However, the security configuration requires some options be set.
>
> What we'd do is call:
> class { 'sec_profile::ssh':
> security_hardening => 'true' (or via hiera lookup) } 
>
This class would, via inheritance or another method, expose all of the 
> existing parameters of the saz-ssh module which we downloaded from the 
> forge.
>


Not via class inheritance, that's for sure.  Puppet does not support 
inheriting from parameterized classes.  If you try to do it anyway then you 
will find that the parent class gets instantiated with all default 
parameters.  And no, what you're describing is not "resource property 
overrides" (the only reason *ever* to consider class inheritance in 
Puppet).  You have fallen into the classic trap of thinking that Puppet 
"classes" are similar to Java or C++ "classes".  They are not.  At best, 
they are distant cousins.  In fairness, though, Puppet terminology borrows 
a lot from the OO world, so that's an easy mistake to make, 

 

> However, within this class, it would specifically set the needed security 
> options. Logic would be added to identify if security hardening is enabled, 
> and if so, set the appropriate parameters as required. This would not 
> modify any of the inherited module logic. As above, sec_profile would then 
> inherit saz-ssh, adding the needed parameters, but allow a profile to set 
> any other parameters. In this way, the only code which needs writing is the 
> specific security options, and the rest is exposed as is. This would 
> obviously link the wrapper module to a specific base module, but that's ok: 
> class { 'sec_profile::ssh':
> security_hardening => 'true',
> non_security_parameter => 'value' } 
>


Coupling the wrapper classes to the underlying profiles is poor form.  Such 
tight coupling should generally occur only among classes of the same 
module, not across module boundaries.  It is doable, but it is certainly 
not "ok" if separation of concerns is a genuine goal of this exercise.

Moreover, in most contexts and for most purposes it is ill-advised to use 
resource-style class declarations at all.  We can have that discussion if 
you like.  I cannot think of a single scenario where using them across 
module boundaries would be a good idea.  If all you want is to modulate 
class parameters, and especially if you're ok with the hardening parameters 
being overridden at need, then you're proposing to go to a whole lot of 
effort to produce bad code to do something that Hiera can already do for 
you.

 

> ...
> The obvious question is: why not put the security options into the 
> profiles themselves and be done with it? 1) As mentioned above, we could 
> have multiple profiles calling the same module, requiring maintainance of 
> settings in multiple places.
>


No, you don't understand.  Putting the option data inside your modules 
(whether for security options or general options) is an inherent problem, 
especially if multiple profiles use the same module.  This is another 
aspect of the situation that Hiera already solves, in conjunction with 
class declarations of appropriate form.

 

> 2) Engineering and security would have to share the profile classes, which 
> breaks some of the role separation and makes auditing (slightly) more 
> complicated.
>


Separating the security options out into separate classes in a separate 
module doesn't help much there because even though the two groups may have 
responsibility for different files, you have very tight coupling between 
those belonging to one group and those belonging to the other.  You don't 
end up with very good role separation that way, either, because changes at 
the profile level require review and possible changes at the security 
level, which may in turn require review and changes back in Engineering at 
the role level.

 

> 3) The goal is to release the security modules publicly, and wrapping them 
> into the site specific profiles makes that impossible. 
>
>

Your community spirit is appreciated, but no knowledgable Puppeteer would 
use modules built along the lines you describe.

Nothing you said gives me any reason to think that there is a better 
approach to your problem than via Hiera (which is not even among the 
options you proposed).  In particular, your concept of an approach based on 
class inheritance is a non-starter.  You could possibly do the job via 
wrapper classes without class inheritance, but I see no reason to think 
that the result would justify all the extra effort.

Instead, take all the site-specific and option data out of your modules 
altogether, and manage it via Hiera and automatic data binding instead.  
Manage the security-related data at a high priority level in your data 
hierarchy, but support overriding hardening options by establishing at 
least one level with higher priority.


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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/f58ce62d-9e4c-416c-9a49-cc6f85bbde6c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to