inspec 0.16.3 → 0.16.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -2
- data/docs/dsl_inspec.rst +43 -0
- data/examples/inheritance/controls/example.rb +1 -1
- data/examples/inheritance/inspec.yml +1 -1
- data/examples/profile/README.md +26 -8
- data/examples/profile/controls/gordon.rb +4 -2
- data/examples/profile/controls/meta.rb +34 -0
- data/examples/profile/inspec.yml +1 -1
- data/examples/profile/libraries/gordon_config.rb +28 -2
- data/lib/bundles/inspec-compliance/cli.rb +3 -1
- data/lib/inspec/backend.rb +5 -0
- data/lib/inspec/cli.rb +2 -0
- data/lib/inspec/profile_context.rb +2 -0
- data/lib/inspec/runner.rb +1 -1
- data/lib/inspec/shell.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/test/functional/helper.rb +36 -0
- data/test/functional/inheritance_test.rb +49 -0
- data/test/functional/inspec_archive_test.rb +80 -0
- data/test/functional/inspec_exec_test.rb +141 -0
- data/test/functional/inspec_json_test.rb +104 -0
- data/test/functional/inspec_test.rb +54 -0
- data/test/unit/profile_context_test.rb +3 -3
- metadata +15 -7
- data/examples/resource/controls/tiny.rb +0 -3
- data/examples/resource/inspec.yml +0 -10
- data/examples/resource/libraries/tiny.rb +0 -3
- data/test/functional/command_test.rb +0 -390
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd9121f0f0fbdd3881f80534bb3fc91cb8256d9a
|
4
|
+
data.tar.gz: d83f04403f4157f117dd9b9ed413217c8554bfc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faa3803af3c3f9d516ccafe00e8abb988ab594e8f2294926333cc8e3d3c4ceaa12dda942fb6edcf4ac7343948bc4ed9f94bfba19909c7c0f53205a0b204e8fef
|
7
|
+
data.tar.gz: a514b070ef2f9d72b631f5289b8d733000faf05fa9ae6538f31183599a72e582fb41c4a14fc819b69f6683db496a8f8995eaf9322e015de7ed621bb475f451ee
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,34 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.16.
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v0.16.
|
3
|
+
## [0.16.4](https://github.com/chef/inspec/tree/0.16.4) (2016-03-25)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.16.3...0.16.4)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- support --controls for inspec json [\#589](https://github.com/chef/inspec/pull/589) ([arlimus](https://github.com/arlimus))
|
9
|
+
- dont fail with stacktrace on connection errors [\#588](https://github.com/chef/inspec/pull/588) ([arlimus](https://github.com/arlimus))
|
10
|
+
|
11
|
+
**Fixed bugs:**
|
12
|
+
|
13
|
+
- Escape whitespace for compliance upload [\#486](https://github.com/chef/inspec/issues/486)
|
14
|
+
- inspec-compliance: url\_encode profile names [\#574](https://github.com/chef/inspec/pull/574) ([srenatus](https://github.com/srenatus))
|
15
|
+
|
16
|
+
**Closed issues:**
|
17
|
+
|
18
|
+
- --controls flag should be supported in all inspec commands [\#568](https://github.com/chef/inspec/issues/568)
|
19
|
+
|
20
|
+
**Merged pull requests:**
|
21
|
+
|
22
|
+
- Improvements to gordon example and docs [\#583](https://github.com/chef/inspec/pull/583) ([alexpop](https://github.com/alexpop))
|
23
|
+
- bugfix: fix rare inspec shell missing all resources [\#582](https://github.com/chef/inspec/pull/582) ([alexpop](https://github.com/alexpop))
|
24
|
+
- document tags and refs [\#561](https://github.com/chef/inspec/pull/561) ([chris-rock](https://github.com/chris-rock))
|
25
|
+
|
26
|
+
## [v0.16.3](https://github.com/chef/inspec/tree/v0.16.3) (2016-03-23)
|
27
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.16.2...v0.16.3)
|
5
28
|
|
6
29
|
**Fixed bugs:**
|
7
30
|
|
31
|
+
- 0.16.3 [\#575](https://github.com/chef/inspec/pull/575) ([srenatus](https://github.com/srenatus))
|
8
32
|
- inspec-compliance: fix upload of profiles [\#573](https://github.com/chef/inspec/pull/573) ([srenatus](https://github.com/srenatus))
|
9
33
|
|
10
34
|
**Closed issues:**
|
data/docs/dsl_inspec.rst
CHANGED
@@ -30,16 +30,23 @@ In various use cases like implementing IT compliance across different department
|
|
30
30
|
Always specify which port the SSH server should listen to.
|
31
31
|
Prevent unexpected settings.
|
32
32
|
'
|
33
|
+
tag 'ssh','sshd','openssh-server'
|
34
|
+
tag cce: 'CCE-27072-8'
|
35
|
+
ref 'NSA-RH6-STIG - Section 3.5.2.1', url: 'https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf'
|
36
|
+
|
33
37
|
describe sshd_config do
|
34
38
|
its('Port') { should eq('22') }
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
42
|
+
|
38
43
|
where
|
39
44
|
|
40
45
|
* ``'sshd-8'`` is the name of the control
|
41
46
|
* ``impact``, ``title``, and ``desc`` define metadata that fully describes the importance of the control, its purpose, with a succinct and complete description
|
42
47
|
* ``impact`` is an float that measures the importance of the compliance results and must be a value between ``0.0`` and ``1.0``.
|
48
|
+
* ``tag`` is optional meta-information with with key or key-value pairs
|
49
|
+
* ``ref`` is a reference to an external document
|
43
50
|
* ``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
|
44
51
|
* ``sshd_config`` is an |inspec| resource. For the full list of InSpec resources, see |inspec| resource documentation
|
45
52
|
* ``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
|
@@ -185,6 +192,42 @@ The following test shows how to audit machines to ensure Safe DLL Seach Mode is
|
|
185
192
|
end
|
186
193
|
end
|
187
194
|
|
195
|
+
|
196
|
+
|
197
|
+
Additional metadata for controls
|
198
|
+
-----------------------------------------------------
|
199
|
+
|
200
|
+
The following example illustrates various ways to add tags and references to `control`
|
201
|
+
|
202
|
+
.. code-block:: ruby
|
203
|
+
|
204
|
+
control 'ssh-1' do
|
205
|
+
impact 1.0
|
206
|
+
|
207
|
+
title 'Allow only SSH Protocol 2'
|
208
|
+
desc 'Only SSH protocol version 2 connections should be permitted.
|
209
|
+
The default setting in /etc/ssh/sshd_config is correct, and can be
|
210
|
+
verified by ensuring that the following line appears: Protocol 2'
|
211
|
+
|
212
|
+
tag 'production','development'
|
213
|
+
tag 'ssh','sshd','openssh-server'
|
214
|
+
|
215
|
+
tag cce: 'CCE-27072-8'
|
216
|
+
tag disa: 'RHEL-06-000227'
|
217
|
+
|
218
|
+
tag remediation: 'stig_rhel6/recipes/sshd-config.rb'
|
219
|
+
tag remediation: 'https://supermarket.chef.io/cookbooks/ssh-hardening'
|
220
|
+
|
221
|
+
ref 'NSA-RH6-STIG - Section 3.5.2.1', url: 'https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf'
|
222
|
+
ref 'http://people.redhat.com/swells/scap-security-guide/RHEL/6/output/ssg-centos6-guide-C2S.html'
|
223
|
+
|
224
|
+
describe ssh_config do
|
225
|
+
its ('Protocol') { should eq '2'}
|
226
|
+
end
|
227
|
+
end`
|
228
|
+
|
229
|
+
|
230
|
+
|
188
231
|
.. |inspec| replace:: InSpec
|
189
232
|
.. |inspec resource| replace:: InSpec Resource
|
190
233
|
.. |chef compliance| replace:: Chef Compliance
|
data/examples/profile/README.md
CHANGED
@@ -8,23 +8,41 @@ InSpec ships with built-in features to verify a profile structure.
|
|
8
8
|
|
9
9
|
```bash
|
10
10
|
$ inspec check examples/profile
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
Summary
|
12
|
+
-------
|
13
|
+
Location: examples/profile
|
14
|
+
Profile: profile
|
15
|
+
Controls: 3
|
16
|
+
Timestamp: 2016-03-24T16:20:21+00:00
|
17
|
+
Valid: true
|
18
|
+
|
19
|
+
Errors
|
20
|
+
------
|
21
|
+
|
22
|
+
Warnings
|
23
|
+
--------
|
17
24
|
```
|
18
25
|
|
19
26
|
## Execute a profile
|
20
27
|
|
21
|
-
To run
|
28
|
+
To run all **supported** controls on a local machine use `inspec exec /path/to/profile`.
|
22
29
|
|
23
30
|
```bash
|
24
31
|
$ inspec exec examples/profile
|
25
32
|
..
|
26
33
|
|
27
34
|
Finished in 0.0025 seconds (files took 0.12449 seconds to load)
|
28
|
-
|
35
|
+
4 examples, 0 failures
|
36
|
+
```
|
37
|
+
|
38
|
+
## Execute a specific control from a profile
|
39
|
+
|
40
|
+
To run one control from the profile use `inspec exec /path/to/profile --controls name`.
|
29
41
|
|
42
|
+
```bash
|
43
|
+
$ inspec exec examples/profile --controls tmp-1.0
|
44
|
+
.
|
45
|
+
|
46
|
+
Finished in 0.0025 seconds (files took 0.12449 seconds to load)
|
47
|
+
1 examples, 0 failures
|
30
48
|
```
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# copyright:
|
2
|
+
# copyright: 2016, Chef Software, Inc.
|
3
3
|
# license: All rights reserved
|
4
4
|
|
5
5
|
title 'Gordon Config Checks'
|
6
6
|
|
7
7
|
# To pass the test, create the following file
|
8
8
|
# ```bash
|
9
|
-
#
|
9
|
+
# mkdir -p /tmp/gordon
|
10
|
+
# cat <<EOF > /tmp/gordon/config.yaml
|
10
11
|
# version: '1.0'
|
11
12
|
# EOF
|
12
13
|
# ```
|
@@ -16,5 +17,6 @@ control 'gordon-1.0' do
|
|
16
17
|
desc 'An optional description...'
|
17
18
|
describe gordon_config do
|
18
19
|
its('version') { should eq('1.0') }
|
20
|
+
its('size') { should <= 20 }
|
19
21
|
end
|
20
22
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
title 'SSH Server Configuration'
|
2
|
+
|
3
|
+
control 'ssh-1' do
|
4
|
+
impact 1.0
|
5
|
+
|
6
|
+
title 'Allow only SSH Protocol 2'
|
7
|
+
desc 'Only SSH protocol version 2 connections should be permitted.
|
8
|
+
The default setting in /etc/ssh/sshd_config is correct, and can be
|
9
|
+
verified by ensuring that the following line appears: Protocol 2'
|
10
|
+
|
11
|
+
tag 'production','development'
|
12
|
+
tag 'ssh','sshd','openssh-server'
|
13
|
+
|
14
|
+
tag cce: 'CCE-27072-8'
|
15
|
+
tag disa: 'RHEL-06-000227'
|
16
|
+
|
17
|
+
tag nist: 'AC-3(10).i'
|
18
|
+
tag nist: 'IA-5(1)'
|
19
|
+
|
20
|
+
tag cci: 'CCI-000776'
|
21
|
+
tag cci: 'CCI-000774'
|
22
|
+
tag cci: 'CCI-001436'
|
23
|
+
|
24
|
+
tag remediation: 'stig_rhel6/recipes/sshd-config.rb'
|
25
|
+
tag remediation: 'https://supermarket.chef.io/cookbooks/ssh-hardening'
|
26
|
+
|
27
|
+
ref 'NSA-RH6-STIG - Section 3.5.2.1', url: 'https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf'
|
28
|
+
ref 'DISA-RHEL6-SG - Section 9.2.1', url: 'http://iasecontent.disa.mil/stigs/zip/Jan2016/U_RedHat_6_V1R10_STIG.zip'
|
29
|
+
ref 'http://people.redhat.com/swells/scap-security-guide/RHEL/6/output/ssg-centos6-guide-C2S.html'
|
30
|
+
|
31
|
+
describe file('/bin/sh') do
|
32
|
+
it { should be_owned_by 'root' }
|
33
|
+
end
|
34
|
+
end
|
data/examples/profile/inspec.yml
CHANGED
@@ -1,16 +1,42 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
|
+
# Custom resource based on the InSpec resource DSL
|
3
4
|
class GordonConfig < Inspec.resource(1)
|
4
5
|
name 'gordon_config'
|
5
6
|
|
7
|
+
desc "
|
8
|
+
Gordon's resource description ...
|
9
|
+
"
|
10
|
+
|
11
|
+
example "
|
12
|
+
describe gordon_config do
|
13
|
+
its('version') { should eq('1.0') }
|
14
|
+
its('size') { should > 1 }
|
15
|
+
end
|
16
|
+
"
|
17
|
+
|
18
|
+
# Load the configuration file on initialization
|
6
19
|
def initialize
|
7
|
-
@path = '/
|
20
|
+
@path = '/tmp/gordon/config.yaml'
|
8
21
|
@file = inspec.file(@path)
|
9
22
|
return skip_resource "Can't find file \"#{@path}\"" if !@file.file?
|
10
23
|
|
11
|
-
|
24
|
+
# Protect from invalid YAML content
|
25
|
+
begin
|
26
|
+
@params = YAML.load(@file.content)
|
27
|
+
rescue Exception
|
28
|
+
return skip_resource "#{@file}: #{$!}"
|
29
|
+
end
|
30
|
+
add_some_extra_params
|
31
|
+
end
|
32
|
+
|
33
|
+
# Extra Ruby helper method
|
34
|
+
def add_some_extra_params
|
35
|
+
@params['size'] = @file.size
|
36
|
+
@params['md5sum'] = @file.md5sum
|
12
37
|
end
|
13
38
|
|
39
|
+
# Expose all parameters
|
14
40
|
def method_missing(name)
|
15
41
|
@params[name.to_s]
|
16
42
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# author: Dominik Richter
|
4
4
|
|
5
5
|
require 'thor'
|
6
|
+
require 'erb'
|
6
7
|
|
7
8
|
module Compliance
|
8
9
|
class ComplianceCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
@@ -106,9 +107,10 @@ module Compliance
|
|
106
107
|
end
|
107
108
|
|
108
109
|
puts "Start upload to #{owner}/#{profile_name}"
|
110
|
+
pname = ERB::Util.url_encode(profile_name)
|
109
111
|
|
110
112
|
# upload the tar to Chef Compliance
|
111
|
-
url = "#{config['server']}/owners/#{owner}/compliance/#{
|
113
|
+
url = "#{config['server']}/owners/#{owner}/compliance/#{pname}/tar"
|
112
114
|
|
113
115
|
puts "Uploading to #{url}"
|
114
116
|
success, msg = Compliance::API.post_file(url, config['token'], '', archive_path, config['insecure'])
|
data/lib/inspec/backend.rb
CHANGED
@@ -37,6 +37,11 @@ module Inspec
|
|
37
37
|
end
|
38
38
|
|
39
39
|
cls.new
|
40
|
+
|
41
|
+
rescue Train::ClientError => e
|
42
|
+
raise "Client error, can't connect to '#{name}' backend: #{e.message}"
|
43
|
+
rescue Train::TransportError => e
|
44
|
+
raise "Transport error, can't connect to '#{name}' backend: #{e.message}"
|
40
45
|
end
|
41
46
|
end
|
42
47
|
end
|
data/lib/inspec/cli.rb
CHANGED
@@ -19,6 +19,8 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
19
19
|
desc: 'Attach a profile ID to all test results'
|
20
20
|
option :output, aliases: :o, type: :string,
|
21
21
|
desc: 'Save the created profile to a path'
|
22
|
+
option :controls, type: :array,
|
23
|
+
desc: 'A list of controls to include. Ignore all other tests.'
|
22
24
|
profile_options
|
23
25
|
def json(target)
|
24
26
|
diagnose
|
@@ -33,6 +33,8 @@ module Inspec
|
|
33
33
|
@current_load = { file: source }
|
34
34
|
if content.is_a? Proc
|
35
35
|
@profile_context.instance_eval(&content)
|
36
|
+
elsif source.nil? && line.nil?
|
37
|
+
@profile_context.instance_eval(content)
|
36
38
|
else
|
37
39
|
@profile_context.instance_eval(content, source || 'unknown', line || 1)
|
38
40
|
end
|
data/lib/inspec/runner.rb
CHANGED
@@ -101,7 +101,7 @@ module Inspec
|
|
101
101
|
def add_test_to_context(test, ctx)
|
102
102
|
content = test[:content]
|
103
103
|
return if content.nil? || content.empty?
|
104
|
-
ctx.load(content, test[:ref], test[:line]
|
104
|
+
ctx.load(content, test[:ref], test[:line])
|
105
105
|
end
|
106
106
|
|
107
107
|
def filter_controls(controls_map, include_list)
|
data/lib/inspec/shell.rb
CHANGED
data/lib/inspec/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
require 'helper'
|
6
|
+
|
7
|
+
require 'minitest/hell'
|
8
|
+
class Minitest::Test
|
9
|
+
parallelize_me!
|
10
|
+
end
|
11
|
+
|
12
|
+
class Module
|
13
|
+
include Minitest::Spec::DSL
|
14
|
+
end
|
15
|
+
|
16
|
+
module FunctionalHelper
|
17
|
+
let(:repo_path) { File.expand_path(File.join( __FILE__, '..', '..', '..')) }
|
18
|
+
let(:exec_inspec) { File.join(repo_path, 'bin', 'inspec') }
|
19
|
+
let(:profile_path) { File.join(repo_path, 'test', 'unit', 'mock', 'profiles') }
|
20
|
+
let(:examples_path) { File.join(repo_path, 'examples') }
|
21
|
+
|
22
|
+
let(:example_profile) { File.join(examples_path, 'profile') }
|
23
|
+
let(:inheritance_profile) { File.join(examples_path, 'profile') }
|
24
|
+
|
25
|
+
let(:dst) {
|
26
|
+
# create a temporary path, but we only want an auto-clean helper
|
27
|
+
# so remove the file and give back the path
|
28
|
+
res = Tempfile.new('inspec-shred')
|
29
|
+
FileUtils.rm(res.path)
|
30
|
+
TMP_CACHE[res.path] = res
|
31
|
+
}
|
32
|
+
|
33
|
+
def inspec(commandline)
|
34
|
+
CMD.run_command("#{exec_inspec} #{commandline}")
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
require 'functional/helper'
|
6
|
+
|
7
|
+
describe 'example inheritance profile' do
|
8
|
+
include FunctionalHelper
|
9
|
+
let(:path) { File.join(examples_path, 'inheritance') }
|
10
|
+
|
11
|
+
[
|
12
|
+
'archive %s --overwrite',
|
13
|
+
'check %s',
|
14
|
+
'json %s',
|
15
|
+
].each do |cmd|
|
16
|
+
it cmd[/^\w/] + ' fails without --profiles-path' do
|
17
|
+
out = inspec(format(cmd, path))
|
18
|
+
out.stderr.must_include 'You must supply a --profiles-path to inherit'
|
19
|
+
# out.stdout.must_equal '' => we still get partial output
|
20
|
+
out.exit_status.must_equal 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'check succeeds with --profiles-path' do
|
25
|
+
out = inspec('check ' + path + ' --profiles-path ' + examples_path)
|
26
|
+
out.stderr.must_equal ''
|
27
|
+
out.stdout.must_match /Valid.*true/
|
28
|
+
out.exit_status.must_equal 0
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'archive is successful with --profiles-path' do
|
32
|
+
out = inspec('archive ' + path + ' --output ' + dst.path + ' --profiles-path ' + examples_path)
|
33
|
+
out.stderr.must_equal ''
|
34
|
+
out.stdout.must_include 'Generate archive '+dst.path
|
35
|
+
out.stdout.must_include 'Finished archive generation.'
|
36
|
+
out.exit_status.must_equal 0
|
37
|
+
File.exist?(dst.path).must_equal true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'read the profile json with --profiles-path' do
|
41
|
+
out = inspec('json ' + path + ' --profiles-path '+examples_path)
|
42
|
+
out.stderr.must_equal ''
|
43
|
+
out.exit_status.must_equal 0
|
44
|
+
s = out.stdout
|
45
|
+
hm = JSON.load(s)
|
46
|
+
hm['name'].must_equal 'inheritance'
|
47
|
+
hm['rules'].length.must_equal 1 # TODO: flatten out or search deeper!
|
48
|
+
end
|
49
|
+
end
|