inspec 0.14.8 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -2
- data/bin/inspec +3 -4
- data/examples/inheritance/README.md +19 -0
- data/examples/inheritance/controls/example.rb +11 -0
- data/examples/inheritance/inspec.yml +10 -0
- data/lib/bundles/inspec-compliance/cli.rb +1 -4
- data/lib/bundles/inspec-supermarket/cli.rb +1 -4
- data/lib/inspec/dsl.rb +48 -55
- data/lib/inspec/profile.rb +6 -2
- data/lib/inspec/profile_context.rb +21 -8
- data/lib/inspec/runner.rb +17 -12
- data/lib/inspec/runner_rspec.rb +1 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/apache.rb +20 -18
- data/lib/resources/apache_conf.rb +92 -90
- data/lib/resources/apt.rb +92 -90
- data/lib/resources/audit_policy.rb +35 -33
- data/lib/resources/auditd_conf.rb +41 -39
- data/lib/resources/auditd_rules.rb +155 -153
- data/lib/resources/bond.rb +1 -1
- data/lib/resources/bridge.rb +97 -95
- data/lib/resources/command.rb +47 -45
- data/lib/resources/csv.rb +23 -21
- data/lib/resources/directory.rb +1 -1
- data/lib/resources/etc_group.rb +116 -114
- data/lib/resources/file.rb +1 -1
- data/lib/resources/gem.rb +39 -37
- data/lib/resources/group.rb +100 -98
- data/lib/resources/host.rb +103 -101
- data/lib/resources/inetd_conf.rb +42 -40
- data/lib/resources/ini.rb +15 -13
- data/lib/resources/interface.rb +106 -104
- data/lib/resources/iptables.rb +36 -34
- data/lib/resources/json.rb +64 -62
- data/lib/resources/kernel_module.rb +30 -28
- data/lib/resources/kernel_parameter.rb +44 -42
- data/lib/resources/limits_conf.rb +41 -39
- data/lib/resources/login_def.rb +38 -36
- data/lib/resources/mount.rb +43 -41
- data/lib/resources/mysql.rb +67 -65
- data/lib/resources/mysql_conf.rb +89 -87
- data/lib/resources/mysql_session.rb +46 -44
- data/lib/resources/npm.rb +35 -33
- data/lib/resources/ntp_conf.rb +44 -42
- data/lib/resources/oneget.rb +46 -44
- data/lib/resources/os.rb +22 -20
- data/lib/resources/os_env.rb +47 -45
- data/lib/resources/package.rb +213 -211
- data/lib/resources/parse_config.rb +59 -57
- data/lib/resources/passwd.rb +89 -87
- data/lib/resources/pip.rb +60 -58
- data/lib/resources/port.rb +352 -350
- data/lib/resources/postgres.rb +26 -24
- data/lib/resources/postgres_conf.rb +66 -64
- data/lib/resources/postgres_session.rb +47 -45
- data/lib/resources/processes.rb +56 -54
- data/lib/resources/registry_key.rb +150 -148
- data/lib/resources/script.rb +30 -28
- data/lib/resources/security_policy.rb +56 -54
- data/lib/resources/service.rb +638 -636
- data/lib/resources/shadow.rb +98 -96
- data/lib/resources/ssh_conf.rb +58 -56
- data/lib/resources/user.rb +363 -361
- data/lib/resources/windows_feature.rb +46 -44
- data/lib/resources/xinetd.rb +111 -109
- data/lib/resources/yaml.rb +16 -14
- data/lib/resources/yum.rb +107 -105
- data/lib/utils/base_cli.rb +18 -0
- data/test/helper.rb +2 -2
- data/test/unit/profile_context_test.rb +1 -1
- data/test/unit/resources/file_test.rb +1 -1
- data/test/unit/resources/mount_test.rb +1 -1
- metadata +5 -2
data/lib/inspec/runner_rspec.rb
CHANGED
data/lib/inspec/version.rb
CHANGED
data/lib/resources/apache.rb
CHANGED
@@ -4,26 +4,28 @@
|
|
4
4
|
# author: Dominik Richter
|
5
5
|
# license: All rights reserved
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Inspec::Resources
|
8
|
+
class Apache < Inspec.resource(1)
|
9
|
+
name 'apache'
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
11
|
+
attr_reader :service, :conf_dir, :conf_path, :user
|
12
|
+
def initialize
|
13
|
+
case inspec.os[:family]
|
14
|
+
when 'ubuntu', 'debian'
|
15
|
+
@service = 'apache2'
|
16
|
+
@conf_dir = '/etc/apache2/'
|
17
|
+
@conf_path = File.join @conf_dir, 'apache2.conf'
|
18
|
+
@user = 'www-data'
|
19
|
+
else
|
20
|
+
@service = 'httpd'
|
21
|
+
@conf_dir = '/etc/httpd/'
|
22
|
+
@conf_path = File.join @conf_dir, '/conf/httpd.conf'
|
23
|
+
@user = 'apache'
|
24
|
+
end
|
23
25
|
end
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
-
|
27
|
+
def to_s
|
28
|
+
'Apache Environment'
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|
@@ -7,118 +7,120 @@
|
|
7
7
|
require 'utils/simpleconfig'
|
8
8
|
require 'utils/find_files'
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
module Inspec::Resources
|
11
|
+
class ApacheConf < Inspec.resource(1)
|
12
|
+
name 'apache_conf'
|
13
|
+
desc 'Use the apache_conf InSpec audit resource to test the configuration settings for Apache. This file is typically located under /etc/apache2 on the Debian and Ubuntu platforms and under /etc/httpd on the Fedora, CentOS, Red Hat Enterprise Linux, and Arch Linux platforms. The configuration settings may vary significantly from platform to platform.'
|
14
|
+
example "
|
15
|
+
describe apache_conf do
|
16
|
+
its('setting_name') { should eq 'value' }
|
17
|
+
end
|
18
|
+
"
|
18
19
|
|
19
|
-
|
20
|
+
include FindFiles
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
def initialize(conf_path = nil)
|
23
|
+
@conf_path = conf_path || inspec.apache.conf_path
|
24
|
+
@conf_dir = File.dirname(@conf_path)
|
25
|
+
@files_contents = {}
|
26
|
+
@content = nil
|
27
|
+
@params = nil
|
28
|
+
read_content
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def content
|
32
|
+
@content ||= read_content
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
def params(*opts)
|
36
|
+
@params || read_content
|
37
|
+
res = @params
|
38
|
+
opts.each do |opt|
|
39
|
+
res = res[opt] unless res.nil?
|
40
|
+
end
|
41
|
+
res
|
39
42
|
end
|
40
|
-
res
|
41
|
-
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
def method_missing(name)
|
45
|
+
# ensure params are loaded
|
46
|
+
@params || read_content
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
# extract values
|
49
|
+
@params[name.to_s] unless @params.nil?
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
def filter_comments(data)
|
53
|
+
content = ''
|
54
|
+
data.each_line do |line|
|
55
|
+
if !line.match(/^\s*#/)
|
56
|
+
content << line
|
57
|
+
end
|
56
58
|
end
|
59
|
+
content
|
57
60
|
end
|
58
|
-
content
|
59
|
-
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
def read_content
|
63
|
+
@content = ''
|
64
|
+
@params = {}
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
# skip if the main configuration file doesn't exist
|
67
|
+
file = inspec.file(@conf_path)
|
68
|
+
if !file.file?
|
69
|
+
return skip_resource "Can't find file \"#{@conf_path}\""
|
70
|
+
end
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
raw_conf = file.content
|
73
|
+
if raw_conf.empty? && file.size > 0
|
74
|
+
return skip_resource("Can't read file \"#{@conf_path}\"")
|
75
|
+
end
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
77
|
+
to_read = [@conf_path]
|
78
|
+
until to_read.empty?
|
79
|
+
raw_conf = read_file(to_read[0])
|
80
|
+
@content += raw_conf
|
81
|
+
|
82
|
+
# parse include file parameters
|
83
|
+
params = SimpleConfig.new(
|
84
|
+
raw_conf,
|
85
|
+
assignment_re: /^\s*(\S+)\s+(.*)\s*$/,
|
86
|
+
multiple_values: true,
|
87
|
+
).params
|
88
|
+
@params.merge!(params)
|
89
|
+
|
90
|
+
to_read = to_read.drop(1)
|
91
|
+
to_read += include_files(params).find_all do |fp|
|
92
|
+
not @files_contents.key? fp
|
93
|
+
end
|
92
94
|
end
|
95
|
+
|
96
|
+
# fiter comments
|
97
|
+
@content = filter_comments @content
|
98
|
+
@content
|
93
99
|
end
|
94
100
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
101
|
+
def include_files(params)
|
102
|
+
# see if there is more config files to include
|
103
|
+
include_files = params['Include'] || []
|
104
|
+
include_files_optional = params['IncludeOptional'] || []
|
99
105
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
106
|
+
includes = []
|
107
|
+
(include_files + include_files_optional).each do |f|
|
108
|
+
id = File.join(@conf_dir, f)
|
109
|
+
files = find_files(id, depth: 1, type: 'file')
|
104
110
|
|
105
|
-
|
106
|
-
|
107
|
-
id = File.join(@conf_dir, f)
|
108
|
-
files = find_files(id, depth: 1, type: 'file')
|
111
|
+
includes.push(files) if files
|
112
|
+
end
|
109
113
|
|
110
|
-
|
114
|
+
# [].flatten! == nil
|
115
|
+
includes.flatten! || []
|
111
116
|
end
|
112
117
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
def read_file(path)
|
118
|
-
@files_contents[path] ||= inspec.file(path).content
|
119
|
-
end
|
118
|
+
def read_file(path)
|
119
|
+
@files_contents[path] ||= inspec.file(path).content
|
120
|
+
end
|
120
121
|
|
121
|
-
|
122
|
-
|
122
|
+
def to_s
|
123
|
+
"Apache Config #{@conf_path}"
|
124
|
+
end
|
123
125
|
end
|
124
126
|
end
|
data/lib/resources/apt.rb
CHANGED
@@ -28,120 +28,122 @@
|
|
28
28
|
|
29
29
|
require 'uri'
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
module Inspec::Resources
|
32
|
+
class AptRepository < Inspec.resource(1)
|
33
|
+
name 'apt'
|
34
|
+
desc 'Use the apt InSpec audit resource to verify Apt repositories on the Debian and Ubuntu platforms, and also PPA repositories on the Ubuntu platform.'
|
35
|
+
example "
|
36
|
+
describe apt('nginx/stable') do
|
37
|
+
it { should exist }
|
38
|
+
it { should be_enabled }
|
39
|
+
end
|
40
|
+
"
|
41
|
+
|
42
|
+
def initialize(ppa_name)
|
43
|
+
@deb_url = nil
|
44
|
+
# check if the os is ubuntu or debian
|
45
|
+
if inspec.os.debian?
|
46
|
+
@deb_url = determine_ppa_url(ppa_name)
|
47
|
+
else
|
48
|
+
# this resource is only supported on ubuntu and debian
|
49
|
+
skip_resource 'The `apt` resource is not supported on your OS yet.'
|
50
|
+
end
|
38
51
|
end
|
39
|
-
"
|
40
|
-
|
41
|
-
def initialize(ppa_name)
|
42
|
-
@deb_url = nil
|
43
|
-
# check if the os is ubuntu or debian
|
44
|
-
if inspec.os.debian?
|
45
|
-
@deb_url = determine_ppa_url(ppa_name)
|
46
|
-
else
|
47
|
-
# this resource is only supported on ubuntu and debian
|
48
|
-
skip_resource 'The `apt` resource is not supported on your OS yet.'
|
49
|
-
end
|
50
|
-
end
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
def exists?
|
54
|
+
find_repo.count > 0
|
55
|
+
end
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
def enabled?
|
58
|
+
return false if find_repo.count == 0
|
59
|
+
actives = find_repo.map { |repo| repo[:active] }
|
60
|
+
actives = actives.uniq
|
61
|
+
actives.size == 1 && actives[0] = true
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
def to_s
|
65
|
+
"Apt Repository #{@deb_url}"
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
+
private
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
def find_repo
|
71
|
+
read_debs.select { |repo| repo[:url] == @deb_url && repo[:type] == 'deb' }
|
72
|
+
end
|
72
73
|
|
73
|
-
|
74
|
+
HTTP_URL_RE = /\A#{URI::DEFAULT_PARSER.make_regexp(%w{http https})}\z/
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
76
|
+
# read
|
77
|
+
def read_debs
|
78
|
+
return @repo_cache if defined?(@repo_cache)
|
78
79
|
|
79
|
-
|
80
|
-
|
80
|
+
# load all lists
|
81
|
+
cmd = inspec.command("find /etc/apt/ -name \*.list -exec sh -c 'cat {} || echo -n' \\;")
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
# @see https://help.ubuntu.com/community/Repositories/CommandLine#Explanation_of_the_Repository_Format
|
84
|
+
@repo_cache = cmd.stdout.chomp.split("\n").each_with_object([]) do |raw_line, lines|
|
85
|
+
active = true
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
# detect if the repo is commented out
|
88
|
+
line = raw_line.gsub(/^(#\s*)*/, '')
|
89
|
+
active = false if raw_line != line
|
89
90
|
|
90
|
-
|
91
|
-
|
91
|
+
# eg.: deb http://archive.ubuntu.com/ubuntu/ wily main restricted
|
92
|
+
parse_repo = /^\s*(\S+)\s+"?([^ "\t\r\n\f]+)"?\s+(\S+)\s+(.*)$/.match(line)
|
92
93
|
|
93
|
-
|
94
|
-
|
94
|
+
# check if we got any result and the second param is an url
|
95
|
+
next if parse_repo.nil? || !parse_repo[2] =~ HTTP_URL_RE
|
95
96
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
97
|
+
# map data
|
98
|
+
repo = {
|
99
|
+
type: parse_repo[1],
|
100
|
+
url: parse_repo[2],
|
101
|
+
distro: parse_repo[3],
|
102
|
+
components: parse_repo[4].chomp.split(' '),
|
103
|
+
active: active,
|
104
|
+
}
|
105
|
+
next unless ['deb', 'deb-src'].include? repo[:type]
|
105
106
|
|
106
|
-
|
107
|
+
lines.push(repo)
|
108
|
+
end
|
107
109
|
end
|
108
|
-
end
|
109
110
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
111
|
+
# resolves ppa urls
|
112
|
+
# @see http://bazaar.launchpad.net/~ubuntu-core-dev/software-properties/main/view/head:/softwareproperties/ppa.py
|
113
|
+
def determine_ppa_url(ppa_url)
|
114
|
+
# verify if we have the url already, then just return
|
115
|
+
return ppa_url if ppa_url =~ HTTP_URL_RE
|
116
|
+
# otherwise start generating the ppa url
|
116
117
|
|
117
|
-
|
118
|
-
|
118
|
+
# special care if the name stats with :
|
119
|
+
ppa_url = ppa_url.split(':')[1] if ppa_url.start_with?('ppa:')
|
119
120
|
|
120
|
-
|
121
|
-
|
122
|
-
|
121
|
+
# parse ppa owner and repo
|
122
|
+
ppa_owner, ppa_repo = ppa_url.split('/')
|
123
|
+
ppa_repo = 'ppa' if ppa_repo.nil?
|
123
124
|
|
124
|
-
|
125
|
-
|
125
|
+
# construct new ppa url and return it
|
126
|
+
format('http://ppa.launchpad.net/%s/%s/ubuntu', ppa_owner, ppa_repo)
|
127
|
+
end
|
126
128
|
end
|
127
|
-
end
|
128
129
|
|
129
|
-
# for compatability with serverspec
|
130
|
-
# this is deprecated syntax and will be removed in future versions
|
131
|
-
class PpaRepository < AptRepository
|
132
|
-
|
130
|
+
# for compatability with serverspec
|
131
|
+
# this is deprecated syntax and will be removed in future versions
|
132
|
+
class PpaRepository < AptRepository
|
133
|
+
name 'ppa'
|
133
134
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
135
|
+
def exists?
|
136
|
+
deprecated
|
137
|
+
super()
|
138
|
+
end
|
138
139
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
140
|
+
def enabled?
|
141
|
+
deprecated
|
142
|
+
super()
|
143
|
+
end
|
143
144
|
|
144
|
-
|
145
|
-
|
145
|
+
def deprecated
|
146
|
+
warn '[DEPRECATION] `ppa(reponame)` is deprecated. Please use `apt(reponame)` instead.'
|
147
|
+
end
|
146
148
|
end
|
147
149
|
end
|