mirror of
https://github.com/inspec/inspec
synced 2024-11-22 20:53:11 +00:00
Markdown and code fence fixes (#3230)
Signed-off-by: kgarmoe <kgarmoe@chef.io>
This commit is contained in:
parent
9581176633
commit
eb87fd384d
9 changed files with 307 additions and 235 deletions
|
@ -45,16 +45,15 @@ 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
|
||||
* `impact` is an float that measures the importance of the compliance results and must be a value between `0.0` and `1.0`. The value ranges are:
|
||||
* `0.0 to <0.4` these are controls with minor criticality
|
||||
* `0.4 to <0.7` these are controls with major criticality
|
||||
* `0.7 to 1.0` these are critical controls
|
||||
* `0.0 to <0.4` these are controls with minor criticality
|
||||
* `0.4 to <0.7` these are controls with major criticality
|
||||
* `0.7 to 1.0` these are critical controls
|
||||
* `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 an InSpec resource. For the full list of InSpec resources, see 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
|
||||
|
||||
With InSpec it is possible to check if at least one of a collection of checks is true. For example: If a setting is configured in two different locations, you may want to test if either configuration A or configuration B have been set. This is accomplished via `describe.one`. It defines a block of tests with at least one valid check.
|
||||
|
@ -71,7 +70,7 @@ describe.one do
|
|||
end
|
||||
```
|
||||
|
||||
#### Sensitive resources
|
||||
### Sensitive resources
|
||||
|
||||
In some scenarios, you may be writing checks involving resources with sensitive content (e.g. a file resource). In the case of failures, it may be desired to suppress output. This can be done by adding the `:sensitive` flag to the resource definition
|
||||
|
||||
|
@ -100,7 +99,7 @@ control 'windows-account-102' do
|
|||
end
|
||||
```
|
||||
|
||||
## Are PostgreSQL passwords empty?
|
||||
## Test if PostgreSQL passwords are empty
|
||||
|
||||
The following test shows how to audit machines running PostgreSQL to ensure that passwords are not empty.
|
||||
|
||||
|
@ -114,7 +113,7 @@ control 'postgres-7' do
|
|||
end
|
||||
```
|
||||
|
||||
## Are MySQL passwords in ENV?
|
||||
## 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`:
|
||||
|
||||
|
@ -132,7 +131,7 @@ control 'mysql-3' do
|
|||
end
|
||||
```
|
||||
|
||||
## Is `/etc/ssh` a Directory?
|
||||
## Test if `/etc/ssh` is a Directory
|
||||
|
||||
The following test shows how to audit machines to ensure that `/etc/ssh` is a directory:
|
||||
|
||||
|
@ -150,7 +149,7 @@ control 'basic-1' do
|
|||
end
|
||||
```
|
||||
|
||||
## Is Apache running?
|
||||
## Test if Apache running
|
||||
|
||||
The following test shows how to audit machines to ensure that Apache is enabled and running:
|
||||
|
||||
|
@ -165,7 +164,7 @@ control 'apache-1' do
|
|||
end
|
||||
```
|
||||
|
||||
## Are insecure packages installed ?
|
||||
## Test if insecure packages are installed
|
||||
|
||||
The following test shows how to audit machines for insecure packages:
|
||||
|
||||
|
@ -223,7 +222,6 @@ Mixing this with other conditionals (like checking existence of the files etc.)
|
|||
|
||||
## Additional metadata for controls
|
||||
|
||||
|
||||
The following example illustrates various ways to add tags and references to `control`
|
||||
|
||||
```ruby
|
||||
|
|
|
@ -11,7 +11,7 @@ There are two ways to use it:
|
|||
|
||||
### Motivating Example
|
||||
|
||||
Suppose we are interested in auditing cars. Let's suppose we have two InSpec resources for auditing: `cars`, which searchs for and filters groups of cars, and `car`, which performs detailed auditing of a single car.
|
||||
Suppose we are interested in auditing cars. Let's suppose we have two 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
|
||||
|
||||
|
@ -134,7 +134,7 @@ A [resource](#resource) that is _not_ included with InSpec. It may be a resource
|
|||
|
||||
The _`describe`_ keyword is used with a _`describe block`_ to refer to an 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
|
||||
|
@ -155,7 +155,7 @@ When using a [matcher](#matcher), the _`expected result`_ is the value the match
|
|||
|
||||
In this example, the [`cmp`](https://www.inspec.io/docs/reference/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
|
||||
|
@ -169,7 +169,7 @@ A filter statement may use method call syntax (which allows basic criteria opera
|
|||
|
||||
In this example, `where(...)` is the filter statement.
|
||||
|
||||
```
|
||||
```Ruby
|
||||
# Count only blue cars
|
||||
describe cars.where(color: 'blue') do
|
||||
its('count') { should eq 20 }
|
||||
|
@ -186,7 +186,7 @@ When method-call syntax is used with the filter statement, you provide filter cr
|
|||
|
||||
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 }
|
||||
|
@ -197,7 +197,7 @@ When block-method syntax is used with the filter statement, you provide a block.
|
|||
|
||||
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' }
|
||||
|
@ -212,7 +212,7 @@ Within a [describe block](#describe), _`it`_ declares an individual [test](#test
|
|||
|
||||
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
|
||||
|
@ -228,7 +228,7 @@ The property to access is passed as a single string argument to `its`. As an adv
|
|||
|
||||
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 }
|
||||
|
@ -249,7 +249,7 @@ For information on how RSpec matchers are related o InSpec matchers, see [InSpec
|
|||
|
||||
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' }
|
||||
|
@ -266,7 +266,7 @@ Plural resources support [filter statements](#filter_statement). See the [resour
|
|||
|
||||
Here, `cars` is a plural resource.
|
||||
|
||||
```
|
||||
```Ruby
|
||||
describe cars.where(color: 'blue') do
|
||||
its('count') { should eq 20 }
|
||||
its('license_plates') { should include 'AUTOAZUL' }
|
||||
|
@ -296,7 +296,7 @@ Each resource has different properties. See the [resource documentation](https:/
|
|||
|
||||
Here, `manufacturer` is a property of the `car` resource.
|
||||
|
||||
```
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
its('manufacturer') { should cmp 'Cadillac' }
|
||||
end
|
||||
|
@ -316,7 +316,7 @@ Resources are used within a [describe block](#describe_block) to perform [tests]
|
|||
|
||||
Here, `car` is a resource.
|
||||
|
||||
```
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
end
|
||||
|
@ -334,7 +334,7 @@ Resource parameters vary from resource to resource; refer to the [resource docum
|
|||
|
||||
Here, `owner: 'Tony Clifton'` is a resource parameter.
|
||||
|
||||
```
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
end
|
||||
|
@ -348,7 +348,7 @@ Resource-specific matchers often provide highly customized behavior. Check the [
|
|||
|
||||
For example, the hypothetical `car` resource defines a `classy?` method, which is exposed as the `be_classy` matcher in InSpec tests.
|
||||
|
||||
```
|
||||
```Ruby
|
||||
describe car(owner: 'Tony Clifton') do
|
||||
it { should be_classy }
|
||||
end
|
||||
|
@ -374,7 +374,7 @@ Universal matchers are documented on the [Universal Matchers](https://www.inspec
|
|||
|
||||
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
|
||||
|
|
|
@ -6,7 +6,7 @@ title: InSpec Integration with Habitat
|
|||
|
||||
InSpec provides an easy method to create an executable Habitat package for an InSpec profile. When run via the Habitat Supervisor, the package will run InSpec with your profile and write out its findings to a JSON file. This provides the ability to ship your compliance controls alongside your Habitat-packaged application and continuously run InSpec, providing you *Continuous Compliance.*
|
||||
|
||||
## What is Habitat?
|
||||
## What is Habitat
|
||||
|
||||
Habitat by Chef 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), Habitat packages the automation with the application instead of relying on an underlying platform.
|
||||
|
||||
|
@ -28,7 +28,7 @@ HAB_INSPEC_PROFILE_FRONTEND1="sleep_time = 60" hab start adamleff/inspec-profile
|
|||
|
||||
The Habitat Supervisor will display output like this:
|
||||
|
||||
```
|
||||
```text
|
||||
hab start adamleff/inspec-profile-frontend1
|
||||
∵ Missing package for core/hab-sup/0.17.0
|
||||
» Installing core/hab-sup/0.17.0
|
||||
|
@ -62,7 +62,7 @@ The above sample output shows the supervisor starting, downloading the necessary
|
|||
|
||||
InSpec will write a JSON file in the `${svc_var_path}/inspec_results` directory containing the results of the last InSpec run. For example, for the `adamleff/inspec-profile-frontend1` package, the InSpec results will be at:
|
||||
|
||||
```
|
||||
```text
|
||||
/hab/svc/inspec-profile-frontend1/var/inspec_results/inspec-profile-frontend1.json
|
||||
```
|
||||
|
||||
|
@ -74,13 +74,13 @@ Create a Habitat package for an InSpec profile. InSpec will validate the profile
|
|||
|
||||
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
|
||||
```
|
||||
|
||||
|
@ -104,13 +104,13 @@ The package can then be manually uploaded to a Habitat Depot or manually distrib
|
|||
|
||||
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
|
||||
```
|
||||
|
||||
|
@ -128,7 +128,7 @@ 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...
|
||||
|
@ -168,7 +168,8 @@ 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...
|
||||
|
|
|
@ -42,10 +42,10 @@ end
|
|||
|
||||
That said, 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.
|
||||
* InSpec is aimed at compliance practitioners and infrastructure testers, so our focus is providing a few, well-supported, easy-to-use [universal matchers](https://www.inspec.io/docs/reference/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 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 InSpec team. While it is possible to use many of the RSpec core features within InSpec profiles, InSpec can only guarantee that the features described at [docs.inspec.io](https://docs.inspec.io) will function correctly. Some RSpec core functionality may be removed in future versions of InSpec as needed to ensure stability in the InSpec project.
|
||||
* 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.
|
||||
* InSpec is aimed at compliance practitioners and infrastructure testers, so our focus is providing a few, well-supported, easy-to-use [universal matchers](https://www.inspec.io/docs/reference/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 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 InSpec team. While it is possible to use many of the RSpec core features within InSpec profiles, InSpec can only guarantee that the features described at [docs.inspec.io](https://docs.inspec.io) will function correctly. Some RSpec core functionality may be removed in future versions of InSpec as needed to ensure stability in the InSpec project.
|
||||
|
||||
## Serverspec
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@ describe file('/proc/cpuinfo') do
|
|||
end
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## cmp
|
||||
|
||||
Unlike `eq`, `cmp` is a matcher for less-restrictive comparisons. It will
|
||||
|
@ -72,6 +70,7 @@ describe auditd_conf do
|
|||
its('log_format') { should cmp 'RAW' }
|
||||
end
|
||||
```
|
||||
|
||||
* Recognize versions embedded in strings
|
||||
|
||||
```ruby
|
||||
|
@ -107,7 +106,6 @@ end
|
|||
expected: 0345
|
||||
got: 0444
|
||||
```
|
||||
<br>
|
||||
|
||||
## eq
|
||||
|
||||
|
@ -132,8 +130,6 @@ its('Port') { should eq 22 }
|
|||
|
||||
For less restrictive comparisons, please use `cmp`.
|
||||
|
||||
<br>
|
||||
|
||||
## include
|
||||
|
||||
Verifies if a value is included in a list.
|
||||
|
@ -144,8 +140,6 @@ describe passwd do
|
|||
end
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## be_in
|
||||
|
||||
Verifies that an item is included in a list.
|
||||
|
@ -156,8 +150,6 @@ describe resource do
|
|||
end
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## match
|
||||
|
||||
Check if a string matches a regular expression.
|
||||
|
|
|
@ -8,43 +8,53 @@ Use InSpec as a Kitchen verifier with `kitchen-inspec`.
|
|||
|
||||
Add the InSpec verifier to the `.kitchen.yml` file:
|
||||
|
||||
verifier:
|
||||
name: inspec
|
||||
```YML
|
||||
verifier:
|
||||
name: inspec
|
||||
```
|
||||
|
||||
Use a compliance profile from the Chef Compliance server:
|
||||
|
||||
suites:
|
||||
- name: compliance
|
||||
run_list:
|
||||
- recipe[ssh-hardening::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- compliance://base/ssh
|
||||
```YML
|
||||
suites:
|
||||
- name: compliance
|
||||
run_list:
|
||||
- recipe[ssh-hardening::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- compliance://base/ssh
|
||||
```
|
||||
|
||||
and then run the following command:
|
||||
|
||||
$ inspec compliance login https://compliance.test --user admin --insecure --token ''
|
||||
```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:
|
||||
|
||||
suites:
|
||||
- name: supermarket
|
||||
run_list:
|
||||
- recipe[ssh-hardening::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- supermarket://dev-sec/ssh-baseline
|
||||
```YML
|
||||
suites:
|
||||
- name: supermarket
|
||||
run_list:
|
||||
- recipe[ssh-hardening::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- supermarket://dev-sec/ssh-baseline
|
||||
```
|
||||
|
||||
Use InSpec tests from the local file system:
|
||||
|
||||
suites:
|
||||
- name: local
|
||||
run_list:
|
||||
- recipe[my_cookbook::default]
|
||||
verifier:
|
||||
inspec_tests:
|
||||
- test/integration/default
|
||||
```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 InSpec profiles.
|
||||
|
|
373
docs/profiles.md
373
docs/profiles.md
|
@ -10,16 +10,18 @@ InSpec supports the creation of complex test and compliance profiles, which orga
|
|||
|
||||
A profile should have the following structure::
|
||||
|
||||
examples/profile
|
||||
├── README.md
|
||||
├── controls
|
||||
│ ├── example.rb
|
||||
│ └── control_etc.rb
|
||||
├── libraries
|
||||
│ └── extension.rb
|
||||
|── files
|
||||
│ └── extras.conf
|
||||
└── inspec.yml
|
||||
```YAML
|
||||
examples/profile
|
||||
├── README.md
|
||||
├── controls
|
||||
│ ├── example.rb
|
||||
│ └── control_etc.rb
|
||||
├── libraries
|
||||
│ └── extension.rb
|
||||
|── files
|
||||
│ └── extras.conf
|
||||
└── inspec.yml
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
|
@ -37,79 +39,92 @@ Also check out [Explore InSpec resources](https://learn.chef.io/modules/explore-
|
|||
|
||||
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 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 `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 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.
|
||||
|
||||
`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
|
||||
inspec_version: "~> 2.1"
|
||||
```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"
|
||||
```
|
||||
|
||||
## Verify Profiles
|
||||
|
||||
Use the `inspec check` command to verify the implementation of a profile:
|
||||
|
||||
$ inspec check examples/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 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
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- os-name: debian
|
||||
```
|
||||
|
||||
and to target only Ubuntu version 14.04
|
||||
|
||||
name: ssh
|
||||
supports:
|
||||
- os-name: ubuntu
|
||||
release: 14.04
|
||||
```YAML
|
||||
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
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- os-family: redhat
|
||||
```
|
||||
|
||||
and to target anything running on Amazon AWS:
|
||||
|
||||
name: ssh
|
||||
supports:
|
||||
- platform: aws
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- platform: aws
|
||||
```
|
||||
|
||||
and to target all of these examples in a single `inspec.yml` file:
|
||||
|
||||
name: ssh
|
||||
supports:
|
||||
- os-name: debian
|
||||
- os-name: ubuntu
|
||||
release: 14.04
|
||||
- os-family: redhat
|
||||
- platform: aws
|
||||
|
||||
```YAML
|
||||
name: ssh
|
||||
supports:
|
||||
- os-name: debian
|
||||
- os-name: ubuntu
|
||||
release: 14.04
|
||||
- os-family: redhat
|
||||
- platform: aws
|
||||
```
|
||||
|
||||
# Profile Dependencies
|
||||
|
||||
|
@ -121,11 +136,13 @@ For hands-on examples, check out [Create a custom InSpec profile](https://learn.
|
|||
|
||||
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:
|
||||
|
||||
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
|
||||
```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
|
||||
```
|
||||
|
||||
InSpec supports a number of dependency sources.
|
||||
|
||||
|
@ -133,21 +150,25 @@ InSpec supports a number of dependency sources.
|
|||
|
||||
The `path` setting defines a profile that is located on disk. This setting is typically used during development of profiles and when debugging profiles.
|
||||
|
||||
depends:
|
||||
- name: my-profile
|
||||
path: /absolute/path
|
||||
- name: another
|
||||
path: ../relative/path
|
||||
```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).
|
||||
|
||||
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
|
||||
```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
|
||||
```
|
||||
|
||||
### git
|
||||
|
||||
|
@ -155,13 +176,15 @@ A `git` setting specifies a profile that is located in a git repository, with op
|
|||
|
||||
For example:
|
||||
|
||||
depends:
|
||||
- name: git-profile
|
||||
git: http://url/to/repo
|
||||
branch: desired_branch
|
||||
tag: desired_version
|
||||
commit: pinned_commit
|
||||
version: semver_via_tags
|
||||
```YAML
|
||||
depends:
|
||||
- name: git-profile
|
||||
git: http://url/to/repo
|
||||
branch: desired_branch
|
||||
tag: desired_version
|
||||
commit: pinned_commit
|
||||
version: semver_via_tags
|
||||
```
|
||||
|
||||
### supermarket
|
||||
|
||||
|
@ -169,9 +192,11 @@ A `supermarket` setting specifies a profile that is located in a cookbook hosted
|
|||
|
||||
For example:
|
||||
|
||||
depends:
|
||||
- name: supermarket-profile
|
||||
supermarket: supermarket-username/supermarket-profile
|
||||
```YAML
|
||||
depends:
|
||||
- name: supermarket-profile
|
||||
supermarket: supermarket-username/supermarket-profile
|
||||
```
|
||||
|
||||
Available Supermarket profiles can be listed with `inspec supermarket profiles`.
|
||||
|
||||
|
@ -181,9 +206,11 @@ A `compliance` setting specifies a profile that is located on the Chef Automate
|
|||
|
||||
For example:
|
||||
|
||||
depends:
|
||||
- name: linux
|
||||
compliance: base/linux
|
||||
```YAML
|
||||
depends:
|
||||
- name: linux
|
||||
compliance: base/linux
|
||||
```
|
||||
|
||||
## Vendoring Dependencies
|
||||
|
||||
|
@ -199,15 +226,17 @@ Once defined in the `inspec.yml`, controls from the included profiles can be use
|
|||
|
||||
With the `include_controls` command in a profile, all controls from the named profile will be executed every time the including profile is executed.
|
||||
|
||||
```YAML
|
||||
![Include Controls](/images/profile_inheritance/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
|
||||
* 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!
|
||||
|
@ -216,7 +245,9 @@ including controls from other profiles!
|
|||
|
||||
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 InSpec to not run a particular control.
|
||||
|
||||
```YAML
|
||||
![Include Controls with Skip](/images/profile_inheritance/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.
|
||||
|
||||
|
@ -226,7 +257,9 @@ Let's say a particular control from an included profile should still be run, but
|
|||
|
||||
When a control is included, it can also be modified!
|
||||
|
||||
```YAML
|
||||
![Include Controls with Modification](/images/profile_inheritance/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`.
|
||||
|
||||
|
@ -234,21 +267,25 @@ In the above example, all controls from `my-baseline` are executed along with al
|
|||
|
||||
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.
|
||||
|
||||
```YAML
|
||||
![Require Controls](/images/profile_inheritance/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
|
||||
* 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.
|
||||
|
||||
```YAML
|
||||
![Require Controls with Modification](/images/profile_inheritance/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.
|
||||
|
||||
|
@ -259,46 +296,54 @@ 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')
|
||||
```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 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.
|
||||
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:
|
||||
|
||||
# define these attributes on the top-level of your file and re-use them across all tests!
|
||||
val_user = attribute('user', default: 'alice', description: 'An identification for the user')
|
||||
val_password = attribute('password', description: 'A value for the password')
|
||||
```Ruby
|
||||
# define these attributes on the top-level of your file and re-use them across all tests!
|
||||
val_user = attribute('user', default: 'alice', description: 'An identification for the user')
|
||||
val_password = attribute('password', description: 'A value for the password')
|
||||
|
||||
control 'system-users' do
|
||||
impact 0.8
|
||||
desc '
|
||||
This test assures that the user "Bob" has a user installed on the system, along with a
|
||||
specified password.
|
||||
'
|
||||
control 'system-users' do
|
||||
impact 0.8
|
||||
desc '
|
||||
This test assures that the user "Bob" has a user installed on the system, along with a
|
||||
specified password.
|
||||
'
|
||||
|
||||
describe val_user do
|
||||
it { should eq 'bob' }
|
||||
end
|
||||
val_user do
|
||||
it { should eq 'bob' }
|
||||
end
|
||||
|
||||
describe val_password do
|
||||
it { should eq 'secret' }
|
||||
end
|
||||
end
|
||||
describe val_password do
|
||||
it { should eq 'secret' }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
And a Yaml file named `profile-attribute.yml`:
|
||||
And a YAML file named `profile-attribute.yml`:
|
||||
|
||||
user: bob
|
||||
password: secret
|
||||
```YAML
|
||||
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
|
||||
```bash
|
||||
$ inspec exec examples/profile-attribute --attrs examples/profile-attribute.yml
|
||||
```
|
||||
|
||||
See the full example in the InSpec open source repository: [Example InSpec Profile with Attributes](https://github.com/chef/inspec/tree/master/examples/profile-attribute)
|
||||
|
||||
|
@ -310,33 +355,39 @@ To access these files, they must be stored in the `files` directory at the root
|
|||
|
||||
Here is an example for reading and testing a list of ports. The folder structure is:
|
||||
|
||||
examples/profile
|
||||
├── controls
|
||||
│ ├── example.rb
|
||||
|── files
|
||||
│ └── services.yml
|
||||
└── inspec.yml
|
||||
```YAML
|
||||
examples/profile
|
||||
├── controls
|
||||
│ ├── example.rb
|
||||
│── files
|
||||
│ └── services.yml
|
||||
└── inspec.yml
|
||||
```
|
||||
|
||||
With `services.yml` containing:
|
||||
|
||||
- service_name: httpd-alpha
|
||||
port: 80
|
||||
- service_name: httpd-beta
|
||||
port: 8080
|
||||
```YAML
|
||||
- service_name: httpd-alpha
|
||||
port: 80
|
||||
- service_name: httpd-beta
|
||||
port: 8080
|
||||
```
|
||||
|
||||
The tests in `example.rb` can now access this file:
|
||||
|
||||
my_services = yaml(content: inspec.profile.file('services.yml')).params
|
||||
```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
|
||||
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
|
||||
describe port(s['port']) do
|
||||
it { should be_listening }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
For a more complete example that uses a profile file, see [Explore InSpec resources](https://learn.chef.io/modules/explore-inspec-resources#/) on Learn Chef Rally.
|
||||
|
||||
|
@ -346,33 +397,43 @@ Users familiar with the RSpec testing framework may know that there are two ways
|
|||
|
||||
InSpec will continue to support both methods of writing tests. Consider this `file` test:
|
||||
|
||||
describe file('/tmp/test.txt') do
|
||||
it { should be_file }
|
||||
end
|
||||
```Ruby
|
||||
describe file('/tmp/test.txt') do
|
||||
it { should be_file }
|
||||
end
|
||||
```
|
||||
|
||||
This can be re-written with `expect` syntax
|
||||
|
||||
describe file('/tmp/test.txt') do
|
||||
it 'should be a file' do
|
||||
expect(subject).to(be_file)
|
||||
end
|
||||
end
|
||||
```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:
|
||||
|
||||
File /tmp/test.txt
|
||||
✔ should be a file
|
||||
```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:
|
||||
|
||||
describe 'test file' do
|
||||
subject { file('/tmp/test.txt') }
|
||||
it 'should be a file' do
|
||||
expect(subject).to(be_file)
|
||||
end
|
||||
end
|
||||
```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:
|
||||
|
||||
test file
|
||||
✔ should be a file
|
||||
```text
|
||||
test file
|
||||
✔ should be a file
|
||||
```
|
|
@ -116,12 +116,12 @@ This reporter includes all information from the rspec runner. Unlike the json re
|
|||
|
||||
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 the Automate 2 suite. To use this reporter you must pass in the correct configuration via a json config `--json-config`.
|
||||
|
||||
Example config:
|
||||
|
||||
```json
|
||||
"reporter": {
|
||||
"automate" : {
|
||||
|
@ -135,27 +135,36 @@ Example config:
|
|||
}
|
||||
```
|
||||
|
||||
### Mandatory fields:
|
||||
### 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.
|
||||
|
||||
PLEASE NOTE: These fields are ONLY needed if you do not have chef-client attached to a chef server running on your node. The fields below will be automaticlly pulled from the chef server.
|
||||
PLEASE NOTE: These fields are ONLY needed if you do not have chef-client attached to a chef server running on your node. The fields below will be automatically pulled from the chef server.
|
||||
|
||||
#### node_name
|
||||
|
||||
This will be the node name which shows up in Automate 2.
|
||||
|
||||
#### node_uuid
|
||||
|
||||
This overrides the node uuid sent up to Automate 2. On non-chef nodes we will try to generate a static node uuid for you from your hardware. This will almost never be needed unless your working with a unique virtual setup.
|
||||
|
||||
#### environment
|
||||
This will set the enviroment metadata for Automate 2.
|
||||
|
||||
This will set the environment metadata for Automate 2.
|
||||
|
|
|
@ -61,7 +61,6 @@ to process the output of `ls` executed on the target system, use
|
|||
Similarly, use `inspec.file(PATH)` to access files or directories from
|
||||
remote systems in your tests or custom resources.
|
||||
|
||||
|
||||
## Using rubygems
|
||||
|
||||
Ruby gems are self-contained programs and libraries. If you create a custom
|
||||
|
@ -158,7 +157,8 @@ When writing tests you can not use standard ruby methods to shellout as it tries
|
|||
However, the `command` resource has a `.stdout` method that will allow you to manipulate the results.
|
||||
Using the above example, you could check the writes on several subdirectories.
|
||||
|
||||
### Example 1:
|
||||
### Example 1
|
||||
|
||||
```ruby
|
||||
$ inspec shell
|
||||
Welcome to the interactive InSpec Shell
|
||||
|
@ -179,7 +179,8 @@ Version: (not specified)
|
|||
Test Summary: 1 successful, 0 failures, 0 skipped
|
||||
```
|
||||
|
||||
### Example 2:
|
||||
### Example 2
|
||||
|
||||
```ruby
|
||||
$ inspec shell
|
||||
Welcome to the interactive InSpec Shell
|
||||
|
|
Loading…
Reference in a new issue