mirror of
https://github.com/inspec/inspec
synced 2024-12-18 00:53:22 +00:00
607de99f75
Signed-off-by: Alex Pop <apop@chef.io>
303 lines
10 KiB
Markdown
303 lines
10 KiB
Markdown
---
|
|
title: About InSpec Profiles
|
|
---
|
|
|
|
# InSpec Profiles
|
|
|
|
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::
|
|
|
|
examples/profile
|
|
├── README.md
|
|
├── controls
|
|
│ ├── example.rb
|
|
│ └── control_etc.rb
|
|
├── libraries
|
|
│ └── extension.rb
|
|
└── 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 InSpec resource extensions are located (optional)
|
|
* `README.md` should be used to explain the profile, its scope, and usage
|
|
|
|
See a complete example profile in the InSpec open source repository: https://github.com/chef/inspec/tree/master/examples/profile
|
|
|
|
## 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 `supports` to specify a list of supported platform targets.
|
|
* Use `depends` to define a list of profiles on which this profile depends.
|
|
|
|
`name` is required; all other profile settings are optional. For example:
|
|
|
|
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
|
|
|
|
## Verify Profiles
|
|
|
|
Use the `inspec check` command to verify the implementation of a profile:
|
|
|
|
$ 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 simple names, names and versions, or detailed flags, and may be combined arbitrarily. For example, to target anything running Debian Linux:
|
|
|
|
name: ssh
|
|
supports:
|
|
- os-name: debian
|
|
|
|
and to target only Ubuntu version 14.04
|
|
|
|
name: ssh
|
|
supports:
|
|
- os-name: ubuntu
|
|
release: 14.04
|
|
|
|
and to target the entire RedHat platform (including CentOS and Oracle Linux):
|
|
|
|
name: ssh
|
|
supports:
|
|
- os-family: redhat
|
|
|
|
and to target anything running on Amazon AWS:
|
|
|
|
name: ssh
|
|
supports:
|
|
- platform: aws
|
|
|
|
and to target all of these examples in a single `inspec.yml` file:
|
|
|
|
name: ssh
|
|
supports:
|
|
- os-name: debian
|
|
supports:
|
|
- os-name: ubuntu
|
|
release: 14.04
|
|
supports:
|
|
- os-family: redhat
|
|
supports:
|
|
- platform: aws
|
|
|
|
|
|
# Profile Dependencies
|
|
|
|
A profile dependency is needed when:
|
|
|
|
* using `include_controls` or `require_controls` in order to load controls defined in another profile
|
|
* using a custom InSpec resource defined in another profile
|
|
|
|
Use the `depends` setting in the `inspec.yml` file to specify one (or more) profiles on which this profile depends. A profile dependency may be sourced from a path, URL, a git repo, a cookbook located on Chef Supermarket or on GitHub, or a profile located on the Chef Compliance server.
|
|
|
|
## 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. This setting does not support version constraints. If the location of the profile does not exist, an error is returned.
|
|
|
|
For example:
|
|
|
|
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, tar.gz format). If the download fails, the profile is inaccessible, or not in the correct format, an error is returned.
|
|
|
|
For example:
|
|
|
|
depends:
|
|
- name: my-profile
|
|
url: https://my.domain/path/to/profile.tgz
|
|
|
|
## git
|
|
|
|
A `git` setting specifies a profile that is located in a git repository, with optional settings for branch, tag, commit, and version. The source location is translated into a URL upon resolution. This type of dependency supports version indexing via semantic versioning as git tags.
|
|
|
|
For example:
|
|
|
|
depends:
|
|
- name: git-profile
|
|
git: http://url/to/repo
|
|
branch: desired_branch
|
|
tag: desired_version
|
|
commit: pinned_commit
|
|
version: semver_via_tags
|
|
|
|
## Chef Supermarket
|
|
|
|
A `supermarket` setting specifies a profile that is located in a cookbook hosted on Chef Supermarket, with optional settings for branch, tag, commit, and version. The source location is translated into a URL upon resolution. This type of dependency supports version indexing via semantic versioning as git tags.
|
|
|
|
For example:
|
|
|
|
depends:
|
|
- name: supermarket-profile
|
|
git: username/profile
|
|
branch: desired_branch
|
|
tag: desired_version
|
|
commit: pinned_commit
|
|
version: semver_via_tags
|
|
|
|
## GitHub
|
|
|
|
A `github` setting specifies a profile that is located in a repository hosted on GitHub, with optional settings for branch, tag, commit, and version. The source location is translated into a URL upon resolution. This type of dependency supports version indexing via semantic versioning as git tags.
|
|
|
|
For example:
|
|
|
|
depends:
|
|
- name: gh-profile
|
|
git: username/project
|
|
branch: desired_branch
|
|
tag: desired_version
|
|
commit: pinned_commit
|
|
version: semver_via_tags
|
|
|
|
## Chef Compliance
|
|
|
|
A `compliance` setting specifies a profile that is located on the Chef Compliance server.
|
|
|
|
For example:
|
|
|
|
depends:
|
|
- name: linux
|
|
compliance: base/linux
|
|
|
|
You need to `inspec vendor` the profile before uploading it to Chef Compliance version 1.7.7 or newer. The vendor subcommand fetches all dependent profiles and stores them in the `vendor` directory.
|
|
|
|
## Define in inspec.yml
|
|
|
|
Use the `depends` setting in the `inspec.yml` file to define any combination of profile dependencies. For example:
|
|
|
|
depends:
|
|
- name: ssh-hardening
|
|
supermarket: hardening/ssh-hardening
|
|
version: '= 2.0.0'
|
|
- name: os-hardening
|
|
url: https://github.com/dev-sec/tests-os-hardening/archive/master.zip
|
|
- name: ssl-benchmark
|
|
git: https://github.com/dev-sec/ssl-benchmark.git
|
|
version: '< 2.0'
|
|
- name: windows-patch-benchmark
|
|
git: https://github.com/chris-rock/windows-patch-benchmark.git
|
|
version: '~> 0.6'
|
|
- 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`, please refresh the lock file by either:
|
|
|
|
* running `inspec vendor` inside the profile directory; or
|
|
* deleting `inspec.lock` before running `inspec exec`
|
|
|
|
# Profile Inheritance
|
|
|
|
When a profile is run, it may include controls that are defined in other profiles. Controls may also be required.
|
|
|
|
This requires an `inspec.yml` dependency to the profile you inherit from.
|
|
|
|
## include_controls
|
|
|
|
The `include_controls` keyword may be used in a profile to import all rules from the named profile.
|
|
|
|
For example, to include controls from the `cis-level-1` profile when running the `cis-fs-2.7` profile:
|
|
|
|
include_controls 'cis-level-1' do
|
|
|
|
control "cis-fs-2.7" do
|
|
impact 1.0
|
|
...
|
|
|
|
end
|
|
|
|
To include controls from the `cis-level-1` profile, but skipping two controls within that profile:
|
|
|
|
include_controls 'cis-level-1' do
|
|
|
|
skip_control "cis-fs-2.1"
|
|
skip_control "cis-fs-2.2"
|
|
|
|
end
|
|
|
|
## require_controls
|
|
|
|
The `require_controls` keyword may be used to load only specific controls from the named profile.
|
|
|
|
For example, to require that controls `cis-fs-2.1` and `cis-fs-2.2` be loaded from the `cis-level-1` profile:
|
|
|
|
require_controls 'cis-level-1' do
|
|
|
|
control "cis-fs-2.1"
|
|
control "cis-fs-2.2"
|
|
|
|
end
|
|
|
|
|
|
## require_resource
|
|
|
|
By default, all of the 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:
|
|
|
|
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 Attributes
|
|
|
|
Attributes may be used in profiles to define secrets, such as user names and passwords, that should not otherwise be stored in plain-text in a cookbook. First specify a variable in the control for each secret, then add the secret to a Yaml file located on the local machine, and then run `inspec exec` and specify the path to that Yaml file using the `--attrs` attribute.
|
|
|
|
For example, a control:
|
|
|
|
val_user = attribute('user', default: 'alice', description: 'An identification for the user')
|
|
val_password = attribute('password', description: 'A value for the password')
|
|
|
|
describe val_user do
|
|
it { should eq 'bob' }
|
|
end
|
|
|
|
describe val_password do
|
|
it { should eq 'secret' }
|
|
end
|
|
|
|
And a Yaml file named `profile-attribute.yml`:
|
|
|
|
user: bob
|
|
password: secret
|
|
|
|
The following command runs the tests and applies the secrets specified in `profile-attribute.yml`:
|
|
|
|
$ inspec exec examples/profile-attribute --attrs examples/profile-attribute.yml
|
|
|
|
See the full example in the InSpec open source repository: https://github.com/chef/inspec/tree/master/examples/profile-attribute
|