Secure your hosts with CFEngine Build modules

March 16, 2022

Last year, we launched functionality for users to add policy for reporting data, compliance reports, promise types, and other code as modules. With CFEngine Build, users can manage and update their own policy, the default policy and any additional modules separately. This makes it very easy to utilize policy or other modules written by the CFEngine team, or other community members. In this post we will take a look at using some modules to improve the security of our infrastructure.

Getting started

If you are not familiar with CFEngine or how to use CFEngine Build, we highly recommend you go through the getting started guide:

We won’t go over the basics of how CFEngine works and how to set it up here, so some prior knowledge is assumed.

New project

For this I will create a new project, but you can also keep using your existing cfbs project if you have one:

$ mkdir -p ~/security_policy
$ cd ~/security_policy
$ cfbs init
$ cfbs add masterfiles

We will be using a similar workflow as in the getting started guide;

  1. Explore CFEngine Build and add modules.
  2. Build your policy set.
  3. Deploy to your CFEngine Hub.
  4. Observe the results in the CFEngine Web UI, Mission Portal.

On the CFEngine Build website, we can use the search functionality to find interesting modules:

In this case I searched for modules with security and supported tags and sorted by popularity (number of downloads).

From that list of search results, I’ve chosen a few modules I’d like to use:

  • Modules which give more reporting data (inventory):
  • Modules related to detecting and fixing CVEs:
  • Security hardening modules which files or packages on the machine:

The command to add all of these is simply:

$ cfbs add inventory-sudoers inventory-yum-update-info cve-2021-3156-sudo cve-2021-44228-log4j prelinking-disabled ftp-server-not-installed tmp-nosuid

Build and deploy:

Building is straight forward and fast:

$ cfbs build

If you’re already using cf-remote and have spawned / saved hubs with it, you can deploy like this:

$ cf-remote deploy

If you have a CFEngine hub and need to save it in cf-remote, this is easy:

$ cf-remote save -H root@ --role hub --name hub

(Replace the root@ with the appropriate SSH username and IP for your hub).

Observing the results

After deploying my policy set, I opened up the CFEngine Enterprise GUI, Mission Portal. It has multiple useful features for security and reporting, such as: Inventory reports, Policy analyzer, Compliance reports and individual host info pages with host specific data and actions.

Inventory reports

I created an Inventory Report with some of the relevant data:

We now have a list of users with sudo, and can double check that it’s correct, we want as few users as possible to have this privilege.

We also see that many of our hosts are affected by the sudo CVE. That’s good to know, let’s look at updating sudo later.

Additionally, we see that our RHEL 7 machine has security updates available.

That is easy to fix, since it’s only 1 machine, we can just log in with SSH and update;

$ ssh ec2-user@
Last login: Wed Mar 16 19:57:57 2022 from
[ec2-user@ip-172-31-1-116 ~]$ sudo yum update -y

Alternately, I have the machine saved with the name rhel7, so it’s easier to just use cf-remote:

$ cf-remote sudo -H rhel7 "yum update -y"

Tip: If you want all your hosts to be upgraded automatically, there is a module for that.

Action buttons in host info page

Now that we’ve updated with yum, let’s refresh the data in Mission Portal. By clicking on the hostname in the inventory report, we get to the host info page, where we can trigger an agent run and report collection:

Now, when we go back to the inventory report, we see that there are no security updates available:

Policy analyzer

Interestingly, we can see a red counter on the Policy analyzer app, indicating problems in our infrastructure:

By opening up the app, we can find out which policy file is encountering issues:

And even the individual line number:

Below that, we can see the affected hosts and even the log messages indicating what’s wrong:

So, it seems our module detected a vulnerable version of sudo and wants to update, but is only configured to log warnings. We can see this documented in the module’s page on CFEngine Build:

This policy tests for the presence of the vulnerability and inventories it’s presence. If the vulnerability is present sudo promises to run the most recent version available in warning mode unless default:cve_2021_3156_remediate or northerntech_security_hardening:cve_2021_3156_remediate is defined in which case sudo is automatically upgraded to the latest version available.

So, we just need to define a class to tell the module to upgrade sudo, let’s use Host specific data for that.

CMDB - Host specific data

By clicking on one of the hosts affected by the sudo vulnerability, either in the policy analyzer results, or in the inventory report, we go to its host info page:

Once here, we can use the Host specific data section to enable or configure specific policy on that host. Let’s enable the upgrade of sudo:

After saving that class, triggering an agent run and waiting for the reporting to happen, we can see in the Inventory report that it’s been patched on Ubuntu 20:

At this point I could remove the class again, if I don’t want the automatic upgrade to happen without me knowing of it.

Note: On some older platforms, a new version of sudo might not be available, and the remediation will not succeed. In that case the module will still tell you that you are affected by the CVE, and it’s up to you to find a way to upgrade sudo (or preferably the OS).

Compliance reports

While we are on the topic of upgrading Operating Systems, let’s take a look at a newer experimental module:


When added, this module will import a compliance report, to help you keep track of which Operating Systems need to be upgraded. Let’s add and deploy it:

$ cfbs add compliance-report-os-is-vendor-supported
$ cfbs build
$ cf-remote deploy

(When using cf-remote and cfbs, these are the 3 commands you need to add a module from our website, build it, and deploy it to your hub, and subsequently the rest of your infrastructure).

We can open up Mission Portal again and go to Reports -> Compliance, to find our new report:

In general, that looks good, but let’s see which Ubuntu version is not supported by clicking on the link for failing:

In this view, we can clearly see that Ubuntu 16 is not supported. Which is correct, regular support for Ubuntu 16 ended in April 2021, so we should upgrade!

Note: This is an experimental module, as we just introduced the ability to import compliance reports. Using experimental modules is great for testing new things and giving feedback, just be aware that they might not be working in the best way or they might change a lot in the future.

Exploring for more modules

Feel free to look around CFEngine Build to find more modules you might be interested in:

If you didn’t see it already, the security calendar we did in December has more examples of security modules for CFEngine:

Get in touch with us
to discuss how we can help!
Contact us
Sign up for
our newsletter
By signing up, you agree to your email address being stored and used to receive newsletters about CFEngine. We use tracking in our newsletter emails to improve our marketing content.