Hi Dan, Chris,
Many thanks for taking the time to respond, some very useful ideas to ponder.
Apologies if this is a bit waffley and repeats itself.
Dan's approach is more elegant in the sense that it implements just what is required, but makes me uncomfortable because it distributes hardening implementation throughout all of the code base.
Using a hardening module is somewhat elegant in the sense that the hardening is 'mostly' in one place, but it makes me uncomfortable that many other modules are affected, not all the hardening can remain in the hardening module if other modules manage conflicting resources, and conflicts can be problematic to diagnose and resolve, it doesn't seem too follow the puppet way of doing things.
My experience is that using a hardening module was a pragmatic way to take advantage of existing code that implements an industry standard hardening guideline, especially without an extensive pre-existing code base and it was easier to communicate that hardening was being enforced.
Agreed -- the CIS Hardening guidelines should not be applied verbatim (as the individual sections don't always apply to the business's use of the system). Each item should be considered and applied to each system as appropriate. There may also be site standards to take into account that can add or subtract hardening requirements.
If you go down the path of using a module specific to hardening....
The implementation of hardening guidelines via an independent module affects many other generic modules and may well cause conflicts.
Resolving these conflicts involves changing either the hardening module or the generic module (assuming you can identify the conflict or lack of convergence). If you have to change the generic module anyway perhaps that should be where the hardening code should be implemented rather than attempting to have a separate module to implement the hardening.
However some of the CIS guidelines don't have a corresponding generic module (at least in the code base I was working on) so the hardening module provides a starting point.
I remember the f000 and c000 things now -- quite a PITA to find and trace the relationships when there are problems, I didn't enjoy that one bit.
I liked the idea of having a cis::el6all include classes for each guideline paragraph, it provides a reference for which paragraphs of the hardening guide are being implemented. The use of sequential numbers for the classes that actually implement the hardening (called from cis:: classes named after the corresponding document section) makes tracing problematic, I think there are couple of cases where they are reused -- still meaningful names would probably help. I don't see why the facts and there corresponding script fragments cant have meaningful names.
If I recall correctly I commented out some of the classes in the cis::el6all class and added a description of where this functionality was implemented in a generic module (ssh, ntp etc). If I end up having to do this again and go down this path I will comment the changed ssh module etc with the CIS section too (should of thought of that before).
I like the idea of having most of the hardening implementation in one place rather than scattered over the whole code base.
The way puppet works doesn't lend itself to taking a cross cutting concern like hardening and putting it in an independent module -- at least not without significant issues -- so its fair to argue it misappropriate use of puppet.
It seems to me that hardening is a distinct aspect and in some circumstances I would like to see all the hardening things and none of the rest of the details, however I'm unaware of any support for a module implementing specific functionality (say ssh) having part of is implementation overideable by a class in a foreign module (say cis hardening).
If you go down the path of implementing hardening directly in the code base without a module then apart from a text search there seems no way of gathering all of the hardening specifics together.
My experience of using arildjensen-cis was that there was quite a bit of breakage that had to be resolved, but that breakage identified things that were managed but non-compliant. Some of the arildjensen-cis classes were not relevant and were disabled before attempting the first run.
I found that arildjensen-cis was a good starting point and covered quite a number sections of the guide, diagnosing problems was not always straight forward and the end solution had most but not all the hardening in one place.
I also subscribe to Dan's disclaimer above, this is just my experience and opinions however code was written systems configured and audits passed.
The $enablehardening idea sounds interesting but don't expect there would be much uptake unless puppetlabs found some way to mandate it or something similar.
I feel like hardening should override other modules resources by some magic, or there should be some way to compose a resource from unrelated modules, but its not the way puppet works and I suspect it would be extremely unworkable. I feel something is missing but I don't have a concrete suggestion of what form a solution should take.
Dan, did you present the security team with the comments in puppet code containing the string CIS or extract the CIS relevant code for their inspection?
Were there new modules that implemented some of the hardening sections and if so did you use module names that describe what they implement along with comments referencing the security guidelines?
On one hand pre-existing code to perform hardening can get you going quicker but on the other hand perhaps Dan's approach is better in the long run and gathering the all hardening information from across the code base is sufficient.
Do you have the code base or some fragments on git-hub, I guess not as security related code is usually quite sensitive but if you don't ask:)
Thanks
Peter