Merge pull request #1120 from chef/dr/docs2

update docs to markdown
This commit is contained in:
Christoph Hartmann 2016-09-22 10:24:15 +02:00 committed by GitHub
commit 568938cbac
16 changed files with 1072 additions and 1026 deletions

20
docs/README.md Normal file
View file

@ -0,0 +1,20 @@
# InSpec documentation
This is the home of the InSpec documentation. This documentation provides an introduction to this mechanism and shows how to write custom tests.
The goal of this folder is for any community member to clone these docs, make the changes, check if they are valid, and contribute to the project.
## How to build docs
TODO
## Stability Index
Every available InSpec resource will indicate its stability. As InSpec matures, certain parts are more reliable than others. Brand new features are likely to be redesigned and marked as such.
The stability indices are as follows:
* `Stability: Deprecated` - This features will be removed in future versions, because its known for being problematic. Do not rely on it.
* `Stability: Experimental` - New features may change or are removed in future versions
* `Stability: Stable` - API is well established and proofed. Maintaining compatibility is a high priority
* `Stability: Locked` - Only security and performance fixes are allowed

245
docs/dsl_inspec.md Normal file
View file

@ -0,0 +1,245 @@
---
title: InSpec DSL
---
# InSpec DSL
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| auditing is the same. The open source |inspec resource| framework is compatible with |chef compliance|.
The 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 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 eq('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 to.
Prevent unexpected settings.
'
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 eq('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
* `impact` is an float that measures the importance of the compliance results and must be a value between `0.0` and `1.0`.
* `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.
```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
```
## 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 pwassword complexity is enabled:
```ruby
control 'windows-account-102' do
impact 1.0
title 'Windows Password Complexity is Enabled'
desc 'Password must meet complexity requirement'
describe security_policy do
its('PasswordComplexity') { should eq 1 }
end
end
```
## Are PosgtreSQL passwords empty?
The following test shows how to audit machines running PostgerSQL 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 eq('') }
end
end
```
## Are MySQL passwords 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
```
## Is `/etc/ssh` 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
```
## Is Apache running?
The following test shows how to audit machines to ensure that Apache is enabled and running:
```ruby
control 'apache-1' do
impact 0.3
title 'Apache2 should be configured and running'
describe service(apache.service) do
it { should be_enabled }
it { should be_running }
end
end
```
## Are insecure packages 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 Seach 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
```
## Exclude specific test
This shows how to allow skipping certain tests if conditions are not met, by using `only_if`.
In this example the test will not be performed if `redis-cli` command does not exist, because for example package on remote host was not installed.
```ruby
control 'nutcracker-connect-redis-001' do
impact 1.0
title 'Check if nutcracker can pass commands to redis'
desc 'execute redis-cli set key command, to check connectivity of the service'
only_if 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 (like checking existence of the files etc.) can help to test different test paths using inspec. This way you can skip certain tests which would 100% fail due to the way servers are prepared, but you know that the same test suites are reused later in different circumstances by different teams.
## 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 eq '2'}
end
end
```

View file

@ -1,259 +0,0 @@
=====================================================
InSpec DSL
=====================================================
|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| auditing is the same. The open source |inspec resource| framework is compatible with |chef compliance|.
The 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 |inspec resources| to define
Syntax
=====================================================
The following resource tests |ssh| server configuration. For example, a simple control may described as:
.. code-block:: ruby
describe sshd_config do
its('Port') { should eq('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:
.. code-block:: ruby
control 'sshd-8' do
impact 0.6
title 'Server: Configure the service port'
desc '
Always specify which port the SSH server should listen to.
Prevent unexpected settings.
'
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 eq('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
* ``impact`` is an float that measures the importance of the compliance results and must be a value between ``0.0`` and ``1.0``.
* ``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.
.. code-block:: 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
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 pwassword complexity is enabled:
.. code-block:: ruby
control 'windows-account-102' do
impact 1.0
title 'Windows Password Complexity is Enabled'
desc 'Password must meet complexity requirement'
describe security_policy do
its('PasswordComplexity') { should eq 1 }
end
end
Are PosgtreSQL passwords empty?
-----------------------------------------------------
The following test shows how to audit machines running |postgresql| to ensure that passwords are not empty.
.. code-block:: 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 eq('') }
end
end
Are MySQL passwords in ENV?
-----------------------------------------------------
The following test shows how to audit machines running |mysql| to ensure that passwords are not stored in ``ENV``:
.. code-block:: 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
Is /etc/ssh a Directory?
-----------------------------------------------------
The following test shows how to audit machines to ensure that ``/etc/ssh`` is a directory:
.. code-block:: 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
Is Apache running?
-----------------------------------------------------
The following test shows how to audit machines to ensure that |apache| is enabled and running:
.. code-block:: ruby
control 'apache-1' do
impact 0.3
title 'Apache2 should be configured and running'
describe service(apache.service) do
it { should be_enabled }
it { should be_running }
end
end
Are insecure packages installed ?
-----------------------------------------------------
The following test shows how to audit machines for insecure packages:
.. code-block:: 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 Seach Mode is enabled:
.. code-block:: 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
Exclude specific test
-----------------------------------------------------
This shows how to allow skipping certain tests if conditions are not met, by using ``only_if``.
In this example the test will not be performed if ``redis-cli`` command does not exist, because for example package on remote host was not installed.
.. code-block:: ruby
control 'nutcracker-connect-redis-001' do
impact 1.0
title 'Check if nutcracker can pass commands to redis'
desc 'execute redis-cli set key command, to check connectivity of the service'
only_if 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 (like checking existence of the files etc.) can help to test different test paths using inspec. This way you can skip certain tests which would 100% fail due to the way servers are prepared, but you know that the same test suites are reused later in different circumstances by different teams.
Additional metadata for controls
-----------------------------------------------------
The following example illustrates various ways to add tags and references to `control`
.. code-block:: 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 eq '2'}
end
end`
.. |inspec| replace:: InSpec
.. |inspec resource| replace:: InSpec Resource
.. |chef compliance| replace:: Chef Compliance
.. |ruby| replace:: Ruby
.. |ssh| replace:: SSH
.. |windows| replace:: Microsoft Windows
.. |postgresql| replace:: PostgreSQL
.. |apache| replace:: Apache

93
docs/dsl_resource.md Normal file
View file

@ -0,0 +1,93 @@
---
title: Resource DSL
---
# Resource DSL
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
│   └── gordon_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 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)
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 GordonConfig < Inspec.resource(1)
name 'gordon_config'
desc '
Resource description ...
'
example '
describe gordon_config do
its("signal") { should eq "on" }
end
'
# Load the configuration file on initialization
def initialize(path = nil)
@path = path || '/etc/gordon.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 gordon_config
skip_resource "Can't read config from #{@path}."
end
end
end
```
For a full example, see our [example resource](../examples/profile/libraries/gordon_config.rb).

View file

@ -1,90 +0,0 @@
=====================================================
Resource DSL
=====================================================
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:
.. code-block:: bash
$ tree examples/profile
examples/profile
...
├── libraries
│   └── gordon_config.rb
Resource structure
-----------------------------------------------------
The smallest possible resource takes this form:
.. code-block:: 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 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)
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:
.. code-block:: ruby
class GordonConfig < Inspec.resource(1)
name 'gordon_config'
desc '
Resource description ...
'
example '
describe gordon_config do
its("signal") { should eq "on" }
end
'
# Load the configuration file on initialization
def initialize(path = nil)
@path = path || '/etc/gordon.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 gordon_config
skip_resource "Can't read config from #{@path}."
end
end
end
For a full example, see our `example resource`_.
.. _example resource: ../examples/profile/libraries/gordon_config.rb

102
docs/inspec_and_friends.md Normal file
View file

@ -0,0 +1,102 @@
---
title: InSpec and friends
---
# InSpec and friends
## RSpec
RSpec is an awesome framework that is widely used to test Ruby code. It
enables test-driven development (TDD) and helps developers to write
better code every day.
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. 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 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
```
## Serverspec
Serverspec can be credited as 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. 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.
### How is InSpec different than Serverspec
One of the key differences is that 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?**
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 InSpec only work on machines managed by Chef?**
No, InSpec can be used on any machine. It doesnt matter if that machine
was configured by Chef or configured lovingly by the hands of your local
System Administrator.
**Is InSpec a replacement of Serverspec?**
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.

View file

@ -1,85 +0,0 @@
=====================================================
InSpec and friends
=====================================================
RSpec
=====================================================
RSpec is an awesome framework that is widely used to test Ruby code. It enables test-driven development (TDD) and helps developers to write better code every day.
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. 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 InSpec rule looks like:
.. code-block:: 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
Serverspec
=====================================================
Serverspec can be credited as 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. 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.
How is InSpec different than Serverspec
-----------------------------------------------------
One of the key differences is that 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.
.. code-block:: 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?**
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 InSpec only work on machines managed by Chef?**
No, InSpec can be used on any machine. It doesnt matter if that machine was configured by Chef or configured lovingly by the hands of your local System Administrator.
**Is InSpec a replacement of Serverspec?**
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.

136
docs/matchers.md Normal file
View file

@ -0,0 +1,136 @@
---
title: InSpec Matchers Reference
---
# InSpec Matchers Reference
Inspec uses matchers to help compare resource values to expectations.
The following matchers are available:
* `be`
* `cmp`
* `eq`
* `include`
* `match`
## 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
its('Protocol') { should eq '2' }
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
```
* 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
```
It 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
```
## match
Check if a string matches a regular expression.
```ruby
describe sshd_config do
its('Ciphers') { should_not match /cbc/ }
end
```

View file

@ -1,137 +0,0 @@
=====================================================
InSpec Matchers Reference
=====================================================
Inspec uses matchers to help compare resource values to expectations. The following matchers are available:
* `be`
* `cmp`
* `eq`
* `include`
* `match`
be
=====================================================
This matcher can be followed by many different comparison operators. Always make sure to use numbers, not strings, for these comparisons.
.. code-block:: 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.
.. code-block:: 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
.. code-block:: ruby
describe sshd_config do
its('Protocol') { should eq '2' }
its('Protocol') { should cmp '2' }
its('Protocol') { should cmp 2 }
end
* String comparisons are not case-sensitive
.. code-block:: ruby
describe auditd_conf do
its('log_format') { should cmp 'raw' }
its('log_format') { should cmp 'RAW' }
end
* Compare arrays with only one entry to a value
.. code-block:: 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
.. code-block:: ruby
describe auditd_conf do
its('log_format') { should cmp /raw/i }
end
* Improved printing of octal comparisons
.. code-block:: ruby
describe file('/proc/cpuinfo') do
its('mode') { should cmp '0345' }
end
expected: 0345
got: 0444
eq
=====================================================
Test for exact equality of two values.
.. code-block:: ruby
describe sshd_config do
its('RSAAuthentication') { should_not eq 'no' }
its('Protocol') { should eq '2' }
end
It fails if types don't match. Please keep this in mind, when comparing configuration
entries that are numbers:
.. code-block:: 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.
.. code-block:: ruby
describe passwd do
its('users') { should include 'my_user' }
end
match
=====================================================
Check if a string matches a regular expression.
.. code-block:: ruby
describe sshd_config do
its('Ciphers') { should_not match /cbc/ }
end

View file

@ -0,0 +1,55 @@
---
title: About kitchen-inspec
---
# kitchen-inspec
The `kitchen-inspec` driver enables InSpec to be used as a verifier within Kitchen.
To use InSpec as a verifier, add it to the kitchen.yml file:
verifier:
name: inspec
To define a suite that pulls its run-list from the Chef Compliance server:
suites:
- name: compliance
run_list:
- recipe[ssh-hardening]
verifier:
inspec_tests:
- compliance://base/ssh
and then run the following command:
$ inspec compliance login https://compliance.test --user admin --insecure --token ''
where `--insecure` is required when using self-signed certificates.
To define a suite that pulls its run-list from the Chef Supermarket:
suites:
- name: supermarket
run_list:
- recipe[ssh-hardening]
verifier:
inspec_tests:
- supermarket://hardening/ssh-hardening
The `kitchen-inspec` driver expects tests to be located in the `test/integration` directory in a cookbook. For example::
.
├── Berksfile
├── Gemfile
├── README.md
├── metadata.rb
├── recipes
│ ├── default.rb
│ └── nginx.rb
└── test
└── integration
└── default
├── controls
├── inspec.yml
└── libraries

271
docs/profiles.md Normal file
View file

@ -0,0 +1,271 @@
---
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
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
## 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
- 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
- name: windows-patch-benchmark
git: https://github.com/chris-rock/windows-patch-benchmark.git
- name: linux
compliance: base/linux
# Profile Inheritance
When a profile is run, it may include controls that are defined in other profiles. Controls may also be required.
## 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
# 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

View file

@ -1,169 +0,0 @@
=====================================================
InSpec Profiles
=====================================================
InSpec supports the creation of complex test and compliance profiles, which organize controls to support dependency management and code re-use. These profiles are standalone structures with their own distribution and execution flow.
InSpec profile structure
-----------------------------------------------------
To create a new profile just place the files according to the following structure:
.. code-block:: bash
$ tree examples/profile
examples/profile
├── README.md
├── controls
│   ├── example.rb
│   └── gordon.rb
├── libraries
│   └── gordon_config.rb
└── inspec.yml
* `inspec.yml` - includes the profile description (required)
* `controls` - a folder which contains all tests (required)
* `libraries` - a folder which contains InSpec resource extensions (optional)
* `README.md` - a best-practice readme to each explain the profile and its scope
For a full example, see our `example profile`_.
.. _example profile: ../examples/profile
InSpec profile manifest
-----------------------------------------------------
Each profile has a manifest file `inspec.yml`. It looks as follows
.. code-block:: 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
A manifest description may contain the following values:
* `name` - Identifier of the profile (required)
* `title` - Human-readable name of the profile (optional)
* `maintainer` - Name of the profile maintainer (optional)
* `copyright` - Copyright holder (optional)
* `copyright_email` - Support contact for profile (optional)
* `license` - License of the profile (optional)
* `summary` - One-line summary of the profile (optional)
* `description` - Description of the profile (optional)
* `version` - Version of the profile (optional)
* `supports` - A list of supported targets (optional)
Supported targets
-----------------------------------------------------
The manifest contains the `supports` flag, which specifies operating systems or even cloud systems that the profile is targeting.
This list can contain simple names, names and versions, or detailed flags for the targeted system. These can freely be combined:
.. code-block:: yaml
name: ssh
supports:
// Runs on any version of Debian Linux
- os-name: debian
// Only runs on Ubuntu 14.04
- os-name: ubuntu
release: 14.04
// Targets RedHat, CentOS, Oracle Linux ...
- os-family: redhat
// Or even broader
- platform: aws
InSpec profile verification
-----------------------------------------------------
InSpec ships with a verification command that verifies the implementation of a profile:
.. code-block:: bash
$ inspec check examples/profile
InSpec profile archive
-----------------------------------------------------
Profiles are composed of multiple files. This hinders easy distribution of a profile. InSpec solves the problem by offering to collect all files in one archive.
The InSpec profile archive format aims for flexibility and reuse of standard and common technologies:
* tar and gzip (default)
* zip
* HTTP
This should enable third-parties to easily build InSpec profile archives:
* InSpec archives MUST be named with the stanard suffix
* InSpec archives MUST be a tar.gz or zip formatted file
* InSpec archives MUST have no duplicate entries
* InSpec archives MAY be compressed with gzip, bzip2, or xz.
InSpec is able to create profile archive for you. By default it generates a tar-file on Unix and zip on Windows or Mac.
.. code-block:: bash
# will generate a example-profile.tar.gz
$ inspec archive examples/profile
# will generate a example-profile.zip
$ inspec archive examples/profile --zip
Profile inheritance
-----------------------------------------------------
**Include controls of existing profile**
The `include_controls` keyword allows you to import all rules from an existing profile. This can be easily extended with additional rules.
.. code-block:: bash
include_controls 'cis-level-1' do
control "cis-fs-2.7" do
impact 1.0
...
end
**Inherit from a profile, but skip some rules**
Sometimes, not all requirements can be fulfilled for a legacy application. To manage the derivation, you can skip certain controls with `skip_control`.
.. code-block:: bash
include_controls 'cis-level-1' do
skip_control "cis-fs-2.1"
skip_control "cis-fs-2.2"
end
**Load specific controls from another profile**
.. code-block:: bash
require_controls 'cis-level-1' do
control "cis-fs-2.1"
control "cis-fs-2.2"
end

View file

@ -1,105 +0,0 @@
=====================================================
InSpec Documentation
=====================================================
InSpec a collection of resources and matchers to test the compliance of your nodes. This documentation provides an introduction to this mechanism and shows how to write custom tests.
Introduction
-----------------------------------------------------
At first, we add our tests to the ``test`` folder. Each test file must end with ``_spec.rb``:
.. code-block:: bash
mkdir test
touch test/example_spec.rb
We add a control to this file, to check the ``/tmp`` path in our system:
.. code-block:: ruby
# encoding: utf-8
control "cis-fs-2.1" do # A unique ID for this control
impact 0.7 # The criticality, if this control fails.
title "Create separate /tmp partition" # A human-readable title
desc "An optional description..."
tag mygroup: "tag" # A tag can be a simple value or
tag "tag" # can have a more complex key/value pair.
ref "name", url: "http://..." # A reference to a document, uri: is optional
describe file('/tmp') do # The actual test
it { should be_mounted }
end
end
Let's add another spec for checking the SSH server configuration:
.. code-block:: bash
touch test/sshd_spec.rb
It will contain:
.. code-block:: ruby
# encoding: utf-8
# Skip all controls, if SSH doesn't exist on the system
only_if do
command('sshd').exist?
end
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: "openssh-server"
ref "Document A-12"
describe sshd_config do
its('Protocol') { should eq('2') }
end
end
control "sshd-7" do
impact 1.0
title "Server: Do not permit root-based login with password."
desc "To reduce the potential to gain full privileges
of a system in the course of an attack (by either misconfiguration
or vulnerabilities), do not allow login as root with password"
tag security: "openssh-server"
ref "Document A-12"
describe sshd_config do
its('PermitRootLogin') { should match(/no|without-password/) }
end
end
Now, we are ready to run the tests locally:
bundle exec bin/inspec exec demo/test/example_spec.rb
.. code-block:: bash
# run tests individually
$ inspec exec test/example_spec.rb
$ inspec exec test/sshd_spec.rb
# if you want to run all test located within the directory
$ inspec exec ./test
Stability Index
-----------------------------------------------------
Every available InSpec resource will indicate its stability. As InSpec matures, certain parts are more reliable than others. Brand new features are likely to be redesigned and marked as such.
The stability indices are as follows:
* ``Stability: Deprecated`` - This features will be removed in future versions, because its known for being problematic. Do not rely on it.
* ``Stability: Experimental`` - New features may change or are removed in future versions
* ``Stability: Stable`` - API is well established and proofed. Maintaining compatibility is a high priority
* ``Stability: Locked`` - Only security and performance fixes are allowed

150
docs/shell.md Normal file
View file

@ -0,0 +1,150 @@
---
title: InSpec Shell
---
# InSpec Shell
The InSpec interactive shell is a pry based REPL that can be used to
quickly run InSpec controls and tests without having to write it to a
file. Its functionality is similar to `chef shell` - it provides a way
to exercise the 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.
## Launching the shell
If you are using InSpec from a platform-specific package (rpm, msi,
etc.) or from a chef prepared shell in ChefDK, you can directly launch
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 privelege 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 docker://container_id # Login to a docker container.
```
## Using Ruby in InSpec shell
Since 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 InSpec DSL in InSpec shell
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
InSpec control or test, the shell will evaluate it as if it were a
regular ruby command.
Bare 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 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/ksubramanian').directory?
=> true
inspec> os_env('HOME')
=> Environment variable HOME
inspec> os_env('HOME').content
=> /Users/ksubramanian
inspec> exit
```
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/ksubramanian' }
inspec> end
inspec> end
✔ my_control: Environment variable HOME content should eq "/Users/ksubramanian"
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 InSpec command
If you wish to run a single 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/ksubramanian") do it { should exist } end'}
Target: local://
✔ File /Users/ksubramanian should exist
Summary: 1 successful, 0 failures, 0 skipped
```
```bash
$ inspec shell --format json -c 'describe file("/Users/ksubramanian") do it { should exist } end'
{"version":"0.30.0","profiles":{"":{"supports":[],"controls":{"(generated from in_memory.rb:1 5aab65c33fb1f133d9244017958eef64)":{"title":null,"desc":null,"impact":0.5,"refs":[],"tags":{},"code":" rule = rule_class.new(id, profile_id, {}) do\n res = describe(*args, &block)\n end\n","source_location":{"ref":"/Users/ksubramanian/repo/chef/inspec/lib/inspec/profile_context.rb","line":184},"results":[{"status":"passed","code_desc":"File /Users/ksubramanian should exist","run_time":0.000747,"start_time":"2016-08-16 11:41:40 -0400"}]}},"groups":{"in_memory.rb":{"title":null,"controls":["(generated from in_memory.rb:1 5aab65c33fb1f133d9244017958eef64)"]}},"attributes":[]}},"other_checks":[],"summary":{"duration":0.001078,"example_count":1,"failure_count":0,"skip_count":0}}}
```

View file

@ -1,130 +0,0 @@
=====================================================
InSpec Shell Usage
=====================================================
The InSpec interactive shell is a pry based REPL that can be used to quickly run InSpec controls and tests without having to write it to a file. Its functionality is similar to ``chef shell`` - it provides a way to exercise the InSpec DSL, its resources, tests and plugins without having to create a profile or write a test file. See http://pryrepl.org/ for an introduction to what pry is and what it can do.
Launching the shell
-----------------------------------------------------
If you are using InSpec from a platform-specific package (rpm, msi, etc.) or from a chef prepared shell in ChefDK, you can directly launch InSpec shell against your local machine using the following. See https://docs.chef.io/install_dk.html#set-system-ruby for details.
.. code-block:: 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 privelege escalation after logging in. For a WinRM connection, use ``--path`` to change the login path, ``--ssl`` to use SSL for transport layer encryption.
.. code-block:: 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 docker://container_id # Login to a docker container.
Using Ruby in InSpec shell
-----------------------------------------------------
Since 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``.
.. code-block:: 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 InSpec DSL in InSpec shell
-----------------------------------------------------
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 InSpec control or test, the shell will evaluate it as if it were a regular ruby command.
Bare 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 InSpec resources documentation online.
.. code-block:: bash
$ inspec shell
Welcome to the interactive InSpec Shell
To find out how to use it, type: help
inspec> file('/Users/ksubramanian').directory?
=> true
inspec> os_env('HOME')
=> Environment variable HOME
inspec> os_env('HOME').content
=> /Users/ksubramanian
inspec> exit
InSpec tests are immediately executed.
.. code-block:: 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.
.. code-block:: bash
inspec> control 'my_control' do
inspec> describe os_env('HOME') do
inspec> its('content') { should eq '/Users/ksubramanian' }
inspec> end
inspec> end
✔ my_control: Environment variable HOME content should eq "/Users/ksubramanian"
Summary: 1 successful, 0 failures, 0 skipped
Syntax errors are illegal tests are also detected and reported.
.. code-block:: 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 InSpec command
-----------------------------------------------------
If you wish to run a single InSpec command and fetch its results, you may use the ``-c`` flag. This is similar to using ``bash -c``.
.. code-block:: bash
$ inspec shell -c 'describe file("/Users/ksubramanian") do it { should exist } end'
Target: local://
✔ File /Users/ksubramanian should exist
Summary: 1 successful, 0 failures, 0 skipped
.. code-block:: bash
$ inspec shell --format json -c 'describe file("/Users/ksubramanian") do it { should exist } end'
{"version":"0.30.0","profiles":{"":{"supports":[],"controls":{"(generated from in_memory.rb:1 5aab65c33fb1f133d9244017958eef64)":{"title":null,"desc":null,"impact":0.5,"refs":[],"tags":{},"code":" rule = rule_class.new(id, profile_id, {}) do\n res = describe(*args, &block)\n end\n","source_location":{"ref":"/Users/ksubramanian/repo/chef/inspec/lib/inspec/profile_context.rb","line":184},"results":[{"status":"passed","code_desc":"File /Users/ksubramanian should exist","run_time":0.000747,"start_time":"2016-08-16 11:41:40 -0400"}]}},"groups":{"in_memory.rb":{"title":null,"controls":["(generated from in_memory.rb:1 5aab65c33fb1f133d9244017958eef64)"]}},"attributes":[]}},"other_checks":[],"summary":{"duration":0.001078,"example_count":1,"failure_count":0,"skip_count":0}}

View file

@ -1,51 +0,0 @@
resource_name
=====================================================
Use the ``resource_name`` audit resource to xxxxx.
Syntax
-----------------------------------------------------
A ``resource_name`` audit resource block declares xxxxx. For example:
.. code-block:: ruby
describe xxxxx(xxxxx) do
it { should xxxxx }
end
where
* ``xxxxx`` must specify xxxxx
* xxxxx
* ``xxxxx`` is a valid matcher for this audit resource
Matchers
-----------------------------------------------------
This audit resource has the following matchers.
xxxxx
+++++++++++++++++++++++++++++++++++++++++++++++++++++
The ``xxxxx`` matcher tests if xxxxx. For example:
.. code-block:: ruby
it { should xxxxx }
xxxxx
+++++++++++++++++++++++++++++++++++++++++++++++++++++
The ``xxxxx`` matcher tests if xxxxx. For example:
.. code-block:: ruby
it { should xxxxx }
Examples
-----------------------------------------------------
The following examples show how to use this audit resource in a recipe.
**xxxxx**
xxxxx
**xxxxx**
xxxxx