Build Secure AMIs with cnspec and HashiCorp Packer
You can run security scans during HashiCorp Packer builds using Packer plugin cnspec by Mondoo. This tutorial includes instructions for using the plugin both with and without an account on Mondoo Platform.
This tutorial provisions resources that qualify under the AWS Free Tier. If your account doesn't qualify under the AWS Free Tier, Mondoo is not responsible for charges that you incur.
Prerequisites
Before you begin, be sure you have:
- An AWS Account
- The AWS CLI installed and configured
- The latest HashiCorp Packer version installed
Packer plugin cnspec by Mondoo
Packer plugin cnspec by Mondoo scans Linux and Windows HashiCorp Packer builds for vulnerabilities and security misconfigurations. The plugin is designed to work with any of the supported Packer builders, including containers.
Plugin modes
Packer plugin cnspec is designed to work in one of two modes:
- Unregistered - In unregistered mode, the plugin works without being registered to Mondoo Platform, and is designed to provide baseline security scanning with minimal configuration. The plugin runs either the Linux Security by Mondoo policy on Linux builds, or the Windows Security by Mondoo policy on Windows builds. Each of these policies provides security hardening checks based off of industry standards for Linux and Windows. Scan results are shown in STDOUT during the Packer run.
- Registered - In registered mode, the plugin is registered to your account in Mondoo Platform using a service account. Registered mode allows you to configure and customize any of the policies in Mondoo Platform including CIS benchmarks and more. Scan results are shown in STDOUT and sent back to Mondoo Platform for your records.
To scan for vulnerabilities, you must register cnspec with Mondoo Platform. Sign up for a free account today.
AWS authentication
Before you can run Packer, you must configure AWS credentials with appropriate permissions to build AMIs. For more information see Configuring the AWS CLI in the AWS documentation.
For a full list of IAM permissions required to run the amazon-ebs builder, refer to the Packer Amazon AMI Builder documentation.
If you don't have access to IAM user credentials, use another authentication method described in the Packer Amazon AMI Builder documentation.
Plugin configuration
Packer plugin cnspec provides this configuration:
score_threshold
- This configuration sets anint
score threshold for security scans. If the scan produces a score that falls below the threshold, the build will fail.on_failure = "continue"
- This configuration ensures that the Packer build will not fail even if the scan produces a score that falls below thescore_threshold
.sudo
- Some of the security configuration checks require elevated permissions to scan a given resource such as thesshd_config
. Setting thesudo
option toactive = true
configures the plugin to run insudo
mode.asset_name
- Override the asset name on Mondoo Platform. This configuration is only used in registered mode.annotations
- Custom annotations can be applied to Packer build assets to provide additional metadata for asset tracking. This configuration is only used in registered mode.
Register with Mondoo Platform
To configure the plugin to work in registered mode, you must first create a Base64-encoded service account. If you do not wish to use custom policies and store results on Mondoo Platform you can skip this step.
To create a Base64-encoded service account:
- Navigate to the space in which you want to create a service account.
- In the left navigation, select Settings. Then select the Service Accounts tab.
- Select ADD ACCOUNT.
- Check the Base64-encoded box to Base64-encode the credentials.
- Select GENERATE NEW CREDENTIALS.
- Copy the Base64-encoded credentials to the clipboard.
- Open a terminal and run:
export MONDOO_CONFIG_BASE64=<paste Base64-encoded token>
Run Packer
With Packer configured, you are ready to run your first build.
Amazon Linux 2 template
Create a new directory named mondoo_packer
, and change to that directory.
mkdir mondoo_packer
cd mondoo_packer
Create a new file called aws-amazon2.pkr.hcl
, and then copy/paste this code snippet into that file.
packer {
required_plugins {
amazon = {
version = ">= 1.1.0"
source = "github.com/hashicorp/amazon"
}
cnspec = {
version = ">= 6.1.3"
source = "github.com/mondoohq/cnspec"
}
}
}
variable "aws_region" {
default = "us-east-1"
type = string
}
variable "image_prefix" {
type = string
description = "Prefix to be applied to image name"
default = "cnspec-tested-amazon-linux-2"
}
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
source "amazon-ebs" "amazon2" {
ami_name = "${var.image_prefix}-${local.timestamp}"
instance_type = "t2.micro"
region = var.aws_region
source_ami_filter {
filters = {
name = "amzn2-ami-kernel-5.*-x86_64-gp2"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["137112412989"]
}
ssh_username = "ec2-user"
tags = {
Base_AMI_Name = "{{ .SourceAMIName }}"
Name = "${var.image_prefix}-${local.timestamp}"
Source_AMI = "{{ .SourceAMI }}"
Creation_Date = "{{ .SourceAMICreationDate }}"
}
}
build {
name = "${var.image_prefix}-${local.timestamp}"
sources = [
"source.amazon-ebs.amazon2"
]
provisioner "shell" {
inline = [
"sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}",
"sudo yum update -y",
"sudo yum upgrade -y"]
}
provisioner "cnspec" {
score_threshold = 80
on_failure = "continue"
sudo {
active = true
}
}
}
This is a complete Packer template that you will use to build an AWS Amazon 2 Linux AMI in the us-east-1
region. In these sections, you will review each block of this template in more detail.
Configure template variables
The template provides a variables
section used to configure the builds.
To learn about the various options to override variables set in the Packer template, see Setting Variables in the HashiCorp Packer documentation.
AWS region
When building AMIs, you must specify which region to build the AMI in. The default region for the template is us-east-1
:
variable "aws_region" {
default = "us-east-1"
type = string
}
Use the optional ami_regions
to configure a list of regions to copy the AMI to. Tags and attributes are copied along with the AMI.
Image prefix
By default the template will create the AMI using a default naming prefix of cnspec-tested-amazon-linux-2
. You can override this with the image_prefix
variable:
variable "image_prefix" {
type = string
description = "Prefix to be applied to image name"
default = "cnspec-tested-amazon-linux-2"
}
Initialize the Packer configuration
Initialize your Packer configuration.
packer init aws-amazon2.pkr.hcl
Executing packer init
instructs Packer to download the plugins defined in the required_plugins
section in the template. Plugins are typically downloaded to the ~/.packer.d/plugins
directory. You can run packer init
as many times as you'd like. If you already have the plugins you need, Packer exits without output.
Build the AMI
Build the image with the packer build aws-amazon2.pkr.hcl
command. Packer prints output similar to what is shown below.
packer build aws-amazon2.pkr.hcl
<image-name>.amazon-ebs.amazon2: output will be in this color.
==> <image-name>.amazon-ebs.amazon2: Prevalidating any provided VPC information
==> <image-name>.amazon-ebs.amazon2: Prevalidating AMI Name: <image-name>
<image-name>.amazon-ebs.amazon2: Found Image ID: ami-0b0dcb5067f052a63
==> <image-name>.amazon-ebs.amazon2: Creating temporary keypair: packer_6382573a-e356-c04a-958f-c1ece4083785
==> <image-name>.amazon-ebs.amazon2: Creating temporary security group for this instance: packer_6382573d-6f07-acc1-f218-df04593a22f1
...
==> <image-name>.amazon-ebs.amazon2: Running cnspec packer provisioner by Mondoo (Version: 0.6.0, Build: dev)
<image-name>.amazon-ebs.amazon2: activated sudo
<image-name>.amazon-ebs.amazon2: detected packer build via ssh
<image-name>.amazon-ebs.amazon2: scan packer build
<image-name>.amazon-ebs.amazon2: scan completed successfully
...
<image-name>.amazon-ebs.amazon2: ✕ Fail: D 20 Ensure sudo logging is enabled
<image-name>.amazon-ebs.amazon2: ✕ Fail: D 20 Ensure kernel module loading and unloading is collected
<image-name>.amazon-ebs.amazon2: ✓ Pass: Ensure no duplicate UIDs exist
<image-name>.amazon-ebs.amazon2: ✕ Fail: D 20 Ensure unsuccessful unauthorized file access attempts are collected
<image-name>.amazon-ebs.amazon2: ✓ Pass: Ensure prelink is disabled
<image-name>.amazon-ebs.amazon2: ✕ Fail: F 0 Ensure that strong Key Exchange algorithms are used
<image-name>.amazon-ebs.amazon2: ✓ Pass: Ensure Samba is stopped and not enabled
<image-name>.amazon-ebs.amazon2:
<image-name>.amazon-ebs.amazon2: Vulnerabilities:
<image-name>.amazon-ebs.amazon2: ■ No advisories found (passed)
<image-name>.amazon-ebs.amazon2:
<image-name>.amazon-ebs.amazon2: Overall CVSS score: 0.0
<image-name>.amazon-ebs.amazon2:
<image-name>.amazon-ebs.amazon2:
<image-name>.amazon-ebs.amazon2: Summary (1 assets)
<image-name>.amazon-ebs.amazon2: ==================
<image-name>.amazon-ebs.amazon2:
<image-name>.amazon-ebs.amazon2: Target: i-0dd30e6f234216dd1
<image-name>.amazon-ebs.amazon2: Score: C 50/100 (100% completed)
<image-name>.amazon-ebs.amazon2: ✓ Passed: ████████ 52% (55)
<image-name>.amazon-ebs.amazon2: ✕ Failed: █████ ██ 44% (46)
<image-name>.amazon-ebs.amazon2: ! Errors: 3% (3)
<image-name>.amazon-ebs.amazon2: » Skipped: 1% (1)
<image-name>.amazon-ebs.amazon2:
<image-name>.amazon-ebs.amazon2: Policies:
<image-name>.amazon-ebs.amazon2: F 0 Linux Security by Mondoo
<image-name>.amazon-ebs.amazon2: A 100 Platform Vulnerability Policy by Mondoo
...
==> Wait completed after 10 minutes 7 seconds
==> Builds finished. The artifacts of successful builds are:
--> <image-name>.amazon-ebs.amazon2: AMIs were created:
us-east-1: ami-0b3e9a14e02dd8f37
View the scan report in Mondoo Platform (registered mode only)
To view the scan report in the Mondoo Console, go to INVENTORY and find the report. You might need to refresh your browser.
View the control details
Select the Controls tab.
Expand any of the checks in the policies that ran against your build to show additional documentation, audit, and remediation steps:
View the image AWS Management Console
After running the above example, you can navigate to the AMIs section of AWS Management Console.
Remove the image
You can remove the AMI by first deregistering it on the AWS AMI management page. Next, delete the associated snapshot on the AWS snapshot management page.
Next steps
In this tutorial, you built an Amazon AMI and scanned it for vulnerabilities and security misconfigurations with cnspec.
The GitHub repository for Packer plugin cnspec contains additional templates for building Ubuntu and Windows images.