6. How to Run InSpec
6.1 How to Run InSpec
In this section, we will discuss how to run InSpec. In Section 8, you will put this into practice!
6.2 Requirements
To run InSpec, you must have:
- The InSpec Executable - InSpec's executable must be installed on the machine running the scans. This does not have to be the same machine that is being tested! (We will run InSpec from the GitHub Codespaces lab environment. InSpec is already downloaded in the GitHub Codespaces lab environment after running the install script using
source build-lab.sh
.) Check out the Installation Tab for more information on installing InSpec in a different environment. - A Target - You need something to test! In the GitHub Codespaces lab environment, we have two Docker containers running to test.
- An InSpec Profile - You need the tests themselves! This is Ruby code containing all of the controls, or tests, that we intend to run against the target. You may have this code stored locally on your runner machine, or you may get it from any accessible network location -- GitHub is an excellent example. We will practice running profiles from local files and from a GitHub repository.
6.3 The InSpec Command Formula
To validate a system, we need to run InSpec from the command line. There are many different options we can use with the InSpec executable to run our tests. Let's break down the simple formula based on the requirements above.
inspec exec <profile> -t <target> --more-flags ... --reporter <report types (json, cli, yaml, etc.)>
inspec exec WHERE_IS_THE_PROFILE # 6.3.1 & 6.3.2
-t WHAT_IS_THE_TARGET # 6.3.3
--more-flags EXTRA_STUFF # 6.3.4
--reporter WHAT_SHOULD_INSPEC_DO_WITH_THE_RESULTS # 6.3.5
6.3.1 Start with inspec exec
(required)
inspec exec
We'll start with inspec exec
so that the InSpec executable knows what we are asking it to do -- in this case, inspec exec
tells InSpec to execute an existing profile. (There are other options, like inspec shell
and inspec profile init
, but they are not our focus right now. We'll look at some of them during other MITRE SAF training classes.)
6.3.2 WHERE_IS_THE_PROFILE (required)
inspec exec WHERE_IS_THE_PROFILE
Then, you must give the location of the InSpec profile. In other words, we need to show the InSpec executable where to find the code for the tests themselves. If the InSpec profile is stored locally, you can simply write out the path to that file location, such as /root/path/to/InSpecProfiles/nginx-profile
. If you wish to run a profile directly from GitHub or some other location on the Internet or other network, you can enter the URL of the profile instead, such as https://github.com/mitre/nginx-stigready-baseline
.
6.3.3 WHAT_IS_THE_TARGET (default: local machine)
-t WHAT_IS_THE_TARGET # 6.3.3
Next, you need to tell your computer what the target is -- or rather, what system we are trying to test. You add this information using the -t
flag.
Without the -t
flag, by default, InSpec will execute the selected profile against your local system. However, we are often trying to run tests against a remote target. You could test a bare metal server, a virtual machine, a Docker container, and many others. You can specify different protocols to connect to your remote system using SSH, WinRM, and more. For example, we could connect to a system using -t ssh://user-name@host-name:port
or -t docker://instance-id
. We will talk more about these options later.
6.3.4 EXTRA_STUFF (optional)
--more-flags EXTRA_STUFF # 6.3.4
There are many more options that you can specify when running the InSpec command. For example, --enhanced-outcomes
is used to show additional context when results are displayed in the CLI reporter. Additionally, inputs can be included for your profile using the --inputs
or --input-file
flags. For example, --input-file /path/to/inputs.yml
allows you to add inputs that tailor your test profile to your environment's particular configuration. You can find more information on inputs in the Tailoring Inputs section.
6.3.5 WHAT_SHOULD_INSPEC_DO_WITH_THE_RESULTS (default: cli)
--reporter WHAT_SHOULD_INSPEC_DO_WITH_THE_RESULTS # 6.3.5
And of course, once our test has been completed, you probably want to see the results! You can specify where those results are displayed or saved based on what you enter after the --reporter
flag at the end of your command. For example, the following would print the results on the command line and save it to a file (by creating or overwriting) the file at /path/to/results.json: --reporter cli json:/path/to/results.json
. If you do not add this information, the command will default to providing results on the command line, but it will not save those into a file unless you specify the --reporter
flag like the example.
Each profile's README should give an example of running the InSpec command for that profile; however, you can always reference the complete documentation on the InSpec command options here.
Want to give it a try?
We will go more in depth on this example in the next two sections, but if you want a head start, you can give running InSpec a try by running this command in your Codespace terminal.
inspec exec https://github.com/mitre/nginx-stigready-baseline -t docker://nginx --enhanced-outcomes --reporter cli
In the above example, we are testing an NGINX server. We get the InSpec profile (all the tests) from GitHub by stating https://github.com/mitre/nginx-stigready-baseline
. We use the NGINX target (-t
) that is running via Docker in our Codespace environment by stating docker://nginx
, and we report the results to the terminal (CLI output) with enhanced-outcomes
enabled for readability. Not all the metadata generated by inspec exec
is displayed in the CLI output. Instead, it is included in the results file so that we can explore it in more detail using Heimdall.
Note: The first time you run InSpec, it will likely ask you to accept Chef's license like this:
+---------------------------------------------+
Chef License Acceptance
Before you can continue, 1 product license
must be accepted. View the license at
https://www.chef.io/end-user-license-agreement/
License that need accepting:
* Chef InSpec
Do you accept the 1 product license (yes/no)?
>
You can type yes
and press enter. This will only happen one time.
If you are using InSpec in a pipeline, you can silently accept the license. Refer to Chef's documentation for more information.
Transports - Advanced Examples
The -t
flag (or --target
flag in long form) specifies what target you want InSpec to scan. How you connect to that target is via a transport. Transports use standard ports and protocols. Some examples are SSH, WinRM, AWS SSM, Docker, and the Kubernetes API.
Containers (docker transport)
inspec exec https://github.com/mitre/nginx-stigready-baseline
-t docker://instance_id
--input-file <path_to_your_input_file/name_of_your_input_file.yml>
--reporter json:<path_to_your_output_file/name_of_your_output_file.json>
SSH Transport
inspec exec https://github.com/mitre/nginx-stigready-baseline
-t ssh://Username:Password@IP
--input-file <path_to_your_input_file/name_of_your_input_file.yml>
--reporter json:<path_to_your_output_file/name_of_your_output_file.json>
Defaults
Note that if you do not provide one of the required flags in the InSpec exec command, there is default behavior.
Missing Flag | Default Behavior |
---|---|
No target (-t or --target) | Uses your local machine (where InSpec is running) as the target. |
No --reporter flag | Prints results to the terminal on the InSpec runner machine |
6.4 How to Deploy InSpec
It is intended and recommended that InSpec be installed on a "runner" host (such as a DevOps orchestration server, an administrative management system, or a developer's workstation/laptop) and run against the target remotely. However, InSpec may be deployed in various ways depending on the needs of the user: