Skip to content

simp/pupmod-simp-compliance_markup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

License CII Best Practices Puppet Forge Puppet Forge Downloads Build Status

Table of Contents

Overview

This module adds a function compliance_markup::compliance_map() to the Puppet language. The compliance_markup::compliance_map() function provides the ability for users to compare their in-scope class parameters against a set of compliant parameters, either in Hiera or at the global scope. Users may also provide custom inline policy documentation and mapping documentation.

The goal of this module is to make it easier for users to both detect, and report on, deviations from a given policy inside their Puppet codebase.

See REFERENCE.md for more information.

Module Description

This module provides the function compliance_markup::compliance_map() and a compliance_markup class for including the functionality into your stack at the global level.

A utility for converting your old compliance_markup::compliance_map() Hiera data has also been included in the utils directory.

Upgrading

A utility script, compliance_map_migrate has been included in the utils directory of the module to upgrade your old compliance data to newer formats.

At minimum, you must pass to the script a compliance profile to migrate, the version of the API it was compatible with, and the version you wish to migrate it to. For instance, to upgrade a compliance map from API 0.0.1 to 1.0.0:

ruby compliance_map_migrate -i /etc/puppetlabs/code/environments/simp/hieradata/compliance_profiles/nist_800_53_rev4.yaml -s 0.0.1 -d 1.0.0

Please validate that the migrated YAML files work as expected prior to deploying them into production.

Reporting

What compliance_markup affects

By default, the compliance_markup::compliance_map() function creates a set of reports, one per node, on your Puppet Server at /opt/puppetlabs/server/data/puppetserver/simp/compliance_reports/<fqdn>.

You may optionally enable the creation of a File resource on each of your clients if you wish to have changes in this data automatically exported into PuppetDB.

Usage

The compliance_markup::compliance_map() function provides a mechanism for mapping compliance data to settings in Puppet and should be globally activated by including the compliance_markup class.

It is primarily designed for use in classes to validate that parameters are properly set but may also be used to perform a full compliance report against multiple profiles across your code base at compile time.

When the compliance_markup class is included, the parameters in all in-scope classes and defined types will be evaluated against top level parameters, lookup() values, or Hiera data, in that order.

The variable space against which the parameters will be evaluated must be structured as the following hash:

  compliance_map :
    <compliance_profile> :
      <class_name>::<parameter> :
        'identifiers' :
        - 'ID String'
        'value'      : 'Compliant Value'
        'notes'      : 'Optional Notes'

For instance, if you were mapping to NIST 800-53 in the SSH class, you would use something like the following:

  compliance_map :
    nist_800_53 :
      ssh::permit_root_login :
        'identifiers' :
        - 'CCE-1234'
        'value'      : false

Alternatively, you may use the compliance_markup::compliance_map() function to add compliance data to your modules outside of a parameter mapping. This is useful if you have more advanced logic that is required to meet a particular internal requirement.

NOTE: The parser does not know what line number and, possibly, what file the function is being called from based on the version of the Puppet parser being used.

The following parameters may be used to add your own compliance data:

:compliance_profile => 'A String, or Array, that denotes the compliance
                        profile(s) to which you are mapping.'
:identifiers        => 'An array of identifiers for the policy to which you
                        are mapping.'
:notes              => 'An *optional* String that allows for arbitrary notes to
                        include in the compliance report'

Report Format

The compliance report is formatted as follows (YAML Representation):

---
# The API version of the report
version: "1.0.1"
fqdn: "my.system.fqdn"
hostname: "my"
ipaddress: "1.2.3.4"
puppetserver_info: "my.puppet.server"
compliance_profiles:
  profile_name:
    summary:
      compliant: 80
      non_compliant: 20
      percent_compliant: 80
      documented_missing_resources: 2
      documented_missing_parameters: 1

    compliant:
      "Class[ClassName]":
        parameters:
          param1:
            identifiers:
              - ID 1
              - ID 2
            compliant_value: 'foo'
            system_value: 'foo'

    non_compliant:
      "Class[BadClass]":
        parameters:
          bad_param:
            identifiers:
              - ID 3
              - ID 4
            compliant_value: 'bar'
            system_value: 'baz'

    documented_missing_resources:
      - missing_class_one
      - missing_class_two

    documented_missing_parameters:
      - "classname::param2"

    custom_entries
      "Class[CustomClass]":
        location: "file.pp:123"
        identifiers:
          - My ID

site_data:
  completely: random user input

Options

The compliance_markup class may take a number of options which must be passed as a Hash.

report_types

Default: [ 'non_compliant', 'unknown_parameters', 'custom_entries' ]

A String, or Array that denotes which types of reports should be generated.

Valid Types:

  • full: The full report, with all other types included.
  • non_compliant: Items that differ from the reference will be reported.
  • compliant: Compliant items will be reported.
  • unknown_resources: Reference resources without a system value will be reported.
  • unknown_parameters: Reference parameters without a system value will be reported.
  • custom_entries: Any one-off custom calls to compliance_markup::compliance_map will be reported.

site_data

Default: None

A valid Hash that will be converted as passed and emitted into your node compliance report.

This can be used to add site-specific or other information to the report that may be useful for post-processing.

client_report

Default: false

A Boolean which, if set, will place a copy of the report on the client itself. This will ensure that PuppetDB will have a copy of the report for later processing.

server_report

Default: true

A Boolean which, if set, will store a copy of the report on the Server.

server_report_dir

Default: Puppet[:vardir]/simp/compliance_reports

An Absolute Path that specifies the location on

server_report_dir

Default: Puppet[:vardir]/simp/compliance_reports

An Absolute Path that specifies the location on the server where the reports should be stored.

A directory will be created for each FQDN that has a report.

catalog_to_compliance_map

Default: false

A Boolean which, if set, will dump a compatible compliance_map of all resources and defines that are in the current catalog.

This will be written to server_report_dir/<client_fqdn> as catalog_compliance_map. Old versions will be overwritten.

NOTE: This is an experimental feature and subject to change without notice.

Reference

The full module reference can be found in the module docs and in the local docs/ directory.

Example 1 - Standard Usage

Manifest

class foo (
  $var_one => 'one',
  $var_two => 'two'
) {
  notify { 'Sample Class': }
}

$compliance_profile = 'my_policy'

include '::foo'
include '::compliance_markup'

Hiera.yaml

:backends:
  - 'yaml'
:yaml:
  :datadir: '/path/to/your/hieradata'
:hierarchy:
  "global"

Hieradata

---
# In file /path/to/your/hieradata/global.yaml
compliance_map :
  my_policy :
    foo::var_one :
      'identifiers' :
      - 'POLICY_SECTION_ID'
      'value' : 'one'

Example 2 - Custom Compliance Map

if $::circumstance {
  compliance_markup::compliance_map('my_policy','POLICY_SECTION_ID','Note about this section')
  ...code that applies POLICY_SECTION_ID...
}

Enforcement

This module also contains a Hiera backend that can be used to enforce compliance profile settings on any module when it is included. It uses the compliance_markup::enforcement Array to determine the profiles to use, and which profiles take priority.

Only a Hiera v5 backend is provided. Because of this, the Hiera backend is only available on versions of Puppet 4.10 or above.

v5 Backend Configuration

---
version: 5
hierarchy:
  - name: SIMP Compliance Engine
    lookup_key: compliance_markup::enforcement
    # All options are optional
    options:
      # Ignore all default data dirs and use these instead
      data_dirs:
        - /fully/qualified/data_dir
  - name: Common
    path: default.yaml
defaults:
  data_hash: yaml_data
  datadir: "/etc/puppetlabs/code/environments/production/hieradata"

Configuring profiles to enforce

To enforce disa stig + nist, with disa stig compliance settings taking priority, add the following to your hiera data files. This will work like any hiera setting, so you can set enforcement based on any factor, including host, hostgroup, kernel or specfic os version.

---
compliance_markup::enforcement: [ 'disa_stig', 'nist_800_53_rev4' ]

Configuring enforcement tolerance

Certain checks have a built-in safety mechanism built in called 'enforcement tolerance' this allows the user to define what level of risk they wish to enfoce and based on their tolerance level.

The default enforcement tolerance is 40. This will allow enforcement of any checks that can not cause any access restrictions or breakages to a system. If you wish to enforce checks that are more dangerous or less dangerous, you can override this default value but using:

---
compliance_markup::enforcement_tolerance_level: 40

Valid levels are:

  • 20: Remediation works fine on all systems, changes will be made.
  • 40: Remediation works, minor issues may arise in special cases
  • 60: May cause login or access issues on system
  • 80: Breaking remediation changes will be enforced

Debugging the Hiera Backend

The Hiera backend exposes a debug interface to users via lookup. These can be used to query the library for data or metrics.

Hiera key Purpose
compliance_markup::debug::dump Returns a Hash of all output data from the Hiera backend
compliance_markup::debug::hiera_backend_compile_time Returns the Hiera backend data compilation time in seconds
compliance_markup::debug::profiles Returns an Array of the available compliance profiles
compliance_markup::debug::compliance_data Returns a Hash of compiled input data to the Hiera backend

Limitations

Depending on the version of Puppet being used, the compliance_markup::compliance_map() function may not be able to precisely determine where the function has been called and a best guess may be provided.

Hash values for Puppet parameters in compliance data will always be deep merged. Configurable merge behavior may be implemented in a future release.

Development

Patches are welcome to the code on the SIMP Project Github account. If you provide code, you are guaranteeing that you own the rights for the code or you have been given rights to contribute the code.

Acceptance tests

To run the tests for this module perform the following actions after installing bundler:

bundle update
bundle exec rake spec
bundle exec rake beaker:suites

Packaging

Running rake pkg:rpm[...] will develop an RPM that is designed to be integrated into a SIMP environment. This module is not restricted to, or dependent on, the SIMP environment in any way.