inspec 0.9.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 +7 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +65 -0
- data/.travis.yml +23 -0
- data/CHANGELOG.md +38 -0
- data/Gemfile +33 -0
- data/LICENSE +201 -0
- data/MAINTAINERS.md +28 -0
- data/MAINTAINERS.toml +42 -0
- data/README.md +257 -0
- data/Rakefile +47 -0
- data/bin/inspec +109 -0
- data/docs/ctl_inspec.rst +195 -0
- data/docs/dsl_inspec.rst +182 -0
- data/docs/readme.rst +100 -0
- data/docs/resources.rst +4319 -0
- data/docs/template.rst +51 -0
- data/examples/test-kitchen/.kitchen.yml +20 -0
- data/examples/test-kitchen/Berksfile +3 -0
- data/examples/test-kitchen/Gemfile +21 -0
- data/examples/test-kitchen/README.md +27 -0
- data/examples/test-kitchen/metadata.rb +7 -0
- data/examples/test-kitchen/recipes/default.rb +6 -0
- data/examples/test-kitchen/recipes/nginx.rb +30 -0
- data/examples/test-kitchen/test/integration/default/web_spec.rb +28 -0
- data/inspec.gemspec +30 -0
- data/lib/inspec.rb +20 -0
- data/lib/inspec/backend.rb +42 -0
- data/lib/inspec/dsl.rb +151 -0
- data/lib/inspec/log.rb +34 -0
- data/lib/inspec/metadata.rb +79 -0
- data/lib/inspec/plugins.rb +9 -0
- data/lib/inspec/plugins/resource.rb +62 -0
- data/lib/inspec/profile.rb +138 -0
- data/lib/inspec/profile_context.rb +170 -0
- data/lib/inspec/resource.rb +76 -0
- data/lib/inspec/rspec_json_formatter.rb +27 -0
- data/lib/inspec/rule.rb +170 -0
- data/lib/inspec/runner.rb +154 -0
- data/lib/inspec/shell.rb +66 -0
- data/lib/inspec/targets.rb +9 -0
- data/lib/inspec/targets/core.rb +27 -0
- data/lib/inspec/targets/dir.rb +67 -0
- data/lib/inspec/targets/file.rb +29 -0
- data/lib/inspec/targets/folder.rb +43 -0
- data/lib/inspec/targets/tar.rb +34 -0
- data/lib/inspec/targets/url.rb +39 -0
- data/lib/inspec/targets/zip.rb +47 -0
- data/lib/inspec/version.rb +7 -0
- data/lib/matchers/matchers.rb +221 -0
- data/lib/resources/apache.rb +29 -0
- data/lib/resources/apache_conf.rb +113 -0
- data/lib/resources/apt.rb +140 -0
- data/lib/resources/audit_policy.rb +63 -0
- data/lib/resources/auditd_conf.rb +56 -0
- data/lib/resources/auditd_rules.rb +53 -0
- data/lib/resources/bond.rb +65 -0
- data/lib/resources/bridge.rb +114 -0
- data/lib/resources/command.rb +57 -0
- data/lib/resources/csv.rb +32 -0
- data/lib/resources/directory.rb +15 -0
- data/lib/resources/etc_group.rb +150 -0
- data/lib/resources/file.rb +110 -0
- data/lib/resources/gem.rb +46 -0
- data/lib/resources/group.rb +132 -0
- data/lib/resources/host.rb +143 -0
- data/lib/resources/inetd_conf.rb +56 -0
- data/lib/resources/interface.rb +127 -0
- data/lib/resources/iptables.rb +65 -0
- data/lib/resources/json.rb +64 -0
- data/lib/resources/kernel_module.rb +40 -0
- data/lib/resources/kernel_parameter.rb +55 -0
- data/lib/resources/limits_conf.rb +55 -0
- data/lib/resources/login_def.rb +60 -0
- data/lib/resources/mysql.rb +81 -0
- data/lib/resources/mysql_conf.rb +116 -0
- data/lib/resources/mysql_session.rb +52 -0
- data/lib/resources/npm.rb +44 -0
- data/lib/resources/ntp_conf.rb +58 -0
- data/lib/resources/oneget.rb +63 -0
- data/lib/resources/os.rb +22 -0
- data/lib/resources/os_env.rb +34 -0
- data/lib/resources/package.rb +169 -0
- data/lib/resources/parse_config.rb +75 -0
- data/lib/resources/passwd.rb +93 -0
- data/lib/resources/pip.rb +75 -0
- data/lib/resources/port.rb +296 -0
- data/lib/resources/postgres.rb +37 -0
- data/lib/resources/postgres_conf.rb +87 -0
- data/lib/resources/postgres_session.rb +59 -0
- data/lib/resources/processes.rb +57 -0
- data/lib/resources/registry_key.rb +54 -0
- data/lib/resources/script.rb +34 -0
- data/lib/resources/security_policy.rb +73 -0
- data/lib/resources/service.rb +379 -0
- data/lib/resources/ssh_conf.rb +75 -0
- data/lib/resources/user.rb +374 -0
- data/lib/resources/windows_feature.rb +77 -0
- data/lib/resources/yaml.rb +23 -0
- data/lib/resources/yum.rb +154 -0
- data/lib/utils/convert.rb +12 -0
- data/lib/utils/detect.rb +15 -0
- data/lib/utils/find_files.rb +36 -0
- data/lib/utils/hash.rb +13 -0
- data/lib/utils/modulator.rb +12 -0
- data/lib/utils/parser.rb +61 -0
- data/lib/utils/simpleconfig.rb +115 -0
- data/tasks/maintainers.rb +213 -0
- data/test/docker_run.rb +156 -0
- data/test/docker_test.rb +51 -0
- data/test/helper.rb +200 -0
- data/test/integration/.kitchen.yml +42 -0
- data/test/integration/Berksfile +4 -0
- data/test/integration/cookbooks/os_prepare/metadata.rb +8 -0
- data/test/integration/cookbooks/os_prepare/recipes/apt.rb +20 -0
- data/test/integration/cookbooks/os_prepare/recipes/default.rb +9 -0
- data/test/integration/cookbooks/os_prepare/recipes/file.rb +21 -0
- data/test/integration/cookbooks/os_prepare/recipes/package.rb +26 -0
- data/test/integration/default/_debug_spec.rb +1 -0
- data/test/integration/default/apt_spec.rb +42 -0
- data/test/integration/default/file_spec.rb +109 -0
- data/test/integration/default/group_spec.rb +32 -0
- data/test/integration/default/kernel_module_spec.rb +17 -0
- data/test/integration/default/kernel_parameter_spec.rb +56 -0
- data/test/integration/default/package_spec.rb +11 -0
- data/test/integration/default/service_spec.rb +28 -0
- data/test/integration/default/user_spec.rb +44 -0
- data/test/resource/command_test.rb +33 -0
- data/test/resource/dsl_test.rb +45 -0
- data/test/resource/file_test.rb +130 -0
- data/test/resource/ssh_config.rb +9 -0
- data/test/resource/sshd_config.rb +9 -0
- data/test/test-extra.yaml +11 -0
- data/test/test.yaml +11 -0
- data/test/unit/mock/cmd/Get-NetAdapter +24 -0
- data/test/unit/mock/cmd/GetUserAccount +33 -0
- data/test/unit/mock/cmd/GetWin32Group +23 -0
- data/test/unit/mock/cmd/PATH +1 -0
- data/test/unit/mock/cmd/Resolve-DnsName +26 -0
- data/test/unit/mock/cmd/Test-NetConnection +4 -0
- data/test/unit/mock/cmd/auditctl +7 -0
- data/test/unit/mock/cmd/auditpol +2 -0
- data/test/unit/mock/cmd/brew-info-jq +1 -0
- data/test/unit/mock/cmd/chage-l-root +7 -0
- data/test/unit/mock/cmd/dpkg-s-curl +21 -0
- data/test/unit/mock/cmd/dscl +5 -0
- data/test/unit/mock/cmd/etc-apt +7 -0
- data/test/unit/mock/cmd/find-etc-rc-d-name-S +12 -0
- data/test/unit/mock/cmd/find-net-interface +9 -0
- data/test/unit/mock/cmd/gem-list-local-a-q-rubocop +1 -0
- data/test/unit/mock/cmd/get-net-tcpconnection +24 -0
- data/test/unit/mock/cmd/get-netadapter-binding-bridge +4 -0
- data/test/unit/mock/cmd/get-package-firefox +30 -0
- data/test/unit/mock/cmd/get-package-ruby +18 -0
- data/test/unit/mock/cmd/get-service-dhcp +10 -0
- data/test/unit/mock/cmd/get-windows-feature +7 -0
- data/test/unit/mock/cmd/getent-hosts-example.com +1 -0
- data/test/unit/mock/cmd/getent-passwd-root +1 -0
- data/test/unit/mock/cmd/id-chartmann +1 -0
- data/test/unit/mock/cmd/id-root +1 -0
- data/test/unit/mock/cmd/initctl-show-config-ssh +3 -0
- data/test/unit/mock/cmd/initctl-status-ssh +1 -0
- data/test/unit/mock/cmd/iptables-s +6 -0
- data/test/unit/mock/cmd/launchctl-list +3 -0
- data/test/unit/mock/cmd/ls-1-etc-init.d +2 -0
- data/test/unit/mock/cmd/ls-sys-class-net-br +2 -0
- data/test/unit/mock/cmd/lsmod +2 -0
- data/test/unit/mock/cmd/lsof-np-itcp +4 -0
- data/test/unit/mock/cmd/netstat-tulpen +5 -0
- data/test/unit/mock/cmd/npm-ls-g--json-bower +9 -0
- data/test/unit/mock/cmd/pacman-qi-curl +21 -0
- data/test/unit/mock/cmd/ping-example.com +6 -0
- data/test/unit/mock/cmd/pip-show-jinja2 +11 -0
- data/test/unit/mock/cmd/ps-aux +3 -0
- data/test/unit/mock/cmd/pw-usershow-root-7 +1 -0
- data/test/unit/mock/cmd/reg_schedule +1 -0
- data/test/unit/mock/cmd/rpm-qia-curl +24 -0
- data/test/unit/mock/cmd/sbin_sysctl +1 -0
- data/test/unit/mock/cmd/secedit-export +7 -0
- data/test/unit/mock/cmd/service-e +2 -0
- data/test/unit/mock/cmd/service-sendmail-onestatus +3 -0
- data/test/unit/mock/cmd/service-sshd-status +1 -0
- data/test/unit/mock/cmd/sockstat +5 -0
- data/test/unit/mock/cmd/success +0 -0
- data/test/unit/mock/cmd/systemctl-show-all-sshd +6 -0
- data/test/unit/mock/cmd/win32_product +8 -0
- data/test/unit/mock/cmd/yum-repolist-all +52 -0
- data/test/unit/mock/files/auditd.conf +4 -0
- data/test/unit/mock/files/bond0 +37 -0
- data/test/unit/mock/files/etcgroup +3 -0
- data/test/unit/mock/files/example.csv +6 -0
- data/test/unit/mock/files/inetd.conf +2 -0
- data/test/unit/mock/files/kitchen.yml +7 -0
- data/test/unit/mock/files/limits.conf +5 -0
- data/test/unit/mock/files/login.defs +5 -0
- data/test/unit/mock/files/mysql.conf +8 -0
- data/test/unit/mock/files/mysql2.conf +2 -0
- data/test/unit/mock/files/ntp.conf +5 -0
- data/test/unit/mock/files/passwd +2 -0
- data/test/unit/mock/files/policyfile.lock.json +12 -0
- data/test/unit/mock/files/ssh_config +5 -0
- data/test/unit/mock/files/sshd_config +7 -0
- data/test/unit/mock/profiles/empty/metadata.rb +0 -0
- data/test/unit/mock/profiles/metadata/metadata.rb +1 -0
- data/test/unit/profile_context_test.rb +140 -0
- data/test/unit/profile_test.rb +49 -0
- data/test/unit/resources/apt_test.rb +46 -0
- data/test/unit/resources/audit_policy_test.rb +13 -0
- data/test/unit/resources/auditd_conf_test.rb +15 -0
- data/test/unit/resources/auditd_rules_test.rb +21 -0
- data/test/unit/resources/bond_test.rb +24 -0
- data/test/unit/resources/bridge_test.rb +56 -0
- data/test/unit/resources/csv_test.rb +35 -0
- data/test/unit/resources/etc_group_test.rb +37 -0
- data/test/unit/resources/gem_test.rb +20 -0
- data/test/unit/resources/group_test.rb +96 -0
- data/test/unit/resources/host_test.rb +38 -0
- data/test/unit/resources/inetd_conf_test.rb +15 -0
- data/test/unit/resources/interface_test.rb +54 -0
- data/test/unit/resources/iptables_test.rb +30 -0
- data/test/unit/resources/json_test.rb +36 -0
- data/test/unit/resources/kernel_module_test.rb +23 -0
- data/test/unit/resources/kernel_parameter_test.rb +13 -0
- data/test/unit/resources/limits_conf_test.rb +14 -0
- data/test/unit/resources/login_def_test.rb +16 -0
- data/test/unit/resources/mysql_conf_test.rb +14 -0
- data/test/unit/resources/npm_test.rb +20 -0
- data/test/unit/resources/ntp_conf_test.rb +16 -0
- data/test/unit/resources/oneget_test.rb +45 -0
- data/test/unit/resources/os_env_test.rb +13 -0
- data/test/unit/resources/package_test.rb +51 -0
- data/test/unit/resources/passwd_test.rb +24 -0
- data/test/unit/resources/pip_test.rb +15 -0
- data/test/unit/resources/port_test.rb +46 -0
- data/test/unit/resources/processes_test.rb +32 -0
- data/test/unit/resources/registry_key_test.rb +19 -0
- data/test/unit/resources/script_test.rb +19 -0
- data/test/unit/resources/security_policy_test.rb +16 -0
- data/test/unit/resources/service_test.rb +116 -0
- data/test/unit/resources/ssh_conf_test.rb +33 -0
- data/test/unit/resources/user_test.rb +93 -0
- data/test/unit/resources/windows_feature.rb +17 -0
- data/test/unit/resources/yaml_test.rb +34 -0
- data/test/unit/resources/yum_test.rb +68 -0
- data/test/unit/simpleconfig_test.rb +80 -0
- data/test/unit/utils/content_parser_test.rb +30 -0
- metadata +555 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Christoph Hartmann
|
|
3
|
+
# author: Dominik Richter
|
|
4
|
+
|
|
5
|
+
# Usage:
|
|
6
|
+
# describe iptables do
|
|
7
|
+
# it { should have_rule('-P INPUT ACCEPT') }
|
|
8
|
+
# end
|
|
9
|
+
#
|
|
10
|
+
# The following serverspec sytax is not implemented:
|
|
11
|
+
# describe iptables do
|
|
12
|
+
# it { should have_rule('-P INPUT ACCEPT').with_table('mangle').with_chain('INPUT') }
|
|
13
|
+
# end
|
|
14
|
+
# Please use the new sytax:
|
|
15
|
+
# describe iptables(table:'mangle', chain: 'input') do
|
|
16
|
+
# it { should have_rule('-P INPUT ACCEPT') }
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# Note: Docker containers normally do not have iptables installed
|
|
20
|
+
#
|
|
21
|
+
# @see http://ipset.netfilter.org/iptables.man.html
|
|
22
|
+
# @see http://ipset.netfilter.org/iptables.man.html
|
|
23
|
+
# @see https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html
|
|
24
|
+
class IpTables < Inspec.resource(1)
|
|
25
|
+
name 'iptables'
|
|
26
|
+
|
|
27
|
+
def initialize(params = {})
|
|
28
|
+
@table = params[:table] || nil
|
|
29
|
+
@chain = params[:chain] || nil
|
|
30
|
+
|
|
31
|
+
# we're done if we are on linux
|
|
32
|
+
return if inspec.os.linux?
|
|
33
|
+
|
|
34
|
+
# ensures, all calls are aborted for non-supported os
|
|
35
|
+
@iptables_cache = []
|
|
36
|
+
skip_resource 'The `iptables` resource is not supported on your OS yet.'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def has_rule?(rule = nil, _table = nil, _chain = nil)
|
|
40
|
+
found = false
|
|
41
|
+
retrieve_rules.each { |line|
|
|
42
|
+
# checks if the rule is part of the ruleset
|
|
43
|
+
# for now, we expect an excact match
|
|
44
|
+
found = true if line.downcase == rule.downcase
|
|
45
|
+
}
|
|
46
|
+
found
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def retrieve_rules
|
|
50
|
+
return @iptables_cache if defined?(@iptables_cache)
|
|
51
|
+
|
|
52
|
+
# construct iptables command to read all rules
|
|
53
|
+
@table.nil? ? table_cmd = '' : table_cmd = " -t #{@table} "
|
|
54
|
+
@chain.nil? ? chain_cmd = '' : chain_cmd = " #{@chain}"
|
|
55
|
+
cmd = inspec.command(format('iptables %s -S %s', table_cmd, chain_cmd).strip)
|
|
56
|
+
return [] if cmd.exit_status.to_i != 0
|
|
57
|
+
|
|
58
|
+
# split rules, returns array or rules
|
|
59
|
+
@iptables_cache = cmd.stdout.chomp.split("\n")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_s
|
|
63
|
+
format('Iptables %s %s', @table.nil? ? '' : "table: #{@table}", @chain.nil? ? '' : "chain: #{@chain}").strip
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Christoph Hartmann
|
|
3
|
+
# author: Dominik Richter
|
|
4
|
+
|
|
5
|
+
# Parses a json document
|
|
6
|
+
# Usage:
|
|
7
|
+
# describe json('policyfile.lock.json') do
|
|
8
|
+
# its('cookbook_locks.omnibus.version') { should eq('2.2.0') }
|
|
9
|
+
# end
|
|
10
|
+
class JsonConfig < Inspec.resource(1)
|
|
11
|
+
name 'json'
|
|
12
|
+
|
|
13
|
+
# make params readable
|
|
14
|
+
attr_reader :params
|
|
15
|
+
|
|
16
|
+
def initialize(path)
|
|
17
|
+
@path = path
|
|
18
|
+
@file_content = inspec.file(@path).content
|
|
19
|
+
@params = parse(@file_content)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def parse(content)
|
|
23
|
+
require 'json'
|
|
24
|
+
JSON.parse(content)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def extract_value(keys, value)
|
|
28
|
+
key = keys.shift
|
|
29
|
+
return nil if key.nil?
|
|
30
|
+
|
|
31
|
+
# check if key is a num, try to extract from array
|
|
32
|
+
if key.to_i.to_s == key
|
|
33
|
+
value = value[key.to_i]
|
|
34
|
+
# if value is an array, iterate over each child
|
|
35
|
+
elsif value.is_a?(Array)
|
|
36
|
+
value = value.map { |i|
|
|
37
|
+
extract_value([key], i)
|
|
38
|
+
}
|
|
39
|
+
# normal value extraction
|
|
40
|
+
else
|
|
41
|
+
value = value[key].nil? ? nil : value[key]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# check if further keys exist
|
|
45
|
+
if !keys.first.nil?
|
|
46
|
+
return extract_value(keys.clone, value)
|
|
47
|
+
else
|
|
48
|
+
return value
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Shorthand to retrieve a parameter name via `#its`.
|
|
53
|
+
# Example: describe json('file') { its('paramX') { should eq 'Y' } }
|
|
54
|
+
#
|
|
55
|
+
# @param [String] name name of the field to retrieve
|
|
56
|
+
# @return [Object] the value stored at this position
|
|
57
|
+
def method_missing(name)
|
|
58
|
+
@params[name.to_s]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def to_s
|
|
62
|
+
"Json #{@path}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Christoph Hartmann
|
|
3
|
+
# author: Dominik Richter
|
|
4
|
+
# license: All rights reserved
|
|
5
|
+
|
|
6
|
+
# Verifies if a kernel module is loaded
|
|
7
|
+
# Usage:
|
|
8
|
+
# describe kernel_module('bridge') do
|
|
9
|
+
# it { should be_loaded }
|
|
10
|
+
# end
|
|
11
|
+
class KernelModule < Inspec.resource(1)
|
|
12
|
+
name 'kernel_module'
|
|
13
|
+
|
|
14
|
+
def initialize(modulename = nil)
|
|
15
|
+
@module = modulename
|
|
16
|
+
|
|
17
|
+
# this resource is only supported on Linux
|
|
18
|
+
return skip_resource 'The `kernel_parameter` resource is not supported on your OS.' if !inspec.os.linux?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def loaded?
|
|
22
|
+
# default lsmod command
|
|
23
|
+
lsmod_cmd = 'lsmod'
|
|
24
|
+
# special care for CentOS 5 and sudo
|
|
25
|
+
lsmod_cmd = '/sbin/lsmod' if inspec.os[:family] == 'centos' && inspec.os[:release].to_i == 5
|
|
26
|
+
|
|
27
|
+
# get list of all modules
|
|
28
|
+
cmd = inspec.command(lsmod_cmd)
|
|
29
|
+
return false if cmd.exit_status != 0
|
|
30
|
+
|
|
31
|
+
# check if module is loaded
|
|
32
|
+
re = Regexp.new('^'+Regexp.quote(@module)+'\s')
|
|
33
|
+
found = cmd.stdout.match(re)
|
|
34
|
+
!found.nil?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def to_s
|
|
38
|
+
"Kernel Module #{@module}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# author: Christoph Hartmann
|
|
3
|
+
# license: All rights reserved
|
|
4
|
+
|
|
5
|
+
# Verifies if a kernel parameter is set
|
|
6
|
+
# describe kernel_parameter('net.ipv4.conf.all.forwarding') do
|
|
7
|
+
# its(:value) { should eq 0 }
|
|
8
|
+
# end
|
|
9
|
+
class KernelParameter < Inspec.resource(1)
|
|
10
|
+
name 'kernel_parameter'
|
|
11
|
+
|
|
12
|
+
def initialize(parameter = nil)
|
|
13
|
+
@parameter = parameter
|
|
14
|
+
|
|
15
|
+
# this resource is only supported on Linux
|
|
16
|
+
return skip_resource 'The `kernel_parameter` resource is not supported on your OS.' if !inspec.os.linux?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def value
|
|
20
|
+
cmd = inspec.command("/sbin/sysctl -q -n #{@parameter}")
|
|
21
|
+
return nil if cmd.exit_status != 0
|
|
22
|
+
# remove whitespace
|
|
23
|
+
cmd = cmd.stdout.chomp.strip
|
|
24
|
+
# convert to number if possible
|
|
25
|
+
cmd = cmd.to_i if cmd.match(/^\d+$/)
|
|
26
|
+
cmd
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_s
|
|
30
|
+
"Kernel Parameter #{@parameter}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# for compatability with serverspec
|
|
35
|
+
# this is deprecated syntax and will be removed in future versions
|
|
36
|
+
class LinuxKernelParameter < KernelParameter
|
|
37
|
+
name 'linux_kernel_parameter'
|
|
38
|
+
|
|
39
|
+
def initialize(parameter)
|
|
40
|
+
super(parameter)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def value
|
|
44
|
+
deprecated
|
|
45
|
+
super()
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def deprecated
|
|
49
|
+
warn '[DEPRECATION] `linux_kernel_parameter(parameter)` is deprecated. Please use `kernel_parameter(parameter)` instead.'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def to_s
|
|
53
|
+
"Kernel Parameter #{@parameter}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# copyright: 2015, Vulcano Security GmbH
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
# author: Dominik Richter
|
|
5
|
+
# license: All rights reserved
|
|
6
|
+
|
|
7
|
+
require 'utils/simpleconfig'
|
|
8
|
+
|
|
9
|
+
# Usage:
|
|
10
|
+
#
|
|
11
|
+
# describe limits_conf do
|
|
12
|
+
# its('*') { should include ['hard','core','0'] }
|
|
13
|
+
# end
|
|
14
|
+
|
|
15
|
+
class LimitsConf < Inspec.resource(1)
|
|
16
|
+
name 'limits_conf'
|
|
17
|
+
|
|
18
|
+
def initialize(path = nil)
|
|
19
|
+
@conf_path = path || '/etc/security/limits.conf'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def method_missing(name)
|
|
23
|
+
read_params[name.to_s]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def read_params
|
|
27
|
+
return @params if defined?(@params)
|
|
28
|
+
|
|
29
|
+
# read the file
|
|
30
|
+
file = inspec.file(@conf_path)
|
|
31
|
+
if !file.file?
|
|
32
|
+
skip_resource "Can't find file \"#{@conf_path}\""
|
|
33
|
+
return @params = {}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
content = file.content
|
|
37
|
+
if content.empty? && file.size > 0
|
|
38
|
+
skip_resource "Can't read file \"#{@conf_path}\""
|
|
39
|
+
return @params = {}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# parse the file
|
|
43
|
+
conf = SimpleConfig.new(
|
|
44
|
+
content,
|
|
45
|
+
assignment_re: /^\s*(\S+?)\s+(.*?)\s+(.*?)\s+(.*?)\s*$/,
|
|
46
|
+
key_vals: 3,
|
|
47
|
+
multiple_values: true,
|
|
48
|
+
)
|
|
49
|
+
@params = conf.params
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def to_s
|
|
53
|
+
'limits.conf'
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# copyright: 2015, Vulcano Security GmbH
|
|
3
|
+
# author: Christoph Hartmann
|
|
4
|
+
# author: Dominik Richter
|
|
5
|
+
# license: All rights reserved
|
|
6
|
+
|
|
7
|
+
require 'utils/simpleconfig'
|
|
8
|
+
|
|
9
|
+
# Usage:
|
|
10
|
+
#
|
|
11
|
+
# describe login_def do
|
|
12
|
+
# its('UMASK') {
|
|
13
|
+
# should eq '077'
|
|
14
|
+
# }
|
|
15
|
+
#
|
|
16
|
+
# its('PASS_MAX_DAYS.to_i') {
|
|
17
|
+
# should be <= 90
|
|
18
|
+
# }
|
|
19
|
+
# end
|
|
20
|
+
|
|
21
|
+
class LoginDef < Inspec.resource(1)
|
|
22
|
+
name 'login_defs'
|
|
23
|
+
|
|
24
|
+
def initialize(path = nil)
|
|
25
|
+
@conf_path = path || '/etc/login.defs'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def method_missing(name)
|
|
29
|
+
read_params[name.to_s]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def read_params
|
|
33
|
+
return @params if defined?(@params)
|
|
34
|
+
|
|
35
|
+
# read the file
|
|
36
|
+
file = inspec.file(@conf_path)
|
|
37
|
+
if !file.file?
|
|
38
|
+
skip_resource "Can't find file \"#{@conf_path}\""
|
|
39
|
+
return @params = {}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
content = file.content
|
|
43
|
+
if content.empty? && file.size > 0
|
|
44
|
+
skip_resource "Can't read file \"#{@conf_path}\""
|
|
45
|
+
return @params = {}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# parse the file
|
|
49
|
+
conf = SimpleConfig.new(
|
|
50
|
+
content,
|
|
51
|
+
assignment_re: /^\s*(\S+)\s+(\S*)\s*$/,
|
|
52
|
+
multiple_values: false,
|
|
53
|
+
)
|
|
54
|
+
@params = conf.params
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def to_s
|
|
58
|
+
'login.defs'
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# copyright: 2015, Vulcano Security GmbH
|
|
3
|
+
# author: Dominik Richter
|
|
4
|
+
# author: Christoph Hartmann
|
|
5
|
+
# license: All rights reserved
|
|
6
|
+
|
|
7
|
+
class Mysql < Inspec.resource(1)
|
|
8
|
+
name 'mysql'
|
|
9
|
+
|
|
10
|
+
attr_reader :package, :service, :conf_dir, :conf_path, :data_dir, :log_dir, :log_path, :log_group, :log_dir_group
|
|
11
|
+
def initialize
|
|
12
|
+
# set OS-dependent filenames and paths
|
|
13
|
+
case inspec.os[:family]
|
|
14
|
+
when 'ubuntu', 'debian'
|
|
15
|
+
init_ubuntu
|
|
16
|
+
when 'redhat', 'fedora'
|
|
17
|
+
init_redhat
|
|
18
|
+
when 'arch'
|
|
19
|
+
init_arch
|
|
20
|
+
else
|
|
21
|
+
# TODO: could not detect
|
|
22
|
+
init_default
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def init_ubuntu
|
|
27
|
+
@package = 'mysql-server'
|
|
28
|
+
@service = 'mysql'
|
|
29
|
+
@conf_path = '/etc/mysql/my.cnf'
|
|
30
|
+
@conf_dir = '/etc/mysql/'
|
|
31
|
+
@data_dir = '/var/lib/mysql/'
|
|
32
|
+
@log_dir = '/var/log/'
|
|
33
|
+
@log_path = '/var/log/mysql.log'
|
|
34
|
+
@log_group = 'adm'
|
|
35
|
+
case os[:release]
|
|
36
|
+
when '14.04'
|
|
37
|
+
@log_dir_group = 'syslog'
|
|
38
|
+
else
|
|
39
|
+
@log_dir_group = 'root'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def init_redhat
|
|
44
|
+
@package = 'mysql-server'
|
|
45
|
+
@service = 'mysqld'
|
|
46
|
+
@conf_path = '/etc/my.cnf'
|
|
47
|
+
@conf_dir = '/etc/'
|
|
48
|
+
@data_dir = '/var/lib/mysql/'
|
|
49
|
+
@log_dir = '/var/log/'
|
|
50
|
+
@log_path = '/var/log/mysqld.log'
|
|
51
|
+
@log_group = 'mysql'
|
|
52
|
+
@log_dir_group = 'root'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def init_arch
|
|
56
|
+
@package = 'mariadb'
|
|
57
|
+
@service = 'mysql'
|
|
58
|
+
@conf_path = '/etc/mysql/my.cnf'
|
|
59
|
+
@conf_dir = '/etc/mysql/'
|
|
60
|
+
@data_dir = '/var/lib/mysql/'
|
|
61
|
+
@log_dir = '/var/log/'
|
|
62
|
+
@log_path = '/var/log/mysql.log'
|
|
63
|
+
@log_group = 'mysql'
|
|
64
|
+
@log_dir_group = 'root'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def init_default
|
|
68
|
+
@service = 'mysqld'
|
|
69
|
+
@conf_path = '/etc/my.cnf'
|
|
70
|
+
@conf_dir = '/etc/'
|
|
71
|
+
@data_dir = '/var/lib/mysql/'
|
|
72
|
+
@log_dir = '/var/log/'
|
|
73
|
+
@log_path = '/var/log/mysqld.log'
|
|
74
|
+
@log_group = 'mysql'
|
|
75
|
+
@log_dir_group = 'root'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def to_s
|
|
79
|
+
'MySQL'
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# copyright: 2015, Vulcano Security GmbH
|
|
3
|
+
# author: Dominik Richter
|
|
4
|
+
# license: All rights reserved
|
|
5
|
+
|
|
6
|
+
require 'utils/simpleconfig'
|
|
7
|
+
require 'utils/find_files'
|
|
8
|
+
require 'utils/hash'
|
|
9
|
+
require 'resources/mysql'
|
|
10
|
+
|
|
11
|
+
class MysqlConfEntry
|
|
12
|
+
def initialize(path, params)
|
|
13
|
+
@params = params
|
|
14
|
+
@path = path
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def method_missing(name, *_)
|
|
18
|
+
k = name.to_s
|
|
19
|
+
res = @params[k]
|
|
20
|
+
return true if res.nil? && @params.key?(k)
|
|
21
|
+
@params[k]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
"MySQL Config entry [#{@path.join(' ')}]"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class MysqlConf < Inspec.resource(1)
|
|
30
|
+
name 'mysql_conf'
|
|
31
|
+
|
|
32
|
+
include FindFiles
|
|
33
|
+
|
|
34
|
+
def initialize(conf_path = nil)
|
|
35
|
+
@conf_path = conf_path || inspec.mysql.conf_path
|
|
36
|
+
@files_contents = {}
|
|
37
|
+
@content = nil
|
|
38
|
+
@params = nil
|
|
39
|
+
read_content
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def content
|
|
43
|
+
@content ||= read_content
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def params(*opts)
|
|
47
|
+
@params || read_content
|
|
48
|
+
res = @params
|
|
49
|
+
opts.each do |opt|
|
|
50
|
+
res = res[opt] unless res.nil?
|
|
51
|
+
end
|
|
52
|
+
MysqlConfEntry.new(opts, res)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def method_missing(name)
|
|
56
|
+
@params || read_content
|
|
57
|
+
@params[name.to_s]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def read_content
|
|
61
|
+
@content = ''
|
|
62
|
+
@params = {}
|
|
63
|
+
|
|
64
|
+
# skip if the main configuration file doesn't exist
|
|
65
|
+
if !inspec.file(@conf_path).file?
|
|
66
|
+
return skip_resource "Can't find file \"#{@conf_path}\""
|
|
67
|
+
end
|
|
68
|
+
raw_conf = read_file(@conf_path)
|
|
69
|
+
if raw_conf.empty? && inspec.file(@conf_path).size > 0
|
|
70
|
+
return skip_resource("Can't read file \"#{@conf_path}\"")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
to_read = [@conf_path]
|
|
74
|
+
until to_read.empty?
|
|
75
|
+
cur_file = to_read[0]
|
|
76
|
+
raw_conf = read_file(cur_file)
|
|
77
|
+
@content += raw_conf
|
|
78
|
+
|
|
79
|
+
params = SimpleConfig.new(raw_conf).params
|
|
80
|
+
@params = @params.deep_merge(params)
|
|
81
|
+
|
|
82
|
+
to_read = to_read.drop(1)
|
|
83
|
+
# see if there is more stuff to include
|
|
84
|
+
|
|
85
|
+
dir = File.dirname(cur_file)
|
|
86
|
+
to_read += include_files(dir, raw_conf).find_all do |fp|
|
|
87
|
+
not @files_contents.key? fp
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
#
|
|
91
|
+
@content
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def include_files(reldir, conf)
|
|
95
|
+
files = conf.scan(/^!include\s+(.*)\s*/).flatten.compact.map { |x| abs_path(reldir, x) }
|
|
96
|
+
dirs = conf.scan(/^!includedir\s+(.*)\s*/).flatten.compact.map { |x| abs_path(reldir, x) }
|
|
97
|
+
dirs.map do |dir|
|
|
98
|
+
# @TODO: non local glob
|
|
99
|
+
files += find_files(dir, depth: 1, type: 'file')
|
|
100
|
+
end
|
|
101
|
+
files
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def abs_path(dir, f)
|
|
105
|
+
return f if f.start_with? '/'
|
|
106
|
+
File.join(dir, f)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def read_file(path)
|
|
110
|
+
@files_contents[path] ||= inspec.file(path).content
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_s
|
|
114
|
+
'MySQL Configuration'
|
|
115
|
+
end
|
|
116
|
+
end
|