Using Puppet Trusted Facts Part 2: Improving Security

Puppet Trusted Facts - How to Use Them - Kinney Group

In Part 1 of this two-part blog series, I covered the basics of Puppet facts. I defined and provided examples of various types of facts in Puppet, including core, custom, and external facts. Deployed in a similar way, we sometimes refer to these facts addressed in Part 1 as “normal facts,” because they are the most commonly used. That now brings us to the main topic of Part 2: Puppet trusted facts. We’ll examine what trusted facts are and how to use them to create higher levels of security for sensitive data held in Puppet.

Introducing Puppet Trusted Facts

There is a lot capability packed into each of the normal fact types, and they can be a very powerful tool in your Puppet implementation. However, there is one thing about all of these fact types that could present a bit of a security concern: They are all self-reported by the node, which means that there is no guarantee of their accuracy.

Let’s consider our previous example of a custom fact for a site identifier. The Puppet master depends on the node to report that information accurately so that it can send the appropriate configuration information back to the node. A site identifier might be used to determine what secrets or sensitive information should be deployed to a node.

By nature of how they are deployed, custom and external facts could be manipulated, maliciously or otherwise, providing a potential opportunity to compromise sensitive information or worse. Trusted facts can be used to address this security issue.

How to Use Trusted Facts

Trusted facts are embedded in the certificate that is used to secure the connection between the node and the Puppet master. This implies that the certificate authority has checked and approved these facts and will prevent them from being overridden manually. We now have a method available to ensure that the fact being sent to the master is accurate because trusted facts are immutable.

Trusted facts are actually keys available in a special hash called a $trusted hash. Custom information is embedded in another hash that is nested in the $trusted hash called extensions.

The $trusted hash might look something like the following example:

{
     ‘authenticated’ => ‘remote’,
     ‘certname’      => ‘appserver01.sample.com’,
     ‘domain’        => ‘sample.com’,
     ‘extensions’    => {
             pp_site    => ‘datacenter013’,
             pp_region  => ‘alpha’,
             pp_env     => ‘production’,
      },
     ‘hostname’      => ‘appserver01’
}

In the example above we have an extension for site, region and environment but how do we get that information into the certificate? When the connection request is made from the node to the Puppet master these extensions must be included in the request. From a Linux node the command to download the Puppet agent software from the master and embed the extensions into the certificate would look like the following:

curl -k https://puppetserver:8140/package/current/install.bash | sudo bash -s agent:certname=appserver01.sample.com extension_requests:pp_site=datacenter013 extension requests:pp_region=alpha extension_requests:pp_env=production

Once the node request from the master has been accepted, the extension data elements are stored in a file on the node called the csr_attributes.yaml file. This file can typically be found at /etc/puppetlabs/puppet/ on Linux machines and C:\ProgramData\PuppetLabs\puppet\etc on Windows-based machines. The file itself will contain an extension_requests that will look similar to the following:

custom_attributes:
  2.1.243.443568.1.9.7: 343gtrbhryts87739380kdjfjf6376hd
extension_requests:
  pp_site: datacenter013
  pp_region: alpha
  pp_env: production

Another, more manual, method you can use to deploy trusted facts is to have your csr_attributes.yaml file in place on the node prior to making and approving the node request. Since trusted facts are immutable once the certificate request is signed, any desired data must be present before Puppet agent attempts to request its node for the first time.

Trusted Facts as a Security Measure

Now that we have trusted facts implemented, we can easily access them in our Hiera hierarchies and in our Puppet code. Using the $trusted hash we are able to access them just like we would any other fact in Puppet. Trusted facts might take a little more effort to deploy because you need to do it manually or have an automated provisioning process in place that can pre-stage your csr_attributes.yaml file or execute the Puppet agent install by running the curl command to download the software from the master.

Since trusted facts cannot be modified during the lifecycle of a node, there are special use cases where these are much more useful than normal fact types. However, in a Puppet environment where additional layers of security are helpful for meeting security requirements or ensuring the integrity of your systems, trusted facts can be a very useful tool.

Trusted facts may be worth considering in the following use cases:

  1. Preventing the inadvertent application of non-production configuration to production nodes.
  2. Preventing secure data or information from being exposed to the wrong users.
  3. Providing an additional layer of security for passing security audits.

Kinney Group was recently named the recipient of Puppet’s Channel Partner of the Year award for Puppet Government Partner of the Year for 2018. For more information about Puppet IT Automation services offered by Kinney Group, contact us here.

Using Puppet Trusted Facts Part 1: An Intro to Puppet Facts

Using Puppet Trusted Facts - Kinney Group

In this two-part blog series, I am ultimately going to address using Puppet trusted facts: what they are, how to use them, and most importantly, how to use them as an added security measure. However, before I get to trusted facts in Part 2, I’d like to make sure we’ve covered the basics here in Part 1: So first, what are Puppet facts?

The Basics: Puppet Facts

Facts in Puppet are nothing new. Facts are information gathered about a node by a tool called Facter. Facts are deployed as pre-set variables that can be used anywhere in your Puppet code. Facter is installed automatically with the Puppet agent software.

When a Puppet agent run takes place on a node, the first thing that happens is that Facter gathers up information about the node and sends that information to the Puppet master server. The Puppet master then uses that information to determine how the node should be configured and sends configuration information back to the node. The Puppet agent uses that information to apply the desired configuration to the node.

Some examples of core facts that are generated by Facter by default are:

  • Operating System
  • Kernel
  • IP Address
  • FQDN
  • Hostname

Typically, facts—once they are sent to the Puppet master—are stored in the PuppetDB (when in use), which means that the Puppet master actually has a detailed inventory of information about your infrastructure. PuppetDB’s API provides a powerful way to share that information with other systems.

What makes Facter even more powerful is that you can also create your own Facter facts called custom facts or external facts. These facts are either deployed within your Puppet modules, generated via a script, or embedded in designated files on your Puppet nodes.

Puppet Custom and External Facts

Custom and external facts give you the ability to attach your own metadata to a node so that you can use them in your Puppet code. One common example would be a custom fact for a site identifier that indicates where a node is deployed in the data center. This fact could be generated in a couple of ways: either by a custom script or a flat file deployed to a designated facts directory on the node.

Most facts can be changed during the lifecycle of a node when the characteristics of a node are changed. For example, if a machine’s operating system is updated, that information is automatically updated by Facter and sent back to the master on the next Puppet agent run.

Fact Types in Puppet

Core, custom, and external facts are deployed in a similar way even though they are generated slightly differently. We sometimes refer to these as normal facts because they are the most commonly used.

  • Core facts: Built-in facts that ship with Facter.
  • Custom facts: Require Ruby code within your Puppet module to produce a value.
  • External facts: Generated by either pre-defined static data on the node or the result of running an executable script or program.

Now that we’ve covered the basis with regard to Puppet facts, we’re prepared to pick back up in Part 2 of this series to cover Puppet trusted facts. More specifically, I will address how trusted facts in Puppet can add additional layers of security for meeting security requirements or ensuring the integrity of your systems.

And with that, we can move on to Part 2 in this series: Using Puppet Trusted Facts: Improving Security.