9. InSpec
• Human-readable
• Test security and compliance
• Create, share, and reuse profiles
• Extend for your applications and systems
• Plug into your existing workflows / build servers
• Fast feedback with Test Kitchen
10. Lifecycle
• When you get a mandate from security, how often is it checked?
• Single big scan, report mailed out with a “due date”?
• Yearly or twice-yearly massive scans with remediation firedrills?
11. SSH Requirement
• If your security team sends you a directive:
SSH supports two different protocol versions. The
original version, SSHv1, was subject to a number
of security issues. All systems must use SSHv2
instead to avoid these issues.
12. What To Do?
• Locate configuration file
• Locate correct setting
• Schedule a fix and restart
• Who fixes OS images?
• Do you need to test new settings?
13. Check that sshd_config
describe sshd_config do
impact 1.0
title 'SSH Version 2'
desc <<-EOF
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.
EOF
its('Protocol') { should cmp 2 }
end
14. Resources
• Resources examine common services, system files, and
configurations
See http://inspec.io/docs/reference/resources/ for the current list!
• Various Linux distros, plus Windows
• Check the characteristics of the resource (e.g., file size, owner)
• InSpec libraries are Matchers for testing and verifying
characteristics
15. • Resources include where the item is and how to look at it
• Included parsers do the work for you
• Similar to Ruby testing language rSpec, meant to be human
readable
16. its.... should...
• it { should exist }
• it { should be_installed }
• it { should be_enabled }
• its('max_log_file') { should cmp 6 }
• its('exit_status') { should eq 0 }
• its('gid') { should eq 0 }
17. SSH Configuration
describe sshd_config do
impact 1.0
title 'SSH Version 2'
desc <<-EOF
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.
EOF
its('Protocol') { should cmp 2 }
end
The Resource – built in
InSpec will find this in the fil
18. Run It
• InSpec is command line
Installs on your workstation as a ruby gem or as part of the ChefDK
• Can be run locally, test the machine it is executing on
• Or remotely
InSpec will log into the target and run the tests for you
• Also a REPL
https://www.inspec.io/docs/reference/shell/
19. Using InSpec
User: chef
Pass: BuildStuff2018
What you need to replicate on your own:
This version is built using CentOS 7.4
Your user needs to have full sudo access
Install git
Install ChefDK from https://downloads.chef.io/chefdk/
20. Find It!
• http://inspec.io/
• Open Source, but cool stuff in the server
• Looks like other "spec" testing languages
• ChefDK or separate from https://downloads.chef.io
• It's already installed on your test host
$ inspec --version
3.0.12
Your version of InSpec is out of date! The latest
version is 3.0.52.
21. Create a Basic Test – test.rb
• Let’s write a basic test to make sure /tmp is a directory
• It also should be owned by root
• And its mode should be 01777 – open to all (plus sticky bit!)
• Let’s check out the docs for the “file” resource for InSpec
22. File Resources in InSpec
• https://www.inspec.io/docs/reference/resources/file/
• We want:
Directory
Owner
Mode
describe file(‘path’) do
it { should MATCHER ‘value’ }
end
23. test.rb
describe file('/tmp') do
it { should exist }
it { should be_directory }
it { should be_owned_by 'root' }
its('mode') { should cmp '01777' }
end
describe file('/tmp/') do
it { should exist }
its('type') { should eq :directory }
it { should_not be_file }
its('owner') { should eq 'root' }
its('mode') { should cmp '01777' }
end
24. Test Any Target
inspec exec test.rb
inspec exec test.rb -i ~/.aws/cert.pem -t ssh://ec2-
user@192.168.1.2
inspec exec test.rb -t winrm://Admin@192.168.1.2 --password
super
inspec exec test.rb -t docker://3dda08e75838
25. Execute InSpec
[chef@host ~]$ inspec exec ./test.rb
Profile: tests from ./test.rb
Version: (not specified)
Target: local://
File /tmp
✔ should exist
✔ should be directory
✔ should be owned by "root"
✔ mode should cmp == "01777"
Test Summary: 4 successful, 0 failures, 0 skipped
27. Security Rule: set ssh login banner
• When logging into any machine your organization, display a notification:
"Welcome to MyCorp. This is a secure system and all activities are logged.
Authorized users only."
• The file /etc/ssh/sshd_banner
• We want it to exist and have the above content
28. $ vi banner.rb
describe file('/etc/ssh/sshd_banner') do
it { should exist }
its('content') { should match /Authorized users only/ }
end
29. $ sudo inspec exec banner.rb
Profile: tests from banner.rb (tests from banner.rb)
Version: (not specified)
Target: local://
File /etc/ssh/sshd_banner
× should exist
expected File /etc/ssh/sshd_banner to exist
× content should match /Authorized users only/
expected nil to match /Authorized users only/
Test Summary: 0 successful, 2 failures, 0 skipped
30. Test-driven Development
• We created the test first
• We know the feature we need does not exist on the machine
• Now we can create the sshd_banner file and re-run our test
• This helps us check our assumptions about the state of the system
• Create the banner file and run inspec again
31. $ sudo vi /etc/ssh/sshd_banner
Welcome to MyCorp.
This is a secure system and all activities are logged.
Authorized users only.
32. $ sudo inspec exec banner.rb
Profile: tests from banner.rb (tests from banner.rb)
Version: (not specified)
Target: local://
File /etc/ssh/sshd_banner
✔ should exist
✔ content should match /Authorized users only/
Test Summary: 2 successful, 0 failures, 0 skipped
33. $ vi banner.rb
...
describe file('/etc/ssh/sshd_config') do
its('content') { should match /^Banner /etc/ssh/sshd_banner/ }
end
34. $ sudo inspec exec banner.rb
Profile: tests from banner.rb (tests from banner.rb)
Version: (not specified)
Target: local://
File /etc/ssh/sshd_banner
✔ should exist
✔ content should match /Authorized users only/
File /etc/ssh/sshd_config
× content should match /^Banner /etc/ssh/sshd_banner/
expected "#t$OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp
$nn# This is the sshd server system...oncvsn#tX11Forwarding
non#tAllowTcpForwarding non#tPermitTTY non#tForceCommand cvs servern" to
match /$Banner /etc/ssh/sshd_banner/
Need sudo this time!
35. $ sudo vi /etc/ssh/sshd_config
Find the line for the banner:
# no default banner path
#Banner none
Change to:
# add default banner path
Banner /etc/ssh/sshd_banner
36. $ sudo inspec exec banner.rb
Profile: tests from banner.rb (tests from banner.rb)
Version: (not specified)
Target: local://
File /etc/ssh/sshd_banner
✔ should exist
✔ content should match /Authorized users only/
File /etc/ssh/sshd_config
✔ content should match /^Banner /etc/ssh/sshd_banner/
Test Summary: 3 successful, 0 failures, 0 skipped
37. Add in the Description and Impact
• Now that we know our tests are working, add info for other users
• Determine the impact of this requirement:
0.0 < 0.01 – Information only
0.01 < 0.4 – LOW impact
0.4 < 0.7 – MEDIUM impact
0.7 < 0.9 – HIGH impact
0.9 – 1.0 – CRITICAL impact
• Add a description of the controls
38. $ vi banner.rb
control 'mycorp-sshd-01' do
impact 1.0
desc 'Require a warning message to be displayed notifying ssh users of the
ownership of the system.'
describe file('/etc/ssh/sshd_banner') do
it { should exist }
its('content') { should match /Authorized users only/ }
end
describe file('/etc/ssh/sshd_config') do
its('content') { should match /^Banner /etc/ssh/sshd_banner/ }
end
end
40. Profiles
• InSpec profiles allow you to package and share sets of InSpec
tests for your organization or for a specific application set
• Profiles are made up of controls
• Controls are made up of resources and tests, with priority and
metadata
Name your controls based on what they do or link them to a written doc
• Each profile can have multiple test files included and many
controls
41. Hardening with InSpec
• Centos 7 host
• os-hardening cookbook from https://supermarket.chef.io
• /dev-sec/linux-baseline InSpec profile from https://github.com/dev-
sec/linux-baseline
42. What’s in the linux-baseline Profile on https://dev-sec.io
control 'os-02' do
impact 1.0
title 'Check owner and permissions for /etc/shadow'
desc 'Check periodically the owner and permissions for /etc/shadow'
describe file('/etc/shadow') do
it { should exist }
it { should be_file }
it { should be_owned_by 'root' }
its('group') { should eq shadow_group }
it { should_not be_executable }
it { should be_writable.by('owner') }
...
43. Use the Profile
$ git clone https://github.com/dev-sec/linux-baseline
...
$ sudo inspec exec linux-baseline
Profile Summary: 26 successful controls, 27 control failures, 1
control skipped
Test Summary: 80 successful, 45 failures, 1 skipped
$
45. Use Chef to Fix the Issues
• We've detected some issues, now we will correct them using Chef
• We'll create a Policyfile for this system that will consume other resources
• No Chef Server needed for this method
• All required Chef resources will be downloaded from Chef's open source
community site, https://supermarket.chef.io/
46. $ vi Policyfile.rb
name 'server-hardening'
default_source :supermarket
run_list 'os-hardening::default'
• This process will create a collection of Chef cookbooks to fix the issues that
caused InSpec to fail
• We won't need to connect to a Chef server for this method, all the
cookbooks will be downloaded locally
47. Run Commands
chef install Policyfile.rb
chef export Policyfile.rb harden
cd harden
sudo chef-client -z
Starting Chef Client, version 14.6.47
Using policy 'server-hardening' at revision '…'
resolving cookbooks for run list: ["os-hardening::default@3.1.0 (193f7ad)"]
Synchronizing Cookbooks:
- sysctl (1.0.5)
- ohai (5.2.5)
- os-hardening (3.1.0)
...
Chef Client finished, 141/206 resources updated in 47 seconds
48. Rerun the Tests
$ cd ~
$ sudo inspec exec linux-baseline/
...
Profile Summary: 52 successful controls, 1 control failure, 1
control skipped
Test Summary: 124 successful, 1 failure, 1 skipped
49. Auditd
× package-08: Install auditd (1 failed)
✔ System Package audit should be installed
✔ Audit Daemon Config log_file should cmp == "/var/log/audit/audit.log"
✔ Audit Daemon Config log_format should cmp == "raw"
✔ Audit Daemon Config flush should match /^INCREMENTAL|INCREMENTAL_ASYNC$/
× Audit Daemon Config max_log_file_action should cmp == "keep_logs"
expected: "keep_logs"
got: ROTATE
(compared using `cmp` matcher)
50. What’s Still Failing?
• Find the controls that aren’t passing
• Decide if you want to fix them or forget them
• We'll build a new profile to wrap around linux-baseline
And exclude the failing test
51.
52. Building New Profiles
$ inspec init profile my_hardening
Create new profile at /home/chef/my_hardening
* Create file README.md
* Create directory controls
* Create file controls/example.rb
* Create file inspec.yml
* Create directory libraries
This is a new InSpec profile, vs the new Chef cookbook we created earlier.
53. Including Profiles
$ vi my_hardening/inspec.yml
name: my_hardening
title: InSpec Profile
...
version: 0.1.0
depends:
- name: linux-baseline
path: ../linux-baseline
54. Profile Dependencies
• InSpec will find or retrieve the included profile
• You can choose to use all of the profile or pick a few controls
• You can also exclude controls that don't meet your needs
• Create a new control file to manage the other profile's controls
55. Skipping Individual Controls
$ vi my_hardening/controls/my.rb
include_controls 'linux-baseline' do
skip_control 'package-08'
end
We want to run all of the controls from linux-baseline except package-08
• You can also remove the file my_hardening/controls/example.rb if you want
to
56. Rerun the InSpec Profile
$ sudo inspec exec my_hardening/
...
Profile Summary: 53 successful controls, 0 control failures, 1
control skipped
Test Summary: 115 successful, 0 failures, 1 skipped
57. Additional Features
• Use InSpec to test resources in the Cloud – Azure, AWS, GCP
describe aws_s3_bucket('test_bucket') do
it { should_not be_public }
end
• Industry-standard profiles such as CIS available via commercial solutions
58. Test Kitchen
• InSpec also runs as a test suite in Test Kitchen
• Test Kitchen is a tool for your team to create fast-feedback loops for
development
• Add InSpec tests to TK so that any change can also be certified with the
security profile before it is pushed to source code repository
• More info at http://kitchen.ci/
59. InSpec and Chef's Automate
• InSpec profiles are a component of Chef's Automate server, providing a
GUI and metrics collection about compliance across your estate
• Additional industry-standard profiles are also available commercially via
Automate
Compliance requirements are often set out in flat documents. Sometimes PDFs, sometimes other formats, but they have a tendency to be a huge list of characteristics and checkboxes to be investigated and potentially remediated. Security tools may be somewhat more flexible, encoded into a set of shell scripts that check and verify the systems after they are built. But what if it was easy to build these checks into the workflow while the systems are being built and applications installed.
For the purposes of compliance, we actually wanted a common language, in code, that would allow all audiences – compliance, security, and devops – to collaborate on. And this code will then act on systems.
This is whyInSpec was developed.
For bits like the ssh configuration that are considered more infrastructure than application, these practices are common, changes are periodically rolled into the source images for new hosts (or containers) and the old configurations are eventually purged from production. It’s a herd-immunity approach.
But what happens if the thing to be tested is affected by a continuously developed application? Like run time configurations for java, or your databases. Can you count on every team to always know all of the requirements?
Plug InSpec into whatever command set you are already using