mirror of
https://github.com/inspec/inspec
synced 2025-02-17 06:28:40 +00:00
Add regular page content and images
Signed-off-by: IanMadd <imaddaus@chef.io>
This commit is contained in:
parent
c93a515c6f
commit
ab17f16b0a
25 changed files with 4693 additions and 0 deletions
55
www/content/inspec/_index.md
Normal file
55
www/content/inspec/_index.md
Normal file
|
@ -0,0 +1,55 @@
|
|||
+++
|
||||
title = "An Overview of Chef InSpec"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Chef InSpec Overview"
|
||||
identifier = "inspec/_index.md Chef InSpec Overview"
|
||||
parent = "inspec"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/_index.md)
|
||||
|
||||
Chef InSpec is an open-source framework for testing and auditing your applications and infrastructure. Chef InSpec works by comparing the actual state of your system with the desired state that you express in easy-to-read and easy-to-write Chef InSpec code. Chef InSpec detects violations and displays findings in the form of a report, but puts you in control of remediation.
|
||||
|
||||
{{< note >}}
|
||||
|
||||
Versions of Chef InSpec 4.0 and later require accepting the EULA. Please
|
||||
visit the [license acceptance page](/chef_license_accept/) for more information.
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
## Getting started with Chef InSpec
|
||||
|
||||
Below are some of the core concepts that make up Chef InSpec.
|
||||
|
||||
### Create a profile
|
||||
|
||||
[Profiles](/inspec/profiles/) are the core of the Chef InSpec testing experience. Use Chef InSpec
|
||||
profiles to manage everything you need to run a security or compliance scan--attributes,
|
||||
metadata, and the tests themselves.
|
||||
|
||||
### Add your tests
|
||||
|
||||
You can create tests three different ways: By composing your own tests, by
|
||||
including tests from the [Chef Supermarket](https://supermarket.chef.io/)
|
||||
or by adding tests from the [Dev-Sec Project](http://dev-sec.io/) as dependencies.
|
||||
You can also customize your tests--pulling in the tests from our Supermarket and
|
||||
change them to suit your unique needs with the easy-to-read and easy-to-write Chef
|
||||
InSpec domain specific language.
|
||||
|
||||
### Target your system
|
||||
|
||||
Run your tests wherever your infrastructure is--locally or in the cloud. Chef
|
||||
InSpec is designed for platforms and treats operating systems as special cases.
|
||||
Chef InSpec helps you, whether you use Windows Server on your own hardware or
|
||||
run Linux in Docker containers in the cloud. As for the cloud, you can use Chef
|
||||
InSpec to target applications and services running on AWS and Azure.
|
||||
|
||||
### Resources
|
||||
|
||||
Chef InSpec has 80+ [resources](/inspec/resources/) ready use--apache to zfs pool.
|
||||
If you need a solution that we haven’t provided, you can write your own [custom
|
||||
resource](/inspec/dsl_resource/).
|
525
www/content/inspec/cli.md
Normal file
525
www/content/inspec/cli.md
Normal file
|
@ -0,0 +1,525 @@
|
|||
+++
|
||||
title = "InSpec CLI"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "InSpec Executable"
|
||||
identifier = "inspec/reference/cli.md InSpec Executable"
|
||||
parent = "inspec/reference"
|
||||
weight = 10
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/cli.md)
|
||||
|
||||
Use the InSpec CLI to run tests and audits against targets using local, SSH, WinRM, or Docker connections.
|
||||
|
||||
## archive
|
||||
|
||||
Archive a profile to tar.gz (default) or zip
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec archive PATH
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``--airgap``, ``--no-airgap``
|
||||
Fallback to using local archives if fetching fails.
|
||||
* ``--ignore-errors``, ``--no-ignore-errors``
|
||||
Ignore profile warnings.
|
||||
* ``-o``, ``--output=OUTPUT``
|
||||
Save the archive to a path
|
||||
* ``--overwrite``, ``--no-overwrite``
|
||||
Overwrite existing archive.
|
||||
* ``--profiles-path=PROFILES_PATH``
|
||||
Folder which contains referenced profiles.
|
||||
* ``--tar``, ``--no-tar``
|
||||
Generates a tar.gz archive.
|
||||
* ``--vendor-cache=VENDOR_CACHE``
|
||||
Use the given path for caching dependencies. (default: ~/.inspec/cache)
|
||||
* ``--zip``, ``--no-zip``
|
||||
Generates a zip archive.
|
||||
|
||||
## check
|
||||
|
||||
Verify all tests at the specified path
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec check PATH
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``--format=FORMAT``
|
||||
|
||||
* ``--profiles-path=PROFILES_PATH``
|
||||
Folder which contains referenced profiles.
|
||||
* ``--vendor-cache=VENDOR_CACHE``
|
||||
Use the given path for caching dependencies. (default: ~/.inspec/cache)
|
||||
|
||||
## detect
|
||||
|
||||
Detect the target os
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec detect
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``-b``, ``--backend=BACKEND``
|
||||
Choose a backend: local, ssh, winrm, docker.
|
||||
* ``--bastion-host=BASTION_HOST``
|
||||
Specifies the bastion host if applicable
|
||||
* ``--bastion-port=BASTION_PORT``
|
||||
Specifies the bastion port if applicable
|
||||
* ``--bastion-user=BASTION_USER``
|
||||
Specifies the bastion user if applicable
|
||||
* ``--config=CONFIG``
|
||||
Read configuration from JSON file (`-` reads from stdin).
|
||||
* ``--enable-password=ENABLE_PASSWORD``
|
||||
Password for enable mode on Cisco IOS devices.
|
||||
* ``--format=FORMAT``
|
||||
|
||||
* ``--host=HOST``
|
||||
Specify a remote host which is tested.
|
||||
* ``--insecure``, ``--no-insecure``
|
||||
Disable SSL verification on select targets
|
||||
* ``-i``, ``--key-files=one two three``
|
||||
Login key or certificate file for a remote scan.
|
||||
* ``--password=PASSWORD``
|
||||
Login password for a remote scan, if required.
|
||||
* ``--path=PATH``
|
||||
Login path to use when connecting to the target (WinRM).
|
||||
* ``-p``, ``--port=N``
|
||||
Specify the login port for a remote scan.
|
||||
* ``--proxy-command=PROXY_COMMAND``
|
||||
Specifies the command to use to connect to the server
|
||||
* ``--self-signed``, ``--no-self-signed``
|
||||
Allow remote scans with self-signed certificates (WinRM).
|
||||
* ``--shell``, ``--no-shell``
|
||||
Run scans in a subshell. Only activates on Unix.
|
||||
* ``--shell-command=SHELL_COMMAND``
|
||||
Specify a particular shell to use.
|
||||
* ``--shell-options=SHELL_OPTIONS``
|
||||
Additional shell options.
|
||||
* ``--ssl``, ``--no-ssl``
|
||||
Use SSL for transport layer encryption (WinRM).
|
||||
* ``--sudo``, ``--no-sudo``
|
||||
Run scans with sudo. Only activates on Unix and non-root user.
|
||||
* ``--sudo-command=SUDO_COMMAND``
|
||||
Alternate command for sudo.
|
||||
* ``--sudo-options=SUDO_OPTIONS``
|
||||
Additional sudo options for a remote scan.
|
||||
* ``--sudo-password=SUDO_PASSWORD``
|
||||
Specify a sudo password, if it is required.
|
||||
* ``-t``, ``--target=TARGET``
|
||||
Simple targeting option using URIs, e.g. ssh://user:pass@host:port
|
||||
* ``--target-id=TARGET_ID``
|
||||
Provide a ID which will be included on reports
|
||||
* ``--user=USER``
|
||||
The login user for a remote scan.
|
||||
* ``--winrm-basic-auth-only``, ``--no-winrm-basic-auth-only``
|
||||
Whether to use basic authentication, defaults to false (WinRM).
|
||||
* ``--winrm-disable-sspi``, ``--no-winrm-disable-sspi``
|
||||
Whether to use disable sspi authentication, defaults to false (WinRM).
|
||||
* ``--winrm-transport=WINRM_TRANSPORT``
|
||||
Specify which transport to use, defaults to negotiate (WinRM).
|
||||
|
||||
## env
|
||||
|
||||
Output shell-appropriate completion configuration
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec env
|
||||
```
|
||||
|
||||
## exec
|
||||
|
||||
Run all test files at the specified locations.
|
||||
|
||||
loads the given profile(s) and fetches their dependencies if needed. then
|
||||
connects to the target and executes any controls contained in the profiles.
|
||||
one or more reporters are used to generate output.
|
||||
|
||||
```
|
||||
exit codes:
|
||||
0 normal exit, all tests passed
|
||||
1 usage or general error
|
||||
2 error in plugin system
|
||||
3 fatal deprecation encountered
|
||||
100 normal exit, at least one test failed
|
||||
101 normal exit, at least one test skipped but none failed
|
||||
172 chef license not accepted
|
||||
```
|
||||
|
||||
below are some examples of using `exec` with different test locations:
|
||||
|
||||
automate:
|
||||
```
|
||||
inspec compliance login
|
||||
inspec exec compliance://username/linux-baseline
|
||||
```
|
||||
|
||||
supermarket:
|
||||
```
|
||||
inspec exec supermarket://username/linux-baseline
|
||||
```
|
||||
|
||||
local profile (executes all tests in `controls/`):
|
||||
```
|
||||
inspec exec /path/to/profile
|
||||
```
|
||||
|
||||
local single test (doesn't allow inputs or custom resources)
|
||||
```
|
||||
inspec exec /path/to/a_test.rb
|
||||
```
|
||||
|
||||
git via ssh
|
||||
```
|
||||
inspec exec git@github.com:dev-sec/linux-baseline.git
|
||||
```
|
||||
|
||||
git via https (.git suffix is required):
|
||||
```
|
||||
inspec exec https://github.com/dev-sec/linux-baseline.git
|
||||
```
|
||||
|
||||
private git via https (.git suffix is required):
|
||||
```
|
||||
inspec exec https://api_token@github.com/dev-sec/linux-baseline.git
|
||||
```
|
||||
|
||||
private git via https and cached credentials (.git suffix is required):
|
||||
```
|
||||
git config credential.helper cache
|
||||
git ls-remote https://github.com/dev-sec/linux-baseline.git
|
||||
inspec exec https://github.com/dev-sec/linux-baseline.git
|
||||
```
|
||||
|
||||
web hosted fileshare (also supports .zip):
|
||||
```
|
||||
inspec exec https://webserver/linux-baseline.tar.gz
|
||||
```
|
||||
|
||||
web hosted fileshare with basic authentication (supports .zip):
|
||||
```
|
||||
inspec exec https://username:password@webserver/linux-baseline.tar.gz
|
||||
```
|
||||
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec exec LOCATIONS
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``--attrs=one two three``
|
||||
Legacy name for --input-file - deprecated.
|
||||
* ``-b``, ``--backend=BACKEND``
|
||||
Choose a backend: local, ssh, winrm, docker.
|
||||
* ``--backend-cache``, ``--no-backend-cache``
|
||||
Allow caching for backend command output. (default: true)
|
||||
* ``--bastion-host=BASTION_HOST``
|
||||
Specifies the bastion host if applicable
|
||||
* ``--bastion-port=BASTION_PORT``
|
||||
Specifies the bastion port if applicable
|
||||
* ``--bastion-user=BASTION_USER``
|
||||
Specifies the bastion user if applicable
|
||||
* ``--config=CONFIG``
|
||||
Read configuration from JSON file (`-` reads from stdin).
|
||||
* ``--controls=one two three``
|
||||
A list of control names to run, or a list of /regexes/ to match against control names. Ignore all other tests.
|
||||
* ``--create-lockfile``, ``--no-create-lockfile``
|
||||
Write out a lockfile based on this execution (unless one already exists)
|
||||
* ``--distinct-exit``, ``--no-distinct-exit``
|
||||
Exit with code 101 if any tests fail, and 100 if any are skipped (default). If disabled, exit 0 on skips and 1 for failures.
|
||||
* ``--enable-password=ENABLE_PASSWORD``
|
||||
Password for enable mode on Cisco IOS devices.
|
||||
* ``--host=HOST``
|
||||
Specify a remote host which is tested.
|
||||
* ``--input=name1=value1 name2=value2``
|
||||
Specify one or more inputs directly on the command line, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures.
|
||||
* ``--input-file=one two three``
|
||||
Load one or more input files, a YAML file with values for the profile to use
|
||||
* ``--insecure``, ``--no-insecure``
|
||||
Disable SSL verification on select targets
|
||||
* ``-i``, ``--key-files=one two three``
|
||||
Login key or certificate file for a remote scan.
|
||||
* ``--password=PASSWORD``
|
||||
Login password for a remote scan, if required.
|
||||
* ``--path=PATH``
|
||||
Login path to use when connecting to the target (WinRM).
|
||||
* ``-p``, ``--port=N``
|
||||
Specify the login port for a remote scan.
|
||||
* ``--profiles-path=PROFILES_PATH``
|
||||
Folder which contains referenced profiles.
|
||||
* ``--proxy-command=PROXY_COMMAND``
|
||||
Specifies the command to use to connect to the server
|
||||
* ``--reporter=one two:/output/file/path``
|
||||
Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit, yaml
|
||||
* ``--reporter-backtrace-inclusion``, ``--no-reporter-backtrace-inclusion``
|
||||
Include a code backtrace in report data (default: true)
|
||||
* ``--reporter-message-truncation=REPORTER_MESSAGE_TRUNCATION``
|
||||
Number of characters to truncate failure messages in report data to (default: no truncation)
|
||||
* ``--self-signed``, ``--no-self-signed``
|
||||
Allow remote scans with self-signed certificates (WinRM).
|
||||
* ``--shell``, ``--no-shell``
|
||||
Run scans in a subshell. Only activates on Unix.
|
||||
* ``--shell-command=SHELL_COMMAND``
|
||||
Specify a particular shell to use.
|
||||
* ``--shell-options=SHELL_OPTIONS``
|
||||
Additional shell options.
|
||||
* ``--show-progress``, ``--no-show-progress``
|
||||
Show progress while executing tests.
|
||||
* ``--silence-deprecations=all|GROUP GROUP...``
|
||||
Suppress deprecation warnings. See install_dir/etc/deprecations.json for list of GROUPs or use 'all'.
|
||||
* ``--ssl``, ``--no-ssl``
|
||||
Use SSL for transport layer encryption (WinRM).
|
||||
* ``--sudo``, ``--no-sudo``
|
||||
Run scans with sudo. Only activates on Unix and non-root user.
|
||||
* ``--sudo-command=SUDO_COMMAND``
|
||||
Alternate command for sudo.
|
||||
* ``--sudo-options=SUDO_OPTIONS``
|
||||
Additional sudo options for a remote scan.
|
||||
* ``--sudo-password=SUDO_PASSWORD``
|
||||
Specify a sudo password, if it is required.
|
||||
* ``-t``, ``--target=TARGET``
|
||||
Simple targeting option using URIs, e.g. ssh://user:pass@host:port
|
||||
* ``--target-id=TARGET_ID``
|
||||
Provide a ID which will be included on reports
|
||||
* ``--user=USER``
|
||||
The login user for a remote scan.
|
||||
* ``--vendor-cache=VENDOR_CACHE``
|
||||
Use the given path for caching dependencies. (default: ~/.inspec/cache)
|
||||
* ``--waiver-file=one two three``
|
||||
Load one or more waiver files.
|
||||
* ``--winrm-basic-auth-only``, ``--no-winrm-basic-auth-only``
|
||||
Whether to use basic authentication, defaults to false (WinRM).
|
||||
* ``--winrm-disable-sspi``, ``--no-winrm-disable-sspi``
|
||||
Whether to use disable sspi authentication, defaults to false (WinRM).
|
||||
* ``--winrm-transport=WINRM_TRANSPORT``
|
||||
Specify which transport to use, defaults to negotiate (WinRM).
|
||||
|
||||
## help
|
||||
|
||||
Describe available commands or one specific command
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec help [COMMAND]
|
||||
```
|
||||
|
||||
## json
|
||||
|
||||
Read all tests in path and generate a json summary
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec json PATH
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``--controls=one two three``
|
||||
A list of controls to include. Ignore all other tests.
|
||||
* ``-o``, ``--output=OUTPUT``
|
||||
Save the created profile to a path
|
||||
* ``--profiles-path=PROFILES_PATH``
|
||||
Folder which contains referenced profiles.
|
||||
* ``--vendor-cache=VENDOR_CACHE``
|
||||
Use the given path for caching dependencies. (default: ~/.inspec/cache)
|
||||
|
||||
## nothing
|
||||
|
||||
Does nothing
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec nothing
|
||||
```
|
||||
|
||||
## schema
|
||||
|
||||
Print the json schema
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec schema NAME
|
||||
```
|
||||
|
||||
## shell
|
||||
|
||||
Open an interactive debugging shell
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec shell
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``-b``, ``--backend=BACKEND``
|
||||
Choose a backend: local, ssh, winrm, docker.
|
||||
* ``--bastion-host=BASTION_HOST``
|
||||
Specifies the bastion host if applicable
|
||||
* ``--bastion-port=BASTION_PORT``
|
||||
Specifies the bastion port if applicable
|
||||
* ``--bastion-user=BASTION_USER``
|
||||
Specifies the bastion user if applicable
|
||||
* ``-c``, ``--command=COMMAND``
|
||||
A single command string to run instead of launching the shell
|
||||
* ``--config=CONFIG``
|
||||
Read configuration from JSON file (`-` reads from stdin).
|
||||
* ``--depends=one two three``
|
||||
A space-delimited list of local folders containing profiles whose libraries and resources will be loaded into the new shell
|
||||
* ``--distinct-exit``, ``--no-distinct-exit``
|
||||
Exit with code 100 if any tests fail, and 101 if any are skipped but none failed (default). If disabled, exit 0 on skips and 1 for failures.
|
||||
* ``--enable-password=ENABLE_PASSWORD``
|
||||
Password for enable mode on Cisco IOS devices.
|
||||
* ``--host=HOST``
|
||||
Specify a remote host which is tested.
|
||||
* ``--insecure``, ``--no-insecure``
|
||||
Disable SSL verification on select targets
|
||||
* ``--inspect``, ``--no-inspect``
|
||||
Use verbose/debugging output for resources.
|
||||
* ``-i``, ``--key-files=one two three``
|
||||
Login key or certificate file for a remote scan.
|
||||
* ``--password=PASSWORD``
|
||||
Login password for a remote scan, if required.
|
||||
* ``--path=PATH``
|
||||
Login path to use when connecting to the target (WinRM).
|
||||
* ``-p``, ``--port=N``
|
||||
Specify the login port for a remote scan.
|
||||
* ``--proxy-command=PROXY_COMMAND``
|
||||
Specifies the command to use to connect to the server
|
||||
* ``--reporter=one two:/output/file/path``
|
||||
Enable one or more output reporters: cli, documentation, html, progress, json, json-min, json-rspec, junit
|
||||
* ``--self-signed``, ``--no-self-signed``
|
||||
Allow remote scans with self-signed certificates (WinRM).
|
||||
* ``--shell``, ``--no-shell``
|
||||
Run scans in a subshell. Only activates on Unix.
|
||||
* ``--shell-command=SHELL_COMMAND``
|
||||
Specify a particular shell to use.
|
||||
* ``--shell-options=SHELL_OPTIONS``
|
||||
Additional shell options.
|
||||
* ``--ssl``, ``--no-ssl``
|
||||
Use SSL for transport layer encryption (WinRM).
|
||||
* ``--sudo``, ``--no-sudo``
|
||||
Run scans with sudo. Only activates on Unix and non-root user.
|
||||
* ``--sudo-command=SUDO_COMMAND``
|
||||
Alternate command for sudo.
|
||||
* ``--sudo-options=SUDO_OPTIONS``
|
||||
Additional sudo options for a remote scan.
|
||||
* ``--sudo-password=SUDO_PASSWORD``
|
||||
Specify a sudo password, if it is required.
|
||||
* ``-t``, ``--target=TARGET``
|
||||
Simple targeting option using URIs, e.g. ssh://user:pass@host:port
|
||||
* ``--target-id=TARGET_ID``
|
||||
Provide a ID which will be included on reports
|
||||
* ``--user=USER``
|
||||
The login user for a remote scan.
|
||||
* ``--winrm-basic-auth-only``, ``--no-winrm-basic-auth-only``
|
||||
Whether to use basic authentication, defaults to false (WinRM).
|
||||
* ``--winrm-disable-sspi``, ``--no-winrm-disable-sspi``
|
||||
Whether to use disable sspi authentication, defaults to false (WinRM).
|
||||
* ``--winrm-transport=WINRM_TRANSPORT``
|
||||
Specify which transport to use, defaults to negotiate (WinRM).
|
||||
|
||||
## supermarket
|
||||
|
||||
Supermarket commands
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec supermarket SUBCOMMAND ...
|
||||
```
|
||||
|
||||
## vendor
|
||||
|
||||
Download all dependencies and generate a lockfile in a `vendor` directory
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec vendor PATH
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``--overwrite``, ``--no-overwrite``
|
||||
Overwrite existing vendored dependencies and lockfile.
|
||||
|
||||
## version
|
||||
|
||||
Prints the version of this tool
|
||||
|
||||
### Syntax
|
||||
|
||||
This subcommand has the following syntax:
|
||||
|
||||
```bash
|
||||
inspec version
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
This subcommand has additional options:
|
||||
|
||||
* ``--format=FORMAT``
|
125
www/content/inspec/config.md
Normal file
125
www/content/inspec/config.md
Normal file
|
@ -0,0 +1,125 @@
|
|||
+++
|
||||
title = "InSpec Configuration File"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Configuration"
|
||||
identifier = "inspec/reference/config.md Configuration"
|
||||
parent = "inspec/reference"
|
||||
weight = 60
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/config.md)
|
||||
|
||||
This documents the Chef InSpec configuration file format introduced in version 3.5 of InSpec and extended in later versions.
|
||||
|
||||
## Config File Location
|
||||
|
||||
By default, Chef InSpec looks for a config file in `~/.inspec/config.json`. Chef InSpec does not need a configuration file to run.
|
||||
|
||||
You may also specify the location using `--config`. For example, to run the shell using a config file in `/etc/inspec`, use `inspec shell --config /etc/inspec/config.json`.
|
||||
|
||||
## Config File Format Versions
|
||||
|
||||
Config files must contain a top-level key, `version`, which indicates the file format. This allows us to add new fields without breaking old installations.
|
||||
|
||||
## Version 1.1
|
||||
|
||||
### Complete Example
|
||||
|
||||
```
|
||||
{
|
||||
"version": "1.1",
|
||||
"cli_options":{
|
||||
"color": "true"
|
||||
},
|
||||
"credentials": {
|
||||
"ssh": {
|
||||
"my-target": {
|
||||
"host":"somewhere.there.com",
|
||||
"user":"bob"
|
||||
}
|
||||
}
|
||||
},
|
||||
"reporter": {
|
||||
"automate" : {
|
||||
"stdout" : false,
|
||||
"url" : "https://YOUR_A2_URL/data-collector/v0/",
|
||||
"token" : "YOUR_A2_API_TOKEN",
|
||||
"insecure" : true,
|
||||
"node_name" : "inspec_test_node",
|
||||
"environment" : "prod"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
version
|
||||
: Should have the value '1.1'.
|
||||
|
||||
cli_options
|
||||
: Any long-form command line option, without the leading dashes.
|
||||
|
||||
credentials
|
||||
: Train-transport-specific options. Store the options keyed first by transport name, then by a name you'll use later on. The combination of transport name and your chosen name can be used in the `--target` option to `inspec exec`, as `--target transport-name://connection-name`.
|
||||
|
||||
For example, if the config file contains:
|
||||
|
||||
```
|
||||
{
|
||||
"credentials": {
|
||||
"winrm": {
|
||||
"myconn": {
|
||||
"user": "Administrator",
|
||||
"host": "prod01.east.example.com",
|
||||
"disable_sspi": true,
|
||||
"connection_retries": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use `-t winrm://myconn` to connect to the host, with the given extra options.
|
||||
|
||||
Each Train transport offers a variety of options. By using the credential set facility, you are able to easily set options that are not accessible via the Train URI.
|
||||
|
||||
You may have as many credential sets in the config file as you require.
|
||||
|
||||
If you use a target URI and the portion after the `://` cannot be matched to credential set name, Chef InSpec will send the URI to Train to be parsed as a Train URI. Thus, you can still do `ssh://someuser@myhost.com`.
|
||||
|
||||
You can use a credential set, and then override individual options using command line options.
|
||||
|
||||
Credential sets are intended to work hand-in-hand with the underlying credentials storage facility of the transport. For example, if you have a `~/.ssh/config` file specifying that the sally-key.pem file should be used with the host `somehost.com`, and you have a credential set that specifies that host, then when Train tries to connect to that host, the SSH library will automatically use the SSH config file to use the indicated key.
|
||||
|
||||
### reporter
|
||||
|
||||
You may also set output (reporter) options in the config file. See the [Reporters Page](/inspec/reporters/) for details.
|
||||
|
||||
## Version 1.2
|
||||
|
||||
Version 1.2 adds a top-level field, "plugins".
|
||||
|
||||
### plugins
|
||||
|
||||
Use the `plugins` top-level configuration field to provide configuration settings to plugins that you use with Chef InSpec. Refer to the documentation of the plugin you are using for details regarding what settings are available.
|
||||
|
||||
To use this new feature, add a new top-level key in your config file named `plugins`. Then create a sub-key named for each plugin you wish to configure. Each plugin will have a key-value are that it may use as it sees fit - Chef Inspec does not specify the structure. Here is an example, using contrived plugins:
|
||||
|
||||
```
|
||||
{
|
||||
"version":"1.2",
|
||||
"plugins": {
|
||||
"inspec-training-wheels": {
|
||||
"diameter": "4 inches"
|
||||
},
|
||||
"inspec-input-secrets": {
|
||||
"security-tokens: [
|
||||
"123456789".
|
||||
"abcdef252875"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
421
www/content/inspec/dsl_inspec.md
Normal file
421
www/content/inspec/dsl_inspec.md
Normal file
|
@ -0,0 +1,421 @@
|
|||
+++
|
||||
title = "Chef InSpec DSL"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Chef InSpec DSL"
|
||||
identifier = "inspec/reference/dsl_inspec.md Chef InSpec DSL"
|
||||
parent = "inspec/reference"
|
||||
weight = 70
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/dsl_inspec.md)
|
||||
|
||||
Chef InSpec is a run-time framework and rule language used to specify compliance,
|
||||
security, and policy requirements. It includes a collection of resources that help
|
||||
you write auditing controls quickly and easily. The syntax used by both open source
|
||||
and [Chef compliance](/compliance/) auditing is the same. The open source [Chef InSpec resource](/inspec/resources/)
|
||||
framework is compatible with [Chef compliance](/compliance/).
|
||||
|
||||
The Chef InSpec DSL is a Ruby DSL for writing audit controls, which includes audit resources that you can invoke.
|
||||
|
||||
The following sections describe the syntax and show some simple examples of using the Chef InSpec resources.
|
||||
|
||||
## Syntax
|
||||
|
||||
The following resource tests |ssh| server configuration. For example, a simple control may described as:
|
||||
|
||||
```ruby
|
||||
describe sshd_config do
|
||||
its('Port') { should cmp 22 }
|
||||
end
|
||||
```
|
||||
|
||||
In various use cases like implementing IT compliance across different departments, it becomes handy to extend the control with metadata. Each control may define an additional ``impact``, ``title`` or ``desc``. An example looks like:
|
||||
|
||||
```ruby
|
||||
control 'sshd-8' do
|
||||
impact 0.6
|
||||
title 'Server: Configure the service port'
|
||||
desc 'Always specify which port the SSH server should listen.'
|
||||
desc 'rationale', 'This ensures that there are no unexpected settings' # Requires Chef InSpec >=2.3.4
|
||||
tag 'ssh','sshd','openssh-server'
|
||||
tag cce: 'CCE-27072-8'
|
||||
ref 'NSA-RH6-STIG - Section 3.5.2.1', url: 'https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf'
|
||||
|
||||
describe sshd_config do
|
||||
its('Port') { should cmp 22 }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
where
|
||||
|
||||
* `'sshd-8'` is the name of the control
|
||||
* `impact`, `title`, and `desc` define metadata that fully describes the importance of the control, its purpose, with a succinct and complete description
|
||||
* `desc` when given only one argument it sets the default description. As of Chef InSpec 2.3.4, when given 2 arguments (see: `'rationale'`) it will use the first argument as a header when rendering in Automate
|
||||
* `impact` is a string, or numeric that measures the importance of the compliance results.
|
||||
Valid strings for impact are `none`, `low`, `medium`, `high`, and `critical`. The values are based off CVSS 3.0.
|
||||
A numeric value must be between `0.0` and `1.0`. The value ranges are:
|
||||
* `0.0 to <0.01` these are controls with no impact, they only provide information
|
||||
* `0.01 to <0.4` these are controls with low impact
|
||||
* `0.4 to <0.7` these are controls with medium impact
|
||||
* `0.7 to <0.9` these are controls with high impact
|
||||
* `0.9 to 1.0` these are critical controls
|
||||
* `tag` is optional meta-information with with key or key-value pairs
|
||||
* `ref` is a reference to an external document
|
||||
* `describe` is a block that contains at least one test. A `control` block must contain at least one `describe` block, but may contain as many as required
|
||||
* `sshd_config` is a Chef InSpec resource. For the full list of Chef InSpec resources, see Chef InSpec resource documentation
|
||||
* `its('Port')` is the matcher; `{ should eq '22' }` is the test. A `describe` block must contain at least one matcher, but may contain as many as required
|
||||
|
||||
## Advanced concepts
|
||||
|
||||
### Checking if at least one condition passes with `describe.one`
|
||||
|
||||
With Chef InSpec, you can check if at least one of a collection of checks is true.
|
||||
For example, if you configure a setting in two different locations, then you may want to test if either configuration A or configuration B is set.
|
||||
Do this task with the `describe.one` block.
|
||||
`describe.one` defines a set of `describe` blocks where only one block needs to pass.
|
||||
|
||||
```ruby
|
||||
describe.one do
|
||||
describe ConfigurationA do
|
||||
its('setting_1') { should eq true }
|
||||
end
|
||||
|
||||
describe ConfigurationB do
|
||||
its('setting_2') { should eq true }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### `describe.one` usage notes
|
||||
|
||||
* A `describe.one` block passes if one of its nested `describe` blocks has all assertions passing. A `describe.one` block needs an entire `describe` block to pass and not just a single assertion.
|
||||
* Chef InSpec will always evaluate all the tests contained within `describe.one`. It does not short-circuit upon evaluating a passing `describe` block.
|
||||
* Nesting a `describe.one` block inside another `describe.one` block is not supported.
|
||||
|
||||
### Sensitive resources
|
||||
|
||||
In some scenarios, you may be writing checks that involve resources with sensitive content, such as a file resource.
|
||||
In case of failures, you may desire to suppress output.
|
||||
Do this task by adding the `:sensitive` flag to the resource definition:
|
||||
|
||||
```ruby
|
||||
describe file('/tmp/mysecretfile'), :sensitive do
|
||||
its('content') { should match /secret_info/ }
|
||||
end
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
The following examples show simple compliance tests using a single `control` block.
|
||||
|
||||
### Test System Event Log
|
||||
|
||||
The following test shows how to audit machines running Windows 2012 R2 that password complexity is enabled:
|
||||
|
||||
```ruby
|
||||
control 'windows-account-102' do
|
||||
impact 'critical'
|
||||
title 'Windows Password Complexity is Enabled'
|
||||
desc 'Password must meet complexity requirement'
|
||||
describe security_policy do
|
||||
its('PasswordComplexity') { should cmp 1 }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Test if PostgreSQL passwords are empty
|
||||
|
||||
The following test shows how to audit machines running PostgreSQL to ensure that passwords are not empty.
|
||||
|
||||
```ruby
|
||||
control 'postgres-7' do
|
||||
impact 1.0
|
||||
title "Don't allow empty passwords"
|
||||
describe postgres_session('user', 'pass').query("SELECT * FROM pg_shadow WHERE passwd IS NULL;") do
|
||||
its('output') { should cmp '' }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Test if MySQL passwords are in ENV
|
||||
|
||||
The following test shows how to audit machines running MySQL to ensure that passwords are not stored in `ENV`:
|
||||
|
||||
```ruby
|
||||
control 'mysql-3' do
|
||||
impact 1.0
|
||||
title 'Do not store your MySQL password in your ENV'
|
||||
desc '
|
||||
Storing credentials in your ENV may easily expose
|
||||
them to an attacker. Prevent this at all costs.
|
||||
'
|
||||
describe command('env') do
|
||||
its('stdout') { should_not match /^MYSQL_PWD=/ }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Test if `/etc/ssh` is a Directory
|
||||
|
||||
The following test shows how to audit machines to ensure that `/etc/ssh` is a directory:
|
||||
|
||||
```ruby
|
||||
control 'basic-1' do
|
||||
impact 1.0
|
||||
title '/etc/ssh should be a directory'
|
||||
desc '
|
||||
In order for OpenSSH to function correctly, its
|
||||
configuration path must be a folder.
|
||||
'
|
||||
describe file('/etc/ssh') do
|
||||
it { should be_directory }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Test if Apache running
|
||||
|
||||
The following test shows how to audit machines to ensure that Apache is enabled and running:
|
||||
|
||||
```ruby
|
||||
control 'apache-1' do
|
||||
impact 'medium'
|
||||
title 'Apache2 should be configured and running'
|
||||
describe service(apache.service) do
|
||||
it { should be_enabled }
|
||||
it { should be_running }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Test if insecure packages are installed
|
||||
|
||||
The following test shows how to audit machines for insecure packages:
|
||||
|
||||
```ruby
|
||||
control 'cis-os-services-5.1.3' do
|
||||
impact 0.7
|
||||
title '5.1.3 Ensure rsh client is not installed'
|
||||
describe package('rsh') do
|
||||
it { should_not be_installed }
|
||||
end
|
||||
describe package('rsh-redone-client') do
|
||||
it { should_not be_installed }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Test Windows Registry Keys
|
||||
|
||||
The following test shows how to audit machines to ensure Safe DLL Search Mode is enabled:
|
||||
|
||||
```ruby
|
||||
control 'windows-base-101' do
|
||||
impact 1.0
|
||||
title 'Safe DLL Search Mode is Enabled'
|
||||
desc '
|
||||
@link: https://msdn.microsoft.com/en-us/library/ms682586(v=vs.85).aspx
|
||||
'
|
||||
describe registry_key('HKLM\\System\\CurrentControlSet\\Control\\Session Manager') do
|
||||
it { should exist }
|
||||
it { should_not have_property_value('SafeDllSearchMode', :type_dword, '0') }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Use `only_if` to exclude a specific control
|
||||
|
||||
This example shows how to allow skipping certain controls if conditions are not
|
||||
met by using `only_if`. In this example, the control will not be performed if
|
||||
the `redis-cli` command does not exist. A optional message can say why it was skipped.
|
||||
|
||||
```ruby
|
||||
control 'nutcracker-connect-redis-001' do
|
||||
impact 'critical'
|
||||
title 'Check if nutcracker can pass commands to redis'
|
||||
desc 'execute redis-cli set key command, to check connectivity of the service'
|
||||
|
||||
only_if('redis is not installed.') do
|
||||
command('redis-cli').exist?
|
||||
end
|
||||
|
||||
describe command('redis-cli SET test_inspec "HELLO"') do
|
||||
its('stdout') { should match /OK/ }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Mixing this with other conditionals, such as checking existence of the files, can
|
||||
help to test different test paths using Chef InSpec. With this way, you can skip
|
||||
certain controls, which would 100% fail due to the way servers are prepared, but
|
||||
you know that the same control suites are reused later in different circumstances
|
||||
by different teams.
|
||||
|
||||
Some notes about `only_if`:
|
||||
|
||||
- `only_if` applies to the entire `control`. If the results of the `only_if`
|
||||
block evaluate to false, any Chef InSpec resources mentioned as part of a
|
||||
`describe` block will not be run. Additionally, the contents of the describe
|
||||
blocks will not be run. However, bare Ruby expressions and bare Chef InSpec
|
||||
resources (not assocated with a describe block) preceding the only_if statement
|
||||
will run
|
||||
|
||||
To illustrate:
|
||||
|
||||
```ruby
|
||||
control "whatruns" do
|
||||
command("do_something") # This will ALWAYS run
|
||||
describe command("do_another_thing") do # This will not run
|
||||
command("do_yet_another_thing") # This will not run
|
||||
end
|
||||
only_if { false }
|
||||
command("do_something_else") # This will not run
|
||||
end
|
||||
```
|
||||
|
||||
* Only one `only_if` is permitted per `control` block. If multiple `only_if` blocks are present, only the last `only_if` block will be honored
|
||||
* If used outside a control block, `only_if` skips all controls in the current file
|
||||
* To implement complex logic, use Ruby 'or' (`||`) and 'and' (`&&`) inside your `only_if` block:
|
||||
|
||||
```ruby
|
||||
only_if('ready for launch') do
|
||||
rocket_is_ready && weather_is_clear
|
||||
end
|
||||
```
|
||||
|
||||
### Additional metadata for controls
|
||||
|
||||
The following example illustrates various ways to add tags and references to `control`
|
||||
|
||||
```ruby
|
||||
control 'ssh-1' do
|
||||
impact 1.0
|
||||
|
||||
title 'Allow only SSH Protocol 2'
|
||||
desc '
|
||||
Only SSH protocol version 2 connections should be permitted.
|
||||
The default setting in /etc/ssh/sshd_config is correct, and can be
|
||||
verified by ensuring that the following line appears: Protocol 2
|
||||
'
|
||||
|
||||
tag 'production','development'
|
||||
tag 'ssh','sshd','openssh-server'
|
||||
|
||||
tag cce: 'CCE-27072-8'
|
||||
tag disa: 'RHEL-06-000227'
|
||||
|
||||
tag remediation: 'stig_rhel6/recipes/sshd-config.rb'
|
||||
tag remediation: 'https://supermarket.chef.io/cookbooks/ssh-hardening'
|
||||
|
||||
ref 'NSA-RH6-STIG - Section 3.5.2.1', url: 'https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf'
|
||||
ref 'http://people.redhat.com/swells/scap-security-guide/RHEL/6/output/ssg-centos6-guide-C2S.html'
|
||||
|
||||
describe ssh_config do
|
||||
its('Protocol') { should cmp 2 }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Using Ruby in InSpec
|
||||
|
||||
The Chef InSpec DSL is a Ruby based language. This allows you to be flexible with
|
||||
Ruby code in controls:
|
||||
|
||||
```ruby
|
||||
json_obj = json('/file.json')
|
||||
json_obj['keys'].each do |value|
|
||||
..
|
||||
end
|
||||
```
|
||||
|
||||
Ruby allows a lot of freedoms, but should be limited in controls so that they
|
||||
remain portable and easy to understand. Please see our [profile style guide](/inspec/style/).
|
||||
|
||||
Core and custom resources are written as regular Ruby classes which inherit from
|
||||
`Inspec.resource`.
|
||||
|
||||
### Interactive Debugging with Pry
|
||||
|
||||
Here's a sample Chef InSpec control that uses Ruby variables to instantiate
|
||||
a Chef InSpec resource once and use the content in multiple tests.
|
||||
|
||||
```ruby
|
||||
control 'check-perl' do
|
||||
impact 0.3
|
||||
title 'Check perl compiled options and permissions'
|
||||
perl_out = command('perl -V')
|
||||
#require 'pry'; binding.pry;
|
||||
describe perl_out do
|
||||
its('exit_status') { should eq 0 }
|
||||
its('stdout') { should match /USE_64_BIT_ALL/ }
|
||||
its('stdout') { should match /useposix=true/ }
|
||||
its('stdout') { should match /-fstack-protector/ }
|
||||
end
|
||||
|
||||
# extract an array of include directories
|
||||
perl_inc = perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
||||
# ensure include directories are only writable by 'owner'
|
||||
perl_inc.each do |path|
|
||||
describe directory(path.strip) do
|
||||
it { should_not be_writable.by 'group' }
|
||||
it { should_not be_writable.by 'other' }
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
An **advanced** but very useful Ruby tip. In the previous example, I
|
||||
commented out the `require 'pry'; binding.pry;` line. If you remove the
|
||||
`#` prefix and run the control, the execution will stop at that line and
|
||||
give you a `pry` shell. Use that to troubleshoot, print variables, see
|
||||
methods available, etc. For the above example:
|
||||
|
||||
```ruby
|
||||
[1] pry> perl_out.exit_status
|
||||
=> 0
|
||||
[2] pry> perl_out.stderr
|
||||
=> ""
|
||||
[3] pry> ls perl_out
|
||||
Inspec::Plugins::Resource#methods: inspect
|
||||
Inspec::Resources::Cmd#methods: command exist? exit_status result stderr stdout to_s
|
||||
Inspec::Resource::Registry::Command#methods: inspec
|
||||
instance variables: @__backend_runner__ @__resource_name__ @command @result
|
||||
[4] pry> perl_out.stdout.partition('@INC:').last.strip.split("\n")
|
||||
=> ["/Library/Perl/5.18/darwin-thread-multi-2level",
|
||||
" /Library/Perl/5.18",
|
||||
...REDACTED...
|
||||
[5] pry> exit # or abort
|
||||
```
|
||||
|
||||
You can use `pry` inside both the controls DSL and resources. Similarly,
|
||||
for dev and test, you can use `inspec shell` which is based on `pry`,
|
||||
for example:
|
||||
|
||||
```ruby
|
||||
$ inspec shell
|
||||
Welcome to the interactive InSpec Shell
|
||||
To find out how to use it, type: help
|
||||
|
||||
inspec> command('ls ~/projects/github/inspec/docs').stdout
|
||||
=> "README.md\nconfig.md\ndev\ndsl_inspec.md\ndsl_resource.md\nglossary.md\nhabitat.md\ninputs.md\ninspec_and_friends.md\nmatchers.md\nmigration.md\nplatforms.md\nplugin_kitchen_inspec.md\nplugins.md\nprofiles.md\nreporters.md\nresources\nshared\nshell.md\nstyle.md\nwaivers.md\n"
|
||||
inspec> command('ls ~/projects/github/inspec/docs').stdout.split("\n").first
|
||||
=> "README.md"
|
||||
|
||||
inspec> help command
|
||||
Name: command
|
||||
|
||||
Description:
|
||||
Use the command InSpec audit resource to test an arbitrary command that is run on the system.
|
||||
|
||||
Example:
|
||||
describe command('ls -al /') do
|
||||
it { should exist }
|
||||
its('stdout') { should match /bin/ }
|
||||
its('stderr') { should eq '' }
|
||||
its('exit_status') { should eq 0 }
|
||||
end
|
||||
```
|
137
www/content/inspec/dsl_resource.md
Normal file
137
www/content/inspec/dsl_resource.md
Normal file
|
@ -0,0 +1,137 @@
|
|||
+++
|
||||
title = "Resource DSL"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Custom Resources"
|
||||
identifier = "inspec/reference/dsl_resource.md Custom Resources"
|
||||
parent = "inspec/reference"
|
||||
weight = 90
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/dsl_resource.md)
|
||||
|
||||
Chef InSpec provides a mechanism for defining custom resources. These become
|
||||
available with their respective names and provide easy functionality to
|
||||
profiles.
|
||||
|
||||
## Resource location
|
||||
|
||||
Resources may be added to profiles in the libraries folder:
|
||||
|
||||
```bash
|
||||
$ tree examples/profile
|
||||
examples/profile
|
||||
...
|
||||
├── libraries
|
||||
│ └── example_config.rb
|
||||
```
|
||||
|
||||
## Resource structure
|
||||
|
||||
The smallest possible resource takes this form:
|
||||
|
||||
```ruby
|
||||
class Tiny < Inspec.resource(1)
|
||||
name 'tiny'
|
||||
end
|
||||
```
|
||||
|
||||
Resources are written as a regular Ruby class which inherits from
|
||||
Inspec.resource. The number (1) specifies the version this resource
|
||||
plugin targets. As Chef InSpec evolves, this interface may change and may
|
||||
require a higher version.
|
||||
|
||||
The following attributes can be configured:
|
||||
|
||||
- name - Identifier of the resource (required)
|
||||
- desc - Description of the resource (optional)
|
||||
- example - Example usage of the resource (optional)
|
||||
- supports - (Chef InSpec 2.0+) Platform restrictions of the resource (optional)
|
||||
|
||||
The following methods are available to the resource:
|
||||
|
||||
- inspec - Contains a registry of all other resources to interact with the operating system or target in general.
|
||||
- skip\_resource - A resource may call this method to indicate that requirements aren't met. All tests that use this resource will be marked as skipped.
|
||||
|
||||
The following example shows a full resource using attributes and methods
|
||||
to provide simple access to a configuration file:
|
||||
|
||||
```ruby
|
||||
class ExampleConfig < Inspec.resource(1)
|
||||
name 'example_config'
|
||||
|
||||
# Restrict to only run on the below platforms (if none were given, all OS's supported)
|
||||
supports platform_family: 'fedora'
|
||||
supports platform: 'centos', release: '6.9'
|
||||
# Supports `*` for wildcard matcher in the release
|
||||
supports platform: 'centos', release: '7.*'
|
||||
|
||||
desc '
|
||||
Resource description ...
|
||||
'
|
||||
|
||||
example '
|
||||
describe example_config do
|
||||
its("signal") { should eq "on" }
|
||||
end
|
||||
'
|
||||
|
||||
# Load the configuration file on initialization
|
||||
def initialize(path = nil)
|
||||
@path = path || '/etc/example.conf'
|
||||
@params = SimpleConfig.new( read_content )
|
||||
end
|
||||
|
||||
# Expose all parameters of the configuration file.
|
||||
def method_missing(name)
|
||||
@params[name]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read_content
|
||||
f = inspec.file(@path)
|
||||
# Test if the path exist and that it's a file
|
||||
if f.file?
|
||||
# Retrieve the file's contents
|
||||
f.content
|
||||
else
|
||||
# If the file doesn't exist, skip all tests that use example_config
|
||||
raise Inspec::Exceptions::ResourceSkipped, "Can't read config at #{@path}"
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
For a full example, see our [example resource](https://github.com/chef/inspec/blob/master/examples/profile/libraries/example_config.rb).
|
||||
|
||||
## Lazy Loading
|
||||
|
||||
Prior to InSpec v4.16, resources were pre-loaded for every invocation
|
||||
of `inspec`. This was a heavy and unnecessary burden on the system and
|
||||
exacerbated startup times (especially on Windows).
|
||||
|
||||
As of InSpec v4.16, resources are lazily loaded into the `inspec`
|
||||
process upon use. This greatly speeds up the initial startup costs of
|
||||
the `inspec` process and only loads what you need to use. For example, `inspec
|
||||
--version` no longer runs for 10 seconds!.
|
||||
|
||||
### Overriding Core Resources
|
||||
|
||||
Lazy loading does change the way the resource registry is handled in
|
||||
ways that might break some assumptions. Specifically,
|
||||
`inspec.<resource>` isn't pre-populated with the core resources that
|
||||
InSpec ships with. If you make a local/custom resource of the same
|
||||
name, referring to the core resource via `inspec.<resource>` will not
|
||||
resolve to the core resource.
|
||||
|
||||
As such, overriding core resources is not recommended best practice.
|
||||
|
||||
If you really do need to do this, it is easiest to make a local
|
||||
resource with a new name and refer to the core resource directly.
|
||||
Otherwise, you need to ensure that the core resource you want is
|
||||
registered (via `require "inspec/resource/<name>"`) _before_ your
|
||||
profile is run to ensure it is eagerly loaded and in the global
|
||||
resource registry.
|
399
www/content/inspec/glossary.md
Normal file
399
www/content/inspec/glossary.md
Normal file
|
@ -0,0 +1,399 @@
|
|||
+++
|
||||
title = "Chef InSpec Glossary"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Chef InSpec Glossary"
|
||||
identifier = "inspec/glossary.md Chef InSpec Glossary"
|
||||
parent = "inspec"
|
||||
weight = 50
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/glossary.md)
|
||||
|
||||
This document should help you become familiar with some of the terminology used by the Chef InSpec project.
|
||||
|
||||
There are two ways to use it:
|
||||
|
||||
- A [text glossary](#text-glossary). Learn the meaning of a word you have encountered.
|
||||
- A [visual glossary](#visual-glossary). Look at examples and see how the parts are labelled. You can then use the text glossary to read details of each concept.
|
||||
|
||||
## Visual Glossary
|
||||
|
||||
### Motivating Example
|
||||
|
||||
Suppose we are interested in auditing cars. Let's suppose we have two Chef InSpec resources for auditing: `cars`, which searches for and filters groups of cars, and `car`, which performs detailed auditing of a single car.
|
||||
|
||||
### Basic Syntax
|
||||
|
||||
Let's look at some simple examples.
|
||||
|
||||
### Singular Resource Example
|
||||
|
||||
```inspec
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should exist }
|
||||
its('license_plate') { should cmp 'MOONMAN' }
|
||||
it { should be_classy }
|
||||
it { should_not have_check_engine_light_on }
|
||||
end
|
||||
```
|
||||
|
||||
#### describe car(owner: 'Tony Clifton') do
|
||||
|
||||
_car_ is a [resource](#resource). Since we are talking about only one car, it is a [singular resource](#singular-resource).
|
||||
|
||||
#### describe car(_owner: 'Tony Clifton'_)
|
||||
|
||||
_owner_ is a [resource parameter](#resource-parameter) and _'Tony Clifton'_ is a resource parameter value.
|
||||
|
||||
#### _it { should exist }_
|
||||
|
||||
Each line within the resource block beginning with `it` or `its` is a [test](#test). Use [it](#it) to access [resource-specific matchers](#resource-specific-matcher), and use [its](#its) to access [properties](#property) of the [resource](#resource), which are in turn used with [universal matchers](#universal-matcher).
|
||||
|
||||
#### its('_license\_plate_') { should cmp 'MOONMAN' }
|
||||
|
||||
_license\_plate_ is a [property](#property) belonging to the [resource](#resource). Properties expose testable information about the resource. Some properties are numbers, some (like this one) are text, some are lists, and some are more complex objects. Properties are always used with [universal matchers](#universal-matcher).
|
||||
|
||||
#### its('license\_plate') { should _cmp_ 'MOONMAN' }
|
||||
|
||||
_cmp_ is a [universal matcher](#universal-matcher). `cmp` is a very flexible, loosely typed equality operator; here it checks to see if the license plate text is the same as the text 'MOONMAN'. Notice that the test operates on the license plate text (the property value) and not on the resource. You can find the full list of supported universal matchers on the [Universal Matcher page](/inspec/matchers/).
|
||||
|
||||
#### its('license\_plate') { should cmp _'MOONMAN'_ }
|
||||
|
||||
_'MOONMAN'_ is an [expected result](#expected-result). Some matchers take an expected result; others do not.
|
||||
|
||||
#### it { should _be\_classy_ }
|
||||
|
||||
_be\_classy_ is a [resource-specific matcher](#resource-specific-matcher). It returns a yes-or-no value, based on whether Tony's car is classy or not. (It is. Tony is a classy guy.)
|
||||
|
||||
#### it { _should\_not_ have\_check\_engine\_light\_on }
|
||||
|
||||
_should\_not_ indicates this is a negated test. So, this test passes if the matcher says "no".
|
||||
|
||||
### Plural Resource Example
|
||||
|
||||
```inspec
|
||||
describe cars.where(color: /^b/) do
|
||||
it { should exist }
|
||||
its('manufacturers') { should include 'Cadillac' }
|
||||
its('count') { should be >= 10 }
|
||||
end
|
||||
```
|
||||
|
||||
#### describe _cars_.where(color: /^b/) do
|
||||
|
||||
_cars_ is a [resource](#resource). Since we are potentially talking about many cars, it is a [plural resource](#plural-resource).
|
||||
|
||||
#### describe cars._where(color: /^b/)_ do
|
||||
|
||||
_where(color: /^b/)_ is a [filter statement](#filter-statement). Without a filter statement, `cars` simply selects all the cars in the world.
|
||||
|
||||
#### describe cars.where(_color: /^b/_) do
|
||||
|
||||
_color_ is a [filter criterion](#filter-criteria) along with its filter value, _/^b/_. Here, the criterion expresses that we want to select all cars whose colors begin with the letter 'b' - blue, brown, burgundy, etc.
|
||||
|
||||
#### _it { should exist }_
|
||||
|
||||
Each line within the resource block beginning with `it` or `its` is a [test](#test). Use [it](#it) to access [resource-specific matchers](#resource-specific-matcher), and use [its](#its) to access [properties](#property) of the [resource](#resource), which are in turn used with [universal matchers](#universal-matcher).
|
||||
|
||||
With plural resources, `exist` has a special meaning: did the filter match anything?
|
||||
|
||||
#### its('_manufacturers_') { should include 'Cadillac' }
|
||||
|
||||
_manufacturers_ is a [property](#property) of the [resource](#resource). Properties expose testable information about the resource. On plural resources, properties are almost always names in the plural, and almost always return a list of values. Here, the test returns a list of the car manufacturer names. Some list properties are de-duplicated; for example, you might have 10 cars, but if they are all Subarus and Cadillacs, it returns only two entries in the `manufacturers` property. Be sure to check the documentation for your resource.
|
||||
|
||||
#### its('manufacturers') { should _include_ 'Cadillac' }
|
||||
|
||||
_include_ is a [universal matcher](#universal-matcher). `include` works with lists, and checks to see if an expected result is present. Here, it checks to see if the list of manufacturers contains an entry with the text 'Cadillac'. Notice it operates on the manufacturers list (the property value) and not on the resource. You can find the full list of supported universal matchers on the [Universal Matcher page](/inspec/matchers/).
|
||||
|
||||
#### its('manufacturers') { should include '_Cadillac_' }
|
||||
|
||||
_'Cadillac'_ is an [expected result](#expected-result). Some matchers take an expected result; others do not.
|
||||
|
||||
#### its('count') { should _be >=_ 10 }
|
||||
|
||||
_be >=_ is an [operator matcher](#operator matcher). It allows you to perform numeric comparisons. All plural resources have a `count` property.
|
||||
|
||||
## Text Glossary
|
||||
|
||||
### attribute
|
||||
|
||||
Deprecated name for [input](#input).
|
||||
|
||||
### control
|
||||
|
||||
### control block
|
||||
|
||||
The _`control`_ keyword is used to declare a _`control block`_. Here, the word 'control' means a 'regulatory control, recommendation, or requirement' - not a software engineering construct. A `control block` has a name (which usually refers to the assigned ID of the regulatory recommendation it implements), metadata such as descriptions, references, and tags, and finally groups together related [describe blocks](#describe-block) to implement the checks.
|
||||
|
||||
### core resource
|
||||
|
||||
A [resource](#resource) that is included with InSpec; you are not required to install additional [plugins](#plugin) or depend on a [resource pack](#resource pack) to use the resource.
|
||||
|
||||
### custom resource
|
||||
|
||||
A [resource](#resource) that is _not_ included with InSpec. It may be a resource of your own creation, or one you obtain by depending on a [resource pack](#resource pack).
|
||||
|
||||
### describe
|
||||
|
||||
### describe block
|
||||
|
||||
The _`describe`_ keyword is used with a _`describe block`_ to refer to a Chef InSpec resource. You use the `describe` keyword along with the name of a [resource](#resource) to enclose related [tests](#test) that apply to the resource. Multiple describe blocks are usually grouped together in a [control](#control), but you can also use them outside of a control.
|
||||
|
||||
```Ruby
|
||||
control 'Rule 1.1 - Color restrictions' do
|
||||
# Count only blue cars
|
||||
describe cars.where(color: 'blue') do
|
||||
its('count') { should eq 20 }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### DSL
|
||||
|
||||
_DSL_ is an acronym for _Domain Specific Language_. It refers to the language extensions Chef InSpec provides to make authoring resources and controls easier. While Chef InSpec control files are use Ruby, the _Control DSL_ makes it easy to write controls without knowledge of Ruby by providing DSL keywords such as [describe](#describe), [control](#control), [it](#it) and [its](#its). See the [Chef InSpec DSL page](/inspec/dsl_inspec/) for details about keywords available to control authors.
|
||||
|
||||
For [custom resource](#custom-resource) authors, an additional DSL is available - see the [Resource DSL page](/inspec/dsl_resource/).
|
||||
|
||||
### expected result
|
||||
|
||||
When using a [matcher](#matcher), the _`expected result`_ is the value the matcher will compare against the [property](#property) being accessed.
|
||||
|
||||
In this example, the [`cmp`](/inspec/matchers/#cmp) matcher is being used to compare the `color` property to the expected result 'black'.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Bruce Wayne') do
|
||||
its('color') { should cmp 'black' }
|
||||
end
|
||||
```
|
||||
|
||||
### filter statement
|
||||
|
||||
When using a [plural resource](#plural-resource), a _`filter statement`_ is used to select individual test subjects using [filter criteria](#filter-criteria). A filter statement almost always is indicated by the keyword `where`, and may be repeated using method chaining.
|
||||
|
||||
A filter statement may use method call syntax (which allows basic criteria operations, such as equality, regex matching, and ruby `===` comparison) or block syntax (which allows arbitrary code).
|
||||
|
||||
In this example, `where(...)` is the filter statement.
|
||||
|
||||
```Ruby
|
||||
# Count only blue cars
|
||||
describe cars.where(color: 'blue') do
|
||||
its('count') { should eq 20 }
|
||||
end
|
||||
```
|
||||
|
||||
### filter criterion
|
||||
|
||||
### filter criteria
|
||||
|
||||
When using a [plural resource](#plural-resource), a _`filter criterion`_ is used to select individual test subjects within a [filter statement](#filter-statement). You may use multiple _`filter criteria`_ in a single filter statement.
|
||||
|
||||
When method-call syntax is used with the filter statement, you provide filter criteria as a Hash, with filter criteria names as keys, and conditions as the Hash values. You may provide test, true/false, or numbers, in which case the comparison is equality; or you may provide a regular expression, in which case a match is performed.
|
||||
|
||||
Here, `(color: blue)` is a single filter criterion being used with a filter statement in method-call syntax.
|
||||
|
||||
```Ruby
|
||||
# Count only blue cars
|
||||
describe cars.where(color: 'blue') do
|
||||
its('count') { should eq 20 }
|
||||
end
|
||||
```
|
||||
|
||||
When block-method syntax is used with the filter statement, you provide a block. The block may contain arbitrary code, and each filter criteria will be available as an accessor. The block will be evaluated once per row, and each block that evaluates to a truthy value will pass the filter.
|
||||
|
||||
Here, `{ engine_cylinders >= 6 }` is a block-syntax filter statement referring to one filter criterion.
|
||||
|
||||
```Ruby
|
||||
# Vroom!
|
||||
describe cars.where { engine_cylinders >= 6 } do
|
||||
its('city_mpg_ratings') { should_not include '4-star' }
|
||||
end
|
||||
```
|
||||
|
||||
### input
|
||||
|
||||
An _`input`_ is a value that Chef InSpec can source from a number of providers, including from the command line, profile metadata, or within the control file DSL itself. You can use this feature either to change a [profile's](#profile) behavior by passing different attribute files or to store secrets that should not be directly present in a profile.
|
||||
|
||||
Inputs were formerly known as `attributes`. Chef InSpec inputs are unrelated to Chef Infra attributes.
|
||||
|
||||
The CLI syntax for inputs is documented under the [`inspec exec`](/inspec/cli/#exec) command.
|
||||
|
||||
Inputs are documented in detail in the [input documentation](/inspec/inputs/).
|
||||
|
||||
### it
|
||||
|
||||
Within a [describe block](#describe), _`it`_ declares an individual [test](#test) directly against the [resource](#resource) (as opposed to testing against one of the resource's [properties](#property), as [its](#its) does). Though it is possible to use [universal matchers](#universal-matcher) with `it`, it is much more typical to use [resource-specific matchers](#resource-specific-matchers).
|
||||
|
||||
`it` may be used with `should`, or negated using `should_not`.
|
||||
|
||||
Here, `it { should ... }` declares a test, calling the `classy?` matcher on Tony Clifton's car.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
end
|
||||
```
|
||||
|
||||
### its
|
||||
|
||||
Within a [describe block](#describe), _`its`_ declares an individual [test](#test) against a property of the [resource](#resource) (as opposed to testing directly against the resource itself, as [it](#it) does). You must use [universal matchers](#universal-matcher) with `its`; you cannot use [resource-specific matchers](#resource-specific-matchers).
|
||||
|
||||
`its` may be used with `should`, or negated using `should_not`.
|
||||
|
||||
The property to access is passed as a single string argument to `its`. As an advanced usage, if the property has methods you are interested in, you can call them using '`.`' within the string; even more advanced calling patterns are possible - see [the rspec-its documentation](https://github.com/rspec/rspec-its#usage).
|
||||
|
||||
Here, `its('fuzzy_dice') { should ... }` declares a test, testing against the `fuzzy_dice` property of Tony Clifton's car. Let's assume - Tony being Tony - that `fuzzy_dice` will return an Array.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
its('fuzzy_dice') { should_not be_empty }
|
||||
its('fuzzy_dice.count') { should be >= 2 }
|
||||
its('fuzzy_dice.first.fuzziness') { should cmp 'outlandishly so' }
|
||||
end
|
||||
```
|
||||
|
||||
### matcher
|
||||
|
||||
A _`matcher`_ performs the actual assertions against [resources](#resource) or the [properties](#property) of resources. Matchers always return a true/false value. Matchers fall into two camps:
|
||||
|
||||
* [resource-specific matchers](#resource-specific-matchers), which operate directly on the resource, are used with [it](#it), and tend to be highly customized to the auditing needs of the resource
|
||||
* [universal matchers](#universal-matchers), which operate on the properties of the resource, are used with [its](#its), and tend to be very generic, operating on text, numbers, and lists
|
||||
|
||||
Some matchers accept parameters, called [expected results](#expected-results).
|
||||
|
||||
For information on how RSpec matchers are related o Chef InSpec matchers, see [Chef InSpec and RSpec](/inspec/inspec_and_friends/#rspec).
|
||||
|
||||
Here, `be_classy` is a resource-specific matcher operating directly on the `car`, while `cmp` is a universal matcher operating on the `manufacturer` property.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
its('manufacturer') { should cmp 'Cadillac' }
|
||||
end
|
||||
```
|
||||
|
||||
### plural resource
|
||||
|
||||
A _`plural resource`_ is a [resource](#resource) that specializes in performing searches and represents multiple occurrences of the resource on the [target](#target) platform. Plural resources are used to audit counts, inspect group properties, and have the unique ability to enforce negative tests ("nothing like this should exist") often required by compliance standards. Plural resources are not intended to perform in-depth auditing of an individual; use [singular resources](#singular-resource) for that.
|
||||
|
||||
Plural resources nearly always have a name that ends in 's': `processes`, `aws_security_groups`, `cars`. Plural resources generally do not have [resource-specific matchers](#resource-specific-matcher). If they have properties, they are almost always list properties, meaning that they return a list of values, which may or may not be de-duplicated.
|
||||
|
||||
Plural resources support [filter statements](#filter-statement). See the [resource documentation](/inspec/resources/) for details regarding which [filter criteria](#filter-criteria) are supported on each resource.
|
||||
|
||||
Here, `cars` is a plural resource.
|
||||
|
||||
```Ruby
|
||||
describe cars.where(color: 'blue') do
|
||||
its('count') { should eq 20 }
|
||||
its('license_plates') { should include 'AUTOAZUL' }
|
||||
|
||||
# License plates are unique, should have 20
|
||||
its('license_plates.count') { should cmp 20 }
|
||||
|
||||
# Manufacturers are de-duplicated
|
||||
its('manufacturers') { should include 'Subaru' }
|
||||
its('manufacturers.count') { should be < 10 }
|
||||
end
|
||||
```
|
||||
|
||||
### profile
|
||||
|
||||
A _`profile`_ is a set of related [controls](#control) in a distributable form. You might have a locally-developed profile that your organization uses to define baseline security on all machines, or you might use a pre-defined profile that implements the requirements of a specific compliance standard. For full details about the capabilities of a profile, see the [profile documentation](/inspec/profiles/).
|
||||
|
||||
Profiles may be distributed locally as a directory tree, as a tarball or zipfile at a URL, as a git repo, and several other ways. Profiles contain metadata, including versioning, and can setup dependency relationships with other profiles.
|
||||
|
||||
Aside from controls, profiles can also contain [custom resources](#custom-resource). If the profile contains only custom resources and no controls, we call it a [resource pack](#resource-pack).
|
||||
|
||||
### property
|
||||
|
||||
A fact about a [resource](#resource). Typically, you use the [its](#its) keyword to access the property and write a [test](#test) within a [describe block](#describe-block), and then use a [universal matcher](#universal-matcher) to make assertions about the value of the property.
|
||||
|
||||
Each resource has different properties. See the [resource documentation](/inspec/resources/) for details.
|
||||
|
||||
Here, `manufacturer` is a property of the `car` resource.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
its('manufacturer') { should cmp 'Cadillac' }
|
||||
end
|
||||
```
|
||||
|
||||
### reporter
|
||||
|
||||
An output format for the `inspec exec` command line. Several reporters are available, including JSON and JUnit; see the [inspec exec documentation](/inspec/cli/#exec).
|
||||
|
||||
### resource
|
||||
|
||||
A _`resource`_ represents a category of things on the [target](#target) you wish to examine. For example, to check for the existence and permissions of a file, you would use the [`file`](/inspec/resources/file/) resource. Chef InSpec offers dozens of different resources, from the highly specialized (such as `aws_security_group`, which examines firewall rules in AWS) to the very general (such as `command`, which runs a command and lets you examine its output).
|
||||
|
||||
Resources are generally categorized as either [singular](#singular-resource) or [plural](#plural-resource), though there are some irregular resources that cannot be cleanly considered one or the other.
|
||||
|
||||
Resources are used within a [describe block](#describe-block) to perform [tests](#test).
|
||||
|
||||
Here, `car` is a resource.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
end
|
||||
```
|
||||
|
||||
### resource pack
|
||||
|
||||
A _resource pack_ is a type of [profile](#profile) that is used to distribute [custom resources](#custom-resource). This specialized type of profile contains no [controls](#control), but it does contain a `libraries` directory within which Ruby files define custom resources.
|
||||
|
||||
### resource parameter
|
||||
|
||||
_`resource parameters`_ are information passed to the resource when they are declared. Typically, resource parameters provide identifying information or connectivity information. Resource parameters are not the same as a [filter statement](#filter-statement).
|
||||
|
||||
Resource parameters vary from resource to resource; refer to the [resource documentation](/inspec/resources/) for details.
|
||||
|
||||
Here, `owner: 'Tony Clifton'` is a resource parameter.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
end
|
||||
```
|
||||
|
||||
### resource-specific matcher
|
||||
|
||||
A [matcher](#matcher) that operates directly on the [resource](#resource), as opposed to operating on a property as a [universal matcher](#universal matcher) does.
|
||||
|
||||
Resource-specific matchers often provide highly customized behavior. Check the [resource documentation](#/inspec/resources/) to discover which resource-specific matchers are available for your resource.
|
||||
|
||||
For example, the hypothetical `car` resource defines a `classy?` method, which is exposed as the `be_classy` matcher in Chef InSpec tests.
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
end
|
||||
```
|
||||
|
||||
### singular resource
|
||||
|
||||
A [resource](#resource) intended to uniquely identify a single object on the [target](#target). Singular resources specialize in providing richer auditing capabilities via resource-specific matchers. Compare to [plural resources](#plural-resource).
|
||||
|
||||
### target
|
||||
|
||||
The _`target`_ is the OS or API on which Chef InSpec is performing audits. In Chef InSpec 1.x, this was always an operating system target (a bare metal machine, VM, or container). In Chef InSpec 2.x and later, this can be an OS target, or an API target, including cloud providers such as AWS. Chef InSpec is agentless, meaning that the Chef InSpec code and profiles remain on your workstation, and the target is remotely interrogated without installing anything.
|
||||
|
||||
### test
|
||||
|
||||
A _`test`_ is an individual assertion about the state of the [resource](#resource) or one of its [properties](#property). All tests begin with the keyword [it](#it) or [its](#its). Tests are grouped within a [describe block](#describe-block).
|
||||
|
||||
### universal matcher
|
||||
|
||||
A _universal matcher_ is a [matcher](#matcher) that can be used on the [properties](#property) of any type of [resource](#resource). For example, you can use the `cmp` matcher to check the value of properties without having to worry about Ruby type-casting. Universal matchers are almost always used with the [its](#its) keyword.
|
||||
|
||||
Universal matchers are documented on the [Universal Matchers](/inspec/matchers/) page.
|
||||
|
||||
Here, we access the 'color' property, then use the `cmp` universal matcher to compare the property to the 'black' [expected result](#expected-result).
|
||||
|
||||
```Ruby
|
||||
describe car(owner: 'Bruce Wayne') do
|
||||
its('color') { should cmp 'black' }
|
||||
end
|
||||
```
|
231
www/content/inspec/habitat.md
Normal file
231
www/content/inspec/habitat.md
Normal file
|
@ -0,0 +1,231 @@
|
|||
+++
|
||||
title = "Chef InSpec Integration with Chef Habitat"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Chef Habitat Integration"
|
||||
identifier = "inspec/reference/habitat.md Habitat Integration"
|
||||
parent = "inspec/reference"
|
||||
weight = 120
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/habitat.md)
|
||||
|
||||
Chef InSpec provides an easy method to create an executable Chef Habitat package for a Chef InSpec profile. When run via the Chef Habitat Supervisor, the package will run Chef InSpec with your profile and write out its findings to the supervisor log. This provides the ability to ship your compliance controls alongside your Chef Habitat-packaged application and continuously run InSpec, providing you *Continuous Compliance.*
|
||||
|
||||
## What is Chef Habitat
|
||||
|
||||
Chef Habitat by Chef Software is our new Application Automation tool that aims
|
||||
to make it easy, safe, and fast to build, deploy, and manage applications. From
|
||||
build dependencies, runtime dependencies, dynamic configuration, and service
|
||||
discovery (just to name a few), Chef Habitat packages the automation with the
|
||||
application instead of relying on an underlying platform.
|
||||
|
||||
To learn more about Chef Habitat and try our demos and tutorials, visit
|
||||
[https://www.habitat.sh](https://www.habitat.sh).
|
||||
|
||||
## Using the Chef Habitat Integration
|
||||
|
||||
After creating a Chef Habitat package for a Chef InSpec profile (see CLI commands
|
||||
below) and uploading the package to a Chef Habitat Depot or manually distributing
|
||||
to a host, start the Chef Habitat Supervisor with your package:
|
||||
|
||||
```bash
|
||||
hab start effortless/audit-baseline
|
||||
```
|
||||
|
||||
The Chef Habitat Supervisor will install Chef InSpec and execute your profile in
|
||||
a loop. The loop is controlled by two variables: the `interval` and the `splay`.
|
||||
The `interval` is a set time you want InSpec to run and its default is `1800`
|
||||
seconds. The `splay` is a randomly generated sleep time that prevents a thundering
|
||||
herd problem, or resource starvation scenario, when sending your report to an
|
||||
external server like Chef Automate. The default for the `splay` is also `1800`
|
||||
seconds. Alternatively, the `splay_first_run` can be set to wait a random period
|
||||
of time between 0 and the number set for the `splay_first_run` before running
|
||||
InSpec when your Habitat package is started or updated. The default of the
|
||||
`splay_first_run` is `0` seconds.
|
||||
|
||||
```bash
|
||||
HAB_INSPEC_PROFILE_FRONTEND1="interval = 60" hab start effortless/audit-baseline
|
||||
```
|
||||
|
||||
The Chef Habitat Supervisor will display output like this:
|
||||
|
||||
```text
|
||||
hab start effortless/audit-baseline
|
||||
∵ Missing package for core/hab-sup/0.17.0
|
||||
» Installing core/hab-sup/0.17.0
|
||||
↓ Downloading core/hab-sup/0.17.0/20170214235450
|
||||
1.68 MB / 1.68 MB - [=========================================================================] 100.00 % 7.43 MB/s
|
||||
|
||||
... more Chef Habitat output here ...
|
||||
|
||||
hab-sup(MN): Starting effortless/audit-baseline/0.1.0/20170328173005
|
||||
hab-sup(CS): effortless/audit-baseline/0.1.0/20170328173005 is not installed
|
||||
↓ Downloading adamleff-20160617201047 public origin key
|
||||
79 B / 79 B | [===============================================================================] 100.00 % 2.64 MB/s
|
||||
☑ Cached adamleff-20160617201047 public origin key
|
||||
↓ Downloading chef/inspec/1.17.0/20170321214949
|
||||
16.93 MB / 16.93 MB / [======================================================================] 100.00 % 10.49 MB/s
|
||||
|
||||
... more Chef Habitat output here ...
|
||||
|
||||
★ Install of effortless/audit-baseline/0.1.0/20170328173005 complete with 9 new packages installed.
|
||||
hab-sup(MR): Butterfly Member ID d9bd761e18c144469d755b1b97406eb2
|
||||
hab-sup(MR): Starting butterfly on 0.0.0.0:9638
|
||||
hab-sup(MR): Starting http-gateway on 0.0.0.0:9631
|
||||
inspec-profile-frontend1.default(SR): Initializing
|
||||
inspec-profile-frontend1.default(SV): Starting process as user=hab, group=hab
|
||||
inspec-profile-frontend1.default(O): Executing InSpec effortless/audit-baseline
|
||||
inspec-profile-frontend1.default(O): InSpec run completed successfully.
|
||||
inspec-profile-frontend1.default(O): sleeping for 2134 seconds
|
||||
```
|
||||
|
||||
The above sample output shows the supervisor starting, downloading the necessary dependencies for the supervisor and the Chef InSpec profile, and then shows the supervisor running Chef InSpec successfully.
|
||||
|
||||
Chef InSpec will write a JSON file in the `${svc_var_path}/inspec_results` directory containing the results of the last Chef InSpec run. For example, for the `effortless/audit-baseline` package, the Chef InSpec results will be at:
|
||||
|
||||
```text
|
||||
/hab/svc/inspec-profile-frontend1/var/inspec_results/inspec-profile-frontend1.json
|
||||
```
|
||||
|
||||
## Chef InSpec Chef Habitat CLI Commands
|
||||
|
||||
### inspec habitat profile create
|
||||
|
||||
Create a Chef Habitat package for a Chef InSpec profile. Chef InSpec will
|
||||
validate the profile, fetch and vendor any dependencies (if necessary), and build
|
||||
the Chef Habitat package with a dependency on the latest InSpec. The resulting
|
||||
package will be saved to the current working directory.
|
||||
|
||||
The package can then be manually uploaded to a Chef Habitat Depot or manually
|
||||
distributed to a host and installed via `hab pkg install`.
|
||||
|
||||
The package file will be named:
|
||||
|
||||
```text
|
||||
HABITAT_ORIGIN-inspec-profile-PROFILE_NAME-PROFILE_VERSION-BUILD_ID-x86_64-linux.hart
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```text
|
||||
adamleff-inspec-profile-frontend1-0.1.0-20170328173005-x86_64-linux.hart
|
||||
```
|
||||
|
||||
#### Syntax
|
||||
|
||||
```bash
|
||||
inspec habitat profile create PROFILE_DIRECTORY
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
inspec habitat profile create ~/profiles/frontend1
|
||||
```
|
||||
|
||||
#### Example Output
|
||||
|
||||
```text
|
||||
$ habitat profile create ~/profiles/frontend1
|
||||
[2017-03-28T13:29:32-04:00] INFO: Creating a Habitat artifact for profile: /Users/aleff/profiles/frontend1
|
||||
[2017-03-28T13:29:32-04:00] INFO: Checking to see if Habitat is installed...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Copying profile contents to the work directory...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Generating Habitat plan at /var/folders/v5/z54gb76j2rs3wrn65hmtyf1r0000gp/T/inspec-habitat-exporter20170328-4932-kg2ltd/habitat/plan.sh...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Generating a Habitat run hook at /var/folders/v5/z54gb76j2rs3wrn65hmtyf1r0000gp/T/inspec-habitat-exporter20170328-4932-kg2ltd/habitat/hooks/run...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Generating Habitat's default.toml configuration...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Building our Habitat artifact...
|
||||
hab-studio: Destroying Studio at /hab/studios/src (default)
|
||||
hab-studio: Creating Studio at /hab/studios/src (default)
|
||||
hab-studio: Importing adamleff secret origin key
|
||||
» Importing origin key from standard input
|
||||
★ Imported secret origin key adamleff-20160617201047.
|
||||
» Installing core/hab-backline
|
||||
↓ Downloading core/hab-backline/0.19.0/20170311034116
|
||||
2.17 KB / 2.17 KB / [=========================================================================] 100.00 % 4.33 MB/s
|
||||
|
||||
... more Chef Habitat output here...
|
||||
|
||||
[2017-03-28T13:30:18-04:00] INFO: Copying artifact to /Users/aleff...
|
||||
```
|
||||
|
||||
### inspec habitat profile setup
|
||||
|
||||
Create a Chef Habitat directory that includes a plan file in a profile directory.
|
||||
|
||||
This is the same process that is used by `inspec habitat profile create` - but
|
||||
this adds the generated Chef Habitat directory and file to your system so that
|
||||
you can commit them to source control. If you commit these files to GitHub, you
|
||||
can connect that plan to the [Chef Habitat Builder Service](https://www.habitat.sh/docs/using-builder/).
|
||||
|
||||
#### Syntax
|
||||
|
||||
```bash
|
||||
inspec habitat profile setup PROFILE_DIRECTORY
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
inspec habitat profile setup ~/profiles/frontend1
|
||||
```
|
||||
|
||||
#### Example Output
|
||||
|
||||
```bash
|
||||
[2018-10-31T23:45:59+00:00] INFO: Setting up profile at /home/nell/profiles/frontend1/ for Habitat...
|
||||
[2018-10-31T23:45:59+00:00] INFO: Checking to see if the profile is valid...
|
||||
[2018-10-31T23:45:59+00:00] INFO: Profile is valid.
|
||||
[2018-10-31T23:45:59+00:00] INFO: Profile's dependencies are already vendored, skipping vendor process.
|
||||
[2018-10-31T23:45:59+00:00] INFO: Generating Habitat plan at /home/nell/profiles/frontend1/habitat/plan.sh...
|
||||
```
|
||||
|
||||
### inspec habitat profile upload
|
||||
|
||||
Create and then upload a Chef Habitat package for a Chef InSpec profile. Like
|
||||
the `inspec habitat profile create` command, Chef InSpec will validate the profile,
|
||||
fetch and vendor any dependencies (if necessary), and build the Chef Habitat
|
||||
package with a dependency on the latest InSpec. However, instead of saving the
|
||||
package locally to the workstation, Chef InSpec will upload it to the depot
|
||||
defined in the `HAB_DEPOT` environment variable. If `HAB_DEPOT` is not defined,
|
||||
the package will be uploaded to the public Chef Habitat depot at
|
||||
[https://app.habitat.sh](https://app.habitat.sh).
|
||||
|
||||
#### Syntax
|
||||
|
||||
```bash
|
||||
inspec habitat profile upload PROFILE_DIRECTORY
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
inspec habitat profile upload ~/profiles/frontend1
|
||||
```
|
||||
|
||||
#### Example Output
|
||||
|
||||
```text
|
||||
[2017-03-28T13:29:32-04:00] INFO: Creating a Habitat artifact for profile: /Users/aleff/profiles/frontend1
|
||||
[2017-03-28T13:29:32-04:00] INFO: Checking to see if Habitat is installed...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Copying profile contents to the work directory...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Generating Habitat plan at /var/folders/v5/z54gb76j2rs3wrn65hmtyf1r0000gp/T/inspec-habitat-exporter20170328-4932-kg2ltd/habitat/plan.sh...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Generating a Habitat run hook at /var/folders/v5/z54gb76j2rs3wrn65hmtyf1r0000gp/T/inspec-habitat-exporter20170328-4932-kg2ltd/habitat/hooks/run...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Generating Habitat's default.toml configuration...
|
||||
[2017-03-28T13:29:32-04:00] INFO: Building our Habitat artifact...
|
||||
hab-studio: Destroying Studio at /hab/studios/src (default)
|
||||
hab-studio: Creating Studio at /hab/studios/src (default)
|
||||
hab-studio: Importing adamleff secret origin key
|
||||
» Importing origin key from standard input
|
||||
★ Imported secret origin key adamleff-20160617201047.
|
||||
» Installing core/hab-backline
|
||||
↓ Downloading core/hab-backline/0.19.0/20170311034116
|
||||
2.17 KB / 2.17 KB / [=========================================================================] 100.00 % 4.33 MB/s
|
||||
|
||||
... more Chef Habitat output here...
|
||||
|
||||
[2017-03-28T13:30:18-04:00] INFO: Uploading the Habitat artifact to our Depot...
|
||||
[2017-03-28T13:30:23-04:00] INFO: Upload complete!
|
||||
```
|
422
www/content/inspec/inputs.md
Normal file
422
www/content/inspec/inputs.md
Normal file
|
@ -0,0 +1,422 @@
|
|||
+++
|
||||
title = "Chef InSpec Inputs"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Inputs"
|
||||
identifier = "inspec/reference/inputs.md Inputs"
|
||||
parent = "inspec/reference"
|
||||
weight = 30
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/inputs.md)
|
||||
|
||||
## What are Inputs?
|
||||
|
||||
Inputs are the "knobs" you can use to customize the behavior of Chef InSpec profiles.
|
||||
If a profile supports inputs, you can set the inputs in a variety of ways, allowing
|
||||
flexibility. Profiles that include other profiles can set inputs in the included
|
||||
profile, enabling a multi-layered approach to configuring profiles.
|
||||
|
||||
### A Simple Example
|
||||
|
||||
Suppose you have a profile named `rock_critic`. In its profile metadata file (inspec.yml):
|
||||
|
||||
```yaml
|
||||
# Optionally declare inputs in the profile metadata
|
||||
# This lets you set up things like type checking, etc.
|
||||
inputs:
|
||||
- name: amplifier_max_volume
|
||||
description: How loud the amplifiers can go
|
||||
type: numeric
|
||||
# More options, including value: and priority: are possible here
|
||||
```
|
||||
|
||||
In the profile's control code:
|
||||
|
||||
```ruby
|
||||
# Set a default value for an input. This is optional.
|
||||
input('amplifier_max_volume', value: 10)
|
||||
|
||||
control 'Big Rock Show' do
|
||||
describe input('amplifier_max_volume') do # This line reads the value of the input
|
||||
it { should cmp 11 } # The UK'S LOUDEST BAND
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
When the above profile is executed by using `inspec exec rock_critic`, you would see something like:
|
||||
|
||||
```
|
||||
× Big Rock Show: 10
|
||||
× 10 is expected to cmp == 11
|
||||
|
||||
expected: 11
|
||||
got: 10
|
||||
|
||||
(compared using `cmp` matcher)
|
||||
Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped
|
||||
```
|
||||
|
||||
That result clearly won't do. Let's override the input's default value.
|
||||
|
||||
We can now run that profile with `inspec exec rock_critic --input amplifier_max_volume=11`:
|
||||
|
||||
```
|
||||
✔ Big Rock Show: 11
|
||||
✔ 11 is expected to cmp == 11
|
||||
|
||||
Profile Summary: 1 successful control, 0 control failures, 0 controls skipped
|
||||
```
|
||||
|
||||
### Which profiles support inputs?
|
||||
|
||||
The best way for a profile to indicate it supports inputs is to list them in the
|
||||
metadata file, `inspec.yml`. Any profile that has an `inputs` (or the deprecated
|
||||
`attributes`) section in its `inspec.yml` metadata file is
|
||||
[configuring](#configuring-inputs-in-profile-metadata) inputs.
|
||||
|
||||
That said, any profile that uses the DSL keyword `input()` (or the deprecated
|
||||
`attribute()`) in the control source code supports inputs. These profiles are
|
||||
*reading* (and possibly setting) input values and using them to make decisions.
|
||||
|
||||
### How can I set Inputs?
|
||||
|
||||
As installed (without specialized plugins), Chef InSpec supports several ways of setting inputs:
|
||||
|
||||
- Inline in control code, using `input('input_name', value: 42)`.
|
||||
- In profile `inspec.yml` metadata files
|
||||
- Using the CLI option `--input name1=value1 name2=value2...` to read directly from the command line
|
||||
- Using the CLI option `--input-file somefile.yaml` to read inputs from files
|
||||
- In kitchen-inspec, using the `verifier/inputs` settings
|
||||
- In the Audit Cookbook, using the `node[:audit][:inputs]`
|
||||
|
||||
In addition, Chef InSpec supports Input Plugins, which can provide optional integrations to specific key-value stores.
|
||||
|
||||
### How does Input precedence work?
|
||||
|
||||
#### Simple Precedence
|
||||
|
||||
Briefly:
|
||||
|
||||
inline DSL < metadata < ( cli-input-file or kitchen-inspec or audit-cookbook ) < cli --input
|
||||
|
||||
In addition, for inherited profiles:
|
||||
|
||||
dependent profile metadata < wrapper profile metadata
|
||||
|
||||
This precedence lets you override input values on the command line, as well as
|
||||
override child profile inline values from the parent profile.
|
||||
This description matches the general behavior of InSpec v3, while also making
|
||||
some edge cases easier to reason.
|
||||
|
||||
#### The Details of Input Precedence
|
||||
|
||||
Whenever an input provider sets a value on an input, a *priority value* is
|
||||
assigned to the operation. Over the life of the input, multiple assignments with
|
||||
varying priority values may occur. When the input is evaluated, the current value
|
||||
is determined by finding the setting event with the highest priority.
|
||||
|
||||
Note that this approach does not rely on execution order, nor does it rely on
|
||||
multiple named precedence levels. Each setting operation is preserved and this
|
||||
allows the user to [debug](#debugging-inputs-with-the-event-log) the history of
|
||||
the input values.
|
||||
|
||||
Some input providers allow you to set a priority when you set the value. For
|
||||
example, to set a priority of 50 in a metadata file, use:
|
||||
|
||||
```yaml
|
||||
inputs:
|
||||
- name: very_important_input
|
||||
value: 12
|
||||
priority: 50
|
||||
```
|
||||
|
||||
To set a priority in DSL, use:
|
||||
```ruby
|
||||
input('also_important', value: 42, priority: 45)
|
||||
```
|
||||
|
||||
As packaged, Chef InSpec uses the following priority values:
|
||||
|
||||
| Input Provider | Priority | May change priority |
|
||||
| -------------------------------------- | -------- | ------------------- |
|
||||
| Inline DSL | 20 | Yes |
|
||||
| Metadata | 30 | Yes |
|
||||
| Metadata in a wrapper cookbook | 35 | Yes |
|
||||
| CLI `--input-file` option | 40 | No |
|
||||
| inspec-kitchen `inputs:` section | 40 | No |
|
||||
| audit cookbook `node[:audit][:inputs]` | 40 | No |
|
||||
| CLI `--input` option | 50 | No |
|
||||
|
||||
### What happened to "Attributes"?
|
||||
|
||||
When originally introduced, the Input facility was named *Attributes*. This name
|
||||
was problematic, because:
|
||||
|
||||
- The Chef Infra tool uses the same word to describe its parameterization system.
|
||||
- Chef Infra attributes have a completely different and much more complex precedence system.
|
||||
- This caused confusion about passing Chef Infra attributes into InSpec when using Audit Cookbook and kitchen-inspec.
|
||||
|
||||
Based on these concerns, InSpec attributes have been renamed to InSpec inputs in Chef InSpec v4.
|
||||
|
||||
Support for using the DSL keyword `attribute()`, the metadata field `attributes:`, and the corresponding kitchen-inspec and audit cookbook values are anticipated to continue through Chef InSpec v5.
|
||||
|
||||
## Working with Inputs in Control Code
|
||||
|
||||
### Input Scope
|
||||
|
||||
Inputs are available throughout the InSpec profile DSL. You can use them anywhere.
|
||||
|
||||
```ruby
|
||||
# some_controls.rb
|
||||
|
||||
input('outer_input', value: 1) # here
|
||||
|
||||
control 'control-1' do
|
||||
input('control_dsl_input', value: 2) # here too
|
||||
describe some_resource do
|
||||
input('test_dsl_input', value: 3) # even here
|
||||
it { should cmp input('expectation_dsl_input') } # and yes here too
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Setting Inputs in Control DSL
|
||||
|
||||
When you write `input('some_name', value: 'some_value')`, you are *setting* an
|
||||
input value in the DSL. Because the `value:` option is present, a new value will
|
||||
be set. You may also pass any other option listed in the
|
||||
[input option reference](#input-options-reference).
|
||||
|
||||
### Reading Inputs in Control DSL
|
||||
|
||||
When you call `input('some_name')`, with or without additional options, the value
|
||||
of the input will be resolved and returned. Note that this process may involve
|
||||
sourcing the value from another provider, using the value set in DSL, or overriding
|
||||
the value provided in the same call.
|
||||
|
||||
```ruby
|
||||
# You can use the value in a Ruby variable
|
||||
some_var = input('some_input_name')
|
||||
|
||||
# Or more directly in a resource parameter
|
||||
describe file(input('important_path')) do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
# Or as the resource itself (this could be a string, here)
|
||||
describe input('some_setting') do
|
||||
it { should cmp 'correct_value' }
|
||||
end
|
||||
|
||||
# Or as the expected value
|
||||
describe file('/etc/httpd/httpd.conf') do
|
||||
its('owner') { should_not cmp input('webserver_user') }
|
||||
end
|
||||
```
|
||||
|
||||
The value returned can be used anywhere a Ruby value is used.
|
||||
|
||||
## Configuring Inputs in Profile Metadata
|
||||
|
||||
Each Chef InSpec profile has a metadata file at the top level named `inspec.yml`.
|
||||
In that file, you may add a section for inputs. You may define inputs there,
|
||||
clearly setting options including values, type checking, and whether the input is
|
||||
required.
|
||||
|
||||
```yaml
|
||||
name: my_profile
|
||||
inputs:
|
||||
- name: webserver_user # Name is the only required field
|
||||
- name: favorite_fruit
|
||||
value: banana # You can set a value; priority is 30 for metadata
|
||||
- name: meaning_of_life
|
||||
type: Numeric
|
||||
value: 42
|
||||
required: true
|
||||
priority: 70
|
||||
```
|
||||
|
||||
All [input options](#input-options-reference) are supported in metadata files.
|
||||
|
||||
There are two major advantages to defining inputs in profile metadata:
|
||||
|
||||
1. The inputs and their configuration are listed explicitly in simple YAML in
|
||||
one place - a consumer of your profile does not need to read through the control
|
||||
code to find the inputs.
|
||||
1. You can set inputs in other profiles that you depend on using profile inheritance.
|
||||
|
||||
### Using inputs with Profile inheritance
|
||||
|
||||
When your profile relies on another profile using the `depends` key in the metadata file, you can set — that is, override — the value of the input in the dependent profile by including the `profile` option and naming the dependent profile.
|
||||
|
||||
|
||||
```yaml
|
||||
# child inspec.yml
|
||||
name: child
|
||||
inputs:
|
||||
- name: favorite_food
|
||||
value: pizza
|
||||
```
|
||||
|
||||
```yaml
|
||||
# wrapper inspec.yml
|
||||
name: wrapper
|
||||
depends:
|
||||
- name: child
|
||||
path: ../child
|
||||
inputs:
|
||||
- name: favorite_food
|
||||
value: broccoli
|
||||
profile: child # <----- REQUIRED to override the value in InSpec 4
|
||||
```
|
||||
|
||||
In Chef InSpec 4+, every input is namespaced. For example, you could have an
|
||||
input named `wrapper/favorite_food` and one named `child/favorite_food`. If no
|
||||
explicit profile option is set within the `wrapper` profile metadata file, then
|
||||
`wrapper` is assumed to be the profile.
|
||||
|
||||
## Setting Input values using `--input-file`
|
||||
|
||||
You may also provide inputs and values via YAML files on the command line. The
|
||||
format can be seen below:
|
||||
|
||||
```yaml
|
||||
an_input: a_value
|
||||
another_input: another_value
|
||||
```
|
||||
|
||||
CLI-input-file-set inputs have a priority of 40.
|
||||
|
||||
As of Chef InSpec 4.3.2, this mechanism has the following limitations:
|
||||
|
||||
1. No [input options](#input-options-reference) may be set - only the name and value.
|
||||
1. Because the CLI is outside the scope of any individual profile and the inputs
|
||||
don't take options, the inputs are clumsily copied into every profile,
|
||||
effectively making the CLI mechanism global.
|
||||
|
||||
## Setting Input values using `--input`
|
||||
|
||||
You may also provide inputs and values directly on the command line:
|
||||
|
||||
```yaml
|
||||
inspec exec my_profile --input input_name=input_value
|
||||
```
|
||||
|
||||
To set multiple inputs, say:
|
||||
```yaml
|
||||
inspec exec my_profile --input input_name1=input_value1 name2=value2
|
||||
```
|
||||
|
||||
If a CLI input value resembles a number, it will be converted to an Integer or
|
||||
Float. Scientific notation is not currently recognized.
|
||||
|
||||
```yaml
|
||||
inspec exec my_profile --input amplifier_volume=-11
|
||||
inspec exec my_profile --input water_depth=11.5
|
||||
```
|
||||
|
||||
You may set inputs with complex values, such as arrays and hashes using either
|
||||
YAML or JSON syntax. Just be sure to protect the string from the shell using single
|
||||
quotes.
|
||||
|
||||
```yaml
|
||||
inspec exec my_profile --input alphabet='[a,b,c]'
|
||||
inspec exec my_profile --input fruits='{a: apples, b: bananas, c: cantelopes}'
|
||||
inspec exec my_profile --input json_fruit='{"a": "apples", "g": ["grape01", "grape02"] }'
|
||||
```
|
||||
|
||||
Do not repeat the `--input` flag; that will override the previous setting.
|
||||
|
||||
CLI-set inputs have a priority of 50.
|
||||
|
||||
As of Chef InSpec 4.12, this mechanism has the following limitations:
|
||||
|
||||
1. No [input options](#input-options-reference) may be set - only the name and
|
||||
value.
|
||||
1. Because the CLI is outside the scope of any individual profile and the inputs
|
||||
don't take options, the inputs are clumsily copied into every profile,
|
||||
effectively making the CLI mechanism global.
|
||||
|
||||
## Input Options Reference
|
||||
|
||||
### Name
|
||||
|
||||
Required `String`. This option identifies the input.
|
||||
|
||||
Allowed in: All. When used in DSL and Metadata, the name is unique within the
|
||||
current profile. When used in CLI input files, audit cookbook, and kitchen-inspec,
|
||||
the input is copied across all profiles using the same name.
|
||||
|
||||
### Description
|
||||
|
||||
Optional `String`. Human-meaningful explanation of the input.
|
||||
|
||||
Allowed in: DSL, Metadata
|
||||
|
||||
### Value
|
||||
|
||||
Optional, any Ruby or YAML type. This is the value that will be available when
|
||||
you read the input. See the [Reading Inputs](#reading-inputs-in-control-dsl) section
|
||||
for more information.
|
||||
|
||||
Allowed in: All
|
||||
|
||||
### Type
|
||||
|
||||
Optional, `String`. This value must be one of `String`, `Numeric`, `Regexp`,
|
||||
`Array`, `Hash`, `Boolean`, or `Any`. If provided, the value of the input will
|
||||
be checked to see if it is of the corresponding type. Note that `Regexp` indicates
|
||||
that the input value itself should be a regular expression, not that it should
|
||||
match any particular regular expression.
|
||||
|
||||
Allowed in: DSL, Metadata
|
||||
|
||||
### Required
|
||||
|
||||
Optional, `true` or `false`. If `true`, a control using the input will be failed
|
||||
if it [reads](#reading-inputs-in-control-dsl) the value when none has been set.
|
||||
|
||||
Allowed in: DSL, Metadata
|
||||
|
||||
### Priority
|
||||
|
||||
Optional, `Integer`, 0-100. Higher values make this assignment have higher
|
||||
precedence. This is an advanced feature.
|
||||
|
||||
Allowed in: DSL, Metadata
|
||||
|
||||
### Profile
|
||||
|
||||
Optional, `String`. Allows you to set an input in another profile from your profile.
|
||||
|
||||
Allowed in: DSL, Metadata
|
||||
|
||||
## Advanced Topics
|
||||
|
||||
### Debugging Inputs with the Event Log
|
||||
|
||||
If it is difficult to determine why a particular value is being used, you can use
|
||||
the Event Log to determine what is happening.
|
||||
|
||||
First, use the `input_object()` DSL method. This method is like `input()` in that
|
||||
it looks up an input, but instead of evaluating the current value, it returns
|
||||
the underlying `Inspec::Input` object.
|
||||
|
||||
```ruby
|
||||
puts input_object('troublesome_input').diagnostic_string
|
||||
|
||||
# Or
|
||||
require 'pp'
|
||||
pp input_object('troublesome_input').events
|
||||
```
|
||||
|
||||
`diagnostic_string` assembles the Event Log into a printable log message for
|
||||
convenience.
|
||||
|
||||
The Event Log contains entries for every time that the value changed, as well as
|
||||
one for when the input was first created. When possible, stack probing is used
|
||||
to determine file and line numbers. Most importantly, you will see priority numbers;
|
||||
remember that highest priority wins; order only matters to break a tie.
|
137
www/content/inspec/inspec_and_friends.md
Normal file
137
www/content/inspec/inspec_and_friends.md
Normal file
|
@ -0,0 +1,137 @@
|
|||
+++
|
||||
title = "Chef InSpec and Friends"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Chef InSpec and Friends"
|
||||
identifier = "inspec/inspec_and_friends.md Chef InSpec and friends"
|
||||
parent = "inspec"
|
||||
weight = 40
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/inspec_and_friends.md)
|
||||
|
||||
This page looks at projects that are similar to Chef InSpec to explain how they
|
||||
relate to each other.
|
||||
|
||||
## RSpec
|
||||
|
||||
RSpec is an awesome framework that is widely used by software engineers to test
|
||||
Ruby code. It enables test-driven development (TDD) and helps developers to write
|
||||
better code every day.
|
||||
|
||||
Chef InSpec is built on top of RSpec and uses it as the underlying foundation
|
||||
to execute tests. It uses the key strengths of RSpec, easily execute
|
||||
tests and a DSL to write tests, but extends the functionality for use as
|
||||
compliance audits. Chef InSpec ships with custom audit resources that make it
|
||||
easy to write audit checks and with the ability to run those checks on
|
||||
remote servers. These audit resources provided know the differences
|
||||
between operating systems and help you abstract from the local operating
|
||||
system, similar to other resources you might use in your Chef recipes.
|
||||
|
||||
A complete Chef InSpec rule looks like:
|
||||
|
||||
```ruby
|
||||
control "sshd-11" do
|
||||
impact 1.0
|
||||
title "Server: Set protocol version to SSHv2"
|
||||
desc "Set the SSH protocol version to 2. Don't use legacy
|
||||
insecure SSHv1 connections anymore."
|
||||
tag security: "level-1"
|
||||
tag "openssh-server"
|
||||
ref "Server Security Guide v.1.0", url: "http://..."
|
||||
|
||||
describe sshd_config do
|
||||
its('Protocol') { should eq('2') }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
That said, Chef InSpec is not RSpec. Some key differences:
|
||||
|
||||
- In InSpec, `describe` blocks should not be nested; instead use `control` blocks
|
||||
to describe a higher-level grouping of tests.
|
||||
- The RSpec `shared_example` construct is not supported. Instead, create a simple
|
||||
custom resource that executes repetitious tasks.
|
||||
- Chef InSpec is aimed at compliance practitioners and infrastructure testers, so
|
||||
our focus is providing a few, well-supported, easy-to-use [universal matchers](/inspec/matchers/),
|
||||
such as `cmp`. In contrast, RSpec is a tool designed for software engineers.
|
||||
It thus supports a very large range of matchers, to enable testing of software
|
||||
engineering constructs such as exceptions, Object Oriented Programming relationships,
|
||||
and so on.
|
||||
- While Chef InSpec uses parts of the RSpec project and codebase, it is a
|
||||
separate project from InSpec. Rspec's release schedule and feature set are beyond
|
||||
the control of the Chef InSpec team. While it is possible to use many of the
|
||||
RSpec core features within Chef InSpec profiles, Chef InSpec can only guarantee
|
||||
that the features described in the [InSpec documentation](/inspec/) will
|
||||
function correctly. Some RSpec core functionality may be removed in future
|
||||
versions of Chef InSpec as needed to ensure stability in the Chef InSpec project.
|
||||
|
||||
## Serverspec
|
||||
|
||||
Serverspec is the first extension of RSpec that enabled
|
||||
users to run RSpec tests on servers to verify deployed artifacts. It was
|
||||
created in March 2013 by Gosuke Miyashita and has been widely adopted.
|
||||
It is also one of the core test frameworks within test-kitchen and has
|
||||
been widely used within the Chef ecosystem. Chef InSpec takes lessons learned
|
||||
implementing and using Serverspec and builds on them to make auditing
|
||||
and compliance easier.
|
||||
|
||||
Lessons learned from Serverspec include:
|
||||
|
||||
- IT, compliance, and security professional require metadata beyond what Serverspec
|
||||
offers, such as criticality, to fully describe controls.
|
||||
- Setting up and running the same tests across multiple machines must be easy.
|
||||
- It must be easy to locate, debug, and extend operating system-dependent code.
|
||||
- It must be easy to extend the language and create custom resources.
|
||||
- It must run multiple tests simultaneously.
|
||||
- Support for Windows is a first-class requirement.
|
||||
- A command line interface (CLI) is required for faster iteration of test code.
|
||||
|
||||
You can also watch this [podcast](http://foodfightshow.org/2016/02/inspec.html)
|
||||
to find out more on the relationship of Chef InSpec and Serverspec.
|
||||
|
||||
### How is Chef InSpec different from Serverspec
|
||||
|
||||
One of the key differences is that Chef InSpec targets more user groups. It
|
||||
is optimized for DevOps, Security, and Compliance professionals.
|
||||
Additional metadata, such as impact, title, and description, make it
|
||||
easier to fully describe the controls which makes it easier to share the
|
||||
controls with other departments. This enables Security departments to
|
||||
prioritize rules. DevOps teams use this information to focus on the most
|
||||
critical issues to remediate.
|
||||
|
||||
```ruby
|
||||
control "sshd-11" do
|
||||
impact 1.0
|
||||
title "Server: Set protocol version to SSHv2"
|
||||
desc "Set the SSH protocol version to 2. Don't use legacy
|
||||
insecure SSHv1 connections anymore."
|
||||
tag security: "level-1"
|
||||
tag "openssh-server"
|
||||
ref "Server Security Guide v.1.0" url: "http://..."
|
||||
|
||||
describe sshd_config do
|
||||
its('Protocol') { should cmp 2 }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Why not fork Serverspec?**
|
||||
|
||||
Chef InSpec started as an extension of Serverspec. As the extension grew, it
|
||||
became clear that a new library was required. Creating and maintaining a
|
||||
fork was not practical so a new project was born.
|
||||
|
||||
**Will Chef InSpec only work on machines managed by Chef?**
|
||||
|
||||
No, Chef InSpec can be used on any machine. It doesn’t matter if that machine
|
||||
was configured by Chef or configured lovingly by the hands of your local
|
||||
System Administrator.
|
||||
|
||||
**Is Chef InSpec a replacement of Serverspec?**
|
||||
|
||||
Chef InSpec is intended to be a drop-in replacement of Serverspec. Popular
|
||||
Serverspec resources have been ported to InSpec. It changed some
|
||||
behaviour as documented in our migration guide.
|
153
www/content/inspec/install.md
Normal file
153
www/content/inspec/install.md
Normal file
|
@ -0,0 +1,153 @@
|
|||
+++
|
||||
title = "Install and Uninstall"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Install and Uninstall"
|
||||
identifier = "inspec/install.md Install and Uninstall"
|
||||
parent = "inspec"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/install.md)
|
||||
|
||||
Users can choose between operating systems of MacOS, Windows, and Linux for Chef InSpec.
|
||||
|
||||
## Install Chef InSpec
|
||||
|
||||
You can download the latest Chef InSpec package relevant to your operating system
|
||||
at [our Downloads Page](https://downloads.chef.io/inspec).
|
||||
|
||||
Alternatively, Chef InSpec can be installed via installer, script, or package
|
||||
manager, according to your operating system and method as listed below.
|
||||
|
||||
### macOS
|
||||
|
||||
#### Homebrew
|
||||
|
||||
Chef InSpec is available as a standalone [Homebrew](https://brew.sh/) package.
|
||||
Run the following command in your terminal to install Chef InSpec:
|
||||
|
||||
```
|
||||
brew cask install chef/chef/inspec
|
||||
```
|
||||
|
||||
While this command is running, you may be prompted to enter your macOS user account
|
||||
password for installation to complete.
|
||||
|
||||
#### CLI
|
||||
|
||||
You can download Chef InSpec via curl script:
|
||||
|
||||
```
|
||||
curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
#### Installer
|
||||
|
||||
Once you downloaded the latest [Chef InSpec package](https://downloads.chef.io/inspec)
|
||||
relevant to your Microsoft version, double-click the `.msi` file to launch the
|
||||
installer and follow the prompts.
|
||||
|
||||
#### Powershell
|
||||
|
||||
Use the following command to install Chef InSpec via Powershell script:
|
||||
|
||||
```powershell
|
||||
. { iwr -useb https://omnitruck.chef.io/install.ps1 } | iex; install -project inspec
|
||||
```
|
||||
|
||||
Once Chef InSpec is installed, run `inspec version` to verify that the installation
|
||||
was successful.
|
||||
|
||||
### Linux
|
||||
|
||||
#### CLI
|
||||
|
||||
The following curl script will install Chef InSpec for Ubuntu and Red Hat Enterprise Linux:
|
||||
|
||||
```
|
||||
curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec
|
||||
```
|
||||
|
||||
If you prefer, you can use a package manager to install Chef InSpec.
|
||||
Once you downloaded the latest [Chef InSpec package](https://downloads.chef.io/inspec)
|
||||
relevant to your Linux-based platform, use the command for the respective package
|
||||
manager listed below. Replace the example file path with the file path leading to
|
||||
your downloaded package.
|
||||
|
||||
For Ubuntu, use the following command to install Chef InSpec:
|
||||
|
||||
```
|
||||
sudo dpkg -i /path/to/inspec.deb
|
||||
```
|
||||
|
||||
For Red Hat Enterprise Linux, use the following command to install Chef InSpec:
|
||||
|
||||
```
|
||||
sudo rpm -U /path-to/inspec.rpm
|
||||
```
|
||||
|
||||
For SUSE Linux Enterprise Server, use the following command to install Chef InSpec:
|
||||
|
||||
```
|
||||
sudo zypper install /path-to/inspec.rpm
|
||||
```
|
||||
|
||||
|
||||
## Uninstall Chef InSpec
|
||||
|
||||
Chef InSpec can be uninstalled using the steps below that are appropriate for the
|
||||
method of Chef InSpec installation.
|
||||
|
||||
### macOS
|
||||
|
||||
#### Homebrew
|
||||
|
||||
Use the following *destructive* command to remove the Chef InSpec standalone Homebrew package:
|
||||
|
||||
```
|
||||
brew cask uninstall inspec
|
||||
```
|
||||
|
||||
#### CLI
|
||||
|
||||
Use the following *destructive* command in your terminal to remove the Chef InSpec package:
|
||||
|
||||
```
|
||||
sudo rm -rf /opt/inspec
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
#### Installer
|
||||
|
||||
Use *Add / Remove Programs* to remove Chef InSpec.
|
||||
|
||||
### Linux
|
||||
|
||||
#### CLI
|
||||
|
||||
The supported Linux-based platforms and their respective *destructive* command
|
||||
for their package manager are listed below.
|
||||
|
||||
For Ubuntu, use the following *destructive* command to uninstall:
|
||||
|
||||
```
|
||||
sudo dpkg -P inspec
|
||||
```
|
||||
|
||||
For Red Hat Enterprise Linux, use the following *destructive* command to uninstall:
|
||||
|
||||
```
|
||||
sudo rpm -e inspec
|
||||
```
|
||||
|
||||
For SUSE Linux Enterprise Server, use the following *destructive* command to uninstall Chef InSpec:
|
||||
|
||||
```
|
||||
sudo zypper remove inspec
|
||||
```
|
173
www/content/inspec/matchers.md
Normal file
173
www/content/inspec/matchers.md
Normal file
|
@ -0,0 +1,173 @@
|
|||
+++
|
||||
title = "Chef InSpec Universal Matchers Reference"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Matchers"
|
||||
identifier = "inspec/reference/matchers.md Matchers"
|
||||
parent = "inspec/reference"
|
||||
weight = 40
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/matchers.md)
|
||||
|
||||
Chef InSpec uses matchers to help compare resource values to expectations.
|
||||
The following matchers are available:
|
||||
|
||||
You may also use any matcher provided by [RSpec::Expectations](https://relishapp.com/rspec/rspec-expectations/docs),
|
||||
but those matchers are outside of InSpec's [scope of support](/inspec/inspec_and_friends/#rspec).
|
||||
|
||||
The following InSpec-supported universal matchers are available:
|
||||
|
||||
- [`be`](#be) - make numeric comparisons
|
||||
- [`be_in`](#be_in) - look for the property value in a list
|
||||
- [`cmp`](#cmp) - general-use equality (try this first)
|
||||
- [`eq`](#eq) - type-specific equality
|
||||
- [`include`](#include) - look for an expected value in a list-valued property
|
||||
- [`match`](#match) - look for patterns in text using regular expressions
|
||||
|
||||
See [Explore Chef InSpec resources](https://learn.chef.io/modules/explore-inspec-resources#/)
|
||||
on Learn Chef Rally to learn more about InSpec's built-in matchers.
|
||||
|
||||
## be
|
||||
|
||||
This matcher can be followed by many different comparison operators.
|
||||
Always make sure to use numbers, not strings, for these comparisons.
|
||||
|
||||
```ruby
|
||||
describe file('/proc/cpuinfo') do
|
||||
its('size') { should be >= 10 }
|
||||
its('size') { should be < 1000 }
|
||||
end
|
||||
```
|
||||
|
||||
## cmp
|
||||
|
||||
Unlike `eq`, `cmp` is a matcher for less-restrictive comparisons. It will
|
||||
try to fit the actual value to the type you are comparing it to. This is
|
||||
meant to relieve the user from having to write type-casts and
|
||||
resolutions.
|
||||
|
||||
```ruby
|
||||
describe sshd_config do
|
||||
its('Protocol') { should cmp 2 }
|
||||
end
|
||||
|
||||
describe passwd.uid(0) do
|
||||
its('users') { should cmp 'root' }
|
||||
end
|
||||
```
|
||||
|
||||
`cmp` behaves in the following way:
|
||||
|
||||
* Compare strings to numbers
|
||||
|
||||
```ruby
|
||||
describe sshd_config do
|
||||
# Only `'2'` works
|
||||
its('Protocol') { should eq '2' }
|
||||
|
||||
# Both of these work
|
||||
its('Protocol') { should cmp '2' }
|
||||
its('Protocol') { should cmp 2 }
|
||||
end
|
||||
```
|
||||
|
||||
* String comparisons are not case-sensitive
|
||||
|
||||
```ruby
|
||||
describe auditd_conf do
|
||||
its('log_format') { should cmp 'raw' }
|
||||
its('log_format') { should cmp 'RAW' }
|
||||
end
|
||||
```
|
||||
|
||||
* Recognize versions embedded in strings
|
||||
|
||||
```ruby
|
||||
describe package('curl') do
|
||||
its('version') { should cmp > '7.35.0-1ubuntu2.10' }
|
||||
end
|
||||
```
|
||||
|
||||
* Compare arrays with only one entry to a value
|
||||
|
||||
```ruby
|
||||
describe passwd.uids(0) do
|
||||
its('users') { should cmp 'root' }
|
||||
its('users') { should cmp ['root'] }
|
||||
end
|
||||
```
|
||||
|
||||
* Single-value arrays of strings may also be compared to a regex
|
||||
|
||||
```ruby
|
||||
describe auditd_conf do
|
||||
its('log_format') { should cmp /raw/i }
|
||||
end
|
||||
```
|
||||
|
||||
* Improved printing of octal comparisons
|
||||
|
||||
```ruby
|
||||
describe file('/proc/cpuinfo') do
|
||||
its('mode') { should cmp '0345' }
|
||||
end
|
||||
|
||||
expected: 0345
|
||||
got: 0444
|
||||
```
|
||||
|
||||
## eq
|
||||
|
||||
Test for exact equality of two values.
|
||||
|
||||
```ruby
|
||||
describe sshd_config do
|
||||
its('RSAAuthentication') { should_not eq 'no' }
|
||||
its('Protocol') { should eq '2' }
|
||||
end
|
||||
```
|
||||
|
||||
`eq` fails if types don't match. Please keep this in mind, when comparing
|
||||
configuration entries that are numbers:
|
||||
|
||||
```ruby
|
||||
its('Port') { should eq '22' } # ok
|
||||
|
||||
its('Port') { should eq 22 }
|
||||
# fails: '2' != 2 (string vs int)
|
||||
```
|
||||
|
||||
For less restrictive comparisons, please use `cmp`.
|
||||
|
||||
## include
|
||||
|
||||
Verifies if a value is included in a list.
|
||||
|
||||
```ruby
|
||||
describe passwd do
|
||||
its('users') { should include 'my_user' }
|
||||
end
|
||||
```
|
||||
|
||||
## be_in
|
||||
|
||||
Verifies that an item is included in a list.
|
||||
|
||||
```ruby
|
||||
describe resource do
|
||||
its('item') { should be_in LIST }
|
||||
end
|
||||
```
|
||||
|
||||
## match
|
||||
|
||||
Check if a string matches a regular expression.
|
||||
|
||||
```ruby
|
||||
describe sshd_config do
|
||||
its('Ciphers') { should_not match /cbc/ }
|
||||
end
|
||||
```
|
301
www/content/inspec/migration.md
Normal file
301
www/content/inspec/migration.md
Normal file
|
@ -0,0 +1,301 @@
|
|||
+++
|
||||
title = "Chef InSpec Migration Guide"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Migration from Serverspec"
|
||||
identifier = "inspec/reference/migration.md Migration from Serverspec"
|
||||
parent = "inspec/reference"
|
||||
weight = 130
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/migration.md)
|
||||
|
||||
## How is Chef InSpec different from Serverspec
|
||||
|
||||
We've written a complete blog post about that topic: [The Road to InSpec](https://blog.chef.io/2015/11/04/the-road-to-inspec/)
|
||||
|
||||
## Is Chef InSpec suitable for infrastructure testing?
|
||||
|
||||
Chef InSpec is a framework that allows you to run infrastructure testing as well as compliance testing. The compliance features are always optional and provide customers a way to use Chef InSpec for both use-cases. To ensure we build the best infrastructure testing, we migrate our cookbooks [chef-cookbooks](https://github.com/chef-cookbooks) to InSpec.
|
||||
|
||||
## Which Serverspec resources are available in InSpec?
|
||||
|
||||
The following resources are available in InSpec:
|
||||
|
||||
| Serverspec | Chef InSpec |
|
||||
|:------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------:|
|
||||
| [`bond`](http://serverspec.org/resource_types.html#bond) | [`bond`](/inspec/resources/bond/) |
|
||||
| [`bridge`](http://serverspec.org/resource_types.html#bridge) | [`bridge`](/inspec/resources/bridge/) |
|
||||
| [`command`](http://serverspec.org/resource_types.html#command) | [`command`](/inspec/resources/command/) |
|
||||
| [`cron`](http://serverspec.org/resource_types.html#cron) | [`crontab`](/inspec/resources/crontab/) |
|
||||
| [`docker_container`](http://serverspec.org/resource_types.html#docker_container) | [`docker_container`](/inspec/resources/docker_container/) |
|
||||
| [`docker_image`](http://serverspec.org/resource_types.html#docker_image) | [`docker_image`](/inspec/resources/docker_image/) |
|
||||
| [`file`](http://serverspec.org/resource_types.html#file) | [`file`](/inspec/resources/file/) |
|
||||
| [`group`](http://serverspec.org/resource_types.html#group) | [`group`](/inspec/resources/group/) |
|
||||
| [`host`](http://serverspec.org/resource_types.html#host) | [`host`](/inspec/resources/host/) |
|
||||
| [`interface`](http://serverspec.org/resource_types.html#interface) | [`interface`](/inspec/resources/interface/) |
|
||||
| [`iis_website`](http://serverspec.org/resource_types.html#iis_website) | [`iis_site`](/inspec/resources/iis_site/) |
|
||||
| [`iis_app_pool`](http://serverspec.org/resource_types.html#iis_app_pool) | [`iis_app`](/inspec/resources/iis_app/) |
|
||||
| [`iptables`](http://serverspec.org/resource_types.html#iptables) | [`iptables`](/inspec/resources/iptables/) |
|
||||
| [`kernel_module`](http://serverspec.org/resource_types.html#kernel_module) | [`kernel_module`](/inspec/resources/kernel_module/) |
|
||||
| [`linux_kernel_parameter`](http://serverspec.org/resource_types.html#linux_kernel_parameter) | [`kernel_parameter`](/inspec/resources/kernel_parameter/) |
|
||||
| [`mysql_config`](http://serverspec.org/resource_types.html#mysql_config) | [`mysql_conf`](/inspec/resources/mysql_conf/) |
|
||||
| [`package`](http://serverspec.org/resource_types.html#package) | [`package`](/inspec/resources/package/) |
|
||||
| [`port`](http://serverspec.org/resource_types.html#port) | [`port`](/inspec/resources/port/) |
|
||||
| [`ppa`](http://serverspec.org/resource_types.html#ppa) | [`apt`](/inspec/resources/apt/) |
|
||||
| [`process`](http://serverspec.org/resource_types.html#process) | [`processes`](/inspec/resources/processes/) |
|
||||
| [`service`](http://serverspec.org/resource_types.html#service) | [`service`](/inspec/resources/service/) |
|
||||
| [`user`](http://serverspec.org/resource_types.html#user) | [`user`](/inspec/resources/user/) |
|
||||
| [`windows_feature`](http://serverspec.org/resource_types.html#windows_feature) | [`windows_feature`](/inspec/resources/windows_feature/) |
|
||||
| [`windows_registry_key`](http://serverspec.org/resource_types.html#windows_registry_key) | [`registry_key`](/inspec/resources/registry_key/) |
|
||||
| [`x509_certificate`](http://serverspec.org/resource_types.html#x509_certificate) | [`x509_certificate`](/inspec/resources/x509_certificate/) |
|
||||
| [`yumrepo`](http://serverspec.org/resource_types.html#yumrepo) | [`yum`](/inspec/resources/yum/) |
|
||||
| [`zfs`](http://serverspec.org/resource_types.html#zfs) | [`zfs_pool`](/inspec/resources/zfs_pool/) |
|
||||
|
||||
Some Serverspec resources are not available yet. We will implement those resources based on user feedback. If you need a resource that is not available in InSpec, please open an [Github issue](https://github.com/chef/inspec/issues). The list of resources that are not available in InSpec:
|
||||
|
||||
* [`cgroup`](http://serverspec.org/resource_types.html#cgroup)
|
||||
* [`default_gateway`](http://serverspec.org/resource_types.html#default_gateway)
|
||||
* [`ip6tables`](http://serverspec.org/resource_types.html#ip6tables)
|
||||
* [`ipfilter`](http://serverspec.org/resource_types.html#ipfilter)
|
||||
* [`ipnat`](http://serverspec.org/resource_types.html#ipnat)
|
||||
* [`linux_audit_system`](http://serverspec.org/resource_types.html#linux_audit_system)
|
||||
* [`lxc`](http://serverspec.org/resource_types.html#lxc)
|
||||
* [`mail_alias`](http://serverspec.org/resource_types.html#mail_alias)
|
||||
* [`php_config`](http://serverspec.org/resource_types.html#php_config)
|
||||
* [`routing_table`](http://serverspec.org/resource_types.html#routing_table)
|
||||
* [`selinux`](http://serverspec.org/resource_types.html#selinux)
|
||||
* [`selinux_module`](http://serverspec.org/resource_types.html#selinux_module)
|
||||
* [`x509_private_key`](http://serverspec.org/resource_types.html#x509_private_key)
|
||||
|
||||
In addition Chef InSpec provides additional [resources](/inspec/resources/) that are not available in Serverspec:
|
||||
|
||||
* [`apache_conf`](/inspec/resources/apache_conf/)
|
||||
* [`apt`](/inspec/resources/apt/)
|
||||
* [`audit_policy`](/inspec/resources/audit_policy/)
|
||||
* [`auditd_conf`](/inspec/resources/auditd_conf/)
|
||||
* [`bash`](/inspec/resources/bash/)
|
||||
* [`csv`](/inspec/resources/csv/)
|
||||
* [`etc_shadow`](/inspec/resources/etc_shadow/)
|
||||
* [`gem`](/inspec/resources/gem/)
|
||||
* [`grub_conf`](/inspec/resources/grub_conf/)
|
||||
* [`inetd_conf`](/inspec/resources/inetd_conf/)
|
||||
* [`ini`](/inspec/resources/ini/)
|
||||
* [`json`](/inspec/resources/json/)
|
||||
* [`npm`](/inspec/resources/npm/)
|
||||
* [`ntp_conf`](/inspec/resources/ntp_conf/)
|
||||
* [`oneget`](/inspec/resources/oneget/)
|
||||
* [`pip`](/inspec/resources/pip/)
|
||||
* [`powershell`](/inspec/resources/powershell/)
|
||||
* [`security_policy`](/inspec/resources/security_policy/)
|
||||
* [`ssh_config`](/inspec/resources/ssh_config/)
|
||||
* [`sshd_config`](/inspec/resources/sshd_config/)
|
||||
* [`sys_info`](/inspec/resources/sys_info/)
|
||||
|
||||
## How do I migrate my Serverspec tests to InSpec
|
||||
|
||||
For most cases, the migration to Chef InSpec is pretty straight forward. First, replace the current verifier in `kitchen.yml` configuration with:
|
||||
|
||||
```
|
||||
verifier:
|
||||
name: inspec
|
||||
```
|
||||
|
||||
Second, rename the directory `test/integration/default/serverspec` to
|
||||
`test/integration/default/inspec`
|
||||
|
||||
Third, remove the Serverspec-specific code from the test files.
|
||||
|
||||
```
|
||||
require 'serverspec'
|
||||
|
||||
# Required by serverspec
|
||||
set :backend, :exec
|
||||
```
|
||||
|
||||
Chef InSpec is now configured with Test-Kitchen:
|
||||
|
||||
```
|
||||
kitchen verify package-install-centos-72
|
||||
-----> Starting Kitchen (v1.14.2)
|
||||
-----> Verifying <package-install-centos-72>...
|
||||
Detected alternative framework tests for `inspec`
|
||||
Loaded
|
||||
|
||||
Target: ssh://vagrant@127.0.0.1:2200
|
||||
|
||||
|
||||
PHP has
|
||||
✔ php
|
||||
✔ the pear.php.net channel
|
||||
✔ the pecl.php.net channel
|
||||
|
||||
Test Summary: 3 successful, 0 failures, 0 skipped
|
||||
Finished verifying <package-install-centos-72> (0m0.40s).
|
||||
-----> Kitchen is finished. (0m3.31s)
|
||||
```
|
||||
|
||||
Some real-world migrations are available:
|
||||
|
||||
* [docker](https://github.com/chef-cookbooks/docker)
|
||||
* [nginx](https://github.com/chef-cookbooks/chef_nginx/pull/5/files)
|
||||
* [mysql](https://github.com/chef-cookbooks/mysql/pull/430/files)
|
||||
* [php](https://github.com/chef-cookbooks/php/pull/189/files)
|
||||
|
||||
Some general recommendations:
|
||||
|
||||
* use test-kitchen 1.14+
|
||||
* in case of errors, increase the log level `kitchen verify package-install-centos-72 -l debug`
|
||||
|
||||
## Do I still need the backend configuration?
|
||||
|
||||
Chef InSpec does not attach backend information to test files. All tests are defined independently of any backend. Therefore a Serverspec test file:
|
||||
|
||||
```
|
||||
require 'serverspec'
|
||||
|
||||
# Required by serverspec
|
||||
set :backend, :exec
|
||||
|
||||
describe 'PHP' do
|
||||
it 'has php' do
|
||||
expect(command('php -v').exit_status).to eq(0)
|
||||
end
|
||||
|
||||
it 'has the pear.php.net channel' do
|
||||
expect(command('pear list-channels').stdout).to include('pear.php.net')
|
||||
end
|
||||
|
||||
it 'has the pecl.php.net channel' do
|
||||
expect(command('pear list-channels').stdout).to include('pecl.php.net')
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
will become the following Chef InSpec test file:
|
||||
|
||||
```
|
||||
describe 'PHP' do
|
||||
it 'has php' do
|
||||
expect(command('php -v').exit_status).to eq(0)
|
||||
end
|
||||
|
||||
it 'has the pear.php.net channel' do
|
||||
expect(command('pear list-channels').stdout).to include('pear.php.net')
|
||||
end
|
||||
|
||||
it 'has the pecl.php.net channel' do
|
||||
expect(command('pear list-channels').stdout).to include('pecl.php.net')
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
As you can see, the Chef InSpec test files just focuses on tests and tries to avoid all clutter.
|
||||
|
||||
## Nested describe blocks
|
||||
|
||||
Serverspec and RSpec allow you to define nested describe blocks. We did a survey and found out that most users use nested describe blocks only to improve their output report. We believe the code structure should not change to improve the output of a report. Nevertheless we understand that nested describe blocks help you to structure test code. A sample code block looks like:
|
||||
|
||||
```
|
||||
describe 'chef-server-directories' do
|
||||
describe file('/etc/opscode') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/opscode-analytics') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'opscode' }
|
||||
it { should be_grouped_into 'opscode' }
|
||||
end
|
||||
|
||||
describe file('/var/log/opscode') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'opscode' }
|
||||
it { should be_grouped_into 'opscode' }
|
||||
end
|
||||
|
||||
describe file('/var/opt/opscode') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
In Chef InSpec you would split up groups into files.
|
||||
|
||||
```
|
||||
tests
|
||||
├── server-directories.rb
|
||||
├── other-tests.rb
|
||||
└── further-tests.rb
|
||||
```
|
||||
|
||||
Each file can have a top-level description of its content:
|
||||
|
||||
```
|
||||
title "Chef Server Directories"
|
||||
|
||||
describe file('/etc/opscode') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
describe file('/etc/opscode-analytics') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'opscode' }
|
||||
it { should be_grouped_into 'opscode' }
|
||||
end
|
||||
|
||||
describe file('/var/log/opscode') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'opscode' }
|
||||
it { should be_grouped_into 'opscode' }
|
||||
end
|
||||
|
||||
describe file('/var/opt/opscode') do
|
||||
it { should be_directory }
|
||||
it { should be_owned_by 'root' }
|
||||
end
|
||||
|
||||
```
|
||||
|
||||
## Are you supporting the `expect` syntax?
|
||||
|
||||
Of course. We still prefer the `should` syntax for UX reasons. We did surveys with various types of customers like devops engineers, auditors, managers. All participants who preferred the `expect` syntax have been Ruby experts. All non-Ruby developers found it easier to understand the `should` syntax.
|
||||
|
||||
### `should` syntax with InSpec
|
||||
|
||||
```
|
||||
describe command('php -v') do
|
||||
its('exit_status') { should eq 0 }
|
||||
end
|
||||
|
||||
describe command('pear list-channels') do
|
||||
its('stdout') { should include('pear.php.net')}
|
||||
end
|
||||
|
||||
describe command('pear list-channels') do
|
||||
its('stdout') { should include('pecl.php.net')}
|
||||
end
|
||||
```
|
||||
|
||||
### `expect` syntax with InSpec
|
||||
|
||||
```
|
||||
describe 'PHP' do
|
||||
it 'has php' do
|
||||
expect(command('php -v').exit_status).to eq(0)
|
||||
end
|
||||
|
||||
it 'has the pear.php.net channel' do
|
||||
expect(command('pear list-channels').stdout).to include('pear.php.net')
|
||||
end
|
||||
|
||||
it 'has the pecl.php.net channel' do
|
||||
expect(command('pear list-channels').stdout).to include('pecl.php.net')
|
||||
end
|
||||
end
|
||||
```
|
220
www/content/inspec/platforms.md
Normal file
220
www/content/inspec/platforms.md
Normal file
|
@ -0,0 +1,220 @@
|
|||
+++
|
||||
title = "Using Chef InSpec on Cloud Platforms"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Chef InSpec for the Cloud"
|
||||
identifier = "inspec/platforms.md Using Chef InSpec on Cloud Platforms"
|
||||
parent = "inspec"
|
||||
weight = 30
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/platforms.md)
|
||||
|
||||
As of Chef InSpec 2.0, we have expanded our platform support beyond individual
|
||||
machines and now include support for select AWS and Azure resources.
|
||||
|
||||
Using InSpec, you can use several Chef InSpec resources to audit properties of
|
||||
your cloud infrastructure - for example, an Amazon Web Services S3 bucket.
|
||||
|
||||
## AWS Platform Support in InSpec
|
||||
|
||||
### Setting up AWS credentials for InSpec
|
||||
|
||||
Chef InSpec uses the standard AWS authentication mechanisms. Typically, you will
|
||||
create an IAM user specifically for auditing activities.
|
||||
|
||||
1. Create an IAM user in the AWS console, with your choice of username. Check the
|
||||
box marked "Programmatic Access."
|
||||
1. On the Permissions screen, choose Direct Attach. Select the AWS-managed IAM
|
||||
Profile named "ReadOnlyAccess." If you wish to restrict the user further, you
|
||||
may do so; see individual Chef InSpec resources to identify which permissions
|
||||
are required.
|
||||
1. After generating the key, record the Access Key ID and Secret Key.
|
||||
|
||||
#### Using Environment Variables to provide credentials
|
||||
|
||||
You may provide the credentials to Chef InSpec by setting the following environment
|
||||
variables: `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_KEY_ID`. You may
|
||||
also use `AWS_PROFILE`, or if you are using MFA, `AWS_SESSION_TOKEN`. See the
|
||||
[AWS Command Line Interface Docs](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)
|
||||
for details.
|
||||
|
||||
Once you have your environment variables set, you can verify your credentials by running:
|
||||
|
||||
```bash
|
||||
you$ inspec detect -t aws://
|
||||
|
||||
== Platform Details
|
||||
Name: aws
|
||||
Families: cloud, api
|
||||
Release: aws-sdk-v2.10.125
|
||||
```
|
||||
|
||||
#### Using the Chef InSpec target option to provide credentials on AWS
|
||||
|
||||
Look for a file in your home directory named `~/.aws/credentials`. If it does not
|
||||
exist, create it. Choose a name for your profile; here, we're using the name
|
||||
'auditing'. Add your credentials as a new profile, in INI format:
|
||||
|
||||
```bash
|
||||
[auditing]
|
||||
aws_access_key_id = AKIA....
|
||||
aws_secret_access_key = 1234....abcd
|
||||
```
|
||||
|
||||
You may now run Chef InSpec using the `--target` / `-t` option, using the format
|
||||
`-t aws://region/profile`. For example, to connect to the Ohio region using a
|
||||
profile named 'auditing', use `-t aws://us-east-2/auditing`.
|
||||
|
||||
To verify your credentials, run
|
||||
|
||||
```bash
|
||||
you$ inspec detect -t aws://
|
||||
|
||||
== Platform Details
|
||||
Name: aws
|
||||
Families: cloud, api
|
||||
Release: aws-sdk-v2.10.125
|
||||
```
|
||||
|
||||
|
||||
## Azure Platform Support in InSpec
|
||||
|
||||
### Setting up Azure credentials for InSpec
|
||||
|
||||
To use Chef InSpec Azure resources, you will need to create a Service Principal
|
||||
Name (SPN) for auditing an Azure subscription.
|
||||
|
||||
This can be done on the command line or from the Azure Portal:
|
||||
|
||||
- [Azure CLI](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal-cli)
|
||||
- [PowerShell](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal)
|
||||
- [Azure Portal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal)
|
||||
|
||||
The information from the SPN can be specified either in the file
|
||||
`~/.azure/credentials`, as environment variables, or by using Chef InSpec target URIs.
|
||||
|
||||
#### Setting up the Azure Credentials File
|
||||
|
||||
By default, Chef InSpec is configured to look at `~/.azure/credentials`, and it
|
||||
should contain:
|
||||
|
||||
```powershell
|
||||
[<SUBSCRIPTION_ID>]
|
||||
client_id = "<CLIENT_ID>"
|
||||
client_secret = "<CLIENT_SECRET>"
|
||||
tenant_id = "<TENANT_ID>"
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
|
||||
In the Azure web portal, these values are labeled differently:
|
||||
- The client_id is referred to as the 'Application ID'
|
||||
- The client_secret is referred to as the 'Key (Password Type)'
|
||||
- The tenant_id is referred to as the 'Directory ID'
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
With the credentials are in place, you may now execute InSpec:
|
||||
|
||||
```bash
|
||||
inspec exec my-inspec-profile -t azure://
|
||||
```
|
||||
|
||||
#### Using Environment variables to provide credentials
|
||||
|
||||
You may also set the Azure credentials via environment variables:
|
||||
|
||||
- `AZURE_SUBSCRIPTION_ID`
|
||||
- `AZURE_CLIENT_ID`
|
||||
- `AZURE_CLIENT_SECRET`
|
||||
- `AZURE_TENANT_ID`
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
AZURE_SUBSCRIPTION_ID="2fbdbb02-df2e-11e6-bf01-fe55135034f3" \
|
||||
AZURE_CLIENT_ID="58dc4f6c-df2e-11e6-bf01-fe55135034f3" \
|
||||
AZURE_CLIENT_SECRET="Jibr4iwwaaZwBb6W" \
|
||||
AZURE_TENANT_ID="6ad89b58-df2e-11e6-bf01-fe55135034f3" inspec exec my-profile -t azure://
|
||||
```
|
||||
|
||||
#### Using the Chef InSpec target option to provide credentials on Azure
|
||||
|
||||
If you have created a `~/.azure/credentials` file as above, you may also use the Chef InSpec command line `--target` / `-t` option to select a subscription ID. For example:
|
||||
|
||||
```bash
|
||||
inspec exec my-profile -t azure://2fbdbb02-df2e-11e6-bf01-fe55135034f3
|
||||
```
|
||||
|
||||
## GCP Platform Support in InSpec
|
||||
|
||||
### Setting up GCP credentials for InSpec
|
||||
|
||||
To use Chef InSpec GCP resources, you will need to install and configure the Google
|
||||
Cloud SDK. Instructions for this pre-requisite can be found in the
|
||||
[Google CLoud SDK documentation](https://cloud.google.com/sdk/docs/). Be sure
|
||||
that your InSpec installation is the latest version. The minimal required InSpec
|
||||
version is 3.0.25.
|
||||
|
||||
### Create an InSpec profile that makes use of `inspec-gcp`.
|
||||
|
||||
With a version of InSpec above 4.0.0, it is possible to create a profile with the
|
||||
following command:
|
||||
|
||||
```
|
||||
$ inspec init profile --platform gcp my-profile
|
||||
Create new profile at /Users/me/my-profile
|
||||
* Creating directory libraries
|
||||
* Creating file README.md
|
||||
* Creating directory controls
|
||||
* Creating file controls/example.rb
|
||||
* Creating file inspec.yml
|
||||
* Creating file attributes.yml
|
||||
* Creating file libraries/.gitkeep
|
||||
```
|
||||
|
||||
Assuming the attributes yml file contains your GCP project ID, this sample
|
||||
profile can then be executed using the following command:
|
||||
|
||||
```
|
||||
inspec exec my-profile --attrs my-profile/attributes.yml -t gcp://
|
||||
```
|
||||
|
||||
#### Setting up the GCP Credentials File
|
||||
|
||||
While InSpec can use user accounts for authentication,
|
||||
[Google Cloud documentation](https://cloud.google.com/docs/authentication/)
|
||||
recommends using service accounts. Following GCP best practices, first create a
|
||||
service account with the scopes appropriate for your needs. See
|
||||
[these instructions](https://cloud.google.com/docs/authentication/getting-started)
|
||||
on creating a service account.
|
||||
|
||||
Then, download the credential JSON file, e.g. `project-credentials.json`, to your
|
||||
workspace and run the following command to activate your service account:
|
||||
|
||||
```bash
|
||||
gcloud auth activate-service-account --key-file project-credentials.json
|
||||
```
|
||||
|
||||
#### Using Environment variables to provide credentials
|
||||
|
||||
You may also set the GCP credentials json file via the `GOOGLE_APPLICATION_CREDENTIALS` environment variable.
|
||||
|
||||
```bash
|
||||
export GOOGLE_APPLICATION_CREDENTIALS='/Users/me/.config/gcloud/myproject-1-feb7993e8660.json'
|
||||
```
|
||||
|
||||
Once you have your environment variables set, you can verify your credentials by running:
|
||||
|
||||
```bash
|
||||
$ inspec detect -t gcp://
|
||||
|
||||
== Platform Details
|
||||
|
||||
Name: gcp
|
||||
Families: cloud, api
|
||||
Release: google-cloud-v
|
||||
```
|
70
www/content/inspec/plugin_kitchen_inspec.md
Normal file
70
www/content/inspec/plugin_kitchen_inspec.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
+++
|
||||
title = "About kitchen-inspec"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "kitchen-inspec"
|
||||
identifier = "inspec/reference/plugin_kitchen_inspec.md kitchen-inspec"
|
||||
parent = "inspec/reference"
|
||||
weight = 110
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/plugin_kitchen_inspec.md)
|
||||
|
||||
Use Chef InSpec as a Kitchen verifier with `kitchen-inspec`.
|
||||
|
||||
Add the Chef InSpec verifier to the `.kitchen.yml` file:
|
||||
|
||||
```YML
|
||||
verifier:
|
||||
name: inspec
|
||||
```
|
||||
|
||||
Use a compliance profile from the Chef Compliance server:
|
||||
|
||||
```YML
|
||||
suites:
|
||||
- name: compliance
|
||||
run_list:
|
||||
- recipe[ssh-hardening::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- compliance://base/ssh
|
||||
```
|
||||
|
||||
and then run the following command:
|
||||
|
||||
```bash
|
||||
inspec compliance login https://compliance.test --user admin --insecure --token ''
|
||||
```
|
||||
|
||||
where `--insecure` is required when using self-signed certificates.
|
||||
|
||||
Use a compliance profile from the Chef Supermarket:
|
||||
|
||||
```YML
|
||||
suites:
|
||||
- name: supermarket
|
||||
run_list:
|
||||
- recipe[ssh-hardening::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- supermarket://dev-sec/ssh-baseline
|
||||
```
|
||||
|
||||
Use Chef InSpec tests from the local file system:
|
||||
|
||||
```YML
|
||||
suites:
|
||||
- name: local
|
||||
run_list:
|
||||
- recipe[my_cookbook::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- test/integration/default
|
||||
```
|
||||
|
||||
Check out [Detect and correct with Test Kitchen](https://learn.chef.io/modules/detect-correct-kitchen#/)
|
||||
on Learn Chef Rally for a hands-on look at how to use Test Kitchen to run Chef
|
||||
InSpec profiles.
|
86
www/content/inspec/plugins.md
Normal file
86
www/content/inspec/plugins.md
Normal file
|
@ -0,0 +1,86 @@
|
|||
+++
|
||||
title = "About Chef InSpec and Train Plugins"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Plugins"
|
||||
identifier = "inspec/reference/plugins.md Plugins"
|
||||
parent = "inspec/reference"
|
||||
weight = 100
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/plugins.md)
|
||||
|
||||
## What are Chef InSpec Plugins?
|
||||
|
||||
Chef InSpec Plugins are optional software components that extend the capabilities
|
||||
of InSpec. For example, [`inspec-iggy`](https://github.com/inspec/inspec-iggy)
|
||||
is a Plugin project that aims to generate Chef InSpec controls from
|
||||
infrastructure-as-code files. Plugins are distributed as RubyGems, and Chef InSpec
|
||||
manages their installation. Chef InSpec Plugins always begin with the prefix
|
||||
'inspec-'.
|
||||
|
||||
## What are Train Plugins?
|
||||
|
||||
Train Plugins allow Chef InSpec to speak to new kinds of targets (typically new
|
||||
remote targets or APIs, but you could treat the local system in a new way if you
|
||||
wished to). For example, if you wanted to audit a Kubernetes cluster, you might
|
||||
want a transport that can talk to the supervisor API. You would develop a Train
|
||||
Plugin for that, and install it using the Chef InSpec command line. Train Plugins
|
||||
always begin with the prefix 'train-'.
|
||||
|
||||
## What can plugins do?
|
||||
|
||||
Currently, each plugin can offer one or more of these capabilities:
|
||||
|
||||
- define new output formats ("reporters")
|
||||
- input sources
|
||||
- define a new command-line-interface (CLI) command suite (`inspec` plugins)
|
||||
- connectivity to new types of hosts or cloud providers (`train` plugins)
|
||||
- DSL extensions at the file, control, describe block, or test level
|
||||
- DSL extensions for custom resources
|
||||
|
||||
## How do I find out which plugins are available?
|
||||
|
||||
The Chef InSpec CLI can tell you which plugins are available:
|
||||
|
||||
```bash
|
||||
inspec plugin search inspec-
|
||||
```
|
||||
|
||||
## How do I install and manage plugins?
|
||||
|
||||
The Chef InSpec command line now offers a new subcommand just for managing plugins.
|
||||
|
||||
You can install a plugin by running:
|
||||
|
||||
```bash
|
||||
inspec plugin install inspec-some-plugin
|
||||
inspec plugin install train-some-plugin
|
||||
```
|
||||
|
||||
For more details on what the `plugin` command can do, see the [online help](/inspec/cli/#plugin),
|
||||
or run `inspec plugin help`.
|
||||
|
||||
## How do I use a different Gem server?
|
||||
|
||||
You can specify an alternate source by passing the base of your Gem repository to
|
||||
the `--source` parameter:
|
||||
|
||||
```bash
|
||||
inspec plugin search --source https://my.private.server inspec-private
|
||||
inspec plugin install --source https://my.private.server inspec-private-plugin
|
||||
```
|
||||
|
||||
## How do I write a plugin?
|
||||
|
||||
### Chef InSpec Plugins
|
||||
|
||||
For details on how to author a Chef InSpec Plugin, see the
|
||||
[developer documentation](https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md)
|
||||
|
||||
### Train Plugins
|
||||
|
||||
For details on how to author a Train Plugin, see the
|
||||
[developer documentation](https://github.com/inspec/train/blob/master/docs/plugins.md)
|
494
www/content/inspec/profiles.md
Normal file
494
www/content/inspec/profiles.md
Normal file
|
@ -0,0 +1,494 @@
|
|||
+++
|
||||
title = "About Chef InSpec Profiles"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Profiles"
|
||||
identifier = "inspec/reference/profiles.md Profiles"
|
||||
parent = "inspec/reference"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/profiles.md)
|
||||
|
||||
Chef InSpec supports the creation of complex test and compliance profiles, which
|
||||
organize controls to support dependency management and code reuse. Each profile
|
||||
is a standalone structure with its own distribution and execution flow.
|
||||
|
||||
## Profile Structure
|
||||
|
||||
A profile should have the following structure::
|
||||
|
||||
```YAML
|
||||
examples/profile
|
||||
├── README.md
|
||||
├── controls
|
||||
│ ├── example.rb
|
||||
│ └── control_etc.rb
|
||||
├── libraries
|
||||
│ └── extension.rb
|
||||
|── files
|
||||
│ └── extras.conf
|
||||
└── inspec.yml
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `inspec.yml` includes the profile description (required)
|
||||
- `controls` is the directory in which all tests are located (required)
|
||||
- `libraries` is the directory in which all Chef InSpec resource extensions are located (optional)
|
||||
- `files` is the directory with additional files that a profile can access (optional)
|
||||
- `README.md` should be used to explain the profile, its scope, and usage
|
||||
|
||||
See a complete example profile in the Chef InSpec open source repository:
|
||||
[Example Chef InSpec Profile](https://github.com/chef/inspec/tree/master/examples/profile)
|
||||
|
||||
Also check out [Explore Chef InSpec resources](https://learn.chef.io/modules/explore-inspec-resources#/)
|
||||
on Learn Chef Rally to learn more about how profiles are structured with hands-on-examples.
|
||||
|
||||
## inspec.yml
|
||||
|
||||
Each profile must have an `inspec.yml` file that defines the following information:
|
||||
|
||||
- Use `name` to specify a unique name for the profile. Required.
|
||||
- Use `title` to specify a human-readable name for the profile.
|
||||
- Use `maintainer` to specify the profile maintainer.
|
||||
- Use `copyright` to specify the copyright holder.
|
||||
- Use `copyright_email` to specify support contact information for the profile, typically an email address.
|
||||
- Use `license` to specify the license for the profile.
|
||||
- Use `summary` to specify a one line summary for the profile.
|
||||
- Use `description` to specify a multiple line description of the profile.
|
||||
- Use `version` to specify the profile version.
|
||||
- Use `inspec_version` to place SemVer constraints on the version of Chef InSpec that the profile can run under.
|
||||
- Use `supports` to specify a list of supported platform targets.
|
||||
- Use `depends` to define a list of profiles on which this profile depends.
|
||||
- Use `attributes` to define a list of attributes you can use in your controls.
|
||||
|
||||
`name` is required; all other profile settings are optional. For example:
|
||||
|
||||
```YAML
|
||||
name: ssh
|
||||
title: Basic SSH
|
||||
maintainer: Chef Software, Inc.
|
||||
copyright: Chef Software, Inc.
|
||||
copyright_email: support@chef.io
|
||||
license: Proprietary, All rights reserved
|
||||
summary: Verify that SSH Server and SSH Client are configured securely
|
||||
version: 1.0.0
|
||||
supports:
|
||||
- os-family: linux
|
||||
depends:
|
||||
- name: profile
|
||||
path: ../path/to/profile
|
||||
inspec_version: "~> 2.1"
|
||||
```
|
||||
|
||||
The `inspec.yml` also supports embedded ERB in the file. For example:
|
||||
|
||||
```YAML
|
||||
name: dummy
|
||||
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
|
||||
depends:
|
||||
- name: inherit
|
||||
url: "https://artifactory.com/artifactory/example-repo-local/inspec/0.4.1.tar.gz"
|
||||
username: <%= ENV['USERNAME'] %>
|
||||
password: <%= ENV['API_KEY'] %>
|
||||
```
|
||||
|
||||
## Verify Profiles
|
||||
|
||||
Use the `inspec check` command to verify the implementation of a profile:
|
||||
|
||||
```bash
|
||||
inspec check examples/profile
|
||||
```
|
||||
|
||||
## Platform Support
|
||||
|
||||
Use the `supports` setting in the `inspec.yml` file to specify one (or more) platforms for which a profile is targeting. The list of supported platforms may contain the following:
|
||||
|
||||
- Use `platform-family` to restrict to a specific platform family.
|
||||
- Use `platform-name` to restrict on a specific platform name.
|
||||
- Use `release` to restrict to a specific platform version (used with platform-name).
|
||||
- Use `platform` to restrict on either platform-name or platform-family.
|
||||
|
||||
For compatibility we support `os-name` and `os-family`. We recommend all users
|
||||
to change `os-name` to `platform-name` and `os-family` to `platform-family`.
|
||||
|
||||
With Chef InSpec 2.0, we introduced new families to help distinguish the cloud
|
||||
platforms. The new families can restrict the platform family to `os`, `aws`, `azure` or `gcp`.
|
||||
|
||||
For example, to target anything running Debian Linux:
|
||||
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- platform-name: debian
|
||||
```
|
||||
|
||||
and to target only Ubuntu version 14.04
|
||||
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- platform-name: ubuntu
|
||||
release: 14.04
|
||||
```
|
||||
|
||||
and to target the entire RedHat platform (including CentOS and Oracle Linux):
|
||||
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- platform-family: redhat
|
||||
```
|
||||
|
||||
and to target anything running on Amazon AWS:
|
||||
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- platform: aws
|
||||
```
|
||||
|
||||
and to target all of these examples in a single `inspec.yml` file:
|
||||
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- platform-name: debian
|
||||
- platform-name: ubuntu
|
||||
release: 14.04
|
||||
- platform-family: redhat
|
||||
- platform: aws
|
||||
```
|
||||
|
||||
## Profile Dependencies
|
||||
|
||||
A Chef InSpec profile can bring in the controls and custom resources from another
|
||||
Chef InSpec profile. Additionally, when inheriting the controls of another profile,
|
||||
a profile can skip or even modify those included controls.
|
||||
|
||||
For hands-on examples, check out [Create a custom Chef InSpec profile](https://learn.chef.io/modules/create-a-custom-profile#/)
|
||||
on Learn Chef Rally.
|
||||
|
||||
### Defining the Dependencies
|
||||
|
||||
Before a profile can use controls from another profile, the to-be-included profile
|
||||
needs to be specified in the including profile’s `inspec.yml` file in the `depends`
|
||||
section. For each profile to be included, a location for the profile from where
|
||||
to be fetched and a name for the profile should be included. For example:
|
||||
|
||||
```YAML
|
||||
depends:
|
||||
- name: linux-baseline
|
||||
url: https://github.com/dev-sec/linux-baseline/archive/master.tar.gz
|
||||
- name: ssh-baseline
|
||||
url: https://github.com/dev-sec/ssh-baseline/archive/master.tar.gz
|
||||
```
|
||||
|
||||
Chef InSpec supports a number of dependency sources.
|
||||
|
||||
#### path
|
||||
|
||||
The `path` setting defines a profile that is located on disk. This setting is
|
||||
typically used during development of profiles and when debugging profiles.
|
||||
|
||||
```YAML
|
||||
depends:
|
||||
- name: my-profile
|
||||
path: /absolute/path
|
||||
- name: another
|
||||
path: ../relative/path
|
||||
```
|
||||
|
||||
#### url
|
||||
|
||||
The `url` setting specifies a profile that is located at an HTTP- or HTTPS-based
|
||||
URL. The profile must be accessible via a HTTP GET operation and must be a valid
|
||||
profile archive (zip, tar, or tar.gz format).
|
||||
|
||||
```YAML
|
||||
depends:
|
||||
- name: my-profile
|
||||
url: https://my.domain/path/to/profile.tgz
|
||||
- name: profile-via-git
|
||||
url: https://github.com/myusername/myprofile-repo/archive/master.tar.gz
|
||||
```
|
||||
|
||||
`url` also supports basic authentication.
|
||||
|
||||
```YAML
|
||||
depends:
|
||||
- name: my-profile
|
||||
url: https://my.domain/path/to/profile.tgz
|
||||
username: user
|
||||
password: password
|
||||
```
|
||||
|
||||
#### git
|
||||
|
||||
A `git` setting specifies a profile that is located in a git repository, with
|
||||
optional settings for branch, tag, commit, version, and relative_path. The source
|
||||
location is translated into a URL upon resolution. This type of dependency supports
|
||||
version constraints via semantic versioning as git tags.
|
||||
|
||||
```YAML
|
||||
depends:
|
||||
- name: git-profile
|
||||
git: http://url/to/repo
|
||||
branch: desired_branch
|
||||
tag: desired_version
|
||||
commit: pinned_commit
|
||||
version: semver_via_tags
|
||||
relative_path: relative/optional/path/to/profile
|
||||
```
|
||||
|
||||
#### supermarket
|
||||
|
||||
A `supermarket` setting specifies a profile that is located in a cookbook hosted
|
||||
on Chef Supermarket. The source location is translated into a URL upon resolution.
|
||||
|
||||
For example:
|
||||
|
||||
```YAML
|
||||
depends:
|
||||
- name: supermarket-profile
|
||||
supermarket: supermarket-username/supermarket-profile
|
||||
```
|
||||
|
||||
Available Supermarket profiles can be listed with `inspec supermarket profiles`.
|
||||
|
||||
#### compliance
|
||||
|
||||
A `compliance` setting specifies a profile that is located on the Chef Automate
|
||||
or Chef Compliance server.
|
||||
|
||||
For example:
|
||||
|
||||
```YAML
|
||||
depends:
|
||||
- name: linux
|
||||
compliance: base/linux
|
||||
```
|
||||
|
||||
## Vendoring Dependencies
|
||||
|
||||
When you execute a local profile, the `inspec.yml` file will be read in order to
|
||||
source any profile dependencies. It will then cache the dependencies locally and
|
||||
generate an `inspec.lock` file.
|
||||
|
||||
If you add or update dependencies in `inspec.yml`, dependencies may be re-vendored
|
||||
and the lockfile updated with `inspec vendor --overwrite`
|
||||
|
||||
## Using Controls from an Included Profile
|
||||
|
||||
Once defined in the `inspec.yml`, controls from the included profiles can be used!
|
||||
Let’s look at some examples.
|
||||
|
||||
### Including All Controls from a Profile
|
||||
|
||||
With the `include_controls` command in a profile, all controls from the named
|
||||
profile will be executed every time the including profile is executed.
|
||||
|
||||
![Include Controls](/images/inspec/include_controls.png)
|
||||
|
||||
In the example above, every time `my-app-profile` is executed, all the controls
|
||||
from `my-baseline` are also executed. Therefore, the following controls would be
|
||||
executed:
|
||||
|
||||
- myapp-1
|
||||
- myapp-2
|
||||
- myapp-3
|
||||
- baseline-1
|
||||
- baseline-2
|
||||
|
||||
This is a great reminder that having a good naming convention for your controls
|
||||
is helpful to avoid confusion when
|
||||
including controls from other profiles!
|
||||
|
||||
### Skipping a Control from a Profile
|
||||
|
||||
What if one of the controls from the included profile does not apply to your
|
||||
environment? Luckily, it is not necessary to maintain a slightly-modified copy
|
||||
of the included profile just to delete a control. The `skip_control` command
|
||||
tells Chef InSpec to not run a particular control.
|
||||
|
||||
![Include Controls with Skip](/images/inspec/include_controls_with_skip.png)
|
||||
|
||||
In the above example, all controls from `my-app-profile` and `my-baseline` profile will be executed every time `my-app-profile` is executed **except** for control `baseline-2` from the `my-baseline` profile.
|
||||
|
||||
### Modifying a Control
|
||||
|
||||
Let's say a particular control from an included profile should still be run, but
|
||||
the impact isn't appropriate? Perhaps the test should still run, but if it fails,
|
||||
it should be treated as low severity instead of high severity?
|
||||
|
||||
When a control is included, it can also be modified!
|
||||
|
||||
![Include Controls with Modification](/images/inspec/include_controls_with_mod.png)
|
||||
|
||||
In the above example, all controls from `my-baseline` are executed along with
|
||||
all the controls from the including profile, `my-app-profile`. However, should
|
||||
control `baseline-1` fail, it will be raised with an impact of `0.5` instead of
|
||||
the originally-intended impact of `1.0`.
|
||||
|
||||
### Selectively Including Controls from a Profile
|
||||
|
||||
If there are only a handful of controls that should be executed from an included
|
||||
profile, it's not necessarily to skip all the unneeded controls, or worse,
|
||||
copy/paste those controls bit-for-bit into your profile. Instead, use the
|
||||
`require_controls` command.
|
||||
|
||||
![Require Controls](/images/inspec/require_controls.png)
|
||||
|
||||
Whenever `my-app-profile` is executed, in addition to its own controls, it will
|
||||
run only the controls specified in the `require_controls` block. In the case, the
|
||||
following controls would be executed:
|
||||
|
||||
- myapp-1
|
||||
- myapp-2
|
||||
- myapp-3
|
||||
- baseline-2
|
||||
- baseline-4
|
||||
|
||||
Controls `baseline-1`, `baseline-3`, and `baseline-5` would not be run, just as
|
||||
if they were manually skipped. This method of including specific controls ensures
|
||||
only the controls specified are executed; if new controls are added to a later
|
||||
version of `my-baseline`, they would not be run.
|
||||
|
||||
And, just the way its possible to modify controls when using `include_controls`,
|
||||
controls can be modified as well.
|
||||
|
||||
![Require Controls with Modification](/images/inspec/require_controls_with_mod.png)
|
||||
|
||||
As with the prior example, only `baseline-2` and `baseline-4` are executed, but
|
||||
if `baseline-2` fails, it will report with an impact of `0.5` instead of the
|
||||
originally-intended `1.0` impact.
|
||||
|
||||
## Using Resources from an Included Profile
|
||||
|
||||
By default, all of the custom resources from a listed dependency are available
|
||||
for use in your profile. If two of your dependencies provide a resource with
|
||||
the same name, you can use the `require_resource` DSL function to
|
||||
disambiguate the two:
|
||||
|
||||
```YAML
|
||||
require_resource(profile: 'my_dep', resource: 'my_res',
|
||||
as: 'my_res2')
|
||||
```
|
||||
|
||||
This will allow you to reference the resource `my_res` from the
|
||||
profile `my_dep` using the name `my_res2`.
|
||||
|
||||
## Profile Inputs
|
||||
|
||||
Our documentation regarding [Inputs](/inspec/inputs/) is now on a dedicated page.
|
||||
|
||||
## Profile files
|
||||
|
||||
A Chef InSpec profile may contain additional files that can be accessed during
|
||||
tests. A profile file enables you to separate the logic of your tests from the
|
||||
data your tests check for, for example, the list of ports you require to be open.
|
||||
|
||||
To access these files, they must be stored in the `files` directory at the root
|
||||
of a profile. They are accessed by their name relative to this folder with
|
||||
`inspec.profile.file(...)`.
|
||||
|
||||
Here is an example for reading and testing a list of ports. The folder structure is:
|
||||
|
||||
```YAML
|
||||
examples/profile
|
||||
├── controls
|
||||
│ ├── example.rb
|
||||
│── files
|
||||
│ └── services.yml
|
||||
└── inspec.yml
|
||||
```
|
||||
|
||||
With `services.yml` containing:
|
||||
|
||||
```YAML
|
||||
- service_name: httpd-alpha
|
||||
port: 80
|
||||
- service_name: httpd-beta
|
||||
port: 8080
|
||||
```
|
||||
|
||||
The tests in `example.rb` can now access this file:
|
||||
|
||||
```Ruby
|
||||
my_services = yaml(content: inspec.profile.file('services.yml')).params
|
||||
|
||||
my_services.each do |s|
|
||||
describe service(s['service_name']) do
|
||||
it { should be_running }
|
||||
end
|
||||
|
||||
describe port(s['port']) do
|
||||
it { should be_listening }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
For a more complete example that uses a profile file, see
|
||||
[Explore Chef InSpec resources](https://learn.chef.io/modules/explore-inspec-resources#/) on Learn Chef Rally.
|
||||
|
||||
## "should" vs. "expect" syntax
|
||||
|
||||
Users familiar with the RSpec testing framework may know that there are two ways
|
||||
to write test statements: `should` and `expect`. The RSpec community decided that
|
||||
`expect` is the preferred syntax. However, Chef InSpec recommends the `should`
|
||||
syntax as it tends to read more easily to those users who are not as technical.
|
||||
|
||||
Chef InSpec will continue to support both methods of writing tests. Consider
|
||||
this `file` test:
|
||||
|
||||
```Ruby
|
||||
describe file('/tmp/test.txt') do
|
||||
it { should be_file }
|
||||
end
|
||||
```
|
||||
|
||||
This can be re-written with `expect` syntax
|
||||
|
||||
```Ruby
|
||||
describe file('/tmp/test.txt') do
|
||||
it 'should be a file' do
|
||||
expect(subject).to(be_file)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
The output of both of the above examples looks like this:
|
||||
|
||||
```text
|
||||
File /tmp/test.txt
|
||||
✔ should be a file
|
||||
```
|
||||
|
||||
In addition, you can make use of the `subject` keyword to further control your
|
||||
output if you choose:
|
||||
|
||||
```Ruby
|
||||
describe 'test file' do
|
||||
subject { file('/tmp/test.txt') }
|
||||
it 'should be a file' do
|
||||
expect(subject).to(be_file)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
... which will render the following output:
|
||||
|
||||
```text
|
||||
test file
|
||||
✔ should be a file
|
||||
```
|
186
www/content/inspec/reporters.md
Normal file
186
www/content/inspec/reporters.md
Normal file
|
@ -0,0 +1,186 @@
|
|||
+++
|
||||
title = "Chef InSpec Reporters"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Reporters"
|
||||
identifier = "inspec/reference/reporters.md Reporters"
|
||||
parent = "inspec/reference"
|
||||
weight = 50
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/reporters.md)
|
||||
|
||||
Introduced in Chef InSpec 1.51.6
|
||||
|
||||
A `reporter` is a facility for formatting and delivering the results of a Chef InSpec auditing run.
|
||||
|
||||
Chef InSpec allows you to output your test results to one or more reporters. Configure the reporter(s) using either the `--reporter` option or as part of the general config file using the `--config` (or `--json-config`, prior to v3.6) option. While you can configure multiple reporters to write to different files, only one reporter can output to the screen(stdout).
|
||||
|
||||
## Syntax
|
||||
|
||||
You can specify one or more reporters using the `--reporter` cli flag. You can also specify a output by appending a path separated by a colon.
|
||||
|
||||
Output json to screen.
|
||||
|
||||
```bash
|
||||
inspec exec example_profile --reporter json
|
||||
# or explicitly specifying output to STDOUT:
|
||||
inspec exec example_profile --reporter json:-
|
||||
```
|
||||
|
||||
Output yaml to screen
|
||||
|
||||
```bash
|
||||
inspec exec example_profile --reporter yaml
|
||||
# or
|
||||
inspec exec example_profile --reporter yaml:-
|
||||
```
|
||||
|
||||
Output cli to screen and write json to a file.
|
||||
|
||||
```bash
|
||||
inspec exec example_profile --reporter cli json:/tmp/output.json
|
||||
```
|
||||
|
||||
Output nothing to screen and write junit and html to a file.
|
||||
|
||||
```bash
|
||||
inspec exec example_profile --reporter junit:/tmp/junit.xml html:www/index.html
|
||||
```
|
||||
|
||||
Output json to screen and write to a file. Write junit to a file.
|
||||
|
||||
```bash
|
||||
inspec exec example_profile --reporter json junit:/tmp/junit.xml | tee out.json
|
||||
```
|
||||
|
||||
If you wish to pass the profiles directly after specifying the reporters you will need to use the end of options flag `--`.
|
||||
|
||||
```bash
|
||||
inspec exec --reporter json junit:/tmp/junit.xml -- profile1 profile2
|
||||
```
|
||||
|
||||
If you are using the cli option `--config`, you can also set reporters.
|
||||
|
||||
Output cli to screen.
|
||||
|
||||
```json
|
||||
{
|
||||
"reporter": {
|
||||
"cli" : {
|
||||
"stdout" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Output cli to screen and write json to a file.
|
||||
|
||||
```json
|
||||
{
|
||||
"reporter": {
|
||||
"cli" : {
|
||||
"stdout" : true
|
||||
},
|
||||
"json" : {
|
||||
"file" : "/tmp/output.json",
|
||||
"stdout" : false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Supported Reporters
|
||||
|
||||
The following are the current supported reporters:
|
||||
|
||||
### cli
|
||||
|
||||
This is the basic text base report. It includes details about which tests passed and failed and includes an overall summary at the end.
|
||||
|
||||
### json
|
||||
|
||||
This reporter includes all information about the profiles and test results in standard json format.
|
||||
|
||||
### json-min
|
||||
|
||||
This reporter is a redacted version of the json and only includes test results.
|
||||
|
||||
### yaml
|
||||
|
||||
This reporter includes all information about the profiles and test results in standard yaml format.
|
||||
|
||||
### documentation
|
||||
|
||||
This reporter is a very minimal text base report. It shows you which tests passed by name and has a small summary at the end.
|
||||
|
||||
### junit
|
||||
|
||||
This reporter outputs the standard junit spec in xml format.
|
||||
|
||||
### progress
|
||||
|
||||
This reporter is very condensed and gives you a `.`(pass), `f`(fail), or `*`(skip) character per test and a small summary at the end.
|
||||
|
||||
### json-rspec
|
||||
|
||||
This reporter includes all information from the rspec runner. Unlike the json reporter this includes rspec specific details.
|
||||
|
||||
### html
|
||||
|
||||
This renders html code to view your tests in a browser. It includes all the test and summary information.
|
||||
|
||||
## Automate Reporter
|
||||
|
||||
The `automate` reporter type is a special reporter used with [Chef Automate](https://automate.chef.io/). To use this reporter you must pass in the correct configuration via a json config `--config`.
|
||||
|
||||
Example config:
|
||||
|
||||
```json
|
||||
{
|
||||
"reporter": {
|
||||
"automate" : {
|
||||
"stdout" : false,
|
||||
"url" : "https://YOUR_A2_URL/data-collector/v0/",
|
||||
"token" : "YOUR_A2_ADMIN_TOKEN",
|
||||
"insecure" : true,
|
||||
"node_name" : "inspec_test_node",
|
||||
"environment" : "prod"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mandatory fields
|
||||
|
||||
#### stdout
|
||||
|
||||
This will either suppress or show the automate report in the CLI screen on completion
|
||||
|
||||
#### url
|
||||
|
||||
This is your Automate 2 url. Append `data-collector/v0/` at the end.
|
||||
|
||||
#### token
|
||||
|
||||
This is your Automate 2 token. You can generate this token by navigating to the admin tab of A2 and then api keys.
|
||||
|
||||
### Optional fields
|
||||
|
||||
#### insecure
|
||||
|
||||
This will disable or enable the ssl check when accessing the Automate 2 instance.
|
||||
|
||||
#### node_name
|
||||
|
||||
This will be the node name which shows up in Automate.
|
||||
|
||||
#### node_uuid
|
||||
|
||||
This will be the node UUID which shows up in Automate. You will want to use a single static UUID per node for all your reports.
|
||||
|
||||
#### environment
|
||||
|
||||
This will set the environment metadata for Automate.
|
233
www/content/inspec/shell.md
Normal file
233
www/content/inspec/shell.md
Normal file
|
@ -0,0 +1,233 @@
|
|||
+++
|
||||
title = "Chef InSpec Shell"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "InSpec Shell"
|
||||
identifier = "inspec/reference/shell.md Chef InSpec Shell"
|
||||
parent = "inspec/reference"
|
||||
weight = 110
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/shell.md)
|
||||
|
||||
The Chef InSpec interactive shell is a pry based REPL that can be used to
|
||||
quickly run Chef InSpec controls and tests without having to write it to a
|
||||
file. Its functionality is similar to [chef-shell](/chef_shell/) as it provides a way
|
||||
to exercise the Chef InSpec DSL, its resources, tests, and plugins without
|
||||
having to create a profile or write a test file. See
|
||||
[http://pryrepl.org/](http://pryrepl.org/) for an introduction to what pry is and what it can
|
||||
do.
|
||||
|
||||
See [Explore Chef InSpec resources](https://learn.chef.io/modules/explore-inspec-resources#/)
|
||||
on Learn Chef Rally for a hands-on example that uses Chef InSpec shell.
|
||||
|
||||
## Launching the shell
|
||||
|
||||
If you are using Chef InSpec from a platform-specific package (rpm, msi,
|
||||
etc.) or from a Chef prepared shell in ChefDK, you can directly launch
|
||||
Chef InSpec shell against your local machine using the following. See
|
||||
<https://docs.chef.io/install_dk.html#set-system-ruby> for details.
|
||||
|
||||
```bash
|
||||
inspec shell
|
||||
inspec help shell # This will describe inspec shell usage
|
||||
```
|
||||
|
||||
If you wish to connect to a remote machine (called a target within
|
||||
InSpec), you can use the `-t` flag. We support connecting using SSH,
|
||||
WinRM and docker. If no target is provided, we implicitly support the
|
||||
"local" target - i.e. tests running on the current machine running
|
||||
InSpec. For an SSH connection, use `-i` for specifying SSH key files,
|
||||
and the `--sudo*` commands for requesting a privilege escalation after
|
||||
logging in. For a WinRM connection, use `--path` to change the login
|
||||
path, `--ssl` to use SSL for transport layer encryption.
|
||||
|
||||
```bash
|
||||
inspec shell -t ssh://root@192.168.64.2:11022 # Login to remote machine using ssh as root.
|
||||
inspec shell -t ssh://user@hostname:1234 -i /path/to/user_key # Login to hostname on port 1234 as user using given ssh key.
|
||||
inspec shell -t winrm://UserName:Password@windowsmachine:1234 # Login to windowsmachine over WinRM as UserName.
|
||||
inspec shell -t winrm://windowsmachine --user 'UserName@domain' --password 'Secret123!' # Login to windowsmachine as UserName@domain.org.
|
||||
inspec shell -t docker://container_id # Login to a Docker container.
|
||||
```
|
||||
|
||||
## Resource Packs
|
||||
|
||||
Use resource packs to share custom resources with other Chef InSpec users.
|
||||
A resource pack is a Chef InSpec profile that contains only custom resources and
|
||||
no other controls or tests.
|
||||
|
||||
For example, the profile in [`examples/profile`](https://github.com/chef/inspec/tree/master/examples/profile)
|
||||
in the Chef InSpec GitHub repository defines an
|
||||
[`example_config` resource](https://github.com/chef/inspec/blob/master/examples/profile/controls/example.rb).
|
||||
To use these resources within the Chef InSpec shell, you will need to download
|
||||
and specify them as a dependency.
|
||||
|
||||
Once you have local access to the profile, you can use the `example_config` custom
|
||||
resource provided in the `examples/profile` GitHub repo in your local environment :
|
||||
|
||||
```bash
|
||||
inspec shell --depends examples/profile
|
||||
```
|
||||
|
||||
Once inside the shell your resource will be available:
|
||||
|
||||
```ruby
|
||||
inspec> example_config
|
||||
```
|
||||
|
||||
## Using Ruby in Chef InSpec shell
|
||||
|
||||
Since Chef InSpec shell is pry based, you may treat the shell as an
|
||||
interactive Ruby session. You may write Ruby expressions and evaluate
|
||||
them. Source high-lighting, automatic indentation and command history
|
||||
(using the up and down arrow keys) are available to make your experience
|
||||
more delightful. You can exit the shell using `exit`.
|
||||
|
||||
```bash
|
||||
$ inspec shell
|
||||
Welcome to the interactive InSpec Shell
|
||||
To find out how to use it, type: help
|
||||
|
||||
inspec> 1 + 2
|
||||
=> 3
|
||||
inspec> exit
|
||||
```
|
||||
|
||||
## Using Chef InSpec DSL in Chef InSpec shell
|
||||
|
||||
Chef InSpec shell will automatically evaluate the result of every command as
|
||||
if it were a test file. If you type in a Ruby command that is not an
|
||||
Chef InSpec control or test, the shell will evaluate it as if it were a
|
||||
regular ruby command.
|
||||
|
||||
Bare Chef InSpec resources are instantiated and their help text is presented.
|
||||
You may also access the resource contents or other matchers that they
|
||||
define. Run `help <resource>` to get more help on using a particular
|
||||
resource or see the Chef InSpec resources documentation online.
|
||||
|
||||
```bash
|
||||
$ inspec shell
|
||||
Welcome to the interactive InSpec Shell
|
||||
To find out how to use it, type: help
|
||||
|
||||
inspec> file('/Users/myuser').directory?
|
||||
=> true
|
||||
inspec> os_env('HOME')
|
||||
=> Environment variable HOME
|
||||
inspec> os_env('HOME').content
|
||||
=> /Users/myuser
|
||||
inspec> exit
|
||||
```
|
||||
|
||||
Chef InSpec tests are immediately executed.
|
||||
|
||||
```bash
|
||||
inspec> describe file('/Users') # Empty test.
|
||||
Summary: 0 successful, 0 failures, 0 skipped
|
||||
inspec> describe file('/Users') do # Test with one check.
|
||||
inspec> it { should exist }
|
||||
inspec> end
|
||||
✔ File /Users should exist
|
||||
|
||||
Summary: 1 successful, 0 failures, 0 skipped
|
||||
```
|
||||
|
||||
All tests in a control are immediately executed as well. If a control is
|
||||
redefined in the shell, the old control's tests are destroyed and
|
||||
replaced with the redefinition and the control is re-run.
|
||||
|
||||
```bash
|
||||
inspec> control 'my_control' do
|
||||
inspec> describe os_env('HOME') do
|
||||
inspec> its('content') { should eq '/Users/myuser' }
|
||||
inspec> end
|
||||
inspec> end
|
||||
✔ my_control: Environment variable HOME content should eq "/Users/myuser"
|
||||
|
||||
Summary: 1 successful, 0 failures, 0 skipped
|
||||
```
|
||||
|
||||
Syntax errors are illegal tests are also detected and reported.
|
||||
|
||||
```bash
|
||||
inspec> control 'foo' do
|
||||
inspec> thisisnonsense
|
||||
inspec> end
|
||||
NameError: undefined local variable or method `thisisnonsense' for #<#<Class:0x007fd63b571f98>:0x007fd639825cc8>
|
||||
from /usr/local/lib/ruby/gems/2.3.0/gems/rspec-expectations-3.5.0/lib/rspec/matchers.rb:967:in `method_missing'
|
||||
inspec> control 'foo' do
|
||||
inspec> describe file('wut') do
|
||||
inspec> its('thismakesnosense') { should cmp 'fail' }
|
||||
inspec> end
|
||||
inspec> end
|
||||
✖ foo: File wut thismakesnosense (undefined method `thismakesnosense' for File wut:Inspec::Resource::Registry::File)
|
||||
|
||||
Summary: 0 successful, 1 failures, 0 skipped
|
||||
```
|
||||
|
||||
## Running a single Chef InSpec command
|
||||
|
||||
If you wish to run a single Chef InSpec command and fetch its results, you
|
||||
may use the `-c` flag. This is similar to using `bash -c`.
|
||||
|
||||
```bash
|
||||
$ inspec shell -c 'describe file("/Users/myuser") do it { should exist } end'
|
||||
Target: local://
|
||||
|
||||
✔ File /Users/myuser should exist
|
||||
|
||||
Summary: 1 successful, 0 failures, 0 skipped
|
||||
```
|
||||
|
||||
```bash
|
||||
$ inspec shell --format json -c 'describe file("/Users/test") do it { should exist } end'
|
||||
{
|
||||
"version": "1.49.2",
|
||||
"controls": [{
|
||||
"status": "passed",
|
||||
"code_desc": "File /Users/test should exist",
|
||||
"run_time": 0.002374,
|
||||
"start_time": "2018-01-06 18:32:38 -0500"
|
||||
}],
|
||||
"other_checks": [],
|
||||
"profiles": [{
|
||||
"name": "inspec-shell",
|
||||
"supports": [],
|
||||
"controls": [{
|
||||
"title": null,
|
||||
"desc": null,
|
||||
"impact": 0.5,
|
||||
"refs": [],
|
||||
"tags": {},
|
||||
"code": "",
|
||||
"source_location": {
|
||||
"ref": "/usr/local/lib/ruby/gems/2.4.0/gems/inspec-1.49.2/lib/inspec/control_eval_context.rb",
|
||||
"line": 89
|
||||
},
|
||||
"id": "(generated from (eval):1 7b6f82c2cc5e4205b3e2c97c8e855f2d)",
|
||||
"results": [{
|
||||
"status": "passed",
|
||||
"code_desc": "File /Users/test should exist",
|
||||
"run_time": 0.002374,
|
||||
"start_time": "2018-01-06 18:32:38 -0500"
|
||||
}]
|
||||
}],
|
||||
"groups": [{
|
||||
"title": null,
|
||||
"controls": ["(generated from (eval):1 7b6f82c2cc5e4205b3e2c97c8e855f2d)"],
|
||||
"id": "unknown"
|
||||
}],
|
||||
"attributes": [],
|
||||
"sha256": "29c070a90b7e3521babf618215573284a790d92907783d5b2c138f411bfd2e74"
|
||||
}],
|
||||
"platform": {
|
||||
"name": "mac_os_x",
|
||||
"release": "17.3.0"
|
||||
},
|
||||
"statistics": {
|
||||
"duration": 0.003171
|
||||
}
|
||||
}
|
||||
```
|
264
www/content/inspec/style.md
Normal file
264
www/content/inspec/style.md
Normal file
|
@ -0,0 +1,264 @@
|
|||
+++
|
||||
title = "Chef InSpec Profile Style Guide"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Profile Style Guide"
|
||||
identifier = "inspec/reference/style.md Profile Style Guide"
|
||||
parent = "inspec/reference"
|
||||
weight = 80
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/style.md)
|
||||
|
||||
This is a set of recommended Chef InSpec rules you should use when writing controls.
|
||||
|
||||
## Control Files
|
||||
|
||||
### Place control files in `controls/` and end them with `.rb`
|
||||
|
||||
Most syntax highlighters will render Chef InSpec files correctly across a wide list
|
||||
of tools.
|
||||
|
||||
Avoid:
|
||||
|
||||
- `controls/ssh_config`
|
||||
- `controls/ssh/config.rb`
|
||||
|
||||
Use:
|
||||
|
||||
- `controls/ssh_config.rb`
|
||||
- `controls/ssh_config.rb`
|
||||
|
||||
### Avoid `controls`/`control` in your control filenames
|
||||
|
||||
Using `controls` in the filename creates unnecessary clutter when reading it.
|
||||
Keep the names short and concise.
|
||||
|
||||
Avoid:
|
||||
|
||||
- `controls/ssh_controls.rb`
|
||||
|
||||
Use:
|
||||
|
||||
- `controls/ssh.rb`
|
||||
|
||||
## Code Style
|
||||
|
||||
### Avoid unnecessary parentheses in matchers
|
||||
|
||||
Adding additional parentheses is not required and provides more readability if
|
||||
it is not used:
|
||||
|
||||
Avoid:
|
||||
|
||||
- `it { should eq(value) }`
|
||||
|
||||
Use:
|
||||
|
||||
- `it { should eq value }`
|
||||
|
||||
The exception are matchers that require additional arguments or named arguments.
|
||||
|
||||
## Controls
|
||||
|
||||
### Avoid wrapping controls in conditional statements
|
||||
|
||||
This will create dynamic profiles whose controls depend on the execution. The
|
||||
problem here is that we cannot render the profile or provide its information
|
||||
before scanning a system. We want to be able to inform users of the contents of
|
||||
their profiles before they run them. It is valid to skip controls that are not
|
||||
necessary for a system, as long as you do it via `only_if` conditions. Ruby's
|
||||
internal conditionals will hide parts of the profile to static analysis and
|
||||
should thus be avoided.
|
||||
|
||||
Avoid:
|
||||
|
||||
```ruby
|
||||
if package('..').installed?
|
||||
control "package-test1" do
|
||||
..
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Use:
|
||||
|
||||
```ruby
|
||||
control "package-test1" do
|
||||
only_if { package('..').installed? }
|
||||
end
|
||||
```
|
||||
|
||||
Avoid:
|
||||
|
||||
```ruby
|
||||
case inspec.platform.name
|
||||
when /centos/
|
||||
include_controls 'centos-profile'
|
||||
...
|
||||
```
|
||||
|
||||
Instead use the `supports` attribute in the `inspec.yml` of the profile you
|
||||
want to include:
|
||||
|
||||
```ruby
|
||||
supports:
|
||||
- platform-name: centos
|
||||
```
|
||||
|
||||
Now whenever you run the base profile you can just
|
||||
`include_controls 'centos-profile'`. It will only run the included profiles is
|
||||
the platform matches the supported platform.
|
||||
|
||||
### Avoid dynamic elements in the control IDs
|
||||
|
||||
Control IDs are used to map test results to the tests and profiles. Dynamic
|
||||
control IDs make it impossible to map results back, since the identifier which
|
||||
connects tests and results may change in the process.
|
||||
|
||||
Avoid:
|
||||
|
||||
```ruby
|
||||
control "test-file-#{name}" do
|
||||
..
|
||||
end
|
||||
```
|
||||
|
||||
Use:
|
||||
|
||||
```ruby
|
||||
control "test-all-files" do
|
||||
..
|
||||
end
|
||||
```
|
||||
|
||||
Sometimes you may create controls from a static list of elements. If this list
|
||||
stays the same no matter what system is scanned, it may be ok to do so and use
|
||||
it as a generator for static controls.
|
||||
|
||||
### Avoid Ruby system calls
|
||||
|
||||
Ruby code is executed on the system that runs InSpec. This allows Chef InSpec to work
|
||||
without Ruby and RubyGems being required on remote targets (servers or
|
||||
containers). System calls are often used to interact with the local OS or remote
|
||||
endpoints from a local installation.
|
||||
|
||||
Chef InSpec tests, however, are designed to be universally executable on all types
|
||||
of runtimes, including local and remote execution. We want to give users the
|
||||
ability to take an OS profile and execute it remotely or locally.
|
||||
|
||||
### Avoid shelling out
|
||||
|
||||
Avoid:
|
||||
|
||||
- `` `ls` ``
|
||||
- `system("ls")`
|
||||
- `IO.popen("ls")`
|
||||
|
||||
Use:
|
||||
|
||||
- `command("ls")` or `powershell("Get-ChildItem")`
|
||||
|
||||
Ruby's command executors will only run locally. Imagine a test like this:
|
||||
|
||||
```ruby
|
||||
describe `whoami` do
|
||||
it { should cmp "bob\n" }
|
||||
end
|
||||
```
|
||||
|
||||
If you run this test on your local system and happen to be using Bob's account
|
||||
it will succeed. But if you were to run it against
|
||||
`--target alice@remote-host.com` it will still report that the user is bob
|
||||
instead of alice.
|
||||
|
||||
Instead, do this:
|
||||
|
||||
```ruby
|
||||
describe command('whoami') do
|
||||
its('stdout') { should cmp "bob\n" }
|
||||
end
|
||||
```
|
||||
|
||||
If the profile is pointed to a remote endpoint using the `command` resource
|
||||
will run it on the remote OS.
|
||||
|
||||
### Avoid Ruby IO on files
|
||||
|
||||
Similar to the command interactions these files will only be read locally with
|
||||
Ruby's internal calls. If you run this test against a remote target it won't
|
||||
read the file from the remote endpoint, but from the local OS instead. Use the
|
||||
`file` resource to read files on the target system.
|
||||
|
||||
Avoid:
|
||||
|
||||
- `File.new("filename").read`
|
||||
- `File.read("filename")`
|
||||
- `IO.read("filename")`
|
||||
|
||||
Use:
|
||||
|
||||
- `file("filename")`
|
||||
|
||||
In general, try to avoid Ruby's IO calls from within Chef InSpec controls and use
|
||||
Chef InSpec resources instead.
|
||||
|
||||
### Avoid Ruby gem dependencies in controls
|
||||
|
||||
In addition to avoiding system-level gems and modules you should also limit the
|
||||
use of external dependencies to resource packs or plugins. Gems need to be
|
||||
resolved, installed, vendored, and protected from conflicts. We aim to avoid
|
||||
exposing this complexity to users of InSpec, to make it a great tool even if you
|
||||
are not a developer.
|
||||
|
||||
Plugins should declare gem dependencies in their gemspec, and then rely on the
|
||||
plugin installation facility to install and manage dependencies.
|
||||
|
||||
### Avoid debugging calls (in production)
|
||||
|
||||
One of the best way to develop and explore tests is the interactive debugging
|
||||
shell `pry` (see [Interactive Debugging with Pry] (/inspec/dsl_inspec/#interactive-debugging-with-pry)
|
||||
at the end of this page). However, after you finish your profile make sure you
|
||||
have no interactive statements included anymore. Sometimes interactive calls are
|
||||
hidden behind conditionals (`if` statements) that are harder to reach. These
|
||||
calls can easily cause trouble when an automated profiles runs into an
|
||||
interactive `pry` call that stops the execution and waits for user input.
|
||||
|
||||
Avoid:
|
||||
- `binding.pry` in production profiles
|
||||
|
||||
Use:
|
||||
- Use debugging calls during development only
|
||||
|
||||
Also you may find it helpful to use the Chef InSpec logging interface:
|
||||
|
||||
```ruby
|
||||
Inspec::Log.info('Hi')
|
||||
```
|
||||
|
||||
#### 9. Favor `cmp` over `eq`
|
||||
|
||||
The `cmp` matcher handles type conversions, case insensitive comparisons,
|
||||
converting strings to versions (e.g. '7.35.0-1ubuntu2.10'), and many other
|
||||
troublesome things. Unless you want an exact match (if so use the `eq` matcher)
|
||||
then the `cmp` matcher should be used.
|
||||
|
||||
For example, this:
|
||||
|
||||
```ruby
|
||||
describe passwd.uids(0) do
|
||||
its('users') { should cmp 'root' }
|
||||
end
|
||||
```
|
||||
|
||||
is preferred over:
|
||||
|
||||
```ruby
|
||||
describe passwd.uids(0) do
|
||||
its('users') { should eq ['root'] }
|
||||
end
|
||||
```
|
||||
|
||||
See the [`cmp` matcher documentation](/inspec/matchers/#cmp) for more examples.
|
61
www/content/inspec/waivers.md
Normal file
61
www/content/inspec/waivers.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
+++
|
||||
title = "Waivers"
|
||||
draft = false
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "Waivers"
|
||||
identifier = "inspec/reference/waivers.md Waivers"
|
||||
parent = "inspec/reference"
|
||||
weight = 140
|
||||
+++
|
||||
|
||||
[\[edit on GitHub\]](https://github.com/inspec/inspec/blob/master/www/content/inspec/waivers.md)
|
||||
|
||||
Waivers is a mechanism to mark controls as "waived" for various reasons, and to
|
||||
control the running and/or reporting of those controls. It uses a YAML input file
|
||||
that identifies:
|
||||
|
||||
1. which controls are waived
|
||||
1. a description of why it is waived
|
||||
1. (optionally) whether they should be skipped from running
|
||||
1. (optionally) an expiration date for the waiver
|
||||
|
||||
## Usage
|
||||
|
||||
To use waivers, you must have a correctly formatted input file and
|
||||
invoke `inspec exec` with `--waiver-file [path]`.
|
||||
|
||||
```bash
|
||||
inspec exec path/to/profile --waiver-file waivers.yaml
|
||||
```
|
||||
|
||||
## File Format
|
||||
|
||||
Waiver files are [input files](/inspec/inputs/) with a specific format:
|
||||
|
||||
```yaml
|
||||
control_id:
|
||||
expiration_date: YYYY-MM-DD
|
||||
run: false
|
||||
justification: "reason for waiving this control"
|
||||
```
|
||||
|
||||
- `expiration_date` is optional. Absence means the waiver is permanent.
|
||||
- `run` is optional. If present and true, the control will run and be
|
||||
reported, but failures in it won't make the overall run fail. If absent or false, the control will not be run. You may use any of yes, no, true or false.
|
||||
- `justification` can be any text you want and might include a reason
|
||||
as well as who signed off on the waiver.
|
||||
|
||||
### Examples:
|
||||
|
||||
```yaml
|
||||
waiver_control_1_2_3:
|
||||
expiration_date: 2019-10-15
|
||||
justification: Not needed until Q3. @secteam
|
||||
|
||||
xccdf_org.cisecurity.benchmarks_rule_1.1.1.4_Ensure_mounting_of_hfs_filesystems_is_disabled:
|
||||
expiration_date: 2020-03-01
|
||||
justification: "This might be a bug in the test. @qateam"
|
||||
run: false
|
||||
```
|
BIN
www/static/images/inspec/include_controls.png
Normal file
BIN
www/static/images/inspec/include_controls.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
www/static/images/inspec/include_controls_with_mod.png
Normal file
BIN
www/static/images/inspec/include_controls_with_mod.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
www/static/images/inspec/include_controls_with_skip.png
Normal file
BIN
www/static/images/inspec/include_controls_with_skip.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
www/static/images/inspec/require_controls.png
Normal file
BIN
www/static/images/inspec/require_controls.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
www/static/images/inspec/require_controls_with_mod.png
Normal file
BIN
www/static/images/inspec/require_controls_with_mod.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Loading…
Add table
Reference in a new issue