Skip to content

Instantly share code, notes, and snippets.

@jessereynolds
Last active April 17, 2019 01:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jessereynolds/ced11eaf8a4ccdbcbd3499557fae9adc to your computer and use it in GitHub Desktop.
Save jessereynolds/ced11eaf8a4ccdbcbd3499557fae9adc to your computer and use it in GitHub Desktop.
puppet compliance module structure

Is nooping the controls which are to be monitored the best way to go? Seems the most conventional / straightforward.

Anyhow, as an operator of a fleet of systems I want to be able to set which CIS sections / controls are to be enforced, and which are to be monitored.

How might this look?

class os_compliance::rule::password_history (
  Enum['enforce','monitor'] $mode = 'monitor',
) {
  if $mode == 'monitor' {
    noop()
  }

  local_security_policy { 'Enforce password history':
    ensure       => present,
    policy_value => String($password_history),
  }

}

and

class os_compliance::apply (
  $rulesets = [],
) {
  $rulesets.each |$ruleset| {
    lookup("os_compliance::ruleset::${ruleset}").each |$rule, $mode| {
      $rule_class = lookup("os_compliance::rule_alias::${rule}")
      class { "os_compliance::rule::${rule_class}":
        mode => $mode,
      }
    }
  }
}

with all the data about which the contents of each CIS benchmark, and which rules correspond to which cis control numbers in hiera:

os_compliance::apply::rulesets:
  'cis-l1-ms-windows-2012r2-2.3.0'

os_compliance::ruleset::cis-l1-ms-windows-2012r2-2.3.0:
  cis_1.1.1: enforce
  cis_1.1.2: monitor
  cis_1.1.3: enforce

os_compliance::ruleset::cis-l1-ms-windows-2008r2-3.1.0:
  cis_1.1.1: monitor
  cis_1.1.2: monitor
  cis_1.1.3: monitor

os_compliance::rule_alias::cis_1.1.1: password_history
os_compliance::rule_alias::cis_1.1.2: maximum_password_age
 

If implementing a set of compliance standards as facts, how might this look?

Thinking out loud...

We want a fact that says whether each control within a stanard is compliant or not, eg:

os_compliance:
  cis_level_1:
    compliancy_percent: 99.3
    version: windows_2012r2_member_server_2.3.0
    total_controls: 273
    total_compliant_controls: 272
    non_compliant_controls: 
      1_1_1:
        description: (L1) Ensure 'Enforce password history' is set to '24 or more password(s)'
        state: 0
      18_9_58_3_9_2:
        description: (L1) Ensure 'Do not use temporary folders per session' is set to 'Disabled'
        state: Enabled
new_control(
  name: 'password_history',
  standards: ['cis-l1-ms-windows-2012r2-2.3.0:1.1.1'],
  os_constraint: 'windows',
  os_version_constraint: 

The implementation should:

  • correctly determine the standard to apply based on OS, version, and whether it's a domain controller or not.

Should the fact also show the number of implemented / unimplemented controls? This would be good during implementation to track progress, and if it's the case that some cannot be implemented it would be important to surface this.

@abuxton
Copy link

abuxton commented Apr 3, 2019

class os_compliance::apply (
  $rulesets = [],
) {
  $rulesets.each |$ruleset| {
    lookup("os_compliance::ruleset::${ruleset}").each |$rule, $mode| {
      $rule_class = lookup("os_compliance::rule_alias::${rule}")
      class { "os_compliance::rule::${rule_class}":
        mode => $mode,
        tag      => $rule,
      }
    }
  }
}

@jessereynolds
Copy link
Author

puppetdb resource endpoint - find all CIS benchmark classes...

["and", ["=", "type", "Class"],
             ["=", "tag", "cis-l1-ms-windows-2012r2-2.3.0"]]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment