inspec 1.20.0 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -1
- data/docs/resources/docker.md.erb +160 -0
- data/docs/resources/docker_container.md.erb +89 -0
- data/docs/resources/docker_image.md.erb +86 -0
- data/docs/resources/{key_rsa.md → key_rsa.md.erb} +0 -0
- data/docs/resources/{x509_certificate.md → x509_certificate.md.erb} +0 -0
- data/docs/ruby_usage.md +50 -0
- data/inspec.gemspec +1 -1
- data/lib/bundles/inspec-habitat/profile.rb +14 -3
- data/lib/inspec/objects/test.rb +8 -7
- data/lib/inspec/resource.rb +3 -0
- data/lib/inspec/shell.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/docker.rb +159 -0
- data/lib/resources/docker_container.rb +97 -0
- data/lib/resources/docker_image.rb +96 -0
- data/lib/resources/http.rb +3 -2
- data/lib/resources/powershell.rb +1 -1
- data/lib/resources/ssh_conf.rb +15 -3
- data/lib/resources/users.rb +31 -31
- metadata +13 -13
- data/examples/inheritance/inspec.lock +0 -11
- data/examples/meta-profile/inspec.lock +0 -18
- data/examples/meta-profile/vendor/11b6287b232c2a689ae87b3ba54897eb9067a749da074b6f3040b6442082dd6a.tar.gz +0 -0
- data/examples/meta-profile/vendor/379757a6ba73c9bc17b37353c1ff5b4eb7dd978a3bd38b29d2dda64f90f16c36.tar.gz +0 -0
- data/examples/meta-profile/vendor/dbb5602f09f58d86f8743dfb44327207e9a23a49ef34f65614f1c1d8cc145f6b.tar.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 765c8898efac5c64dbba0583086f069eea4b521b
|
4
|
+
data.tar.gz: 28d639d2d72be737cb57366790ac1ee572eedc5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a48f8574446241505bb8678bedc9069931841bee798e8d5dbeb133151e195191cacaa67bfb48441d219d498ed14752f98dea4273120138298df5530545e9b3d3
|
7
|
+
data.tar.gz: c3f91d119061a9695653ee94f50f8c2588b9c6eb08a262578f2caef1b75ac9bef41d290aaa2af51fe9d0e154be0e093aabae23173e1c583fadaa1714d69f7f35
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v1.21.0](https://github.com/chef/inspec/tree/v1.21.0) (2017-04-24)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v1.20.0...v1.21.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- user resource is not fetching groups for windows [\#1400](https://github.com/chef/inspec/issues/1400)
|
9
|
+
- docker resources [\#71](https://github.com/chef/inspec/issues/71)
|
10
|
+
|
11
|
+
**Fixed bugs:**
|
12
|
+
|
13
|
+
- Web references in inspec shell help are wrong [\#1667](https://github.com/chef/inspec/issues/1667)
|
14
|
+
- bugfix: solve warn on uninitialized [\#1694](https://github.com/chef/inspec/pull/1694) ([arlimus](https://github.com/arlimus))
|
15
|
+
|
16
|
+
**Closed issues:**
|
17
|
+
|
18
|
+
- Adding windows domain users to users resource [\#1688](https://github.com/chef/inspec/issues/1688)
|
19
|
+
- stdout matcher has depreciation warnings [\#1685](https://github.com/chef/inspec/issues/1685)
|
20
|
+
- profile upload with dependencies fails uploading to compliance server [\#1670](https://github.com/chef/inspec/issues/1670)
|
21
|
+
- Retrying Inspec Tests [\#1665](https://github.com/chef/inspec/issues/1665)
|
22
|
+
- Add a way to retry a test if failing [\#1404](https://github.com/chef/inspec/issues/1404)
|
23
|
+
- --sudo does not appear to elevate privileges when evaluating local systems. [\#1279](https://github.com/chef/inspec/issues/1279)
|
24
|
+
|
25
|
+
**Merged pull requests:**
|
26
|
+
|
27
|
+
- \[www\] Update www Gemfile.lock [\#1691](https://github.com/chef/inspec/pull/1691) ([adamleff](https://github.com/adamleff))
|
28
|
+
- showing how to shellout in docs [\#1689](https://github.com/chef/inspec/pull/1689) ([rshade](https://github.com/rshade))
|
29
|
+
- \[www\] Fix docs pages for x509\_certificate and key\_rsa [\#1683](https://github.com/chef/inspec/pull/1683) ([adamleff](https://github.com/adamleff))
|
30
|
+
- fix spelling mistake in powershell resource documentation [\#1682](https://github.com/chef/inspec/pull/1682) ([Happycoil](https://github.com/Happycoil))
|
31
|
+
- fetch user groups while building user object [\#1681](https://github.com/chef/inspec/pull/1681) ([Happycoil](https://github.com/Happycoil))
|
32
|
+
- update sslshake to v1.2 [\#1680](https://github.com/chef/inspec/pull/1680) ([arlimus](https://github.com/arlimus))
|
33
|
+
- Fix type-o in control code [\#1676](https://github.com/chef/inspec/pull/1676) ([hannah-radish](https://github.com/hannah-radish))
|
34
|
+
- fix web reference url [\#1669](https://github.com/chef/inspec/pull/1669) ([chris-rock](https://github.com/chris-rock))
|
35
|
+
- fix sshd config help [\#1668](https://github.com/chef/inspec/pull/1668) ([chris-rock](https://github.com/chris-rock))
|
36
|
+
- ER-508 Extended http resource to support no ssl verification [\#1663](https://github.com/chef/inspec/pull/1663) ([ElizabethU](https://github.com/ElizabethU))
|
37
|
+
- Move Habitat sleep time to config file [\#1662](https://github.com/chef/inspec/pull/1662) ([adamleff](https://github.com/adamleff))
|
38
|
+
- Docker resource [\#1566](https://github.com/chef/inspec/pull/1566) ([chris-rock](https://github.com/chris-rock))
|
39
|
+
|
3
40
|
## [v1.20.0](https://github.com/chef/inspec/tree/v1.20.0) (2017-04-13)
|
4
41
|
[Full Changelog](https://github.com/chef/inspec/compare/v1.19.2...v1.20.0)
|
5
42
|
|
@@ -15,6 +52,7 @@
|
|
15
52
|
|
16
53
|
**Merged pull requests:**
|
17
54
|
|
55
|
+
- Release 1.20.0 [\#1657](https://github.com/chef/inspec/pull/1657) ([adamleff](https://github.com/adamleff))
|
18
56
|
- Habitat packages should run as root [\#1656](https://github.com/chef/inspec/pull/1656) ([adamleff](https://github.com/adamleff))
|
19
57
|
- harmonize compliance profiles view with supermarket views [\#1654](https://github.com/chef/inspec/pull/1654) ([chris-rock](https://github.com/chris-rock))
|
20
58
|
- \[www\] Update community page [\#1651](https://github.com/chef/inspec/pull/1651) ([adamleff](https://github.com/adamleff))
|
@@ -466,6 +504,7 @@
|
|
466
504
|
- do not load controls from test directory [\#1327](https://github.com/chef/inspec/pull/1327) ([chris-rock](https://github.com/chris-rock))
|
467
505
|
- Replaced Colors for output [\#1320](https://github.com/chef/inspec/pull/1320) ([hannah-radish](https://github.com/hannah-radish))
|
468
506
|
- Hannah vj/fix tests formatting [\#1319](https://github.com/chef/inspec/pull/1319) ([hannah-radish](https://github.com/hannah-radish))
|
507
|
+
- revert style changes temporarily [\#1317](https://github.com/chef/inspec/pull/1317) ([vjeffrey](https://github.com/vjeffrey))
|
469
508
|
- Updated color palettes, label colors and icons [\#1313](https://github.com/chef/inspec/pull/1313) ([hannah-radish](https://github.com/hannah-radish))
|
470
509
|
- Remove extra `'` in registry key examples [\#1308](https://github.com/chef/inspec/pull/1308) ([jerryaldrichiii](https://github.com/jerryaldrichiii))
|
471
510
|
- also push docker latest tag with each release [\#1307](https://github.com/chef/inspec/pull/1307) ([chris-rock](https://github.com/chris-rock))
|
@@ -486,7 +525,6 @@
|
|
486
525
|
|
487
526
|
**Merged pull requests:**
|
488
527
|
|
489
|
-
- revert style changes temporarily [\#1317](https://github.com/chef/inspec/pull/1317) ([vjeffrey](https://github.com/vjeffrey))
|
490
528
|
- ensure metadata release entry is a string [\#1305](https://github.com/chef/inspec/pull/1305) ([chris-rock](https://github.com/chris-rock))
|
491
529
|
- Fixes resources in the docs [\#1303](https://github.com/chef/inspec/pull/1303) ([burtlo](https://github.com/burtlo))
|
492
530
|
- copy vendored dependencies into cache [\#1291](https://github.com/chef/inspec/pull/1291) ([chris-rock](https://github.com/chris-rock))
|
@@ -0,0 +1,160 @@
|
|
1
|
+
---
|
2
|
+
title: About the docker Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# docker
|
6
|
+
|
7
|
+
Use the `docker` InSpec audit resource to test configuration data for docker daemon. It is a very comprehensive resource. Please have a look at [docker_container](docker_container) and [docker_image](docker_image), too.
|
8
|
+
|
9
|
+
## Syntax
|
10
|
+
|
11
|
+
A `docker` resource block declares allows you to write test for many containers:
|
12
|
+
|
13
|
+
describe docker.containers do
|
14
|
+
its('images') { should_not include 'u12:latest' }
|
15
|
+
end
|
16
|
+
|
17
|
+
or:
|
18
|
+
|
19
|
+
describe docker.containers.where { name == 'flamboyant_colden' } do
|
20
|
+
it { should be_running }
|
21
|
+
end
|
22
|
+
|
23
|
+
where
|
24
|
+
|
25
|
+
* `.where()` may specify a specific item and value, to which the matchers are compared
|
26
|
+
* `commands`, `ids`, `images`, `labels`, `local_volumes`, `mounts`, `names`, `networks`, `ports`, `sizes` and `'status'` are valid matchers for `containers`
|
27
|
+
|
28
|
+
The `docker` resource block also declares allows you to write test for many images:
|
29
|
+
|
30
|
+
describe docker.images do
|
31
|
+
its('repositories') { should_not include 'inssecure_image' }
|
32
|
+
end
|
33
|
+
|
34
|
+
or if you want to query specific images:
|
35
|
+
|
36
|
+
describe docker.images.where { repository == 'ubuntu' && tag == '12.04' } do
|
37
|
+
it { should_not exist }
|
38
|
+
end
|
39
|
+
|
40
|
+
where
|
41
|
+
|
42
|
+
* `.where()` may specify a specific item and value, to which the matchers are compared
|
43
|
+
* `commands`, `ids`, `images`, `labels`, `local_volumes`, `mounts`, `names`, `networks`, `ports`, `sizes` and `'status'` are valid matchers for `containers`
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
## Matchers
|
48
|
+
|
49
|
+
This InSpec audit resource has the following matchers:
|
50
|
+
|
51
|
+
### containers
|
52
|
+
|
53
|
+
`containers` returns information about containers as returned by [docker ps -a](https://docs.docker.com/engine/reference/commandline/ps/). You can determine specific information about
|
54
|
+
|
55
|
+
describe docker.containers do
|
56
|
+
its('ids') { should include 'sha:71b5df59...442b' }
|
57
|
+
its('commands') { should_not include '/bin/sh' }
|
58
|
+
its('images') { should_not include 'u12:latest' }
|
59
|
+
its('ports') { should include '0.0.0.0:1234->1234/tcp' }
|
60
|
+
its('labels') { should include 'License=GPLv2,Vendor=CentOS' }
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
### images
|
65
|
+
|
66
|
+
`images` returns information about docker image as returned by [docker images](https://docs.docker.com/engine/reference/commandline/images/). You can determine specific information about
|
67
|
+
|
68
|
+
describe docker.images do
|
69
|
+
its('ids') { should include 'sha:12b5df59...442b' }
|
70
|
+
its('repositories') { should_not include 'my_image' }
|
71
|
+
its('tags') { should_not include 'unwanted_tag' }
|
72
|
+
its('sizes') { should_not include "1.41 GB" }
|
73
|
+
end
|
74
|
+
|
75
|
+
### version
|
76
|
+
|
77
|
+
`info` returns the parsed result of [docker version](https://docs.docker.com/engine/reference/commandline/version/)
|
78
|
+
|
79
|
+
describe docker.version do
|
80
|
+
its('Server.Version') { should cmp >= '1.12'}
|
81
|
+
its('Client.Version') { should cmp >= '1.12'}
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
### info
|
86
|
+
|
87
|
+
`info` returns the parsed result of [docker info](https://docs.docker.com/engine/reference/commandline/info/)
|
88
|
+
|
89
|
+
describe docker.info do
|
90
|
+
its('Configuration.Path') { should eq 'value' }
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
### object('id')
|
95
|
+
|
96
|
+
`object` returns low-level information about docker objects. It is calling [docker inspect](https://docs.docker.com/engine/reference/commandline/info/) under the hood.
|
97
|
+
|
98
|
+
describe docker.object(id) do
|
99
|
+
its('Configuration.Path') { should eq 'value' }
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
## Examples
|
104
|
+
|
105
|
+
The following examples show how to use this InSpec audit resource.
|
106
|
+
|
107
|
+
### Return all running containers
|
108
|
+
|
109
|
+
docker.containers.running?.ids.each do |id|
|
110
|
+
describe docker.object(id) do
|
111
|
+
its('State.Health.Status') { should eq 'healthy' }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
### Verify a Docker Server and Client version
|
116
|
+
|
117
|
+
describe docker.version do
|
118
|
+
its('Server.Version') { should cmp >= '1.12'}
|
119
|
+
its('Client.Version') { should cmp >= '1.12'}
|
120
|
+
end
|
121
|
+
|
122
|
+
### Iterate over all containers to verify host coniguration
|
123
|
+
|
124
|
+
docker.containers.ids.each do |id|
|
125
|
+
# call docker inspect for a specific container id
|
126
|
+
describe docker.object(id) do
|
127
|
+
its(%w(HostConfig Privileged)) { should cmp false }
|
128
|
+
its(%w(HostConfig Privileged)) { should_not cmp true }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
### Iterate over all images to verify the container was built without ADD instruction
|
133
|
+
|
134
|
+
docker.images.ids.each do |id|
|
135
|
+
describe command("docker history #{id}| grep 'ADD'") do
|
136
|
+
its('stdout') { should eq '' }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
### Verify that health-checks are enabled for a container
|
141
|
+
|
142
|
+
describe docker.object('71b5df59442b') do
|
143
|
+
its(%w(Config Healthcheck)) { should_not eq nil }
|
144
|
+
end
|
145
|
+
|
146
|
+
### Run the DevSec docker baseline profile
|
147
|
+
|
148
|
+
There are two ways to run the `docker-baseline` profile to test Docker via the `docker` resource.
|
149
|
+
|
150
|
+
Clone the profile:
|
151
|
+
|
152
|
+
$ git clone https://github.com/dev-sec/cis-docker-benchmark.git
|
153
|
+
|
154
|
+
and then run:
|
155
|
+
|
156
|
+
$ inspec exec cis-docker-benchmark
|
157
|
+
|
158
|
+
Or execute the profile directly via URL:
|
159
|
+
|
160
|
+
$ inspec exec https://github.com/dev-sec/cis-docker-benchmark
|
@@ -0,0 +1,89 @@
|
|
1
|
+
---
|
2
|
+
title: About the docker_container Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# docker_container
|
6
|
+
|
7
|
+
Use the `docker_container` InSpec audit resource to test a docker container.
|
8
|
+
|
9
|
+
## Syntax
|
10
|
+
|
11
|
+
A `docker_container` resource block declares the configuration data to be tested:
|
12
|
+
|
13
|
+
describe docker_container('container') do
|
14
|
+
it { should exist }
|
15
|
+
it { should be_running }
|
16
|
+
its('id') { should_not eq '' }
|
17
|
+
its('image') { should eq 'busybox:latest' }
|
18
|
+
its('repo') { should eq 'busybox' }
|
19
|
+
its('tag') { should eq 'latest' }
|
20
|
+
its('ports') { should eq [] }
|
21
|
+
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
|
22
|
+
end
|
23
|
+
|
24
|
+
The container name can also be passed with the `name` argument:
|
25
|
+
|
26
|
+
describe docker_container(name: 'an-echo-server') do
|
27
|
+
it { should exist }
|
28
|
+
it { should be_running }
|
29
|
+
end
|
30
|
+
|
31
|
+
Alternatively, you can pass in the container id:
|
32
|
+
|
33
|
+
describe docker_container(id: '71b5df59442b') do
|
34
|
+
it { should exist }
|
35
|
+
it { should be_running }
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
## Matchers
|
40
|
+
|
41
|
+
This InSpec audit resource has the following matchers:
|
42
|
+
|
43
|
+
### id
|
44
|
+
|
45
|
+
The `id` matcher tests the container id:
|
46
|
+
|
47
|
+
its('id') { should eq 'sha:71b5df59...442b' }
|
48
|
+
|
49
|
+
### repo
|
50
|
+
|
51
|
+
The `repo` matcher tests the value of the image repository:
|
52
|
+
|
53
|
+
its('repo') { should eq 'busybox' }
|
54
|
+
|
55
|
+
### tag
|
56
|
+
|
57
|
+
The `tag` matcher tests the value of the image tag:
|
58
|
+
|
59
|
+
its('tag') { should eq 'latest' }
|
60
|
+
|
61
|
+
### ports
|
62
|
+
|
63
|
+
The `ports` matcher tests the value the docker ports:
|
64
|
+
|
65
|
+
its('ports') { should eq '0.0.0.0:1234->1234/tcp' }
|
66
|
+
|
67
|
+
### command
|
68
|
+
|
69
|
+
The `command` matcher tests the value of the container run command:
|
70
|
+
|
71
|
+
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
|
72
|
+
|
73
|
+
|
74
|
+
## Examples
|
75
|
+
|
76
|
+
The following examples show how to use this InSpec resource.
|
77
|
+
|
78
|
+
### Verify an running container:
|
79
|
+
|
80
|
+
describe docker_container('an-echo-server') do
|
81
|
+
it { should exist }
|
82
|
+
it { should be_running }
|
83
|
+
its('id') { should_not eq '' }
|
84
|
+
its('image') { should eq 'busybox:latest' }
|
85
|
+
its('repo') { should eq 'busybox' }
|
86
|
+
its('tag') { should eq 'latest' }
|
87
|
+
its('ports') { should eq [] }
|
88
|
+
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
|
89
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
---
|
2
|
+
title: About the docker_image Resource
|
3
|
+
---
|
4
|
+
|
5
|
+
# docker_image
|
6
|
+
|
7
|
+
Use the `docker_image` InSpec audit resource to verify a docker image.
|
8
|
+
|
9
|
+
## Syntax
|
10
|
+
|
11
|
+
A `docker_image` resource block declares the image:
|
12
|
+
|
13
|
+
describe docker_image('alpine:latest') do
|
14
|
+
it { should exist }
|
15
|
+
its('id') { should eq 'sha256:4a415e...a526' }
|
16
|
+
its('repo') { should eq 'alpine' }
|
17
|
+
its('tag') { should eq 'latest' }
|
18
|
+
end
|
19
|
+
|
20
|
+
The resource allows you to pass in an image id:
|
21
|
+
|
22
|
+
describe docker_image(id: alpine_id) do
|
23
|
+
...
|
24
|
+
end
|
25
|
+
|
26
|
+
If the tag is missing for an image, `latest` is assumed as default:
|
27
|
+
|
28
|
+
describe docker_image('alpine') do
|
29
|
+
...
|
30
|
+
end
|
31
|
+
|
32
|
+
You can also pass in repository and tag as separate values
|
33
|
+
|
34
|
+
describe docker_image(repo: 'alpine', tag: 'latest') do
|
35
|
+
...
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
## Matchers
|
40
|
+
|
41
|
+
This InSpec audit resource has the following matchers:
|
42
|
+
|
43
|
+
### exist
|
44
|
+
|
45
|
+
The `exist` matcher tests if the image is available on the node:
|
46
|
+
|
47
|
+
it { should exist }
|
48
|
+
|
49
|
+
### id
|
50
|
+
|
51
|
+
The `id` matcher returns the full image id:
|
52
|
+
|
53
|
+
its('id') { should eq 'sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526' }
|
54
|
+
|
55
|
+
### image
|
56
|
+
|
57
|
+
The `image` matcher tests the value of the image. It is a combination of `repository/tag`:
|
58
|
+
|
59
|
+
its('image') { should eq 'alpine:latest' }
|
60
|
+
|
61
|
+
### repo
|
62
|
+
|
63
|
+
The `repo` matcher tests the value of the repository name:
|
64
|
+
|
65
|
+
its('repo') { should eq 'alpine' }
|
66
|
+
|
67
|
+
### tag
|
68
|
+
|
69
|
+
The `tag` matcher tests the value of image tag:
|
70
|
+
|
71
|
+
its('tag') { should eq 'latest' }
|
72
|
+
|
73
|
+
|
74
|
+
## Examples
|
75
|
+
|
76
|
+
The following examples show how to use this InSpec `docker_image` resource.
|
77
|
+
|
78
|
+
### Test a docker image
|
79
|
+
|
80
|
+
describe docker_image('alpine:latest') do
|
81
|
+
it { should exist }
|
82
|
+
its('id') { should eq 'sha256:4a415e...a526' }
|
83
|
+
its('image') { should eq 'alpine:latest' }
|
84
|
+
its('repo') { should eq 'alpine' }
|
85
|
+
its('tag') { should eq 'latest' }
|
86
|
+
end
|
File without changes
|
File without changes
|
data/docs/ruby_usage.md
CHANGED
@@ -152,3 +152,53 @@ describe command('ls -al /') do
|
|
152
152
|
its('exit_status') { should eq 0 }
|
153
153
|
end
|
154
154
|
```
|
155
|
+
|
156
|
+
## Shelling out in tests
|
157
|
+
|
158
|
+
When writing tests you can not use standard ruby methods to shellout as it tries to execute those commands locally.
|
159
|
+
However, the `command` resource has a `.stdout` method that will allow you to manipulate the results.
|
160
|
+
Using the above example, you could check the writes on several subdirectories.
|
161
|
+
|
162
|
+
### Example 1:
|
163
|
+
```ruby
|
164
|
+
$ inspec shell
|
165
|
+
Welcome to the interactive InSpec Shell
|
166
|
+
To find out how to use it, type: help
|
167
|
+
|
168
|
+
inspec> output=command('echo test').stdout
|
169
|
+
=> "test\n"
|
170
|
+
inspec> describe command('echo test') do
|
171
|
+
inspec> its('stdout') { should eq output }
|
172
|
+
inspec> end
|
173
|
+
|
174
|
+
Profile: inspec-shell
|
175
|
+
Version: (not specified)
|
176
|
+
|
177
|
+
Command echo
|
178
|
+
✔ test stdout should eq "test\n"
|
179
|
+
|
180
|
+
Test Summary: 1 successful, 0 failures, 0 skipped
|
181
|
+
```
|
182
|
+
|
183
|
+
### Example 2:
|
184
|
+
```ruby
|
185
|
+
$ inspec shell
|
186
|
+
Welcome to the interactive InSpec Shell
|
187
|
+
To find out how to use it, type: help
|
188
|
+
|
189
|
+
inspec> dirs = command('ls -d /home/gordon/git/inspec/docs').stdout.split("\n")
|
190
|
+
=> ["/home/gordon/git/inspec/docs"]
|
191
|
+
inspec> dirs.each do |dir|
|
192
|
+
inspec> describe directory(dir) do
|
193
|
+
inspec> its('mode') { should cmp '0775' }
|
194
|
+
inspec> end
|
195
|
+
inspec> end
|
196
|
+
|
197
|
+
Profile: inspec-shell
|
198
|
+
Version: (not specified)
|
199
|
+
|
200
|
+
File /home/gordon/git/inspec/docs/
|
201
|
+
✔ mode should cmp == "0775"
|
202
|
+
|
203
|
+
Test Summary: 1 successful, 0 failures, 0 skipped
|
204
|
+
```
|
data/inspec.gemspec
CHANGED
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_dependency 'pry', '~> 0'
|
38
38
|
spec.add_dependency 'hashie', '~> 3.4'
|
39
39
|
spec.add_dependency 'mixlib-log'
|
40
|
-
spec.add_dependency 'sslshake', '~> 1.
|
40
|
+
spec.add_dependency 'sslshake', '~> 1.2'
|
41
41
|
spec.add_dependency 'parallel', '~> 1.9'
|
42
42
|
spec.add_dependency 'faraday', '>=0.9.0'
|
43
43
|
spec.add_dependency 'toml', '~> 0.1'
|
@@ -43,6 +43,7 @@ module Habitat
|
|
43
43
|
copy_profile_to_work_dir
|
44
44
|
create_plan
|
45
45
|
create_run_hook
|
46
|
+
create_settings_file
|
46
47
|
create_default_config
|
47
48
|
|
48
49
|
# returns the path to the .hart file in the work directory
|
@@ -152,6 +153,7 @@ module Habitat
|
|
152
153
|
@work_dir ||= Dir.mktmpdir('inspec-habitat-exporter')
|
153
154
|
Dir.mkdir(File.join(@work_dir, 'src'))
|
154
155
|
Dir.mkdir(File.join(@work_dir, 'habitat'))
|
156
|
+
Dir.mkdir(File.join(@work_dir, 'habitat', 'config'))
|
155
157
|
Dir.mkdir(File.join(@work_dir, 'habitat', 'hooks'))
|
156
158
|
Habitat::Log.debug("Generated work directory #{@work_dir}")
|
157
159
|
|
@@ -185,6 +187,12 @@ module Habitat
|
|
185
187
|
File.write(run_hook_file, run_hook_contents)
|
186
188
|
end
|
187
189
|
|
190
|
+
def create_settings_file
|
191
|
+
settings_file = File.join(work_dir, 'habitat', 'config', 'settings.sh')
|
192
|
+
Habitat::Log.info("Generating a settings file at #{settings_file}...")
|
193
|
+
File.write(settings_file, "SLEEP_TIME={{cfg.sleep_time}}\n")
|
194
|
+
end
|
195
|
+
|
188
196
|
def create_default_config
|
189
197
|
default_toml = File.join(work_dir, 'habitat', 'default.toml')
|
190
198
|
Habitat::Log.info("Generating Habitat's default.toml configuration...")
|
@@ -335,7 +343,6 @@ export PATH=${PATH}:$(hab pkg path core/ruby)/bin
|
|
335
343
|
export HOME={{pkg.svc_var_path}}
|
336
344
|
|
337
345
|
PROFILE_IDENT="#{habitat_origin}/#{package_name}"
|
338
|
-
SLEEP_TIME={{cfg.sleep_time}}
|
339
346
|
RESULTS_DIR="{{pkg.svc_var_path}}/inspec_results"
|
340
347
|
RESULTS_FILE="${RESULTS_DIR}/#{package_name}.json"
|
341
348
|
ERROR_FILE="{{pkg.svc_var_path}}/inspec.err"
|
@@ -350,11 +357,15 @@ while true; do
|
|
350
357
|
|
351
358
|
if [ "x${RC}" == "x0" ]; then
|
352
359
|
echo "InSpec run completed successfully."
|
353
|
-
|
354
|
-
echo "InSpec run did NOT complete successfully."
|
360
|
+
elsif [ -s ${ERROR_FILE} ]
|
361
|
+
echo "InSpec run did NOT complete successfully. Error:"
|
355
362
|
cat ${ERROR_FILE}
|
363
|
+
else
|
364
|
+
echo "InSpec run completed successfully, but there were control failures."
|
365
|
+
echo "Check the output at ${RESULTS_FILE} for details."
|
356
366
|
fi
|
357
367
|
|
368
|
+
source {{pkg.svc_config_path}}/settings.sh
|
358
369
|
echo "sleeping for ${SLEEP_TIME} seconds"
|
359
370
|
sleep ${SLEEP_TIME}
|
360
371
|
done
|
data/lib/inspec/objects/test.rb
CHANGED
@@ -66,13 +66,14 @@ module Inspec
|
|
66
66
|
res, xtra = describe_chain
|
67
67
|
itsy = xtra.nil? ? 'it' : 'its(' + xtra.to_s.inspect + ')'
|
68
68
|
naughty = @negated ? '_not' : ''
|
69
|
-
xpect = defined?(@expectation)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
69
|
+
xpect = if !defined?(@expectation)
|
70
|
+
''
|
71
|
+
elsif @expectation.class == Regexp
|
72
|
+
# without this, xpect values like / \/zones\// will not be parsed properly
|
73
|
+
"(#{@expectation.inspect})"
|
74
|
+
elsif xpect != ''
|
75
|
+
' ' + expectation.inspect
|
76
|
+
end
|
76
77
|
format("%sdescribe %s do\n %s { should%s %s%s }\nend",
|
77
78
|
vars, res, itsy, naughty, matcher, xpect)
|
78
79
|
end
|
data/lib/inspec/resource.rb
CHANGED
@@ -82,6 +82,9 @@ require 'resources/command'
|
|
82
82
|
require 'resources/crontab'
|
83
83
|
require 'resources/dh_params'
|
84
84
|
require 'resources/directory'
|
85
|
+
require 'resources/docker'
|
86
|
+
require 'resources/docker_image'
|
87
|
+
require 'resources/docker_container'
|
85
88
|
require 'resources/etc_group'
|
86
89
|
require 'resources/file'
|
87
90
|
require 'resources/gem'
|
data/lib/inspec/shell.rb
CHANGED
data/lib/inspec/version.rb
CHANGED
@@ -0,0 +1,159 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright 2017, Christoph Hartmann
|
4
|
+
#
|
5
|
+
# author: Christoph Hartmann
|
6
|
+
# author: Patrick Muench
|
7
|
+
# author: Dominik Richter
|
8
|
+
|
9
|
+
require 'utils/filter'
|
10
|
+
require 'hashie/mash'
|
11
|
+
|
12
|
+
module Inspec::Resources
|
13
|
+
class DockerContainerFilter
|
14
|
+
# use filtertable for containers
|
15
|
+
filter = FilterTable.create
|
16
|
+
filter.add_accessor(:where)
|
17
|
+
.add_accessor(:entries)
|
18
|
+
.add(:commands, field: 'command')
|
19
|
+
.add(:ids, field: 'id')
|
20
|
+
.add(:images, field: 'image')
|
21
|
+
.add(:labels, field: 'labels')
|
22
|
+
.add(:local_volumes, field: 'localvolumes')
|
23
|
+
.add(:mounts, field: 'mounts')
|
24
|
+
.add(:names, field: 'names')
|
25
|
+
.add(:networks, field: 'networks')
|
26
|
+
.add(:ports, field: 'ports')
|
27
|
+
.add(:running_for, field: 'runningfor')
|
28
|
+
.add(:sizes, field: 'size')
|
29
|
+
.add(:status, field: 'status')
|
30
|
+
.add(:exists?) { |x| !x.entries.empty? }
|
31
|
+
.add(:running?) { |x|
|
32
|
+
x.where { status.downcase.start_with?('up') }
|
33
|
+
}
|
34
|
+
filter.connect(self, :containers)
|
35
|
+
|
36
|
+
attr_reader :containers
|
37
|
+
def initialize(containers)
|
38
|
+
@containers = containers
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class DockerImageFilter
|
43
|
+
filter = FilterTable.create
|
44
|
+
filter.add_accessor(:where)
|
45
|
+
.add_accessor(:entries)
|
46
|
+
.add(:ids, field: 'id')
|
47
|
+
.add(:repositories, field: 'repository')
|
48
|
+
.add(:tags, field: 'tag')
|
49
|
+
.add(:sizes, field: 'size')
|
50
|
+
.add(:digests, field: 'digest')
|
51
|
+
.add(:created, field: 'createdat')
|
52
|
+
.add(:created_since, field: 'createdsize')
|
53
|
+
.add(:exists?) { |x| !x.entries.empty? }
|
54
|
+
filter.connect(self, :images)
|
55
|
+
|
56
|
+
attr_reader :images
|
57
|
+
def initialize(images)
|
58
|
+
@images = images
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# This resource helps to parse information from the docker host
|
63
|
+
# For compatability with Serverspec we also offer the following resouses:
|
64
|
+
# - docker_container
|
65
|
+
# - docker_image
|
66
|
+
class Docker < Inspec.resource(1)
|
67
|
+
name 'docker'
|
68
|
+
|
69
|
+
desc "
|
70
|
+
A resource to retrieve information about docker
|
71
|
+
"
|
72
|
+
|
73
|
+
example "
|
74
|
+
describe docker.containers do
|
75
|
+
its('images') { should_not include 'u12:latest' }
|
76
|
+
end
|
77
|
+
|
78
|
+
describe docker.images do
|
79
|
+
its('repositories') { should_not include 'inssecure_image' }
|
80
|
+
end
|
81
|
+
|
82
|
+
describe docker.version do
|
83
|
+
its('Server.Version') { should cmp >= '1.12'}
|
84
|
+
its('Client.Version') { should cmp >= '1.12'}
|
85
|
+
end
|
86
|
+
|
87
|
+
describe docker.object(id) do
|
88
|
+
its('Configuration.Path') { should eq 'value' }
|
89
|
+
end
|
90
|
+
|
91
|
+
docker.containers.ids.each do |id|
|
92
|
+
# call docker inspect for a specific container id
|
93
|
+
describe docker.object(id) do
|
94
|
+
its(%w(HostConfig Privileged)) { should cmp false }
|
95
|
+
its(%w(HostConfig Privileged)) { should_not cmp true }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
"
|
99
|
+
|
100
|
+
def containers
|
101
|
+
DockerContainerFilter.new(parse_containers)
|
102
|
+
end
|
103
|
+
|
104
|
+
def images
|
105
|
+
DockerImageFilter.new(parse_images)
|
106
|
+
end
|
107
|
+
|
108
|
+
def version
|
109
|
+
return @version if defined?(@version)
|
110
|
+
data = JSON.parse(inspec.command('docker version --format \'{{ json . }}\'').stdout)
|
111
|
+
@version = Hashie::Mash.new(data)
|
112
|
+
end
|
113
|
+
|
114
|
+
def info
|
115
|
+
return @info if defined?(@info)
|
116
|
+
data = JSON.parse(inspec.command('docker info --format \'{{ json . }}\'').stdout)
|
117
|
+
@info = Hashie::Mash.new(data)
|
118
|
+
end
|
119
|
+
|
120
|
+
# returns information about docker objects
|
121
|
+
def object(id)
|
122
|
+
return @inspect if defined?(@inspect)
|
123
|
+
data = JSON.parse(inspec.command("docker inspect #{id}").stdout)
|
124
|
+
data = data[0] if data.is_a?(Array)
|
125
|
+
@inspect = Hashie::Mash.new(data)
|
126
|
+
end
|
127
|
+
|
128
|
+
def to_s
|
129
|
+
'Docker Host'
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def parse_containers
|
135
|
+
raw_containers = inspec.command('docker ps -a --no-trunc --format \'{{ json . }}\'').stdout
|
136
|
+
ps = []
|
137
|
+
# since docker is not outputting valid json, we need to parse each row
|
138
|
+
raw_containers.each_line { |entry|
|
139
|
+
j = JSON.parse(entry)
|
140
|
+
# convert all keys to lower_case to work well with ruby and filter table
|
141
|
+
j = j.map { |k, v|
|
142
|
+
[k.downcase, v]
|
143
|
+
}.to_h
|
144
|
+
ps.push(j)
|
145
|
+
}
|
146
|
+
ps
|
147
|
+
end
|
148
|
+
|
149
|
+
def parse_images
|
150
|
+
# docker does not support the `json .` function here, therefore we need to emulate that behavior.
|
151
|
+
raw_images = inspec.command('docker images -a --no-trunc --format \'{ "id": {{json .ID}}, "repository": {{json .Repository}}, "tag": {{json .Tag}}, "size": {{json .Size}}, "digest": {{json .Digest}}, "createdat": {{json .CreatedAt}}, "createdsize": {{json .CreatedSince}} }\'').stdout
|
152
|
+
c_images = []
|
153
|
+
raw_images.each_line { |entry|
|
154
|
+
c_images.push(JSON.parse(entry))
|
155
|
+
}
|
156
|
+
c_images
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright 2017, Christoph Hartmann
|
4
|
+
#
|
5
|
+
# author: Christoph Hartmann
|
6
|
+
# author: Patrick Muench
|
7
|
+
# author: Dominik Richter
|
8
|
+
|
9
|
+
module Inspec::Resources
|
10
|
+
class DockerContainer < Inspec.resource(1)
|
11
|
+
name 'docker_container'
|
12
|
+
desc ''
|
13
|
+
example "
|
14
|
+
describe docker_container('an-echo-server') do
|
15
|
+
it { should exist }
|
16
|
+
it { should be_running }
|
17
|
+
its('id') { should_not eq '' }
|
18
|
+
its('image') { should eq 'busybox:latest' }
|
19
|
+
its('repo') { should eq 'busybox' }
|
20
|
+
its('tag') { should eq 'latest' }
|
21
|
+
its('ports') { should eq [] }
|
22
|
+
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe docker_container(id: 'e2c52a183358') do
|
26
|
+
it { should exist }
|
27
|
+
it { should be_running }
|
28
|
+
end
|
29
|
+
"
|
30
|
+
|
31
|
+
def initialize(opts = {})
|
32
|
+
# if a string is provided, we expect it is the name
|
33
|
+
if opts.is_a?(String)
|
34
|
+
@opts = { name: opts }
|
35
|
+
else
|
36
|
+
@opts = opts
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def exist?
|
41
|
+
container_info.exists?
|
42
|
+
end
|
43
|
+
|
44
|
+
# is allways returning the full id
|
45
|
+
def id
|
46
|
+
container_info.ids[0] if container_info.entries.length == 1
|
47
|
+
end
|
48
|
+
|
49
|
+
def running?
|
50
|
+
status.downcase.start_with?('up') if container_info.entries.length == 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def status
|
54
|
+
container_info.status[0] if container_info.entries.length == 1
|
55
|
+
end
|
56
|
+
|
57
|
+
def labels
|
58
|
+
container_info.labels[0] if container_info.entries.length == 1
|
59
|
+
end
|
60
|
+
|
61
|
+
def ports
|
62
|
+
container_info.ports[0] if container_info.entries.length == 1
|
63
|
+
end
|
64
|
+
|
65
|
+
def command
|
66
|
+
if container_info.entries.length == 1
|
67
|
+
cmd = container_info.commands[0]
|
68
|
+
cmd.slice(1, cmd.length - 2)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def image
|
73
|
+
container_info.images[0] if container_info.entries.length == 1
|
74
|
+
end
|
75
|
+
|
76
|
+
def repo
|
77
|
+
image.split(':')[0] unless image.nil?
|
78
|
+
end
|
79
|
+
|
80
|
+
def tag
|
81
|
+
image.split(':')[1] unless image.nil?
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_s
|
85
|
+
name = @opts[:name] || @opts[:id]
|
86
|
+
"Docker Container #{name}"
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def container_info
|
92
|
+
return @info if defined?(@info)
|
93
|
+
opts = @opts
|
94
|
+
@info = inspec.docker.containers.where { names == opts[:name] || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id]))) }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright 2017, Christoph Hartmann
|
4
|
+
#
|
5
|
+
# author: Christoph Hartmann
|
6
|
+
# author: Patrick Muench
|
7
|
+
# author: Dominik Richter
|
8
|
+
|
9
|
+
module Inspec::Resources
|
10
|
+
class DockerImage < Inspec.resource(1)
|
11
|
+
name 'docker_image'
|
12
|
+
desc ''
|
13
|
+
example "
|
14
|
+
describe docker_image('alpine:latest') do
|
15
|
+
it { should exist }
|
16
|
+
its('id') { should_not eq '' }
|
17
|
+
its('image') { should eq 'alpine:latest' }
|
18
|
+
its('repo') { should eq 'alpine' }
|
19
|
+
its('tag') { should eq 'latest' }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe docker_image('alpine:latest') do
|
23
|
+
it { should exist }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe docker_image(id: '4a415e366388') do
|
27
|
+
it { should exist }
|
28
|
+
end
|
29
|
+
"
|
30
|
+
|
31
|
+
def initialize(opts = {})
|
32
|
+
# do sanitizion of input values
|
33
|
+
o = opts.dup
|
34
|
+
o = { image: opts } if opts.is_a?(String)
|
35
|
+
@opts = sanitize_options(o)
|
36
|
+
end
|
37
|
+
|
38
|
+
def exist?
|
39
|
+
image_info.exists?
|
40
|
+
end
|
41
|
+
|
42
|
+
def id
|
43
|
+
image_info.ids[0] if image_info.entries.size == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
def image
|
47
|
+
"#{repo}:#{tag}" if image_info.entries.size == 1
|
48
|
+
end
|
49
|
+
|
50
|
+
def repo
|
51
|
+
image_info.repositories[0] if image_info.entries.size == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
def tag
|
55
|
+
image_info.tags[0] if image_info.entries.size == 1
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
img = @opts[:image] || @opts[:id]
|
60
|
+
"Docker Image #{img}"
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def sanitize_options(opts)
|
66
|
+
if !opts[:image].nil?
|
67
|
+
if !opts[:image].index(':').nil?
|
68
|
+
repo, tag = opts[:image].split(':')
|
69
|
+
else
|
70
|
+
opts[:repo] = opts[:image]
|
71
|
+
opts[:image] = nil
|
72
|
+
end
|
73
|
+
opts[:repo] ||= repo
|
74
|
+
opts[:tag] ||= tag
|
75
|
+
end
|
76
|
+
|
77
|
+
if !opts[:id].nil?
|
78
|
+
if opts[:id].index(':').nil?
|
79
|
+
opts[:id] = 'sha256:' + opts[:id]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
opts[:tag] ||= 'latest'
|
84
|
+
opts[:image] ||= "#{opts[:repo]}:#{opts[:tag]}" unless opts[:repo].nil?
|
85
|
+
opts
|
86
|
+
end
|
87
|
+
|
88
|
+
def image_info
|
89
|
+
return @info if defined?(@info)
|
90
|
+
opts = @opts
|
91
|
+
@info = inspec.docker.images.where {
|
92
|
+
(repository == opts[:repo] && tag == opts[:tag]) || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id])))
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/resources/http.rb
CHANGED
@@ -25,13 +25,14 @@ module Inspec::Resources
|
|
25
25
|
"
|
26
26
|
|
27
27
|
# rubocop:disable ParameterLists
|
28
|
-
def initialize(url, method: 'GET', params: nil, auth: {}, headers: {}, data: nil)
|
28
|
+
def initialize(url, method: 'GET', params: nil, auth: {}, headers: {}, data: nil, ssl_verify: true)
|
29
29
|
@url = url
|
30
30
|
@method = method
|
31
31
|
@params = params
|
32
32
|
@auth = auth
|
33
33
|
@headers = headers
|
34
34
|
@data = data
|
35
|
+
@ssl_verify = ssl_verify
|
35
36
|
end
|
36
37
|
|
37
38
|
def status
|
@@ -53,7 +54,7 @@ module Inspec::Resources
|
|
53
54
|
private
|
54
55
|
|
55
56
|
def response
|
56
|
-
conn = Faraday.new url: @url, headers: @headers, params: @params
|
57
|
+
conn = Faraday.new url: @url, headers: @headers, params: @params, ssl: { verify: @ssl_verify }
|
57
58
|
|
58
59
|
# set basic authentication
|
59
60
|
conn.basic_auth @auth[:user], @auth[:pass] unless @auth.empty?
|
data/lib/resources/powershell.rb
CHANGED
@@ -10,7 +10,7 @@ module Inspec::Resources
|
|
10
10
|
desc 'Use the powershell InSpec audit resource to test a Windows PowerShell script on the Microsoft Windows platform.'
|
11
11
|
example "
|
12
12
|
script = <<-EOH
|
13
|
-
#
|
13
|
+
# your powershell script
|
14
14
|
EOH
|
15
15
|
|
16
16
|
describe powershell(script) do
|
data/lib/resources/ssh_conf.rb
CHANGED
@@ -9,10 +9,12 @@ require 'utils/simpleconfig'
|
|
9
9
|
module Inspec::Resources
|
10
10
|
class SshConf < Inspec.resource(1)
|
11
11
|
name 'ssh_config'
|
12
|
-
desc 'Use the
|
12
|
+
desc 'Use the `ssh_config` InSpec audit resource to test OpenSSH client configuration data located at `/etc/ssh/ssh_config` on Linux and Unix platforms.'
|
13
13
|
example "
|
14
|
-
describe
|
15
|
-
its('
|
14
|
+
describe ssh_config do
|
15
|
+
its('cipher') { should contain '3des' }
|
16
|
+
its('port') { should eq '22' }
|
17
|
+
its('hostname') { should include('example.com') }
|
16
18
|
end
|
17
19
|
"
|
18
20
|
|
@@ -83,9 +85,19 @@ module Inspec::Resources
|
|
83
85
|
|
84
86
|
class SshdConf < SshConf
|
85
87
|
name 'sshd_config'
|
88
|
+
desc 'Use the sshd_config InSpec audit resource to test configuration data for the Open SSH daemon located at /etc/ssh/sshd_config on Linux and UNIX platforms. sshd---the Open SSH daemon---listens on dedicated ports, starts a daemon for each incoming connection, and then handles encryption, authentication, key exchanges, command execution, and data exchanges.'
|
89
|
+
example "
|
90
|
+
describe sshd_config do
|
91
|
+
its('Protocol') { should eq '2' }
|
92
|
+
end
|
93
|
+
"
|
86
94
|
|
87
95
|
def initialize(path = nil)
|
88
96
|
super(path || '/etc/ssh/sshd_config')
|
89
97
|
end
|
98
|
+
|
99
|
+
def to_s
|
100
|
+
'SSHD Configuration'
|
101
|
+
end
|
90
102
|
end
|
91
103
|
end
|
data/lib/resources/users.rb
CHANGED
@@ -576,42 +576,42 @@ module Inspec::Resources
|
|
576
576
|
def collect_user_details # rubocop:disable Metrics/MethodLength
|
577
577
|
return @users_cache if defined?(@users_cache)
|
578
578
|
script = <<-EOH
|
579
|
-
Function
|
580
|
-
(New-Object
|
579
|
+
Function ConvertTo-SID { Param([byte[]]$BinarySID)
|
580
|
+
(New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value
|
581
581
|
}
|
582
582
|
|
583
|
-
Function
|
584
|
-
$List
|
585
|
-
Switch
|
586
|
-
($UserFlag
|
587
|
-
($UserFlag
|
588
|
-
($UserFlag
|
589
|
-
($UserFlag
|
590
|
-
($UserFlag
|
591
|
-
($UserFlag
|
592
|
-
($UserFlag
|
593
|
-
($UserFlag
|
594
|
-
($UserFlag
|
595
|
-
($UserFlag
|
596
|
-
($UserFlag
|
597
|
-
($UserFlag
|
598
|
-
($UserFlag
|
599
|
-
($UserFlag
|
600
|
-
($UserFlag
|
601
|
-
($UserFlag
|
602
|
-
($UserFlag
|
603
|
-
($UserFlag
|
604
|
-
($UserFlag
|
605
|
-
($UserFlag
|
606
|
-
($UserFlag
|
607
|
-
($UserFlag
|
583
|
+
Function Convert-UserFlag { Param ($UserFlag)
|
584
|
+
$List = @()
|
585
|
+
Switch ($UserFlag) {
|
586
|
+
($UserFlag -BOR 0x0001) { $List += 'SCRIPT' }
|
587
|
+
($UserFlag -BOR 0x0002) { $List += 'ACCOUNTDISABLE' }
|
588
|
+
($UserFlag -BOR 0x0008) { $List += 'HOMEDIR_REQUIRED' }
|
589
|
+
($UserFlag -BOR 0x0010) { $List += 'LOCKOUT' }
|
590
|
+
($UserFlag -BOR 0x0020) { $List += 'PASSWD_NOTREQD' }
|
591
|
+
($UserFlag -BOR 0x0040) { $List += 'PASSWD_CANT_CHANGE' }
|
592
|
+
($UserFlag -BOR 0x0080) { $List += 'ENCRYPTED_TEXT_PWD_ALLOWED' }
|
593
|
+
($UserFlag -BOR 0x0100) { $List += 'TEMP_DUPLICATE_ACCOUNT' }
|
594
|
+
($UserFlag -BOR 0x0200) { $List += 'NORMAL_ACCOUNT' }
|
595
|
+
($UserFlag -BOR 0x0800) { $List += 'INTERDOMAIN_TRUST_ACCOUNT' }
|
596
|
+
($UserFlag -BOR 0x1000) { $List += 'WORKSTATION_TRUST_ACCOUNT' }
|
597
|
+
($UserFlag -BOR 0x2000) { $List += 'SERVER_TRUST_ACCOUNT' }
|
598
|
+
($UserFlag -BOR 0x10000) { $List += 'DONT_EXPIRE_PASSWORD' }
|
599
|
+
($UserFlag -BOR 0x20000) { $List += 'MNS_LOGON_ACCOUNT' }
|
600
|
+
($UserFlag -BOR 0x40000) { $List += 'SMARTCARD_REQUIRED' }
|
601
|
+
($UserFlag -BOR 0x80000) { $List += 'TRUSTED_FOR_DELEGATION' }
|
602
|
+
($UserFlag -BOR 0x100000) { $List += 'NOT_DELEGATED' }
|
603
|
+
($UserFlag -BOR 0x200000) { $List += 'USE_DES_KEY_ONLY' }
|
604
|
+
($UserFlag -BOR 0x400000) { $List += 'DONT_REQ_PREAUTH' }
|
605
|
+
($UserFlag -BOR 0x800000) { $List += 'PASSWORD_EXPIRED' }
|
606
|
+
($UserFlag -BOR 0x1000000) { $List += 'TRUSTED_TO_AUTH_FOR_DELEGATION' }
|
607
|
+
($UserFlag -BOR 0x04000000) { $List += 'PARTIAL_SECRETS_ACCOUNT' }
|
608
608
|
}
|
609
609
|
$List
|
610
610
|
}
|
611
611
|
|
612
|
-
$Computername =
|
613
|
-
$adsi
|
614
|
-
$adsi.Children | where {$_.SchemaClassName -eq
|
612
|
+
$Computername = $Env:Computername
|
613
|
+
$adsi = [ADSI]"WinNT://$Computername"
|
614
|
+
$adsi.Children | where {$_.SchemaClassName -eq 'user'} | ForEach {
|
615
615
|
New-Object PSObject -property @{
|
616
616
|
uid = ConvertTo-SID -BinarySID $_.ObjectSID[0]
|
617
617
|
username = $_.Name[0]
|
@@ -627,7 +627,7 @@ $adsi.Children | where {$_.SchemaClassName -eq 'user'} | ForEach {
|
|
627
627
|
maxbadpasswords = $_.MaxBadPasswordsAllowed[0]
|
628
628
|
gid = $null
|
629
629
|
group = $null
|
630
|
-
groups = $null
|
630
|
+
groups = @($_.Groups() | Foreach-Object { $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null) })
|
631
631
|
home = $_.HomeDirectory[0]
|
632
632
|
shell = $null
|
633
633
|
domain = $Computername
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: train
|
@@ -182,14 +182,14 @@ dependencies:
|
|
182
182
|
requirements:
|
183
183
|
- - "~>"
|
184
184
|
- !ruby/object:Gem::Version
|
185
|
-
version: '1.
|
185
|
+
version: '1.2'
|
186
186
|
type: :runtime
|
187
187
|
prerelease: false
|
188
188
|
version_requirements: !ruby/object:Gem::Requirement
|
189
189
|
requirements:
|
190
190
|
- - "~>"
|
191
191
|
- !ruby/object:Gem::Version
|
192
|
-
version: '1.
|
192
|
+
version: '1.2'
|
193
193
|
- !ruby/object:Gem::Dependency
|
194
194
|
name: parallel
|
195
195
|
requirement: !ruby/object:Gem::Requirement
|
@@ -291,7 +291,6 @@ files:
|
|
291
291
|
- docs/migration.md
|
292
292
|
- docs/plugin_kitchen_inspec.html.md
|
293
293
|
- docs/profiles.md
|
294
|
-
- docs/resources.md
|
295
294
|
- docs/resources/apache_conf.md.erb
|
296
295
|
- docs/resources/apt.md.erb
|
297
296
|
- docs/resources/audit_policy.md.erb
|
@@ -306,6 +305,9 @@ files:
|
|
306
305
|
- docs/resources/csv.md.erb
|
307
306
|
- docs/resources/dh_params.md
|
308
307
|
- docs/resources/directory.md.erb
|
308
|
+
- docs/resources/docker.md.erb
|
309
|
+
- docs/resources/docker_container.md.erb
|
310
|
+
- docs/resources/docker_image.md.erb
|
309
311
|
- docs/resources/etc_group.md.erb
|
310
312
|
- docs/resources/etc_passwd.md.erb
|
311
313
|
- docs/resources/etc_shadow.md.erb
|
@@ -323,7 +325,7 @@ files:
|
|
323
325
|
- docs/resources/json.md.erb
|
324
326
|
- docs/resources/kernel_module.md.erb
|
325
327
|
- docs/resources/kernel_parameter.md.erb
|
326
|
-
- docs/resources/key_rsa.md
|
328
|
+
- docs/resources/key_rsa.md.erb
|
327
329
|
- docs/resources/launchd_service.md.erb
|
328
330
|
- docs/resources/limits_conf.md.erb
|
329
331
|
- docs/resources/login_def.md.erb
|
@@ -362,7 +364,7 @@ files:
|
|
362
364
|
- docs/resources/windows_feature.md.erb
|
363
365
|
- docs/resources/windows_task.md.erb
|
364
366
|
- docs/resources/wmi.md.erb
|
365
|
-
- docs/resources/x509_certificate.md
|
367
|
+
- docs/resources/x509_certificate.md.erb
|
366
368
|
- docs/resources/xinetd_conf.md.erb
|
367
369
|
- docs/resources/yaml.md.erb
|
368
370
|
- docs/resources/yum.md.erb
|
@@ -378,7 +380,6 @@ files:
|
|
378
380
|
- examples/README.md
|
379
381
|
- examples/inheritance/README.md
|
380
382
|
- examples/inheritance/controls/example.rb
|
381
|
-
- examples/inheritance/inspec.lock
|
382
383
|
- examples/inheritance/inspec.yml
|
383
384
|
- examples/kitchen-ansible/.kitchen.yml
|
384
385
|
- examples/kitchen-ansible/Gemfile
|
@@ -404,11 +405,7 @@ files:
|
|
404
405
|
- examples/kitchen-puppet/test/integration/default/web_spec.rb
|
405
406
|
- examples/meta-profile/README.md
|
406
407
|
- examples/meta-profile/controls/example.rb
|
407
|
-
- examples/meta-profile/inspec.lock
|
408
408
|
- examples/meta-profile/inspec.yml
|
409
|
-
- examples/meta-profile/vendor/11b6287b232c2a689ae87b3ba54897eb9067a749da074b6f3040b6442082dd6a.tar.gz
|
410
|
-
- examples/meta-profile/vendor/379757a6ba73c9bc17b37353c1ff5b4eb7dd978a3bd38b29d2dda64f90f16c36.tar.gz
|
411
|
-
- examples/meta-profile/vendor/dbb5602f09f58d86f8743dfb44327207e9a23a49ef34f65614f1c1d8cc145f6b.tar.gz
|
412
409
|
- examples/profile-attribute.yml
|
413
410
|
- examples/profile-attribute/README.md
|
414
411
|
- examples/profile-attribute/controls/example.rb
|
@@ -531,6 +528,9 @@ files:
|
|
531
528
|
- lib/resources/csv.rb
|
532
529
|
- lib/resources/dh_params.rb
|
533
530
|
- lib/resources/directory.rb
|
531
|
+
- lib/resources/docker.rb
|
532
|
+
- lib/resources/docker_container.rb
|
533
|
+
- lib/resources/docker_image.rb
|
534
534
|
- lib/resources/etc_group.rb
|
535
535
|
- lib/resources/file.rb
|
536
536
|
- lib/resources/gem.rb
|
@@ -625,7 +625,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
625
625
|
version: '0'
|
626
626
|
requirements: []
|
627
627
|
rubyforge_project:
|
628
|
-
rubygems_version: 2.
|
628
|
+
rubygems_version: 2.6.11
|
629
629
|
signing_key:
|
630
630
|
specification_version: 4
|
631
631
|
summary: Infrastructure and compliance testing.
|
@@ -1,11 +0,0 @@
|
|
1
|
-
---
|
2
|
-
lockfile_version: 1
|
3
|
-
depends:
|
4
|
-
- name: profile
|
5
|
-
resolved_source:
|
6
|
-
path: "/Users/aleff/projects/inspec/examples/profile"
|
7
|
-
version_constraints: ">= 0"
|
8
|
-
- name: profile-attribute
|
9
|
-
resolved_source:
|
10
|
-
path: "/Users/aleff/projects/inspec/examples/profile-attribute"
|
11
|
-
version_constraints: ">= 0"
|
@@ -1,18 +0,0 @@
|
|
1
|
-
---
|
2
|
-
lockfile_version: 1
|
3
|
-
depends:
|
4
|
-
- name: dev-sec/ssh-baseline
|
5
|
-
resolved_source:
|
6
|
-
url: https://github.com/dev-sec/ssh-baseline/archive/master.tar.gz
|
7
|
-
sha256: 379757a6ba73c9bc17b37353c1ff5b4eb7dd978a3bd38b29d2dda64f90f16c36
|
8
|
-
version_constraints: ">= 0"
|
9
|
-
- name: ssl-benchmark
|
10
|
-
resolved_source:
|
11
|
-
url: https://github.com/dev-sec/ssl-benchmark/archive/master.tar.gz
|
12
|
-
sha256: 11b6287b232c2a689ae87b3ba54897eb9067a749da074b6f3040b6442082dd6a
|
13
|
-
version_constraints: ">= 0"
|
14
|
-
- name: windows-patch-benchmark
|
15
|
-
resolved_source:
|
16
|
-
url: https://github.com/chris-rock/windows-patch-benchmark/archive/master.tar.gz
|
17
|
-
sha256: dbb5602f09f58d86f8743dfb44327207e9a23a49ef34f65614f1c1d8cc145f6b
|
18
|
-
version_constraints: ">= 0"
|
Binary file
|
Binary file
|