Skip to content

Commit

Permalink
Merge pull request #2881 from stmcginnis/cis-agent
Browse files Browse the repository at this point in the history
Add CIS Agent for automated CIS compliance checking
  • Loading branch information
stmcginnis authored Jun 21, 2023
2 parents 55868d8 + 63efa64 commit a4a1039
Show file tree
Hide file tree
Showing 16 changed files with 1,863 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/os/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ source-groups = [
"shimpei",
"driverdog",
"cfsignal",
"bloodhound",
]
package-features = [ "systemd-networkd" ]

Expand Down
5 changes: 5 additions & 0 deletions packages/os/bottlerocket-cis-checks-metadata-json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "CIS Bottlerocket Benchmark",
"version": "v1.0.0",
"url": "https://www.cisecurity.org/benchmark/bottlerocket"
}
30 changes: 28 additions & 2 deletions packages/os/os.spec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Source7: host-ctr-toml
Source8: oci-default-hooks-json
Source9: cfsignal-toml
Source10: warm-pool-wait-toml
Source11: bottlerocket-cis-checks-metadata-json

# 1xx sources: systemd units
Source100: apiserver.service
Expand Down Expand Up @@ -64,6 +65,7 @@ Source302: supplemental-storage.rules
BuildRequires: %{_cross_os}glibc-devel
Requires: %{_cross_os}apiclient
Requires: %{_cross_os}apiserver
Requires: %{_cross_os}bloodhound
Requires: %{_cross_os}bootstrap-containers
Requires: %{_cross_os}bork
Requires: %{_cross_os}corndog
Expand All @@ -78,13 +80,13 @@ Requires: %{_cross_os}netdog
Requires: %{_cross_os}prairiedog
Requires: %{_cross_os}schnauzer
Requires: %{_cross_os}settings-committer
Requires: %{_cross_os}shimpei
Requires: %{_cross_os}signpost
Requires: %{_cross_os}storewolf
Requires: %{_cross_os}sundog
Requires: %{_cross_os}thar-be-settings
Requires: %{_cross_os}thar-be-updates
Requires: %{_cross_os}updog
Requires: %{_cross_os}shimpei

%if %{with aws_k8s_family}
Requires: %{_cross_os}pluto
Expand Down Expand Up @@ -280,6 +282,11 @@ Summary: Manages bootstrap-containers
%description -n %{_cross_os}bootstrap-containers
%{summary}.

%package -n %{_cross_os}bloodhound
Summary: Compliance check framework
%description -n %{_cross_os}bloodhound
%{summary}.

%prep
%setup -T -c
%cargo_prep
Expand Down Expand Up @@ -338,6 +345,7 @@ echo "** Output from non-static builds:"
-p prairiedog \
-p certdog \
-p shimpei \
-p bloodhound \
%{?with_ecs_runtime: -p ecs-settings-applier} \
%{?with_aws_platform: -p shibaken -p cfsignal} \
%{?with_aws_k8s_family: -p pluto} \
Expand All @@ -363,7 +371,7 @@ for p in \
migrator prairiedog certdog \
signpost updog metricdog logdog \
ghostdog bootstrap-containers \
shimpei \
shimpei bloodhound bottlerocket-checks \
%{?with_ecs_runtime: ecs-settings-applier} \
%{?with_aws_platform: shibaken cfsignal} \
%{?with_aws_k8s_family: pluto} \
Expand All @@ -373,6 +381,19 @@ for p in \
install -p -m 0755 ${HOME}/.cache/%{__cargo_target}/release/${p} %{buildroot}%{_cross_bindir}
done

# Add the bloodhound checker symlinks
mkdir -p %{buildroot}%{_cross_libexecdir}/cis-checks/bottlerocket
for p in \
br01020100 br01060000 br03040103 br03040203 \
br01010101 br01030100 br01040100 br01040200 br01040300 br01040400 \
br01050100 br01050200 br02010101 br03010100 br03020100 br03020200 \
br03020300 br03020400 br03020500 br03020600 br03020700 br03030100 \
br03040101 br03040102 br03040201 br03040202 br04010101 br04010200 \
; do
ln -rs %{buildroot}%{_cross_bindir}/bottlerocket-checks %{buildroot}%{_cross_libexecdir}/cis-checks/bottlerocket/${p}
done
install -m 0644 %{S:11} %{buildroot}%{_cross_libexecdir}/cis-checks/bottlerocket/metadata.json

for p in apiclient ; do
install -p -m 0755 ${HOME}/.cache/.static/%{__cargo_target_static}/release/${p} %{buildroot}%{_cross_bindir}
done
Expand Down Expand Up @@ -605,4 +626,9 @@ install -p -m 0644 %{S:121} %{buildroot}%{_cross_unitdir}
%{_cross_unitdir}/[email protected]
%{_cross_tmpfilesdir}/bootstrap-containers.conf

%files -n %{_cross_os}bloodhound
%{_cross_bindir}/bloodhound
%{_cross_bindir}/bottlerocket-checks
%{_cross_libexecdir}/cis-checks/bottlerocket

%changelog
13 changes: 13 additions & 0 deletions sources/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions sources/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ members = [
"api/migration/migrations/v1.14.0/aws-control-container-v0-7-2",
"api/migration/migrations/v1.14.0/public-control-container-v0-7-2",

"bloodhound",

"bottlerocket-release",

"bottlerocket-variant",
Expand Down
22 changes: 22 additions & 0 deletions sources/bloodhound/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "bloodhound"
version = "0.1.0"
authors = ["Sean McGinnis <[email protected]>"]
license = "Apache-2.0 OR MIT"
edition = "2021"
publish = false
# Don't rebuild crate just because of changes to README.
exclude = ["README.md"]

[dependencies]
argh = "0.1"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
walkdir = "2"

[dev-dependencies]
tempfile = "3"

[build-dependencies]
generate-readme = { version = "0.1", path = "../generate-readme" }
25 changes: 25 additions & 0 deletions sources/bloodhound/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# bloodhound

Current version: 0.1.0

## Introduction

Bloodhound is a command line orchestrator for running a set of compliance
checks. This can be used to run CIS benchmark compliance, though it can be extended
to perform any kind of check that adheres to the expected checker interface.

Checks are performed and their results are provided in an overall report.
The checker report can be written to a file, or viewed from stdout.
By default the report is provided in a human readable text format, but can also
be generated as JSON to make it easy to consume programmatically for integrating
into further compliance automation.

## Usage

Bloodhound is ultimately intended to be used through the Bottlerocket `apiclient`
interface.
If executing directly, run `bloodhound --help` for usage information.

## Colophon

This text was generated from `README.tpl` using [cargo-readme](https://crates.io/crates/cargo-readme), and includes the rustdoc from `src/main.rs`.
9 changes: 9 additions & 0 deletions sources/bloodhound/README.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# {{crate}}

Current version: {{version}}

{{readme}}

## Colophon

This text was generated from `README.tpl` using [cargo-readme](https://crates.io/crates/cargo-readme), and includes the rustdoc from `src/main.rs`.
3 changes: 3 additions & 0 deletions sources/bloodhound/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
generate_readme::from_main().unwrap();
}
51 changes: 51 additions & 0 deletions sources/bloodhound/src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use argh::FromArgs;
use std::str::FromStr;

pub const DEFAULT_CHECK_PATH: &str = "/usr/libexec/cis-checks/bottlerocket";

#[derive(Clone, Debug)]
pub enum Format {
Text,
Json,
}

impl FromStr for Format {
type Err = ();

fn from_str(value: &str) -> Result<Format, Self::Err> {
match value.to_ascii_lowercase().as_str() {
"text" => Ok(Format::Text),
"json" => Ok(Format::Json),
_ => Err(()),
}
}
}

fn str_to_format(value: &str) -> Result<Format, String> {
match Format::from_str(value) {
Ok(f) => Ok(f),
_ => Err("invalid format, options are 'text' or 'json'".to_string()),
}
}

#[derive(FromArgs, Debug)]
/// Command line arguments for the bloodhound program.
pub struct Arguments {
/// path to the directory containing checker binaries
#[argh(option, default = "DEFAULT_CHECK_PATH.to_string()", short = 'c')]
pub check_dir: String,
/// format of the output
#[argh(
option,
default = "Format::Text",
from_str_fn(str_to_format),
short = 'f'
)]
pub format: Format,
/// the CIS benchmark compliance level to check
#[argh(option, default = "1", short = 'l')]
pub level: u8,
/// write output to a file at given path [default: stdout]
#[argh(option, short = 'o')]
pub output: Option<String>,
}
Loading

0 comments on commit a4a1039

Please sign in to comment.