SlideShare a Scribd company logo
1 of 155
Chef InSpec
Jumpstart
Introductions
Introductions
Larry
Eichenbaum
larryebaum@chef.io
@larryebaum
larryebaum
larryebaum
Alan
Thatcher
athatcher@chef.io
@alntht
alanwthatcher
alanwthatcher
Introductions
Daniel
Flores -Montanez
James
Massardo
dmontanez@chef.io
@danf425
danf425
danf425
jmassardo@chef.io
@jamesmassardo
jamesmassard
o
jmassardo
About you
• Hands up if you have Chef InSpec experience
About you
• Hands up if you have Chef InSpec experience
• Keep it up if you have Chef Infra experience
About you
• Hands up if you have Chef InSpec experience
• Keep it up if you have Chef Infra experience
• Keep it up if you have at least 1 years experience
About you
• Hands up if you have Chef InSpec experience
• Keep it up if you have Chef Infra experience
• Keep it up if you have at least 1 years experience
• Keep it up if you have at least 2 years experience
About you
• Hands up if you have Chef InSpec experience
• Keep it up if you have Chef Infra experience
• Keep it up if you have at least 1 years experience
• Keep it up if you have at least 2 years experience
• Keep it up if you have at least 3 years experience
About you
• Hands up if you have Chef InSpec experience
• Keep it up if you have Chef Infra experience
• Keep it up if you have at least 1 years experience
• Keep it up if you have at least 2 years experience
• Keep it up if you have at least 3 years experience
• Well, you’ll all have at least one day’s experience
Agenda
• Introduction
• Introduction to Automated Testing
• Chef InSpec and Integration
Testing
• Chef InSpec Profiles
• Remote Scans
• Chef InSpec DSL - Deeper Dive
• Chef InSpec and Cloud
Infrastructure
• OSS Profiles
• Chef InSpec DSL and Compliance
Regulations
• Chef InSpec and Chef Automate
• Further Resources
Expectations
• This class focuses on Chef InSpec and assumes no previous
experience
• You will leave this class with the ability to
o Explain and create Chef InSpec profiles and controls
o Invoke Chef InSpec on local and remote target nodes, and cloud
infrastructure
o Use Chef Automate to scan your whole environment
o Run Chef to remediate non-compliances issues
Task Slides
If you see this on the top of a slide,
Then that’s your cue to get with the typey typey
TASK
Task: Create Control File aws.rb and add
Controls
TASK
$ ./command
output
File to Edit/Create on InSpec Workstation
Template
TASK
/filepath/file.rb
File contents here.
This template tells you to create or edit the specified file on your Workstation
What’s next…?
In the next section we’ll briefly look at types of automated testing, the
reasons for it, and the tooling used
Introduction to
Automated Testing
Objectives
➢ After completing this lesson you will be able to:
o Discuss the types of testing that are prevalent in our industry
o Explain why automated testing is important
o Explain when each type of test gets run, and why
o Appreciate the distinction, and similarity, between integration tests and
compliance tests
o Explain what Chef InSpec is
Types of Testing
Code Correctness Unit Testing Integration Testing Compliance Scanning
● Foodcritic
● Cookstyle
(Rubocop)
● ChefSpec ● Test Kitchen
● Chef InSpec
● Chef Automate
● Chef InSpec
Is the code syntactically
correct & does it follow
style guidelines?
Do individual pieces of
code do what they’re
supposed to do?
Does the full application
work end to end?
Is the application (&
infrastructure it runs on)
secure and does it meet
regulations?
Historical Timeline
Static
Code
Analysis
Unit
Testing
Compliance
Scanning
Integration
Testing
Compliance
Scanning
Development Production
Timeline
Many types of tests
Is web server listening on tcp/80?
Is web server delivering the correct content?
Using TLS or SSL?
SSH v2 Configured?
User ‘foo’ has read no write access to /myapp?
User ‘foo’ exists?
User ‘foo’ has read access to /myapp?
User ‘foo’ does not have sudo access?
User ‘foo’ does not have read access to /etc?
SSH v1 Configured?
Many types of tests
Is web server listening on tcp/80?
Is web server delivering the correct content?
Using TLS or SSL?
SSH v2 Configured?
User ‘foo’ has read no write access to /myapp?
User ‘foo’ exists?
User ‘foo’ has read access to /myapp?
User ‘foo’ does not have sudo access?
User ‘foo’ does not have read access to /etc?
SSH v1 Configured?
• There is zero consistency when testing
infrastructure
o All configuration files are proprietary
o All commands have different syntaxes &
command line switches
o They’re platform specific (RHEL, Debian,
Windows, …)
Introducing...
What is Chef InSpec
• Chef InSpec provides consistent DSL that is platform agnostic to
check status of any component:
o packages
o files
o users
o AWS IAM users
o AWS S3 buckets
o …
• Complex implementation code abstracted out
• Many Chef InSpec profiles exist in the community, and Chef
provides profiles matching specific compliance regulations
Bash vs Chef InSpec for testing
For example, SSH supports two different protocol versions. The
original version, SSHv1, was subject to a number of security issues.
Please use SSHv2 instead to avoid these.
Chef InSpec for any infrastructure
describe port(22) do
its('processes') { should include 'sshd' }
its('protocols') { should include 'tcp' }
its('addresses') { should include '0.0.0.0' }
end
• No agent, nor Ruby, required on target node
• Chef InSpec tests your servers’ actual state by executing the appropriate
command locally via SSH, via WinRM, via Docker API and so on
Chef InSpec for AWS
describe aws_iam_user(name: 'test_user') do
it { should have_mfa_enabled }
it { should have_console_password }
end
Chef InSpec for Azure
describe azure_virtual_machine(group_name: 'InSpec-Azure', name: 'Linux-Internal-VM') do
its('size') { should eq 'Standard_DS2_v2' }
its('location') { should eq 'westeurope' }
its('admin_settings') { should eq 'azure' }
end
Chef InSpec is cross platform
• One language • Chef InSpec for Windows
Chef InSpec is agentless
• Chef InSpec was born out of Rspec and ServerSpec
• No agent needs to be installed on the target node
• Requires
o SSH access for Linux nodes
o WinRM access for Windows
Integration (functional) vs Compliance (security)
Tests
Is web server listening on tcp/80? Integration Test
Is web server delivering the correct content? Integration Test
Using TLS or SSL? Compliance
Test
SSH v2 Configured? Integration
Test / Compliance Test
User ‘foo’ has read no write access to /myapp? Compliance Test
User ‘foo’ exists?
Integration Test
User ‘foo’ has read access to /myapp? Integration Test
User ‘foo’ does not have sudo access? Compliance Test
User ‘foo’ does not have read access to /etc? Compliance Test
SSH v1 Configured? Compliance
Integration (functional) vs Compliance (security)
Tests
Is web server listening on tcp/80? Integration Test
Is web server delivering the correct content? Integration Test
User ‘foo’ exists?
Integration Test
User ‘foo’ has read access to /myapp? Integration Test
SSH v2 Configured? Integration
Test / Compliance Test
Using TLS or SSL? Compliance
Test
User ‘foo’ has read no write access to /myapp? Compliance Test
User ‘foo’ does not have sudo access? Compliance Test
User ‘foo’ does not have read access to /etc? Compliance Test
SSH v1 Configured? Compliance
Integration Tests
(Does the thing work?)
● Tests usually
maintained within a
cookbook
● Invoked by Test
Kitchen
Compliance Scans
(Is the thing secure?)
● Tests collated in
InSpec profiles and
maintained
externally, e.g.,
GitHub,
Compliance server
● Invoked by ‘inspec’
cli or from Chef
Automate
Integration AND Compliance Tests — Two Separate Use
Cases
Use Case 1
Cookbook Integration Test
Is web server listening on tcp/80?
Is web server delivering the correct content?
User ‘foo’ exists?
User ‘foo’ has read access to /myapp?
We’ll look at this use case
briefly initially
Use Case 2
Server Compliance Scan
Using TLS or SSL?
User ‘foo’ has read no write access to /myapp?
User ‘foo’ does not have sudo access?
User ‘foo’ does not have read access to /etc?
SSH v1 Configured?
We’ll spend most of the workshop
looking at this use case
SSH v2
Configured?
Chef InSpec Integration vs Compliance
Testing
Same language — two distinct use cases
Chef InSpec Rules Integration tests Compliance scan
Types of Rules Governed by the application
(cookbook) requirements
Generic rules defined by industry security
requirements (not governed by the
application requirements)
Location of Rules Shipped with a cookbook Stored centrally (Compliance server,
GitHub)
Invocation Use Test Kitchen to provision a
sandbox environment to perform
functional tests of the cookbook
Use Chef InSpec DSL or Chef Automate to
perform compliance tests during
development, or in production
Key Takeaways
Chef InSpec has two separate very different use cases
1. Integration testing of Chef cookbooks within the Test Kitchen framework, and
2. Scanning your server estate for compliance reasons
What’s next… ?
In the next section we’ll get ourselves set up with a remote workstation to play
with...
Let's Get Everyone a Workstation
https://bit.ly/student_ips
Find your Workstation IP Address
TASK
Task: Log in to your workstation
The authenticity of host '12.34.56.78 (12.34.56.78)' can't be
established.ECDSA key fingerprint is
SHA256:GpuZBeC1yoO64HsyYseMnd/DRJSj0k/JqljtGX0aU9M.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '12.34.56.78' (ECDSA) to the list of
known hosts. chef@12.34.56.78's password: **********
Password = 123Chef321
$ ssh chef@12.34.56.78
TASK
Task: Ensure you’re in the correct VM
$ touch firstname-lastname
$ ls -l
<firstname-lastname> automate-credential.toml config.toml
chef-automate cookbooks deploy-chef-
automate.sh profiles
TASK
Everyone just seeing their own name?
Task: Let's check software versions
$ which inspec
/usr/bin/inspec
TASK
$ which chef
/usr/bin/chef
$ inspec version
3.0.52
$ chef --version
Chef Development Kit Version: 3.6.0
chef-client version: 14.7.17
delivery version: master (5234f9fda9629d727169c37882d026dec9ed7d00)
berks version: 7.0.7
kitchen version: 1.23.2
inspec version: 3.0.52
Chef InSpec & Integration Testing
Use Case 1: Chef InSpec and
Integration Testing
Chef InSpec and TDD
Objectives
• After completing this lesson you will be able to:
o Navigate the Chef InSpec documentation
o Write custom Chef InSpec controls
o Use the “:skip” directive to skip tests
o Use Chef InSpec along with Test Kitchen for integration testing
o Read and understand Chef InSpec output
Chef InSpec and TDD
• We discussed earlier how Chef InSpec can be used for integration
testing as part of the CI/CD pipeline
• We will explore this in more detail using a Test Driven
Development (TDD) approach by way of example
• Our scenario is we need a web server to deliver some specific
content
Problem: We need a web server
• We will deploy this with Chef
using a TDD approach, i.e.,
o Write a test for your code
o Execute the test and watch it fail
o Write the code
o Rerun the test and watch it pass
We need to create a Nginx web server
What tests need to pass?
• We will be successful if http://localhost returns:
o 200 ok status code
o The content “inspec jumpstart”
o The correct content-Type header
What tests need to pass?
What tests need to pass?
• We will be successful if http://localhost returns:
o 200 ok status code
o The content “inspec jumpstart”
o The correct content-Type header
What tests need to pass?
Let’s look at the docs
What tests need to pass?
• We will be successful if http://localhost returns:
o 200 ok status code
o The content “inspec jumpstart”
o The correct content-Type header
Task: Browse to https://inspec.io
TASK
Task: Browse to https://inspec.io
TASK
Task: View the ‘http’ InSpec resource
TASK
Task: Template integration tests are
templated
We’ve pre-created the nginx cookbook
Note there is nothing in the recipe yet, so
nothing will be configured on the system
Using Chef is a workshop in itself - here
we’ll concentrate on InSpec
$ tree cookbooks/mynginx
TASK
Task: Append new InSpec test to
default_test.rb
NOTE: nano editor can be used instead of vi… $ nano ~/cookbooks/...
…
describe http('http://localhost', enable_remote_worker: true) do
its('status') { should cmp 200 }
its('body') { should cmp 'Inspec Jumpstart' }
its('headers.Content-Type') { should cmp 'text/html' }
end
What does this code mean?
cheat sheet
https://bit.ly/default_test
$ vi ~/cookbooks/mynginx/test/smoke/default/default_test.rb
TASK
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Control Contains
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Control Contains
- a describe
statement
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Control Contains
- a describe
statement
- a resource
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Control Contains
- a describe
statement
- a resource
- an optional
argument
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Control Contains
- a describe
statement
- a resource
- an optional
argument
- an optional
parameter
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Control Contains
- a describe
statement
- a resource
- an optional
argument
- an optional
parameter
- a do …. end block
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Control Contains
- a describe
statement
- a resource
- an optional
argument
- an optional
parameter
- a do …. end block
- one or more tests
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Test Contains
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Test Contains:
- one or more it
and/or its
statement
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Test Contains:
- one or more it
and/or its
statement
- an optional
property (its
statement)
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Test Contains:
- one or more it
and/or its
statement
- an optional
property (its
statement)
- each with a
condition
statement
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Test Contains:
- one or more it
and/or its
statement
- an optional
property (its
statement)
- each with a
condition
statement
Each Condition
Contains:
- a condition
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Test Contains:
- one or more it
and/or its
statement
- an optional
property (its
statement)
- each with a
condition
statement
Each Condition
Contains:
- a condition
- a matcher
Anatomy of a Chef InSpec test
describe http(‘http://localhost’, enable_remote_worker: true) do
its(‘status’) { should cmp 200 }
its(’body’) { should cmp ‘Inspec Jumpstart’ }
its(‘headers-Content-type’) { should cmp ‘text/html’ }
end
Each Test Contains:
- one or more it
and/or its
statement
- an optional
property (its
statement)
- each with a
condition
statement
Each Condition
Contains:
- a condition
- a matcher
- an expected result
Matchers
➢ Each Chef InSpec resource has a number of relevant matchers
you can use to check the status of that item
➢ For example, the file resource allows you to test the status of any
file (or directory) and as such relevant matchers are:
- exists
- be_readable
- content
- etc
➢ Whereas the package resource applicable matchers are
- version
- be_installed
- etc
Note skipped tests
Tests can be defined but skipped allowing for placeholders
$ cat ~/cookbooks/mynginx/test/smoke/default/default_test.rb
Problem: We need a web server
➢ We will deploy this with Chef
using a TDD approach, i.e.,
○ Write a test for your code
○ Execute the test and watch it fail
○ Write the code
○ Rerun the test and watch it pass
We need to create a web server
Introduction to Test Kitchen
➢ Now that we have created our tests, the second step is to execute
it and watch it fail
➢ We will use Test Kitchen to test our code
➢ Test Kitchen provides a harness to execute code on ephemeral
infrastructure - forms part of a CI/CD pipeline
Task: Navigate into cookbooks/mynginx
directory
We’ll remain in this directory for the remainder of this section
$ cd ~/cookbooks/mynginx
TASK
Task: View Test Kitchen Config file
This configuration file tells Test Kitchen to:
- spin up a centos-6.7 docker container (via ‘dokken’ driver)
- use Chef Zero to run this recipe - recipe[mynginx:default]
- then use InSpec to run the tests specified in test/smoke/default
$ cat .kitchen.yml
TASK
Task: Run Test Kitchen
kitchen verify
- spin up a centos-6.7 docker container
- use Chef Zero to run this recipe - recipe[mynginx:default] (recipe currently blank so does nothing)
- then use InSpec to run the tests specified in test/smoke/default
$ kitchen verify
TASK
Problem: We need a web server
➢ We will deploy this with Chef
using a TDD approach, i.e.,
○ Write a test for your code
○ Execute the test and watch it fail
○ Write the code
○ Rerun the test and watch it pass
We need to create a web server
Task: Create your recipe
include_recipe 'nginx::repo'
package 'nginx' do
action :install
end
remote_file '/usr/share/nginx/html/index.html' do
source 'https://inspec-jumpstart-2019.s3.amazonaws.com/web01.html'
end
service 'nginx' do
supports status: true, restart: true, reload: true
action [ :enable, :start ]
end
$ vi ~/cookbooks/mynginx/recipes/default.rb
TASK
cheat sheet
https://bit.ly/recipe_default
Test: run Test Kitchen
kitchen converge
- provisions a new server (or container in our case)
- installs Chef
- runs the recipe in the .kitchen.yml file
$ kitchen converge
TASK
Problem: We need a web server
➢ We will deploy this with Chef
using a TDD approach, i.e.,
○ Write a test for your code
○ Execute the test and watch it fail
○ Write the code
○ Rerun the test and watch it pass
We need to create a web server
Test: run Test Kitchen again
$ kitchen verify
TASK
Problem: We need a web server
➢ We will deploy this with Chef
using a TDD approach, i.e.,
○ Write a test for your code
○ Execute the test and watch it fail
○ Write the code
○ Rerun the test and watch it pass
We need to create a web server
Chef InSpec and TDD
➢ The key takeaway here is the Chef InSpec plugin for Test Kitchen
can be a valuable tool in the test driven development of Chef
cookbooks
➢ In that workflow the Chef InSpec controls are in control files
shipped along with the cookbook itself, as follows:
~/cookbooks/ <cookbook name>/test/smoke/default/control-filename_test.rb
➢ However, Chef InSpec is a standalone tool and can be used for
more general testing purposes, including compliance scanning
➢ Note: we will focus on using Chef InSpec for compliance scanning
for the remainder of the class
Key Takeaways
One very specific use case for Chef InSpec is for integration testing
of Chef cookbooks within the Test Kitchen framework
In this use case the Chef InSpec tests are shipped as .rb files
within the cookbook
In the next section we’ll look at the Chef InSpec tool itself,
creating Chef InSpec profiles, and the more general use case of
scanning infrastructure for compliance
What’s Next?
Chef InSpec CLI, Profiles and
Compliance Scanning
Introduction to Chef InSpec CLI and creating and executing profiles
Objectives
➢ After completing this lesson you will be able to
➢ Describe Chef InSpec as a standalone tool
➢ Create & Navigate Chef InSpec profiles
➢ Identify the contents of an Chef InSpec profile
➢ Explain the structure of an Chef InSpec profile
➢ Invoke Chef InSpec tests on a local host
➢ Use formatters to format the output of an Chef InSpec test as
JSON, HTML, etc
Chef InSpec as a Standalone Tool
➢ We've seen how Chef InSpec controls may be shipped within Chef
cookbooks & invoked using Test Kitchen
○ Integration testing of Chef cookbooks use case
➢ For the remainder of the class we'll look at Chef InSpec as a
standalone tool to scan 1+ nodes for compliance using custom or
industry standard controls
○ This primary use case is unrelated to Test Kitchen and Chef – apart from
remediation cookbooks if necessary
Chef InSpec code is maintained in 'Profiles'
Chef InSpec organizes controls into versioned 'profiles'
A profile is a standalone structure containing
● control files
● documentation
● extension libraries
● dependencies
Lets look at profiles by way of an example
Problem Statement
➢ We need to ensure our web node is using SSH2 only and not
SSH1, as SSH1 has security vulnerabilities
➢ We will use InSpec to ensure the node is compliant
Problem: SSH v1 is Insecure
We need to ensure our web node is using SSH2 only and not SSH1,
as SSH1 has security vulnerabilities
The tasks are
1. Create a skeleton Chef InSpec profile for SSH
2. Review the technical requirements and create the Chef InSpec
control including the actual test
3. Execute the Chef InSpec profile to determine current system state
4. Correct the state and rerun Chef InSpec check
Chef InSpec Command Line Interface
➢ In this section we will use the Chef InSpec command line interface
(CLI) to help us create profiles and run audit tests against targets
➢ The Chef InSpec CLI commands can run audit tests against targets
using SSH, WinRM, locally, or on Docker containers
Chef InSpec Command Line Interface
➢ We'll be using inspec init, inspec check and inspec exec
➢ inspec check verifies the compliance profile code that you write
➢ inspec exec will run the tests against a system
Note: the Chef InSpec tests we executed in the previous section (using
Test Kitchen) were tied to the specific cookbook, and were used to
verify that cookbook
inspec exec can be used to scan for compliance – Test Kitchen isn't used
Task: Execute the 'inspec' command
● Chef InSpec has its own CLI for creating and executing profiles, amongst other things
● We will look more at the inspec command later – for now we'll use inspec init to create our new
profile
TASK
$ inspec
Commands:
inspec archive PATH # archive a profile to tar.gz (default) or zip
inspec artifact SUBCOMMAND ... # Sign, verify and install artifacts
inspec check PATH # verify all tests at the specified PATH
inspec compliance SUBCOMMAND ... # Chef Compliance commands
inspec detect # detect the target OS
inspec env # Output shell-appropriate completion configuration
inspec exec PATHS # run all test files at the specified PATH.
inspec habitat SUBCOMMAND ... # Commands for InSpec + Habitat Integration
inspec help [COMMAND] # Describe available commands or one specific command
inspec init TEMPLATE ... # Scaffolds a new project
inspec json PATH # read all tests in PATH and generate a JSON summary
inspec shell # open an interactive debugging shell
...
Task: Create an InSpec Profile
TASK
$ inspec init profile ~/profiles/webnode_profile
Create new profile at /home/chef/profiles/webnode_profile
* Create file README.md
* Create directory controls
* Create file controls/example.rb
* Create file inspec.yml
* Create directory libraries
Task: Create an InSpec Profile
$ inspec init profile ~/profiles/webnode_profile
Create new profile at /home/chef/profiles/webnode_profile
* Create file README.md
* Create directory controls
* Create file controls/example.rb
* Create file inspec.yml
* Create directory libraries
Use the
'inspec'
command
To initialise (i.e.
create) a profile
In the '~/profiles'
directory
Called
'webnode_profile'
TASK
Task: View webnode_profile InSpec Profile
TASK
$ tree ~/profiles/webnode_profile
/home/chef/profiles/webnode_profile/
├── controls
│ └── example.rb
├── inspec.yml
└── libraries
└── README.md
Chef InSpec Profile akin to Chef Cookbooks
Spot the resemblance?
profiles/webnode_profile
│
├── inspec.yml
│
├── README.md
│
├── controls
│ └── example.rb
│
├── libraries
│
└── files
cookbooks/webnode_cookbook
│
├── metadata.rb
│
├── README.md
│
├── recipes
│ └── default.rb
│
├── libraries
│
└── files
Anatomy of a Chef InSpec Profile
profiles/webnode_profile
│
├── inspec.yml
│
├── README.md
│
├── controls
│ └── example.rb
│
├── libraries
│
└── files
A Chef InSpec profile contains
● inspec.yml which includes the profile
description, dependencies, versioning, etc
The inspec.yml file
For those familiar with Chef, 'inspec.yml' is akin to 'metadata.rb'
TASK
$ cat ~/profiles/webnode_profile/inspec.yml
name: webnode_profile
title: InSpec Profile
maintainer: The Authors
copyright: The Authors
copyright_email: you@example.com
license: Apache-2.0
summary: An InSpec Compliance Profile
version: 0.1.0
supports:
platform: os
Anatomy of a Chef InSpec Profile
profiles/webnode_profile
│
├── inspec.yml
│
├── README.md
│
├── controls
│ └── example.rb
│
├── libraries
│
└── files
A Chef InSpec profile contains
● inspec.yml
● README.md
● controls directory in which all tests are
located. An example.rb file is stubbed with
sample controls
Sample Controls File
TASK
$ cat ~/profiles/webnode_profile/controls/example.rb
# encoding: utf-8
# copyright: 2018, The Authors
title 'sample section'
# you can also use plain tests
describe file('/tmp') do
it { should be_directory }
end
# you add controls here
control 'tmp-1.0' do # A unique ID for this control
impact 0.7 # The criticality, if this control fails.
title 'Create /tmp directory' # A human-readable title
desc 'An optional description...'
describe file('/tmp') do # The actual test
it { should be_directory }
end
end
Anatomy of a Chef InSpec Profile
profiles/webnode_profile
│
├── inspec.yml
│
├── README.md
│
├── controls
│ └── example.rb
│
├── libraries
│
└── files
A Chef InSpec profile contains
● inspec.yml
● README.md
● controls
● optional libraries directory in which optional
InSpec resource extensions are located
Anatomy of a Chef InSpec Profile
profiles/webnode_profile
│
├── inspec.yml
│
├── README.md
│
├── controls
│ └── example.rb
│
├── libraries
│
└── files
A Chef InSpec profile contains
● inspec.yml
● README.md
● Controls
● libraries
● optional files directory for additional files that
a profile can access
Problem: SSH v1 is Insecure
We need to ensure our web node is using SSH2 only and not SSH1,
as SSH1 has security vulnerabilities.
The tasks are
✓ Create a skeleton Chef InSpec profile for SSH
2. Review the technical requirements and create the Chef InSpec
control including the actual test
3. Execute the Chef InSpec profile to determine current system state
4. Correct the state and rerun Chef InSpec check
Back to our SSH problem - which resource shall we
use?
➢ We need to ensure our web node is using SSH2 only and not
SSH1, as SSH1 has security vulnerabilities.
➢ We'll use the ssh_config resource
Task: Create a new controls file ssh.rb within our profile
TASK
$ touch ~/profiles/webnode_profile/controls/ssh.rb
Task: Include some controls from OSS profile in our profile
TASK
$ vi ~/profiles/webnode_profile/controls/ssh.rb
title 'ssh'
control 'sshv2' do
impact 0.7
title 'Check SSH Version'
desc 'Only SSH version 2 should be enabled'
describe ssh_config do
its('Protocol') { should cmp 2 }
end
end cheat sheet
https://bit.ly/controls_ssh
Control Files
A profile contains one or more control
files, each containing a number of tests
• A control block contains at least
one describe block, but may
contain as many as required
• A describe block contains at least
one test
# encoding: utf-8
# copyright: 2018, The Authors
title 'sample section'
describe file('/tmp') do
it { should be_directory }
end
control 'tmp-1.0' do
tag 'tmp',
tag dir: '/tmp'
ref 'NSA-RH6 - Section 3.5.2.1'
impact 0.7
title 'Create /tmp directory'
desc 'An optional description...'
describe file('/tmp') do
it { should be_directory }
end
end
The Anatomy of a Control File
A control file within a profile contains
• Some boilerplate information and a title
# encoding: utf-8
# copyright: 2018, The Authors
title 'sample section'
describe file('/tmp') do
it { should be_directory }
end
control 'tmp-1.0' do
tag 'tmp',
tag dir: '/tmp'
ref 'NSA-RH6 - Section 3.5.2.1'
impact 0.7
title 'Create /tmp directory'
desc 'An optional description...'
describe file('/tmp') do
it { should be_directory }
end
end
The Anatomy of a Control File
A control file within a profile contains
• Some boilerplate information and a title
• One or more describe statements, each
containing one or more tests
# encoding: utf-8
# copyright: 2018, The Authors
title 'sample section'
describe file('/tmp') do
it { should be_directory }
end
control 'tmp-1.0' do
tag 'tmp',
tag dir: '/tmp'
ref 'NSA-RH6 - Section 3.5.2.1'
impact 0.7
title 'Create /tmp directory'
desc 'An optional description...'
describe file('/tmp') do
it { should be_directory }
end
end
The Anatomy of a Control File
A control file within a profile contains
• Some boilerplate information and a title
• One or more describe statements, each
containing one or more tests
• describe statements may be grouped
within control statements
# encoding: utf-8
# copyright: 2018, The Authors
title 'sample section'
describe file('/tmp') do
it { should be_directory }
end
control 'tmp-1.0' do
tag 'tmp',
tag dir: '/tmp'
ref 'NSA-RH6 - Section 3.5.2.1'
impact 0.7
title 'Create /tmp directory'
desc 'An optional description...'
describe file('/tmp') do
it { should be_directory }
end
end
The Anatomy of a Control File
A control file within a profile contains
• Some boilerplate information and a title
• One or more describe statements, each
containing one or more tests
• describe statements may be grouped
within control statements
• control statements may include extra
metadata defining for example
o a unique ID for this control
o the criticality, if this control fails.
o a human-readable title and
description
o reference documentation
# encoding: utf-8
# copyright: 2018, The Authors
title 'sample section'
describe file('/tmp') do
it { should be_directory }
end
control 'tmp-1.0' do
tag 'tmp',
tag dir: '/tmp'
ref 'NSA-RH6 - Section 3.5.2.1'
impact 0.7
title 'Create /tmp directory'
desc 'An optional description...'
describe file('/tmp') do
it { should be_directory }
end
end
Impact
➢ Impact is a measure of the importance of the compliance results
➢ The value ranges are:
○ 0.0 to <0.4 - these are controls with minor criticality
○ 0.4 to <0.7 - these are controls with major criticality
○ 0.7 to 1.0 - these are critical controls
➢ The impact value is configurable for each control
Chef InSpec Code Metadata
➢ Chef InSpec 'describe' statements abstract out the test implementation detail
➢ Compliance code contains further metadata pertaining to the compliance rule
Compliance DSL includes additional metadata around 'describe' statementsScripting Tools are platform specific
InSpec within a cookbook
Task: Update the profile's version number to 0.2.0
TASK
$ vi ~/profiles/webnode_profile/inspec.yml
name: webnode_profile
title: InSpec Profile
maintainer: The Authors
copyright: The Authors
copyright_email: you@example.com
license: Apache-2.0
summary: An InSpec Compliance Profile
version: 0.2.0
Task: Run 'inspec check' to check if profile is syntactically
correct
TASK
$ inspec check ~/profiles/webnode_profile
Location: /home/chef/profiles/webnode_profile
Profile: webnode_profile
Controls: 3
Timestamp: 2019-04-11T13:45:02+00:00
Valid: true
No errors or warnings
Problem: SSH v1 is Insecure
We need to ensure our web node is using SSH2 only and not SSH1,
as SSH1 has security vulnerabilities.
The tasks are
✓ Create a skeleton Chef InSpec profile for SSH
✓ Review the technical requirements and create the Chef InSpec
control including the actual test
3. Execute the Chef InSpec profile to determine current system state
4. Correct the state and rerun Chef InSpec check
Executing our code
We now need to execute our Chef InSpec profile
We will use inspec exec command to do this
Task: Run profile locally with Chef InSpec
command
TASK
$ inspec exec ~/profiles/webnode_profile
Profile: InSpec Profile (webnode_profile)
Version: 0.2.0
Target: local://
✔ tmp-1.0: Create /tmp directory
✔ File /tmp should be directory
× sshv2: Check SSH Version
× SSHD Configuration Protocol should cmp == 2
expected: 2
got: nil
(compared using `cmp` matcher)
File /tmp
✔ should be directory
Profile Summary: 1 successful control, 1 control failure, 0 controls skipped
Test Summary: 2 successful, 1 failure, 0 skipped
Our test failed
Why did it fail?
Why did our test fail?
# Protocol 2
It seems 'Protocol 2' line is commented out of our config file
Correcting it manually would not make sense, especially if you have
100's of nodes, so you would normally use Chef to configure this
But we'll just fix it manually for now
TASK
$ sudo grep 'Protocol' /etc/ssh/ssh_config
Problem: SSH v1 is Insecure
We need to ensure our web node is using SSH2 only and not SSH1,
as SSH1 has security vulnerabilities.
The tasks are
✓ Create a skeleton Chef InSpec profile for SSH
✓ Review the technical requirements and create the Chef InSpec
control including the actual test
✓ Execute the Chef InSpec profile to determine current system state
4. Correct the state and rerun Chef InSpec check
Task: Update the SSH Config File
...
# IdentityFile ~/.ssh/id_ecdsa
# IdentityFile ~/.ssh/id_ed25519
# Port 22
Protocol 2
# Cipher 3des
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
...
Manually update the SSH configuration file - uncomment the line to
enable SSH2 (line 42)
Usually this would be done by Chef
TASK
$ sudo vi /etc/ssh/ssh_config
Remember Test-Driven Development?
1. Write a test for your code
2. Execute the test and watch it fail
3. Write the code
4. Rerun the test and watch it pass
5. Repeat steps 1 through 4
Task: Again run profile locally with InSpec
command
Profile: InSpec Profile (webnode_profile)
Version: 0.2.0
Target: local://
✔ tmp-1.0: Create /tmp directory
✔ File /tmp should be directory
✔ sshv2: Check SSH Version
✔ SSH Configuration Protocol should cmp == 2
File /tmp
✔ should be directory
Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped
Test Summary: 3 successful, 0 failures, 0 skipped
TASK
$ inspec exec ~/profiles/webnode_profile
Problem: SSH v1 is Insecure
We need to ensure our web node is using SSH2 only and not SSH1,
as SSH1 has security vulnerabilities.
The tasks are
✓ Create a skeleton Chef InSpec profile for SSH
✓ Review the technical requirements and create the Chef InSpec
control including the actual test
✓ Execute the Chef InSpec profile to determine current system state
✓ Correct the state and rerun Chef InSpec check
Executing specific controls files
➢ In some circumstances you may only wish to run those tests in a
specific control file in the profile
Task: Run just the controls in 'ssh.rb'
Profile: tests from profiles/webnode_profile/controls/ssh.rb (tests
from profiles.webnode_profile.controls.ssh.rb)
Version: (not specified)
Target: local://
✔ sshv2: Check SSH Version
✔ SSH Configuration Protocol should cmp == 2
Profile Summary: 1 successful control, 0 control failures, 0 controls
skipped
Test Summary: 1 successful, 0 failures, 0 skipped
TASK
$ inspec exec ~/profiles/webnode_profile/controls/ssh.rb
Executing specific controls
➢ In some circumstances you may wish to restrict the tests run to
specific controls within the profile
➢ In some circumstances you may only wish to run those tests in a
specific control file in the profile
● control tmp-1.0 in our example.rb control file
● control sshv2 in our ssh.rb controls file, and
control 'tmp-1.0' do
impact 0.7
title 'Create /tmp directory'
...
control 'sshv2' do
impact 0.7
title 'Check SSH Version'
...
Task: Use the --controls command line switch to run individual
controls
Profile: InSpec Profile (webnode_profile)
Version: 0.2.0
Target: local://
✔ tmp-1.0: Create /tmp directory
✔ File /tmp should be directory
Profile Summary: 1 successful controls, 0 control failures, 0 controls
skipped
Test Summary: 1 successful, 0 failures, 0 skipped
TASK
$ inspec exec ~/profiles/webnode_profile --controls tmp-1.0
Executing specific controls
➢ By default the inspec command returns results in human readable
format
➢ But you can use --reporter= flag to output in a number of other
formats, including
○ Documentation
○ Html
○ Progress
○ Json
○ Json-min
○ Json-rspec
○ Junit
○ cli (default)
➢ We'll look at a number of examples
Task: Format the Output as JSON
...
"id": "controls/nginx.rb"
}
],
"license": "Apache-2.0",
"maintainer": "The Authors",
"name": "webnode_profile",
"sha256": "faa3f30f9c0d14962280ce21de110508d3c43ab572a1cc529d3b6db9fac0415b",
"summary": "An InSpec Compliance Profile",
"supports": [],
"title": "InSpec Profile",
"version": "0.2.0"
}
],
"statistics": {
"duration": 0.013274985
},
"version": "1.51.21"
}
$ inspec exec ~/profiles/webnode_profile --reporter=json | python -m json.tool
TASK
Optional Task : Get a summary of the results using json-min
formatter
{
"controls": [
{
"code_desc": "SSH Configuration Protocol should cmp == 2",
"id": "sshv2",
"profile_id": "webnode_profile",
"profile_sha256": "faa3f30f9c0d14962280ce21de110508d3c43ab572a1cc529d3b6db9fac0415b",
"status": "passed"
}
],
"statistics": {
"duration": 0.001906135
},
"version": "1.51.21"
}
Try the other formatters
● documentation
● html
● progress
● json
● json-min
● json-rspec
● junit
● cli
$ inspec exec ~/profiles/webnode_profile --reporter=json-min | python -m json.tool
TASK
Optional Task: html formatter returns standard rspec output
...
<div id="div_group_2" class="example_group passed">
<dl style="margin-left: 15px;">
<dt id="example_group_2" class="passed">Protocol</dt>
<script type="text/javascript">moveProgressBar('100.0');</script>
<dd class="example passed"><span class="passed_spec_name">should cmp == 2</span><span class='duration'>0.00086s</span></dd>
</dl>
</div>
<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>0.00335
seconds</strong>";</script>
<script type="text/javascript">document.getElementById('totals').innerHTML = "1 example, 0 failures";</script>
</div>
</div>
</body>
</html>
$ inspec exec ~/profiles/webnode_profile --reporter=html
TASK
Optional Task : Format the Output as JUnit
<?xml version='1.0'?>
<testsuites>
<testsuite name='webnode_profile' tests='1' failed='0'>
<testcase name='SSH Configuration Protocol should cmp == 2'
classname='webnode_profile.sshv2' time='0.000727831'/>
</testsuite>
</testsuites>
$ inspec exec ~/profiles/webnode_profile --reporter=junit
TASK
Takeaways
➢ A key primary Chef InSpec use case is for scanning machines for
regulatory compliance
➢ Used as such, Chef InSpec is used as a standalone tool (not within
Test Kitchen) and tests are maintained within Chef InSpec Profiles,
and executed using 'inspec exec' command
What’s next…?
In the next section we'll look at invoking Chef InSpec compliance
tests on remote hosts
Running Remote Scans
Running your local profiles on a remote target
Objectives
➢ After completing this lesson you will be able to:
○ Execute scans on a remote VM and Docker container
Running Chef InSpec locally and remote
Up until now we’ve been running InSpec profiles on localhost
But the real power of InSpec is the ability to run it on remote targets
○ InSpec uses the appropriate transport mechanism to log into that target and
invoke the relevant command(s) — SSH or WinRM
○ Neither InSpec nor Ruby need to be installed on the remote target
Different ways to run Chef InSpec
Test your machine locally
> inspec exec profile .
Test a machine remotely via SSH
> inspec exec test.rb -i identify.key -t ssh://root@172.17.0.1 .
Test a machine remotely via WinRM
> inspec exec test.rb -t winrm://Admin@192.168.1.2 --password super .
Test a Docker container
> inspec exec test.rb -t docker://5cc8837bb6a8 .
We’ll run through a few examples
Pick the student
below you on the
spreadsheet!
TASK
https://bit.ly/student_ips
Find another Students Workstation IP
Address
Task: Execute control ‘sshv2’ from your profile on a remote
target
Note the ‘target’ is specified in the output
TASK
$ inspec exec ~/profiles/webnode_profile -t ssh://chef@<IP ADDRESS> --
password thepassword
Profile: InSpec Profile (webnode_profile)
Version: 0.2.0
Target: ssh://chef@52.90.72.1:22
✔ tmp-1.0: Create /tmp directory
✔ File /tmp should be directory
× sshv2: Check SSH Version
× SSH Configuration Protocol should cmp == 2
expected: 2
got:
(compared using `cmp` matcher)
File /tmp
✔ should be directory
Profile Summary: 1 successful control, 1 control failure, 0 controls skipped
Test Summary: 2 successful, 1 failure, 0 skipped
Task: Execute control ‘sshv2’ from your profile on a remote
target
This test may/not pass, depending on the target
selected, and if they completed the earlier lab.
TASK
$ inspec exec ~/profiles/webnode_profile -t ssh://chef@<IP ADDRESS> --
password thepassword --controls sshv2
Profile: InSpec Profile (webnode_profile)
Version: 0.2.0
Target: ssh://chef@52.90.72.1:22
× sshv2: Check SSH Version
× SSH Configuration Protocol should cmp == 2
expected: 2
got:
(compared using `cmp` matcher)
Profile Summary: 0 successful control, 1 control failure, 0 controls skipped
Test Summary: 2 successful, 1 failure, 0 skipped
Task: Determine the ID of your Docker container
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS
9d4fb40ed45e 177eec0ee5-default-centos-67:latest "sh -c 'trap exit 0 …" 3 hours ago Up 3 hours
We could run your InSpec profile against the Docker container created earlier by Test Kitchen
Run the command docker ps and copy the container ID.
If there is no container running, then first run kitchen converge from within the
cookbooks/mynginx directory$ cd ~/cookbooks/mynginx/
$ kitchen converge
Creating container 177eec0ee5-default-centos-67
Finished creating <default-centos-67> (0m0.55s).
-----> Kitchen is finished. (0m2.12s)
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS
9d4fb40ed45e 177eec0ee5-default-centos-67:latest "sh -c 'trap exit 0 …" 3 hours ago Up 3 hours
$ cd ~
TASK
Task: Running InSpec on your Docker
container
TASK
$ inspec exec ~/profiles/webnode_profile/ -t docker://<CONTAINER ID> --
controls tmp-1.0
Profile: InSpec Profile (webnode_profile)
Version: 0.2.0
Target: ssh://chef@52.90.72.1:22
Target: docker://93c07bebf4a4a91c707ba3862c6297026b18a26833649c9bd7abcf940b3e4326
✔ tmp-1.0: Create /tmp directory
✔ File /tmp should be directory
Profile Summary: 1 successful controls, 0 control failure, 0 controls skipped
Test Summary: 1 successful, 0 failure, 0 skipped
Housekeeping:
Let’s copy our existing mynginx smoke test to within a control block in our profile
Task: Copy Chef InSpec test from mynginx cookbook into our
profile
TASK
$ cp ~/cookbooks/mynginx/test/smoke/default/default_test.rb
~/profiles/webnode_profile/controls/nginx.rb
Task: Tidy and format our nginx control file
1. Remove these placeholder
tests (these samples are
created automatically when
the cookbook is created)
1. Put the describe statement
into a control block called
mynginx-01
unless os.windows?
# This is an example test, replace with your own test.
describe user('root'), :skip do
it { should exist }
end
end
# This is an example test, replace it with your own test.
describe port(80), :skip do
it { should_not be_listening }
end
control 'mynginx-01' do
title 'Functional Tests'
desc 'Ensuring the web server is functioning correctly'
describe http('http://localhost', enable_remote_worker: true) do
its('status') { should cmp 200 }
its('body') { should cmp 'InSpec Jumpstart' }
its('headers.Content-Type') { should cmp 'text/html' }
end
end
TASK
$ vi ~/profiles/webnode_profile/controls/nginx.rb
Housekeeping:
Let’s remove the example.rb file that was stubbed, just to reduce output.
Task: Remove example.rb
TASK
$ rm ~/profiles/webnode_profile/controls/example.rb
Task: Running InSpec on your Docker
container
TASK
$ inspec exec ~/profiles/webnode_profile/ -t docker://<CONTAINER ID>
Profile: InSpec Profile (webnode_profile)
Version: 0.2.0
Target: docker://93c07bebf4a4a91c707ba3862c6297026b18a26833649c9bd7abcf940b3e4326
↺ sshv2: Check SSH Version
↺ Can't find file: /etc/ssh/ssh_config
✔ mynginx-01: http GET on http://localhost
✔ http GET on http://localhost status should cmp == 200
✔ http GET on http://localhost body should cmp == "InSpec Jumpstart"
✔ http GET on http://localhost headers.Content-Type should cmp == "text/html"
Profile Summary: 1 successful controls, 0 control failure, 1 controls skipped
Test Summary: 3 successful, 0 failure, 1 skipped
Task: Run ‘inspec detect’ to see OS details
== Operating System Details
Name: centos
Family: redhat
Release: 7.4.1708
Arch: x86_64
Before we run inspec exec, we can run inspec detect to get OS information.
This can help you identify what profiles should be executed on a remote target.
TASK
$ inspec detect -t ssh://chef@<IP ADDRESS> --password thepassword
Task: Run ‘inspec detect’ on Docker container
== Operating System Details
Name: centos
Family: redhat
Release: 7.4.1708
Arch: x86_64
--target= EQUALS -t
TASK
$ inspec detect --target=docker://<containerID>
Takeaways
➢ Chef InSpec uses SSH or WinRM to log onto a target and invoke
relevant command(s) to invoke the Chef InSpec code
➢ Neither Chef InSpec or Ruby need to be installed on the remote
target
What’s next…?
In the next section we’ll look at the InSpec DSL in a little more
detail, and see how we can use some more advanced Chef InSpec
constructs and Ruby in our profiles
2019 Chef InSpec Jumpstart Part 1 of 2

More Related Content

What's hot

How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...
How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...
How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...
eG Innovations
 

What's hot (20)

Microservices
MicroservicesMicroservices
Microservices
 
Building Serverless ETL Pipelines with AWS Glue
Building Serverless ETL Pipelines with AWS GlueBuilding Serverless ETL Pipelines with AWS Glue
Building Serverless ETL Pipelines with AWS Glue
 
Chaos Engineering for Docker
Chaos Engineering for DockerChaos Engineering for Docker
Chaos Engineering for Docker
 
Microservices the Good Bad and the Ugly
Microservices the Good Bad and the UglyMicroservices the Good Bad and the Ugly
Microservices the Good Bad and the Ugly
 
AWS Neptune - A Fast and reliable Graph Database Built for the Cloud
AWS Neptune - A Fast and reliable Graph Database Built for the CloudAWS Neptune - A Fast and reliable Graph Database Built for the Cloud
AWS Neptune - A Fast and reliable Graph Database Built for the Cloud
 
Hbase at Salesforce.com
Hbase at Salesforce.comHbase at Salesforce.com
Hbase at Salesforce.com
 
(NET406) Deep Dive: AWS Direct Connect and VPNs
(NET406) Deep Dive: AWS Direct Connect and VPNs(NET406) Deep Dive: AWS Direct Connect and VPNs
(NET406) Deep Dive: AWS Direct Connect and VPNs
 
Exposing and Controlling Kafka Event Streaming with Kong Konnect Enterprise |...
Exposing and Controlling Kafka Event Streaming with Kong Konnect Enterprise |...Exposing and Controlling Kafka Event Streaming with Kong Konnect Enterprise |...
Exposing and Controlling Kafka Event Streaming with Kong Konnect Enterprise |...
 
Behind the Scenes: Exploring the AWS Global Network (NET305) - AWS re:Invent ...
Behind the Scenes: Exploring the AWS Global Network (NET305) - AWS re:Invent ...Behind the Scenes: Exploring the AWS Global Network (NET305) - AWS re:Invent ...
Behind the Scenes: Exploring the AWS Global Network (NET305) - AWS re:Invent ...
 
Deep dive into AWS IAM
Deep dive into AWS IAMDeep dive into AWS IAM
Deep dive into AWS IAM
 
Hashicorp Corporate Pitch Deck Stenio_v2
Hashicorp Corporate Pitch Deck Stenio_v2 Hashicorp Corporate Pitch Deck Stenio_v2
Hashicorp Corporate Pitch Deck Stenio_v2
 
Staying on Topic - Invoke OpenFaaS functions with Kafka
Staying on Topic - Invoke OpenFaaS functions with KafkaStaying on Topic - Invoke OpenFaaS functions with Kafka
Staying on Topic - Invoke OpenFaaS functions with Kafka
 
How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...
How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...
How To Achieve Single Pane of Glass Performance Management: A Road Map to Uni...
 
Fundamentals of AWS Security
Fundamentals of AWS SecurityFundamentals of AWS Security
Fundamentals of AWS Security
 
What’s New in Amazon Aurora for MySQL and PostgreSQL
What’s New in Amazon Aurora for MySQL and PostgreSQLWhat’s New in Amazon Aurora for MySQL and PostgreSQL
What’s New in Amazon Aurora for MySQL and PostgreSQL
 
Build your first blockchain application with Amazon Managed Blockchain - SVC2...
Build your first blockchain application with Amazon Managed Blockchain - SVC2...Build your first blockchain application with Amazon Managed Blockchain - SVC2...
Build your first blockchain application with Amazon Managed Blockchain - SVC2...
 
Combining logs, metrics, and traces for unified observability
Combining logs, metrics, and traces for unified observabilityCombining logs, metrics, and traces for unified observability
Combining logs, metrics, and traces for unified observability
 
How to Design a Multi-Region Active-Active Architecture
How to Design a Multi-Region Active-Active ArchitectureHow to Design a Multi-Region Active-Active Architecture
How to Design a Multi-Region Active-Active Architecture
 
AWS Governance at Scale_AWSPSSummit_Singapore
AWS Governance at Scale_AWSPSSummit_SingaporeAWS Governance at Scale_AWSPSSummit_Singapore
AWS Governance at Scale_AWSPSSummit_Singapore
 
Getting Started with Amazon Database Migration Service
Getting Started with Amazon Database Migration ServiceGetting Started with Amazon Database Migration Service
Getting Started with Amazon Database Migration Service
 

Similar to 2019 Chef InSpec Jumpstart Part 1 of 2

Similar to 2019 Chef InSpec Jumpstart Part 1 of 2 (20)

Compliance Automation with InSpec - Chef NYC Meetup - April 2017
Compliance Automation with InSpec - Chef NYC Meetup - April 2017Compliance Automation with InSpec - Chef NYC Meetup - April 2017
Compliance Automation with InSpec - Chef NYC Meetup - April 2017
 
Test Driven Infrastructure
Test Driven InfrastructureTest Driven Infrastructure
Test Driven Infrastructure
 
OSDC 2017 - Mandi Walls - Building security into your workflow with inspec
OSDC 2017 - Mandi Walls - Building security into your workflow with inspecOSDC 2017 - Mandi Walls - Building security into your workflow with inspec
OSDC 2017 - Mandi Walls - Building security into your workflow with inspec
 
Adding Security to Your Workflow with InSpec (MAY 2017)
Adding Security to Your Workflow with InSpec (MAY 2017)Adding Security to Your Workflow with InSpec (MAY 2017)
Adding Security to Your Workflow with InSpec (MAY 2017)
 
OSDC 2017 | Building Security Into Your Workflow with InSpec by Mandi Walls
OSDC 2017 | Building Security Into Your Workflow with InSpec by Mandi WallsOSDC 2017 | Building Security Into Your Workflow with InSpec by Mandi Walls
OSDC 2017 | Building Security Into Your Workflow with InSpec by Mandi Walls
 
Adding Security and Compliance to Your Workflow with InSpec
Adding Security and Compliance to Your Workflow with InSpecAdding Security and Compliance to Your Workflow with InSpec
Adding Security and Compliance to Your Workflow with InSpec
 
Inspec: Turn your compliance, security, and other policy requirements into au...
Inspec: Turn your compliance, security, and other policy requirements into au...Inspec: Turn your compliance, security, and other policy requirements into au...
Inspec: Turn your compliance, security, and other policy requirements into au...
 
InSpec - June 2018 at Open28.be
InSpec - June 2018 at Open28.beInSpec - June 2018 at Open28.be
InSpec - June 2018 at Open28.be
 
Compliance Automation with InSpec
Compliance Automation with InSpecCompliance Automation with InSpec
Compliance Automation with InSpec
 
Ingite Slides for InSpec
Ingite Slides for InSpecIngite Slides for InSpec
Ingite Slides for InSpec
 
Adding Security to Your Workflow With InSpec - SCaLE17x
Adding Security to Your Workflow With InSpec - SCaLE17xAdding Security to Your Workflow With InSpec - SCaLE17x
Adding Security to Your Workflow With InSpec - SCaLE17x
 
InSpec Workshop DevSecCon 2017
InSpec Workshop DevSecCon 2017InSpec Workshop DevSecCon 2017
InSpec Workshop DevSecCon 2017
 
DevSecCon London 2017: Inspec workshop by Mandi Walls
DevSecCon London 2017: Inspec workshop by Mandi WallsDevSecCon London 2017: Inspec workshop by Mandi Walls
DevSecCon London 2017: Inspec workshop by Mandi Walls
 
Chef Cookbook Workflow
Chef Cookbook WorkflowChef Cookbook Workflow
Chef Cookbook Workflow
 
Building Security into Your Workflow with InSpec
Building Security into Your Workflow with InSpecBuilding Security into Your Workflow with InSpec
Building Security into Your Workflow with InSpec
 
Continuous Integration with Open Source Tools - PHPUgFfm 2014-11-20
Continuous Integration with Open Source Tools - PHPUgFfm 2014-11-20Continuous Integration with Open Source Tools - PHPUgFfm 2014-11-20
Continuous Integration with Open Source Tools - PHPUgFfm 2014-11-20
 
Prescriptive System Security with InSpec
Prescriptive System Security with InSpecPrescriptive System Security with InSpec
Prescriptive System Security with InSpec
 
Prescriptive Security with InSpec - All Things Open 2019
Prescriptive Security with InSpec - All Things Open 2019Prescriptive Security with InSpec - All Things Open 2019
Prescriptive Security with InSpec - All Things Open 2019
 
Chef Jumpstart
Chef JumpstartChef Jumpstart
Chef Jumpstart
 
BuildStuff.LT 2018 InSpec Workshop
BuildStuff.LT 2018 InSpec WorkshopBuildStuff.LT 2018 InSpec Workshop
BuildStuff.LT 2018 InSpec Workshop
 

Recently uploaded

The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Recently uploaded (20)

ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 

2019 Chef InSpec Jumpstart Part 1 of 2

  • 5. About you • Hands up if you have Chef InSpec experience
  • 6. About you • Hands up if you have Chef InSpec experience • Keep it up if you have Chef Infra experience
  • 7. About you • Hands up if you have Chef InSpec experience • Keep it up if you have Chef Infra experience • Keep it up if you have at least 1 years experience
  • 8. About you • Hands up if you have Chef InSpec experience • Keep it up if you have Chef Infra experience • Keep it up if you have at least 1 years experience • Keep it up if you have at least 2 years experience
  • 9. About you • Hands up if you have Chef InSpec experience • Keep it up if you have Chef Infra experience • Keep it up if you have at least 1 years experience • Keep it up if you have at least 2 years experience • Keep it up if you have at least 3 years experience
  • 10. About you • Hands up if you have Chef InSpec experience • Keep it up if you have Chef Infra experience • Keep it up if you have at least 1 years experience • Keep it up if you have at least 2 years experience • Keep it up if you have at least 3 years experience • Well, you’ll all have at least one day’s experience
  • 11. Agenda • Introduction • Introduction to Automated Testing • Chef InSpec and Integration Testing • Chef InSpec Profiles • Remote Scans • Chef InSpec DSL - Deeper Dive • Chef InSpec and Cloud Infrastructure • OSS Profiles • Chef InSpec DSL and Compliance Regulations • Chef InSpec and Chef Automate • Further Resources
  • 12. Expectations • This class focuses on Chef InSpec and assumes no previous experience • You will leave this class with the ability to o Explain and create Chef InSpec profiles and controls o Invoke Chef InSpec on local and remote target nodes, and cloud infrastructure o Use Chef Automate to scan your whole environment o Run Chef to remediate non-compliances issues
  • 13. Task Slides If you see this on the top of a slide, Then that’s your cue to get with the typey typey TASK
  • 14. Task: Create Control File aws.rb and add Controls TASK $ ./command output
  • 15. File to Edit/Create on InSpec Workstation Template TASK /filepath/file.rb File contents here. This template tells you to create or edit the specified file on your Workstation
  • 16. What’s next…? In the next section we’ll briefly look at types of automated testing, the reasons for it, and the tooling used
  • 17.
  • 19. Objectives ➢ After completing this lesson you will be able to: o Discuss the types of testing that are prevalent in our industry o Explain why automated testing is important o Explain when each type of test gets run, and why o Appreciate the distinction, and similarity, between integration tests and compliance tests o Explain what Chef InSpec is
  • 20. Types of Testing Code Correctness Unit Testing Integration Testing Compliance Scanning ● Foodcritic ● Cookstyle (Rubocop) ● ChefSpec ● Test Kitchen ● Chef InSpec ● Chef Automate ● Chef InSpec Is the code syntactically correct & does it follow style guidelines? Do individual pieces of code do what they’re supposed to do? Does the full application work end to end? Is the application (& infrastructure it runs on) secure and does it meet regulations?
  • 22. Many types of tests Is web server listening on tcp/80? Is web server delivering the correct content? Using TLS or SSL? SSH v2 Configured? User ‘foo’ has read no write access to /myapp? User ‘foo’ exists? User ‘foo’ has read access to /myapp? User ‘foo’ does not have sudo access? User ‘foo’ does not have read access to /etc? SSH v1 Configured?
  • 23. Many types of tests Is web server listening on tcp/80? Is web server delivering the correct content? Using TLS or SSL? SSH v2 Configured? User ‘foo’ has read no write access to /myapp? User ‘foo’ exists? User ‘foo’ has read access to /myapp? User ‘foo’ does not have sudo access? User ‘foo’ does not have read access to /etc? SSH v1 Configured? • There is zero consistency when testing infrastructure o All configuration files are proprietary o All commands have different syntaxes & command line switches o They’re platform specific (RHEL, Debian, Windows, …)
  • 25. What is Chef InSpec • Chef InSpec provides consistent DSL that is platform agnostic to check status of any component: o packages o files o users o AWS IAM users o AWS S3 buckets o … • Complex implementation code abstracted out • Many Chef InSpec profiles exist in the community, and Chef provides profiles matching specific compliance regulations
  • 26. Bash vs Chef InSpec for testing For example, SSH supports two different protocol versions. The original version, SSHv1, was subject to a number of security issues. Please use SSHv2 instead to avoid these.
  • 27. Chef InSpec for any infrastructure describe port(22) do its('processes') { should include 'sshd' } its('protocols') { should include 'tcp' } its('addresses') { should include '0.0.0.0' } end • No agent, nor Ruby, required on target node • Chef InSpec tests your servers’ actual state by executing the appropriate command locally via SSH, via WinRM, via Docker API and so on
  • 28. Chef InSpec for AWS describe aws_iam_user(name: 'test_user') do it { should have_mfa_enabled } it { should have_console_password } end Chef InSpec for Azure describe azure_virtual_machine(group_name: 'InSpec-Azure', name: 'Linux-Internal-VM') do its('size') { should eq 'Standard_DS2_v2' } its('location') { should eq 'westeurope' } its('admin_settings') { should eq 'azure' } end
  • 29. Chef InSpec is cross platform • One language • Chef InSpec for Windows
  • 30. Chef InSpec is agentless • Chef InSpec was born out of Rspec and ServerSpec • No agent needs to be installed on the target node • Requires o SSH access for Linux nodes o WinRM access for Windows
  • 31. Integration (functional) vs Compliance (security) Tests Is web server listening on tcp/80? Integration Test Is web server delivering the correct content? Integration Test Using TLS or SSL? Compliance Test SSH v2 Configured? Integration Test / Compliance Test User ‘foo’ has read no write access to /myapp? Compliance Test User ‘foo’ exists? Integration Test User ‘foo’ has read access to /myapp? Integration Test User ‘foo’ does not have sudo access? Compliance Test User ‘foo’ does not have read access to /etc? Compliance Test SSH v1 Configured? Compliance
  • 32. Integration (functional) vs Compliance (security) Tests Is web server listening on tcp/80? Integration Test Is web server delivering the correct content? Integration Test User ‘foo’ exists? Integration Test User ‘foo’ has read access to /myapp? Integration Test SSH v2 Configured? Integration Test / Compliance Test Using TLS or SSL? Compliance Test User ‘foo’ has read no write access to /myapp? Compliance Test User ‘foo’ does not have sudo access? Compliance Test User ‘foo’ does not have read access to /etc? Compliance Test SSH v1 Configured? Compliance Integration Tests (Does the thing work?) ● Tests usually maintained within a cookbook ● Invoked by Test Kitchen Compliance Scans (Is the thing secure?) ● Tests collated in InSpec profiles and maintained externally, e.g., GitHub, Compliance server ● Invoked by ‘inspec’ cli or from Chef Automate
  • 33. Integration AND Compliance Tests — Two Separate Use Cases Use Case 1 Cookbook Integration Test Is web server listening on tcp/80? Is web server delivering the correct content? User ‘foo’ exists? User ‘foo’ has read access to /myapp? We’ll look at this use case briefly initially Use Case 2 Server Compliance Scan Using TLS or SSL? User ‘foo’ has read no write access to /myapp? User ‘foo’ does not have sudo access? User ‘foo’ does not have read access to /etc? SSH v1 Configured? We’ll spend most of the workshop looking at this use case SSH v2 Configured?
  • 34. Chef InSpec Integration vs Compliance Testing Same language — two distinct use cases Chef InSpec Rules Integration tests Compliance scan Types of Rules Governed by the application (cookbook) requirements Generic rules defined by industry security requirements (not governed by the application requirements) Location of Rules Shipped with a cookbook Stored centrally (Compliance server, GitHub) Invocation Use Test Kitchen to provision a sandbox environment to perform functional tests of the cookbook Use Chef InSpec DSL or Chef Automate to perform compliance tests during development, or in production
  • 35. Key Takeaways Chef InSpec has two separate very different use cases 1. Integration testing of Chef cookbooks within the Test Kitchen framework, and 2. Scanning your server estate for compliance reasons What’s next… ? In the next section we’ll get ourselves set up with a remote workstation to play with...
  • 36.
  • 37. Let's Get Everyone a Workstation
  • 39. Task: Log in to your workstation The authenticity of host '12.34.56.78 (12.34.56.78)' can't be established.ECDSA key fingerprint is SHA256:GpuZBeC1yoO64HsyYseMnd/DRJSj0k/JqljtGX0aU9M. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '12.34.56.78' (ECDSA) to the list of known hosts. chef@12.34.56.78's password: ********** Password = 123Chef321 $ ssh chef@12.34.56.78 TASK
  • 40. Task: Ensure you’re in the correct VM $ touch firstname-lastname $ ls -l <firstname-lastname> automate-credential.toml config.toml chef-automate cookbooks deploy-chef- automate.sh profiles TASK
  • 41. Everyone just seeing their own name?
  • 42. Task: Let's check software versions $ which inspec /usr/bin/inspec TASK $ which chef /usr/bin/chef $ inspec version 3.0.52 $ chef --version Chef Development Kit Version: 3.6.0 chef-client version: 14.7.17 delivery version: master (5234f9fda9629d727169c37882d026dec9ed7d00) berks version: 7.0.7 kitchen version: 1.23.2 inspec version: 3.0.52
  • 43. Chef InSpec & Integration Testing
  • 44. Use Case 1: Chef InSpec and Integration Testing Chef InSpec and TDD
  • 45. Objectives • After completing this lesson you will be able to: o Navigate the Chef InSpec documentation o Write custom Chef InSpec controls o Use the “:skip” directive to skip tests o Use Chef InSpec along with Test Kitchen for integration testing o Read and understand Chef InSpec output
  • 46. Chef InSpec and TDD • We discussed earlier how Chef InSpec can be used for integration testing as part of the CI/CD pipeline • We will explore this in more detail using a Test Driven Development (TDD) approach by way of example • Our scenario is we need a web server to deliver some specific content
  • 47. Problem: We need a web server • We will deploy this with Chef using a TDD approach, i.e., o Write a test for your code o Execute the test and watch it fail o Write the code o Rerun the test and watch it pass We need to create a Nginx web server
  • 48. What tests need to pass? • We will be successful if http://localhost returns: o 200 ok status code o The content “inspec jumpstart” o The correct content-Type header
  • 49. What tests need to pass? What tests need to pass? • We will be successful if http://localhost returns: o 200 ok status code o The content “inspec jumpstart” o The correct content-Type header
  • 50. What tests need to pass? Let’s look at the docs What tests need to pass? • We will be successful if http://localhost returns: o 200 ok status code o The content “inspec jumpstart” o The correct content-Type header
  • 51. Task: Browse to https://inspec.io TASK
  • 52. Task: Browse to https://inspec.io TASK
  • 53. Task: View the ‘http’ InSpec resource TASK
  • 54. Task: Template integration tests are templated We’ve pre-created the nginx cookbook Note there is nothing in the recipe yet, so nothing will be configured on the system Using Chef is a workshop in itself - here we’ll concentrate on InSpec $ tree cookbooks/mynginx TASK
  • 55. Task: Append new InSpec test to default_test.rb NOTE: nano editor can be used instead of vi… $ nano ~/cookbooks/... … describe http('http://localhost', enable_remote_worker: true) do its('status') { should cmp 200 } its('body') { should cmp 'Inspec Jumpstart' } its('headers.Content-Type') { should cmp 'text/html' } end What does this code mean? cheat sheet https://bit.ly/default_test $ vi ~/cookbooks/mynginx/test/smoke/default/default_test.rb TASK
  • 56. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Control Contains
  • 57. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Control Contains - a describe statement
  • 58. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Control Contains - a describe statement - a resource
  • 59. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Control Contains - a describe statement - a resource - an optional argument
  • 60. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Control Contains - a describe statement - a resource - an optional argument - an optional parameter
  • 61. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Control Contains - a describe statement - a resource - an optional argument - an optional parameter - a do …. end block
  • 62. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Control Contains - a describe statement - a resource - an optional argument - an optional parameter - a do …. end block - one or more tests
  • 63. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Test Contains
  • 64. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Test Contains: - one or more it and/or its statement
  • 65. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Test Contains: - one or more it and/or its statement - an optional property (its statement)
  • 66. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Test Contains: - one or more it and/or its statement - an optional property (its statement) - each with a condition statement
  • 67. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Test Contains: - one or more it and/or its statement - an optional property (its statement) - each with a condition statement Each Condition Contains: - a condition
  • 68. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Test Contains: - one or more it and/or its statement - an optional property (its statement) - each with a condition statement Each Condition Contains: - a condition - a matcher
  • 69. Anatomy of a Chef InSpec test describe http(‘http://localhost’, enable_remote_worker: true) do its(‘status’) { should cmp 200 } its(’body’) { should cmp ‘Inspec Jumpstart’ } its(‘headers-Content-type’) { should cmp ‘text/html’ } end Each Test Contains: - one or more it and/or its statement - an optional property (its statement) - each with a condition statement Each Condition Contains: - a condition - a matcher - an expected result
  • 70. Matchers ➢ Each Chef InSpec resource has a number of relevant matchers you can use to check the status of that item ➢ For example, the file resource allows you to test the status of any file (or directory) and as such relevant matchers are: - exists - be_readable - content - etc ➢ Whereas the package resource applicable matchers are - version - be_installed - etc
  • 71. Note skipped tests Tests can be defined but skipped allowing for placeholders $ cat ~/cookbooks/mynginx/test/smoke/default/default_test.rb
  • 72. Problem: We need a web server ➢ We will deploy this with Chef using a TDD approach, i.e., ○ Write a test for your code ○ Execute the test and watch it fail ○ Write the code ○ Rerun the test and watch it pass We need to create a web server
  • 73. Introduction to Test Kitchen ➢ Now that we have created our tests, the second step is to execute it and watch it fail ➢ We will use Test Kitchen to test our code ➢ Test Kitchen provides a harness to execute code on ephemeral infrastructure - forms part of a CI/CD pipeline
  • 74. Task: Navigate into cookbooks/mynginx directory We’ll remain in this directory for the remainder of this section $ cd ~/cookbooks/mynginx TASK
  • 75. Task: View Test Kitchen Config file This configuration file tells Test Kitchen to: - spin up a centos-6.7 docker container (via ‘dokken’ driver) - use Chef Zero to run this recipe - recipe[mynginx:default] - then use InSpec to run the tests specified in test/smoke/default $ cat .kitchen.yml TASK
  • 76. Task: Run Test Kitchen kitchen verify - spin up a centos-6.7 docker container - use Chef Zero to run this recipe - recipe[mynginx:default] (recipe currently blank so does nothing) - then use InSpec to run the tests specified in test/smoke/default $ kitchen verify TASK
  • 77. Problem: We need a web server ➢ We will deploy this with Chef using a TDD approach, i.e., ○ Write a test for your code ○ Execute the test and watch it fail ○ Write the code ○ Rerun the test and watch it pass We need to create a web server
  • 78. Task: Create your recipe include_recipe 'nginx::repo' package 'nginx' do action :install end remote_file '/usr/share/nginx/html/index.html' do source 'https://inspec-jumpstart-2019.s3.amazonaws.com/web01.html' end service 'nginx' do supports status: true, restart: true, reload: true action [ :enable, :start ] end $ vi ~/cookbooks/mynginx/recipes/default.rb TASK cheat sheet https://bit.ly/recipe_default
  • 79. Test: run Test Kitchen kitchen converge - provisions a new server (or container in our case) - installs Chef - runs the recipe in the .kitchen.yml file $ kitchen converge TASK
  • 80. Problem: We need a web server ➢ We will deploy this with Chef using a TDD approach, i.e., ○ Write a test for your code ○ Execute the test and watch it fail ○ Write the code ○ Rerun the test and watch it pass We need to create a web server
  • 81. Test: run Test Kitchen again $ kitchen verify TASK
  • 82. Problem: We need a web server ➢ We will deploy this with Chef using a TDD approach, i.e., ○ Write a test for your code ○ Execute the test and watch it fail ○ Write the code ○ Rerun the test and watch it pass We need to create a web server
  • 83. Chef InSpec and TDD ➢ The key takeaway here is the Chef InSpec plugin for Test Kitchen can be a valuable tool in the test driven development of Chef cookbooks ➢ In that workflow the Chef InSpec controls are in control files shipped along with the cookbook itself, as follows: ~/cookbooks/ <cookbook name>/test/smoke/default/control-filename_test.rb ➢ However, Chef InSpec is a standalone tool and can be used for more general testing purposes, including compliance scanning ➢ Note: we will focus on using Chef InSpec for compliance scanning for the remainder of the class
  • 84. Key Takeaways One very specific use case for Chef InSpec is for integration testing of Chef cookbooks within the Test Kitchen framework In this use case the Chef InSpec tests are shipped as .rb files within the cookbook In the next section we’ll look at the Chef InSpec tool itself, creating Chef InSpec profiles, and the more general use case of scanning infrastructure for compliance What’s Next?
  • 85.
  • 86. Chef InSpec CLI, Profiles and Compliance Scanning Introduction to Chef InSpec CLI and creating and executing profiles
  • 87. Objectives ➢ After completing this lesson you will be able to ➢ Describe Chef InSpec as a standalone tool ➢ Create & Navigate Chef InSpec profiles ➢ Identify the contents of an Chef InSpec profile ➢ Explain the structure of an Chef InSpec profile ➢ Invoke Chef InSpec tests on a local host ➢ Use formatters to format the output of an Chef InSpec test as JSON, HTML, etc
  • 88. Chef InSpec as a Standalone Tool ➢ We've seen how Chef InSpec controls may be shipped within Chef cookbooks & invoked using Test Kitchen ○ Integration testing of Chef cookbooks use case ➢ For the remainder of the class we'll look at Chef InSpec as a standalone tool to scan 1+ nodes for compliance using custom or industry standard controls ○ This primary use case is unrelated to Test Kitchen and Chef – apart from remediation cookbooks if necessary
  • 89. Chef InSpec code is maintained in 'Profiles' Chef InSpec organizes controls into versioned 'profiles' A profile is a standalone structure containing ● control files ● documentation ● extension libraries ● dependencies Lets look at profiles by way of an example
  • 90. Problem Statement ➢ We need to ensure our web node is using SSH2 only and not SSH1, as SSH1 has security vulnerabilities ➢ We will use InSpec to ensure the node is compliant
  • 91. Problem: SSH v1 is Insecure We need to ensure our web node is using SSH2 only and not SSH1, as SSH1 has security vulnerabilities The tasks are 1. Create a skeleton Chef InSpec profile for SSH 2. Review the technical requirements and create the Chef InSpec control including the actual test 3. Execute the Chef InSpec profile to determine current system state 4. Correct the state and rerun Chef InSpec check
  • 92. Chef InSpec Command Line Interface ➢ In this section we will use the Chef InSpec command line interface (CLI) to help us create profiles and run audit tests against targets ➢ The Chef InSpec CLI commands can run audit tests against targets using SSH, WinRM, locally, or on Docker containers
  • 93. Chef InSpec Command Line Interface ➢ We'll be using inspec init, inspec check and inspec exec ➢ inspec check verifies the compliance profile code that you write ➢ inspec exec will run the tests against a system Note: the Chef InSpec tests we executed in the previous section (using Test Kitchen) were tied to the specific cookbook, and were used to verify that cookbook inspec exec can be used to scan for compliance – Test Kitchen isn't used
  • 94. Task: Execute the 'inspec' command ● Chef InSpec has its own CLI for creating and executing profiles, amongst other things ● We will look more at the inspec command later – for now we'll use inspec init to create our new profile TASK $ inspec Commands: inspec archive PATH # archive a profile to tar.gz (default) or zip inspec artifact SUBCOMMAND ... # Sign, verify and install artifacts inspec check PATH # verify all tests at the specified PATH inspec compliance SUBCOMMAND ... # Chef Compliance commands inspec detect # detect the target OS inspec env # Output shell-appropriate completion configuration inspec exec PATHS # run all test files at the specified PATH. inspec habitat SUBCOMMAND ... # Commands for InSpec + Habitat Integration inspec help [COMMAND] # Describe available commands or one specific command inspec init TEMPLATE ... # Scaffolds a new project inspec json PATH # read all tests in PATH and generate a JSON summary inspec shell # open an interactive debugging shell ...
  • 95. Task: Create an InSpec Profile TASK $ inspec init profile ~/profiles/webnode_profile Create new profile at /home/chef/profiles/webnode_profile * Create file README.md * Create directory controls * Create file controls/example.rb * Create file inspec.yml * Create directory libraries
  • 96. Task: Create an InSpec Profile $ inspec init profile ~/profiles/webnode_profile Create new profile at /home/chef/profiles/webnode_profile * Create file README.md * Create directory controls * Create file controls/example.rb * Create file inspec.yml * Create directory libraries Use the 'inspec' command To initialise (i.e. create) a profile In the '~/profiles' directory Called 'webnode_profile' TASK
  • 97. Task: View webnode_profile InSpec Profile TASK $ tree ~/profiles/webnode_profile /home/chef/profiles/webnode_profile/ ├── controls │ └── example.rb ├── inspec.yml └── libraries └── README.md
  • 98. Chef InSpec Profile akin to Chef Cookbooks Spot the resemblance? profiles/webnode_profile │ ├── inspec.yml │ ├── README.md │ ├── controls │ └── example.rb │ ├── libraries │ └── files cookbooks/webnode_cookbook │ ├── metadata.rb │ ├── README.md │ ├── recipes │ └── default.rb │ ├── libraries │ └── files
  • 99. Anatomy of a Chef InSpec Profile profiles/webnode_profile │ ├── inspec.yml │ ├── README.md │ ├── controls │ └── example.rb │ ├── libraries │ └── files A Chef InSpec profile contains ● inspec.yml which includes the profile description, dependencies, versioning, etc
  • 100. The inspec.yml file For those familiar with Chef, 'inspec.yml' is akin to 'metadata.rb' TASK $ cat ~/profiles/webnode_profile/inspec.yml name: webnode_profile title: InSpec Profile maintainer: The Authors copyright: The Authors copyright_email: you@example.com license: Apache-2.0 summary: An InSpec Compliance Profile version: 0.1.0 supports: platform: os
  • 101. Anatomy of a Chef InSpec Profile profiles/webnode_profile │ ├── inspec.yml │ ├── README.md │ ├── controls │ └── example.rb │ ├── libraries │ └── files A Chef InSpec profile contains ● inspec.yml ● README.md ● controls directory in which all tests are located. An example.rb file is stubbed with sample controls
  • 102. Sample Controls File TASK $ cat ~/profiles/webnode_profile/controls/example.rb # encoding: utf-8 # copyright: 2018, The Authors title 'sample section' # you can also use plain tests describe file('/tmp') do it { should be_directory } end # you add controls here control 'tmp-1.0' do # A unique ID for this control impact 0.7 # The criticality, if this control fails. title 'Create /tmp directory' # A human-readable title desc 'An optional description...' describe file('/tmp') do # The actual test it { should be_directory } end end
  • 103. Anatomy of a Chef InSpec Profile profiles/webnode_profile │ ├── inspec.yml │ ├── README.md │ ├── controls │ └── example.rb │ ├── libraries │ └── files A Chef InSpec profile contains ● inspec.yml ● README.md ● controls ● optional libraries directory in which optional InSpec resource extensions are located
  • 104. Anatomy of a Chef InSpec Profile profiles/webnode_profile │ ├── inspec.yml │ ├── README.md │ ├── controls │ └── example.rb │ ├── libraries │ └── files A Chef InSpec profile contains ● inspec.yml ● README.md ● Controls ● libraries ● optional files directory for additional files that a profile can access
  • 105. Problem: SSH v1 is Insecure We need to ensure our web node is using SSH2 only and not SSH1, as SSH1 has security vulnerabilities. The tasks are ✓ Create a skeleton Chef InSpec profile for SSH 2. Review the technical requirements and create the Chef InSpec control including the actual test 3. Execute the Chef InSpec profile to determine current system state 4. Correct the state and rerun Chef InSpec check
  • 106. Back to our SSH problem - which resource shall we use? ➢ We need to ensure our web node is using SSH2 only and not SSH1, as SSH1 has security vulnerabilities. ➢ We'll use the ssh_config resource
  • 107. Task: Create a new controls file ssh.rb within our profile TASK $ touch ~/profiles/webnode_profile/controls/ssh.rb
  • 108. Task: Include some controls from OSS profile in our profile TASK $ vi ~/profiles/webnode_profile/controls/ssh.rb title 'ssh' control 'sshv2' do impact 0.7 title 'Check SSH Version' desc 'Only SSH version 2 should be enabled' describe ssh_config do its('Protocol') { should cmp 2 } end end cheat sheet https://bit.ly/controls_ssh
  • 109. Control Files A profile contains one or more control files, each containing a number of tests • A control block contains at least one describe block, but may contain as many as required • A describe block contains at least one test # encoding: utf-8 # copyright: 2018, The Authors title 'sample section' describe file('/tmp') do it { should be_directory } end control 'tmp-1.0' do tag 'tmp', tag dir: '/tmp' ref 'NSA-RH6 - Section 3.5.2.1' impact 0.7 title 'Create /tmp directory' desc 'An optional description...' describe file('/tmp') do it { should be_directory } end end
  • 110. The Anatomy of a Control File A control file within a profile contains • Some boilerplate information and a title # encoding: utf-8 # copyright: 2018, The Authors title 'sample section' describe file('/tmp') do it { should be_directory } end control 'tmp-1.0' do tag 'tmp', tag dir: '/tmp' ref 'NSA-RH6 - Section 3.5.2.1' impact 0.7 title 'Create /tmp directory' desc 'An optional description...' describe file('/tmp') do it { should be_directory } end end
  • 111. The Anatomy of a Control File A control file within a profile contains • Some boilerplate information and a title • One or more describe statements, each containing one or more tests # encoding: utf-8 # copyright: 2018, The Authors title 'sample section' describe file('/tmp') do it { should be_directory } end control 'tmp-1.0' do tag 'tmp', tag dir: '/tmp' ref 'NSA-RH6 - Section 3.5.2.1' impact 0.7 title 'Create /tmp directory' desc 'An optional description...' describe file('/tmp') do it { should be_directory } end end
  • 112. The Anatomy of a Control File A control file within a profile contains • Some boilerplate information and a title • One or more describe statements, each containing one or more tests • describe statements may be grouped within control statements # encoding: utf-8 # copyright: 2018, The Authors title 'sample section' describe file('/tmp') do it { should be_directory } end control 'tmp-1.0' do tag 'tmp', tag dir: '/tmp' ref 'NSA-RH6 - Section 3.5.2.1' impact 0.7 title 'Create /tmp directory' desc 'An optional description...' describe file('/tmp') do it { should be_directory } end end
  • 113. The Anatomy of a Control File A control file within a profile contains • Some boilerplate information and a title • One or more describe statements, each containing one or more tests • describe statements may be grouped within control statements • control statements may include extra metadata defining for example o a unique ID for this control o the criticality, if this control fails. o a human-readable title and description o reference documentation # encoding: utf-8 # copyright: 2018, The Authors title 'sample section' describe file('/tmp') do it { should be_directory } end control 'tmp-1.0' do tag 'tmp', tag dir: '/tmp' ref 'NSA-RH6 - Section 3.5.2.1' impact 0.7 title 'Create /tmp directory' desc 'An optional description...' describe file('/tmp') do it { should be_directory } end end
  • 114. Impact ➢ Impact is a measure of the importance of the compliance results ➢ The value ranges are: ○ 0.0 to <0.4 - these are controls with minor criticality ○ 0.4 to <0.7 - these are controls with major criticality ○ 0.7 to 1.0 - these are critical controls ➢ The impact value is configurable for each control
  • 115. Chef InSpec Code Metadata ➢ Chef InSpec 'describe' statements abstract out the test implementation detail ➢ Compliance code contains further metadata pertaining to the compliance rule Compliance DSL includes additional metadata around 'describe' statementsScripting Tools are platform specific InSpec within a cookbook
  • 116. Task: Update the profile's version number to 0.2.0 TASK $ vi ~/profiles/webnode_profile/inspec.yml name: webnode_profile title: InSpec Profile maintainer: The Authors copyright: The Authors copyright_email: you@example.com license: Apache-2.0 summary: An InSpec Compliance Profile version: 0.2.0
  • 117. Task: Run 'inspec check' to check if profile is syntactically correct TASK $ inspec check ~/profiles/webnode_profile Location: /home/chef/profiles/webnode_profile Profile: webnode_profile Controls: 3 Timestamp: 2019-04-11T13:45:02+00:00 Valid: true No errors or warnings
  • 118. Problem: SSH v1 is Insecure We need to ensure our web node is using SSH2 only and not SSH1, as SSH1 has security vulnerabilities. The tasks are ✓ Create a skeleton Chef InSpec profile for SSH ✓ Review the technical requirements and create the Chef InSpec control including the actual test 3. Execute the Chef InSpec profile to determine current system state 4. Correct the state and rerun Chef InSpec check
  • 119. Executing our code We now need to execute our Chef InSpec profile We will use inspec exec command to do this
  • 120. Task: Run profile locally with Chef InSpec command TASK $ inspec exec ~/profiles/webnode_profile Profile: InSpec Profile (webnode_profile) Version: 0.2.0 Target: local:// ✔ tmp-1.0: Create /tmp directory ✔ File /tmp should be directory × sshv2: Check SSH Version × SSHD Configuration Protocol should cmp == 2 expected: 2 got: nil (compared using `cmp` matcher) File /tmp ✔ should be directory Profile Summary: 1 successful control, 1 control failure, 0 controls skipped Test Summary: 2 successful, 1 failure, 0 skipped
  • 121. Our test failed Why did it fail?
  • 122. Why did our test fail? # Protocol 2 It seems 'Protocol 2' line is commented out of our config file Correcting it manually would not make sense, especially if you have 100's of nodes, so you would normally use Chef to configure this But we'll just fix it manually for now TASK $ sudo grep 'Protocol' /etc/ssh/ssh_config
  • 123. Problem: SSH v1 is Insecure We need to ensure our web node is using SSH2 only and not SSH1, as SSH1 has security vulnerabilities. The tasks are ✓ Create a skeleton Chef InSpec profile for SSH ✓ Review the technical requirements and create the Chef InSpec control including the actual test ✓ Execute the Chef InSpec profile to determine current system state 4. Correct the state and rerun Chef InSpec check
  • 124. Task: Update the SSH Config File ... # IdentityFile ~/.ssh/id_ecdsa # IdentityFile ~/.ssh/id_ed25519 # Port 22 Protocol 2 # Cipher 3des # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc # MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 ... Manually update the SSH configuration file - uncomment the line to enable SSH2 (line 42) Usually this would be done by Chef TASK $ sudo vi /etc/ssh/ssh_config
  • 125. Remember Test-Driven Development? 1. Write a test for your code 2. Execute the test and watch it fail 3. Write the code 4. Rerun the test and watch it pass 5. Repeat steps 1 through 4
  • 126. Task: Again run profile locally with InSpec command Profile: InSpec Profile (webnode_profile) Version: 0.2.0 Target: local:// ✔ tmp-1.0: Create /tmp directory ✔ File /tmp should be directory ✔ sshv2: Check SSH Version ✔ SSH Configuration Protocol should cmp == 2 File /tmp ✔ should be directory Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped Test Summary: 3 successful, 0 failures, 0 skipped TASK $ inspec exec ~/profiles/webnode_profile
  • 127. Problem: SSH v1 is Insecure We need to ensure our web node is using SSH2 only and not SSH1, as SSH1 has security vulnerabilities. The tasks are ✓ Create a skeleton Chef InSpec profile for SSH ✓ Review the technical requirements and create the Chef InSpec control including the actual test ✓ Execute the Chef InSpec profile to determine current system state ✓ Correct the state and rerun Chef InSpec check
  • 128. Executing specific controls files ➢ In some circumstances you may only wish to run those tests in a specific control file in the profile
  • 129. Task: Run just the controls in 'ssh.rb' Profile: tests from profiles/webnode_profile/controls/ssh.rb (tests from profiles.webnode_profile.controls.ssh.rb) Version: (not specified) Target: local:// ✔ sshv2: Check SSH Version ✔ SSH Configuration Protocol should cmp == 2 Profile Summary: 1 successful control, 0 control failures, 0 controls skipped Test Summary: 1 successful, 0 failures, 0 skipped TASK $ inspec exec ~/profiles/webnode_profile/controls/ssh.rb
  • 130. Executing specific controls ➢ In some circumstances you may wish to restrict the tests run to specific controls within the profile ➢ In some circumstances you may only wish to run those tests in a specific control file in the profile ● control tmp-1.0 in our example.rb control file ● control sshv2 in our ssh.rb controls file, and control 'tmp-1.0' do impact 0.7 title 'Create /tmp directory' ... control 'sshv2' do impact 0.7 title 'Check SSH Version' ...
  • 131. Task: Use the --controls command line switch to run individual controls Profile: InSpec Profile (webnode_profile) Version: 0.2.0 Target: local:// ✔ tmp-1.0: Create /tmp directory ✔ File /tmp should be directory Profile Summary: 1 successful controls, 0 control failures, 0 controls skipped Test Summary: 1 successful, 0 failures, 0 skipped TASK $ inspec exec ~/profiles/webnode_profile --controls tmp-1.0
  • 132. Executing specific controls ➢ By default the inspec command returns results in human readable format ➢ But you can use --reporter= flag to output in a number of other formats, including ○ Documentation ○ Html ○ Progress ○ Json ○ Json-min ○ Json-rspec ○ Junit ○ cli (default) ➢ We'll look at a number of examples
  • 133. Task: Format the Output as JSON ... "id": "controls/nginx.rb" } ], "license": "Apache-2.0", "maintainer": "The Authors", "name": "webnode_profile", "sha256": "faa3f30f9c0d14962280ce21de110508d3c43ab572a1cc529d3b6db9fac0415b", "summary": "An InSpec Compliance Profile", "supports": [], "title": "InSpec Profile", "version": "0.2.0" } ], "statistics": { "duration": 0.013274985 }, "version": "1.51.21" } $ inspec exec ~/profiles/webnode_profile --reporter=json | python -m json.tool TASK
  • 134. Optional Task : Get a summary of the results using json-min formatter { "controls": [ { "code_desc": "SSH Configuration Protocol should cmp == 2", "id": "sshv2", "profile_id": "webnode_profile", "profile_sha256": "faa3f30f9c0d14962280ce21de110508d3c43ab572a1cc529d3b6db9fac0415b", "status": "passed" } ], "statistics": { "duration": 0.001906135 }, "version": "1.51.21" } Try the other formatters ● documentation ● html ● progress ● json ● json-min ● json-rspec ● junit ● cli $ inspec exec ~/profiles/webnode_profile --reporter=json-min | python -m json.tool TASK
  • 135. Optional Task: html formatter returns standard rspec output ... <div id="div_group_2" class="example_group passed"> <dl style="margin-left: 15px;"> <dt id="example_group_2" class="passed">Protocol</dt> <script type="text/javascript">moveProgressBar('100.0');</script> <dd class="example passed"><span class="passed_spec_name">should cmp == 2</span><span class='duration'>0.00086s</span></dd> </dl> </div> <script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>0.00335 seconds</strong>";</script> <script type="text/javascript">document.getElementById('totals').innerHTML = "1 example, 0 failures";</script> </div> </div> </body> </html> $ inspec exec ~/profiles/webnode_profile --reporter=html TASK
  • 136. Optional Task : Format the Output as JUnit <?xml version='1.0'?> <testsuites> <testsuite name='webnode_profile' tests='1' failed='0'> <testcase name='SSH Configuration Protocol should cmp == 2' classname='webnode_profile.sshv2' time='0.000727831'/> </testsuite> </testsuites> $ inspec exec ~/profiles/webnode_profile --reporter=junit TASK
  • 137. Takeaways ➢ A key primary Chef InSpec use case is for scanning machines for regulatory compliance ➢ Used as such, Chef InSpec is used as a standalone tool (not within Test Kitchen) and tests are maintained within Chef InSpec Profiles, and executed using 'inspec exec' command What’s next…? In the next section we'll look at invoking Chef InSpec compliance tests on remote hosts
  • 138.
  • 139. Running Remote Scans Running your local profiles on a remote target
  • 140. Objectives ➢ After completing this lesson you will be able to: ○ Execute scans on a remote VM and Docker container
  • 141. Running Chef InSpec locally and remote Up until now we’ve been running InSpec profiles on localhost But the real power of InSpec is the ability to run it on remote targets ○ InSpec uses the appropriate transport mechanism to log into that target and invoke the relevant command(s) — SSH or WinRM ○ Neither InSpec nor Ruby need to be installed on the remote target
  • 142. Different ways to run Chef InSpec Test your machine locally > inspec exec profile . Test a machine remotely via SSH > inspec exec test.rb -i identify.key -t ssh://root@172.17.0.1 . Test a machine remotely via WinRM > inspec exec test.rb -t winrm://Admin@192.168.1.2 --password super . Test a Docker container > inspec exec test.rb -t docker://5cc8837bb6a8 . We’ll run through a few examples
  • 143. Pick the student below you on the spreadsheet! TASK https://bit.ly/student_ips Find another Students Workstation IP Address
  • 144. Task: Execute control ‘sshv2’ from your profile on a remote target Note the ‘target’ is specified in the output TASK $ inspec exec ~/profiles/webnode_profile -t ssh://chef@<IP ADDRESS> -- password thepassword Profile: InSpec Profile (webnode_profile) Version: 0.2.0 Target: ssh://chef@52.90.72.1:22 ✔ tmp-1.0: Create /tmp directory ✔ File /tmp should be directory × sshv2: Check SSH Version × SSH Configuration Protocol should cmp == 2 expected: 2 got: (compared using `cmp` matcher) File /tmp ✔ should be directory Profile Summary: 1 successful control, 1 control failure, 0 controls skipped Test Summary: 2 successful, 1 failure, 0 skipped
  • 145. Task: Execute control ‘sshv2’ from your profile on a remote target This test may/not pass, depending on the target selected, and if they completed the earlier lab. TASK $ inspec exec ~/profiles/webnode_profile -t ssh://chef@<IP ADDRESS> -- password thepassword --controls sshv2 Profile: InSpec Profile (webnode_profile) Version: 0.2.0 Target: ssh://chef@52.90.72.1:22 × sshv2: Check SSH Version × SSH Configuration Protocol should cmp == 2 expected: 2 got: (compared using `cmp` matcher) Profile Summary: 0 successful control, 1 control failure, 0 controls skipped Test Summary: 2 successful, 1 failure, 0 skipped
  • 146. Task: Determine the ID of your Docker container $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS 9d4fb40ed45e 177eec0ee5-default-centos-67:latest "sh -c 'trap exit 0 …" 3 hours ago Up 3 hours We could run your InSpec profile against the Docker container created earlier by Test Kitchen Run the command docker ps and copy the container ID. If there is no container running, then first run kitchen converge from within the cookbooks/mynginx directory$ cd ~/cookbooks/mynginx/ $ kitchen converge Creating container 177eec0ee5-default-centos-67 Finished creating <default-centos-67> (0m0.55s). -----> Kitchen is finished. (0m2.12s) $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS 9d4fb40ed45e 177eec0ee5-default-centos-67:latest "sh -c 'trap exit 0 …" 3 hours ago Up 3 hours $ cd ~ TASK
  • 147. Task: Running InSpec on your Docker container TASK $ inspec exec ~/profiles/webnode_profile/ -t docker://<CONTAINER ID> -- controls tmp-1.0 Profile: InSpec Profile (webnode_profile) Version: 0.2.0 Target: ssh://chef@52.90.72.1:22 Target: docker://93c07bebf4a4a91c707ba3862c6297026b18a26833649c9bd7abcf940b3e4326 ✔ tmp-1.0: Create /tmp directory ✔ File /tmp should be directory Profile Summary: 1 successful controls, 0 control failure, 0 controls skipped Test Summary: 1 successful, 0 failure, 0 skipped
  • 148. Housekeeping: Let’s copy our existing mynginx smoke test to within a control block in our profile Task: Copy Chef InSpec test from mynginx cookbook into our profile TASK $ cp ~/cookbooks/mynginx/test/smoke/default/default_test.rb ~/profiles/webnode_profile/controls/nginx.rb
  • 149. Task: Tidy and format our nginx control file 1. Remove these placeholder tests (these samples are created automatically when the cookbook is created) 1. Put the describe statement into a control block called mynginx-01 unless os.windows? # This is an example test, replace with your own test. describe user('root'), :skip do it { should exist } end end # This is an example test, replace it with your own test. describe port(80), :skip do it { should_not be_listening } end control 'mynginx-01' do title 'Functional Tests' desc 'Ensuring the web server is functioning correctly' describe http('http://localhost', enable_remote_worker: true) do its('status') { should cmp 200 } its('body') { should cmp 'InSpec Jumpstart' } its('headers.Content-Type') { should cmp 'text/html' } end end TASK $ vi ~/profiles/webnode_profile/controls/nginx.rb
  • 150. Housekeeping: Let’s remove the example.rb file that was stubbed, just to reduce output. Task: Remove example.rb TASK $ rm ~/profiles/webnode_profile/controls/example.rb
  • 151. Task: Running InSpec on your Docker container TASK $ inspec exec ~/profiles/webnode_profile/ -t docker://<CONTAINER ID> Profile: InSpec Profile (webnode_profile) Version: 0.2.0 Target: docker://93c07bebf4a4a91c707ba3862c6297026b18a26833649c9bd7abcf940b3e4326 ↺ sshv2: Check SSH Version ↺ Can't find file: /etc/ssh/ssh_config ✔ mynginx-01: http GET on http://localhost ✔ http GET on http://localhost status should cmp == 200 ✔ http GET on http://localhost body should cmp == "InSpec Jumpstart" ✔ http GET on http://localhost headers.Content-Type should cmp == "text/html" Profile Summary: 1 successful controls, 0 control failure, 1 controls skipped Test Summary: 3 successful, 0 failure, 1 skipped
  • 152. Task: Run ‘inspec detect’ to see OS details == Operating System Details Name: centos Family: redhat Release: 7.4.1708 Arch: x86_64 Before we run inspec exec, we can run inspec detect to get OS information. This can help you identify what profiles should be executed on a remote target. TASK $ inspec detect -t ssh://chef@<IP ADDRESS> --password thepassword
  • 153. Task: Run ‘inspec detect’ on Docker container == Operating System Details Name: centos Family: redhat Release: 7.4.1708 Arch: x86_64 --target= EQUALS -t TASK $ inspec detect --target=docker://<containerID>
  • 154. Takeaways ➢ Chef InSpec uses SSH or WinRM to log onto a target and invoke relevant command(s) to invoke the Chef InSpec code ➢ Neither Chef InSpec or Ruby need to be installed on the remote target What’s next…? In the next section we’ll look at the InSpec DSL in a little more detail, and see how we can use some more advanced Chef InSpec constructs and Ruby in our profiles