inspec-core 2.1.67
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/CHANGELOG.md +3136 -0
- data/Gemfile +56 -0
- data/LICENSE +14 -0
- data/MAINTAINERS.md +33 -0
- data/MAINTAINERS.toml +52 -0
- data/README.md +453 -0
- data/bin/inspec +12 -0
- data/docs/.gitignore +2 -0
- data/docs/README.md +40 -0
- data/docs/dev/control-eval.md +62 -0
- data/docs/dsl_inspec.md +258 -0
- data/docs/dsl_resource.md +100 -0
- data/docs/glossary.md +99 -0
- data/docs/habitat.md +192 -0
- data/docs/inspec_and_friends.md +114 -0
- data/docs/matchers.md +169 -0
- data/docs/migration.md +293 -0
- data/docs/platforms.md +119 -0
- data/docs/plugin_kitchen_inspec.md +50 -0
- data/docs/profiles.md +378 -0
- data/docs/reporters.md +105 -0
- data/docs/resources/aide_conf.md.erb +76 -0
- data/docs/resources/apache.md.erb +67 -0
- data/docs/resources/apache_conf.md.erb +68 -0
- data/docs/resources/apt.md.erb +71 -0
- data/docs/resources/audit_policy.md.erb +47 -0
- data/docs/resources/auditd.md.erb +79 -0
- data/docs/resources/auditd_conf.md.erb +68 -0
- data/docs/resources/bash.md.erb +75 -0
- data/docs/resources/bond.md.erb +90 -0
- data/docs/resources/bridge.md.erb +57 -0
- data/docs/resources/bsd_service.md.erb +67 -0
- data/docs/resources/chocolatey_package.md.erb +58 -0
- data/docs/resources/command.md.erb +138 -0
- data/docs/resources/cpan.md.erb +79 -0
- data/docs/resources/cran.md.erb +64 -0
- data/docs/resources/crontab.md.erb +89 -0
- data/docs/resources/csv.md.erb +54 -0
- data/docs/resources/dh_params.md.erb +205 -0
- data/docs/resources/directory.md.erb +30 -0
- data/docs/resources/docker.md.erb +219 -0
- data/docs/resources/docker_container.md.erb +103 -0
- data/docs/resources/docker_image.md.erb +94 -0
- data/docs/resources/docker_service.md.erb +114 -0
- data/docs/resources/elasticsearch.md.erb +242 -0
- data/docs/resources/etc_fstab.md.erb +125 -0
- data/docs/resources/etc_group.md.erb +75 -0
- data/docs/resources/etc_hosts.md.erb +78 -0
- data/docs/resources/etc_hosts_allow.md.erb +74 -0
- data/docs/resources/etc_hosts_deny.md.erb +74 -0
- data/docs/resources/file.md.erb +526 -0
- data/docs/resources/filesystem.md.erb +41 -0
- data/docs/resources/firewalld.md.erb +107 -0
- data/docs/resources/gem.md.erb +79 -0
- data/docs/resources/group.md.erb +61 -0
- data/docs/resources/grub_conf.md.erb +101 -0
- data/docs/resources/host.md.erb +86 -0
- data/docs/resources/http.md.erb +197 -0
- data/docs/resources/iis_app.md.erb +122 -0
- data/docs/resources/iis_site.md.erb +135 -0
- data/docs/resources/inetd_conf.md.erb +94 -0
- data/docs/resources/ini.md.erb +76 -0
- data/docs/resources/interface.md.erb +58 -0
- data/docs/resources/iptables.md.erb +64 -0
- data/docs/resources/json.md.erb +63 -0
- data/docs/resources/kernel_module.md.erb +120 -0
- data/docs/resources/kernel_parameter.md.erb +53 -0
- data/docs/resources/key_rsa.md.erb +85 -0
- data/docs/resources/launchd_service.md.erb +57 -0
- data/docs/resources/limits_conf.md.erb +75 -0
- data/docs/resources/login_defs.md.erb +71 -0
- data/docs/resources/mount.md.erb +69 -0
- data/docs/resources/mssql_session.md.erb +60 -0
- data/docs/resources/mysql_conf.md.erb +99 -0
- data/docs/resources/mysql_session.md.erb +74 -0
- data/docs/resources/nginx.md.erb +79 -0
- data/docs/resources/nginx_conf.md.erb +138 -0
- data/docs/resources/npm.md.erb +60 -0
- data/docs/resources/ntp_conf.md.erb +60 -0
- data/docs/resources/oneget.md.erb +53 -0
- data/docs/resources/oracledb_session.md.erb +52 -0
- data/docs/resources/os.md.erb +141 -0
- data/docs/resources/os_env.md.erb +91 -0
- data/docs/resources/package.md.erb +120 -0
- data/docs/resources/packages.md.erb +67 -0
- data/docs/resources/parse_config.md.erb +103 -0
- data/docs/resources/parse_config_file.md.erb +138 -0
- data/docs/resources/passwd.md.erb +141 -0
- data/docs/resources/pip.md.erb +67 -0
- data/docs/resources/port.md.erb +137 -0
- data/docs/resources/postgres_conf.md.erb +79 -0
- data/docs/resources/postgres_hba_conf.md.erb +93 -0
- data/docs/resources/postgres_ident_conf.md.erb +76 -0
- data/docs/resources/postgres_session.md.erb +69 -0
- data/docs/resources/powershell.md.erb +102 -0
- data/docs/resources/processes.md.erb +109 -0
- data/docs/resources/rabbitmq_config.md.erb +41 -0
- data/docs/resources/registry_key.md.erb +158 -0
- data/docs/resources/runit_service.md.erb +57 -0
- data/docs/resources/security_policy.md.erb +47 -0
- data/docs/resources/service.md.erb +121 -0
- data/docs/resources/shadow.md.erb +146 -0
- data/docs/resources/ssh_config.md.erb +73 -0
- data/docs/resources/sshd_config.md.erb +83 -0
- data/docs/resources/ssl.md.erb +119 -0
- data/docs/resources/sys_info.md.erb +42 -0
- data/docs/resources/systemd_service.md.erb +57 -0
- data/docs/resources/sysv_service.md.erb +57 -0
- data/docs/resources/upstart_service.md.erb +57 -0
- data/docs/resources/user.md.erb +140 -0
- data/docs/resources/users.md.erb +127 -0
- data/docs/resources/vbscript.md.erb +55 -0
- data/docs/resources/virtualization.md.erb +57 -0
- data/docs/resources/windows_feature.md.erb +47 -0
- data/docs/resources/windows_hotfix.md.erb +53 -0
- data/docs/resources/windows_task.md.erb +95 -0
- data/docs/resources/wmi.md.erb +81 -0
- data/docs/resources/x509_certificate.md.erb +151 -0
- data/docs/resources/xinetd_conf.md.erb +156 -0
- data/docs/resources/xml.md.erb +85 -0
- data/docs/resources/yaml.md.erb +69 -0
- data/docs/resources/yum.md.erb +98 -0
- data/docs/resources/zfs_dataset.md.erb +53 -0
- data/docs/resources/zfs_pool.md.erb +47 -0
- data/docs/ruby_usage.md +203 -0
- data/docs/shared/matcher_be.md.erb +1 -0
- data/docs/shared/matcher_cmp.md.erb +43 -0
- data/docs/shared/matcher_eq.md.erb +3 -0
- data/docs/shared/matcher_include.md.erb +1 -0
- data/docs/shared/matcher_match.md.erb +1 -0
- data/docs/shell.md +217 -0
- data/examples/README.md +8 -0
- data/examples/inheritance/README.md +65 -0
- data/examples/inheritance/controls/example.rb +14 -0
- data/examples/inheritance/inspec.yml +15 -0
- data/examples/kitchen-ansible/.kitchen.yml +25 -0
- data/examples/kitchen-ansible/Gemfile +19 -0
- data/examples/kitchen-ansible/README.md +53 -0
- data/examples/kitchen-ansible/files/nginx.repo +6 -0
- data/examples/kitchen-ansible/tasks/main.yml +16 -0
- data/examples/kitchen-ansible/test/integration/default/default.yml +5 -0
- data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-chef/.kitchen.yml +20 -0
- data/examples/kitchen-chef/Berksfile +3 -0
- data/examples/kitchen-chef/Gemfile +19 -0
- data/examples/kitchen-chef/README.md +27 -0
- data/examples/kitchen-chef/metadata.rb +7 -0
- data/examples/kitchen-chef/recipes/default.rb +6 -0
- data/examples/kitchen-chef/recipes/nginx.rb +30 -0
- data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -0
- data/examples/kitchen-puppet/.kitchen.yml +23 -0
- data/examples/kitchen-puppet/Gemfile +20 -0
- data/examples/kitchen-puppet/Puppetfile +25 -0
- data/examples/kitchen-puppet/README.md +53 -0
- data/examples/kitchen-puppet/manifests/site.pp +33 -0
- data/examples/kitchen-puppet/metadata.json +11 -0
- data/examples/kitchen-puppet/modules/.gitkeep +0 -0
- data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -0
- data/examples/meta-profile/README.md +37 -0
- data/examples/meta-profile/controls/example.rb +13 -0
- data/examples/meta-profile/inspec.yml +13 -0
- data/examples/profile-attribute.yml +2 -0
- data/examples/profile-attribute/README.md +14 -0
- data/examples/profile-attribute/controls/example.rb +11 -0
- data/examples/profile-attribute/inspec.yml +8 -0
- data/examples/profile-sensitive/README.md +29 -0
- data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -0
- data/examples/profile-sensitive/controls/sensitive.rb +9 -0
- data/examples/profile-sensitive/inspec.yml +8 -0
- data/examples/profile/README.md +48 -0
- data/examples/profile/controls/example.rb +23 -0
- data/examples/profile/controls/gordon.rb +36 -0
- data/examples/profile/controls/meta.rb +34 -0
- data/examples/profile/inspec.yml +10 -0
- data/examples/profile/libraries/gordon_config.rb +59 -0
- data/inspec-core.gemspec +43 -0
- data/lib/bundles/README.md +3 -0
- data/lib/bundles/inspec-artifact.rb +7 -0
- data/lib/bundles/inspec-artifact/README.md +1 -0
- data/lib/bundles/inspec-artifact/cli.rb +277 -0
- data/lib/bundles/inspec-compliance.rb +16 -0
- data/lib/bundles/inspec-compliance/.kitchen.yml +20 -0
- data/lib/bundles/inspec-compliance/README.md +193 -0
- data/lib/bundles/inspec-compliance/api.rb +360 -0
- data/lib/bundles/inspec-compliance/api/login.rb +193 -0
- data/lib/bundles/inspec-compliance/bootstrap.sh +41 -0
- data/lib/bundles/inspec-compliance/cli.rb +260 -0
- data/lib/bundles/inspec-compliance/configuration.rb +103 -0
- data/lib/bundles/inspec-compliance/http.rb +125 -0
- data/lib/bundles/inspec-compliance/images/cc-token.png +0 -0
- data/lib/bundles/inspec-compliance/support.rb +36 -0
- data/lib/bundles/inspec-compliance/target.rb +106 -0
- data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -0
- data/lib/bundles/inspec-habitat.rb +12 -0
- data/lib/bundles/inspec-habitat/cli.rb +36 -0
- data/lib/bundles/inspec-habitat/log.rb +10 -0
- data/lib/bundles/inspec-habitat/profile.rb +391 -0
- data/lib/bundles/inspec-init.rb +8 -0
- data/lib/bundles/inspec-init/README.md +31 -0
- data/lib/bundles/inspec-init/cli.rb +97 -0
- data/lib/bundles/inspec-init/templates/profile/README.md +3 -0
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -0
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -0
- data/lib/bundles/inspec-init/templates/profile/libraries/.gitkeep +0 -0
- data/lib/bundles/inspec-supermarket.rb +13 -0
- data/lib/bundles/inspec-supermarket/README.md +45 -0
- data/lib/bundles/inspec-supermarket/api.rb +84 -0
- data/lib/bundles/inspec-supermarket/cli.rb +73 -0
- data/lib/bundles/inspec-supermarket/target.rb +34 -0
- data/lib/fetchers/git.rb +163 -0
- data/lib/fetchers/local.rb +74 -0
- data/lib/fetchers/mock.rb +35 -0
- data/lib/fetchers/url.rb +247 -0
- data/lib/inspec.rb +24 -0
- data/lib/inspec/archive/tar.rb +29 -0
- data/lib/inspec/archive/zip.rb +19 -0
- data/lib/inspec/backend.rb +93 -0
- data/lib/inspec/base_cli.rb +368 -0
- data/lib/inspec/cached_fetcher.rb +66 -0
- data/lib/inspec/cli.rb +292 -0
- data/lib/inspec/completions/bash.sh.erb +45 -0
- data/lib/inspec/completions/fish.sh.erb +34 -0
- data/lib/inspec/completions/zsh.sh.erb +61 -0
- data/lib/inspec/control_eval_context.rb +179 -0
- data/lib/inspec/dependencies/cache.rb +72 -0
- data/lib/inspec/dependencies/dependency_set.rb +92 -0
- data/lib/inspec/dependencies/lockfile.rb +115 -0
- data/lib/inspec/dependencies/requirement.rb +123 -0
- data/lib/inspec/dependencies/resolver.rb +86 -0
- data/lib/inspec/describe.rb +27 -0
- data/lib/inspec/dsl.rb +66 -0
- data/lib/inspec/dsl_shared.rb +33 -0
- data/lib/inspec/env_printer.rb +157 -0
- data/lib/inspec/errors.rb +14 -0
- data/lib/inspec/exceptions.rb +12 -0
- data/lib/inspec/expect.rb +45 -0
- data/lib/inspec/fetcher.rb +45 -0
- data/lib/inspec/file_provider.rb +275 -0
- data/lib/inspec/formatters.rb +3 -0
- data/lib/inspec/formatters/base.rb +259 -0
- data/lib/inspec/formatters/json_rspec.rb +20 -0
- data/lib/inspec/formatters/show_progress.rb +12 -0
- data/lib/inspec/library_eval_context.rb +58 -0
- data/lib/inspec/log.rb +11 -0
- data/lib/inspec/metadata.rb +247 -0
- data/lib/inspec/method_source.rb +24 -0
- data/lib/inspec/objects.rb +14 -0
- data/lib/inspec/objects/attribute.rb +75 -0
- data/lib/inspec/objects/control.rb +61 -0
- data/lib/inspec/objects/describe.rb +92 -0
- data/lib/inspec/objects/each_loop.rb +36 -0
- data/lib/inspec/objects/list.rb +15 -0
- data/lib/inspec/objects/or_test.rb +40 -0
- data/lib/inspec/objects/ruby_helper.rb +15 -0
- data/lib/inspec/objects/tag.rb +27 -0
- data/lib/inspec/objects/test.rb +87 -0
- data/lib/inspec/objects/value.rb +27 -0
- data/lib/inspec/plugins.rb +60 -0
- data/lib/inspec/plugins/cli.rb +24 -0
- data/lib/inspec/plugins/fetcher.rb +86 -0
- data/lib/inspec/plugins/resource.rb +135 -0
- data/lib/inspec/plugins/secret.rb +15 -0
- data/lib/inspec/plugins/source_reader.rb +40 -0
- data/lib/inspec/polyfill.rb +12 -0
- data/lib/inspec/profile.rb +513 -0
- data/lib/inspec/profile_context.rb +208 -0
- data/lib/inspec/profile_vendor.rb +66 -0
- data/lib/inspec/reporters.rb +60 -0
- data/lib/inspec/reporters/automate.rb +76 -0
- data/lib/inspec/reporters/base.rb +25 -0
- data/lib/inspec/reporters/cli.rb +356 -0
- data/lib/inspec/reporters/json.rb +116 -0
- data/lib/inspec/reporters/json_min.rb +48 -0
- data/lib/inspec/reporters/junit.rb +78 -0
- data/lib/inspec/require_loader.rb +33 -0
- data/lib/inspec/resource.rb +190 -0
- data/lib/inspec/rule.rb +280 -0
- data/lib/inspec/runner.rb +345 -0
- data/lib/inspec/runner_mock.rb +41 -0
- data/lib/inspec/runner_rspec.rb +175 -0
- data/lib/inspec/runtime_profile.rb +26 -0
- data/lib/inspec/schema.rb +213 -0
- data/lib/inspec/secrets.rb +19 -0
- data/lib/inspec/secrets/yaml.rb +30 -0
- data/lib/inspec/shell.rb +220 -0
- data/lib/inspec/shell_detector.rb +90 -0
- data/lib/inspec/source_reader.rb +29 -0
- data/lib/inspec/version.rb +8 -0
- data/lib/matchers/matchers.rb +339 -0
- data/lib/resources/aide_conf.rb +151 -0
- data/lib/resources/apache.rb +48 -0
- data/lib/resources/apache_conf.rb +149 -0
- data/lib/resources/apt.rb +149 -0
- data/lib/resources/audit_policy.rb +63 -0
- data/lib/resources/auditd.rb +231 -0
- data/lib/resources/auditd_conf.rb +46 -0
- data/lib/resources/bash.rb +35 -0
- data/lib/resources/bond.rb +69 -0
- data/lib/resources/bridge.rb +122 -0
- data/lib/resources/chocolatey_package.rb +78 -0
- data/lib/resources/command.rb +73 -0
- data/lib/resources/cpan.rb +58 -0
- data/lib/resources/cran.rb +64 -0
- data/lib/resources/crontab.rb +169 -0
- data/lib/resources/csv.rb +56 -0
- data/lib/resources/dh_params.rb +77 -0
- data/lib/resources/directory.rb +25 -0
- data/lib/resources/docker.rb +236 -0
- data/lib/resources/docker_container.rb +89 -0
- data/lib/resources/docker_image.rb +83 -0
- data/lib/resources/docker_object.rb +57 -0
- data/lib/resources/docker_service.rb +90 -0
- data/lib/resources/elasticsearch.rb +169 -0
- data/lib/resources/etc_fstab.rb +94 -0
- data/lib/resources/etc_group.rb +154 -0
- data/lib/resources/etc_hosts.rb +66 -0
- data/lib/resources/etc_hosts_allow_deny.rb +112 -0
- data/lib/resources/file.rb +298 -0
- data/lib/resources/filesystem.rb +31 -0
- data/lib/resources/firewalld.rb +143 -0
- data/lib/resources/gem.rb +70 -0
- data/lib/resources/groups.rb +215 -0
- data/lib/resources/grub_conf.rb +227 -0
- data/lib/resources/host.rb +306 -0
- data/lib/resources/http.rb +253 -0
- data/lib/resources/iis_app.rb +101 -0
- data/lib/resources/iis_site.rb +148 -0
- data/lib/resources/inetd_conf.rb +54 -0
- data/lib/resources/ini.rb +29 -0
- data/lib/resources/interface.rb +129 -0
- data/lib/resources/iptables.rb +80 -0
- data/lib/resources/json.rb +111 -0
- data/lib/resources/kernel_module.rb +107 -0
- data/lib/resources/kernel_parameter.rb +58 -0
- data/lib/resources/key_rsa.rb +63 -0
- data/lib/resources/limits_conf.rb +46 -0
- data/lib/resources/login_def.rb +57 -0
- data/lib/resources/mount.rb +88 -0
- data/lib/resources/mssql_session.rb +101 -0
- data/lib/resources/mysql.rb +82 -0
- data/lib/resources/mysql_conf.rb +127 -0
- data/lib/resources/mysql_session.rb +85 -0
- data/lib/resources/nginx.rb +96 -0
- data/lib/resources/nginx_conf.rb +226 -0
- data/lib/resources/npm.rb +48 -0
- data/lib/resources/ntp_conf.rb +51 -0
- data/lib/resources/oneget.rb +71 -0
- data/lib/resources/oracledb_session.rb +139 -0
- data/lib/resources/os.rb +36 -0
- data/lib/resources/os_env.rb +86 -0
- data/lib/resources/package.rb +370 -0
- data/lib/resources/packages.rb +111 -0
- data/lib/resources/parse_config.rb +112 -0
- data/lib/resources/passwd.rb +76 -0
- data/lib/resources/pip.rb +130 -0
- data/lib/resources/platform.rb +109 -0
- data/lib/resources/port.rb +771 -0
- data/lib/resources/postgres.rb +131 -0
- data/lib/resources/postgres_conf.rb +114 -0
- data/lib/resources/postgres_hba_conf.rb +90 -0
- data/lib/resources/postgres_ident_conf.rb +79 -0
- data/lib/resources/postgres_session.rb +71 -0
- data/lib/resources/powershell.rb +67 -0
- data/lib/resources/processes.rb +204 -0
- data/lib/resources/rabbitmq_conf.rb +51 -0
- data/lib/resources/registry_key.rb +297 -0
- data/lib/resources/security_policy.rb +180 -0
- data/lib/resources/service.rb +794 -0
- data/lib/resources/shadow.rb +159 -0
- data/lib/resources/ssh_conf.rb +97 -0
- data/lib/resources/ssl.rb +99 -0
- data/lib/resources/sys_info.rb +28 -0
- data/lib/resources/toml.rb +32 -0
- data/lib/resources/users.rb +654 -0
- data/lib/resources/vbscript.rb +68 -0
- data/lib/resources/virtualization.rb +247 -0
- data/lib/resources/windows_feature.rb +84 -0
- data/lib/resources/windows_hotfix.rb +35 -0
- data/lib/resources/windows_task.rb +102 -0
- data/lib/resources/wmi.rb +110 -0
- data/lib/resources/x509_certificate.rb +137 -0
- data/lib/resources/xinetd.rb +106 -0
- data/lib/resources/xml.rb +46 -0
- data/lib/resources/yaml.rb +43 -0
- data/lib/resources/yum.rb +180 -0
- data/lib/resources/zfs_dataset.rb +60 -0
- data/lib/resources/zfs_pool.rb +49 -0
- data/lib/source_readers/flat.rb +39 -0
- data/lib/source_readers/inspec.rb +75 -0
- data/lib/utils/command_wrapper.rb +27 -0
- data/lib/utils/convert.rb +12 -0
- data/lib/utils/database_helpers.rb +77 -0
- data/lib/utils/enumerable_delegation.rb +9 -0
- data/lib/utils/erlang_parser.rb +192 -0
- data/lib/utils/file_reader.rb +25 -0
- data/lib/utils/filter.rb +273 -0
- data/lib/utils/filter_array.rb +27 -0
- data/lib/utils/find_files.rb +47 -0
- data/lib/utils/hash.rb +41 -0
- data/lib/utils/json_log.rb +18 -0
- data/lib/utils/latest_version.rb +22 -0
- data/lib/utils/modulator.rb +12 -0
- data/lib/utils/nginx_parser.rb +105 -0
- data/lib/utils/object_traversal.rb +49 -0
- data/lib/utils/parser.rb +274 -0
- data/lib/utils/pkey_reader.rb +15 -0
- data/lib/utils/plugin_registry.rb +93 -0
- data/lib/utils/simpleconfig.rb +120 -0
- data/lib/utils/spdx.rb +13 -0
- data/lib/utils/spdx.txt +344 -0
- metadata +713 -0
@@ -0,0 +1,227 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'utils/simpleconfig'
|
4
|
+
require 'utils/file_reader'
|
5
|
+
|
6
|
+
class GrubConfig < Inspec.resource(1)
|
7
|
+
name 'grub_conf'
|
8
|
+
supports platform: 'unix'
|
9
|
+
desc 'Use the grub_conf InSpec audit resource to test the boot config of Linux systems that use Grub.'
|
10
|
+
example "
|
11
|
+
describe grub_conf('/etc/grub.conf', 'default') do
|
12
|
+
its('kernel') { should include '/vmlinuz-2.6.32-573.7.1.el6.x86_64' }
|
13
|
+
its('initrd') { should include '/initramfs-2.6.32-573.el6.x86_64.img=1' }
|
14
|
+
its('default') { should_not eq '1' }
|
15
|
+
its('timeout') { should eq '5' }
|
16
|
+
end
|
17
|
+
|
18
|
+
also check specific kernels
|
19
|
+
describe grub_conf('/etc/grub.conf', 'CentOS (2.6.32-573.12.1.el6.x86_64)') do
|
20
|
+
its('kernel') { should include 'audit=1' }
|
21
|
+
end
|
22
|
+
"
|
23
|
+
|
24
|
+
include FileReader
|
25
|
+
|
26
|
+
class UnknownGrubConfig < StandardError; end
|
27
|
+
|
28
|
+
def initialize(path = nil, kernel = nil)
|
29
|
+
config_for_platform(path)
|
30
|
+
@content = read_file(@conf_path)
|
31
|
+
@kernel = kernel || 'default'
|
32
|
+
rescue UnknownGrubConfig
|
33
|
+
return skip_resource 'The `grub_config` resource is not supported on your OS yet.'
|
34
|
+
end
|
35
|
+
|
36
|
+
def config_for_platform(path)
|
37
|
+
os = inspec.os
|
38
|
+
if os.redhat? || os[:name] == 'fedora'
|
39
|
+
config_for_redhatish(path)
|
40
|
+
elsif os.debian?
|
41
|
+
@conf_path = path || '/boot/grub/grub.cfg'
|
42
|
+
@defaults_path = '/etc/default/grub'
|
43
|
+
@grubenv_path = '/boot/grub2/grubenv'
|
44
|
+
@version = 'grub2'
|
45
|
+
elsif os[:name] == 'amazon'
|
46
|
+
@conf_path = path || '/etc/grub.conf'
|
47
|
+
@version = 'legacy'
|
48
|
+
else
|
49
|
+
raise UnknownGrubConfig
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def config_for_redhatish(path)
|
54
|
+
if inspec.os[:release].to_f < 7
|
55
|
+
@conf_path = path || '/etc/grub.conf'
|
56
|
+
@version = 'legacy'
|
57
|
+
else
|
58
|
+
@conf_path = path || '/boot/grub2/grub.cfg'
|
59
|
+
@defaults_path = '/etc/default/grub'
|
60
|
+
@grubenv_path = '/boot/grub2/grubenv'
|
61
|
+
@version = 'grub2'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def method_missing(name)
|
66
|
+
read_params[name.to_s]
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
'Grub Config'
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
######################################################################
|
76
|
+
# Grub2 This is used by all supported versions of Ubuntu and Rhel 7+ #
|
77
|
+
######################################################################
|
78
|
+
|
79
|
+
def grub2_parse_kernel_lines(content, conf)
|
80
|
+
menu_entries = extract_menu_entries(content)
|
81
|
+
|
82
|
+
if @kernel == 'default'
|
83
|
+
default_menu_entry(menu_entries, conf['GRUB_DEFAULT'])
|
84
|
+
else
|
85
|
+
menu_entries.find { |entry| entry['name'] == @kernel }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def extract_menu_entries(content)
|
90
|
+
menu_entries = []
|
91
|
+
|
92
|
+
lines = content.split("\n")
|
93
|
+
lines.each_with_index do |line, index|
|
94
|
+
next unless line =~ /^menuentry\s+.*/
|
95
|
+
entry = {}
|
96
|
+
entry['insmod'] = []
|
97
|
+
|
98
|
+
# Extract name from menuentry line
|
99
|
+
capture_data = line.match(/(?:^|\s+).*menuentry\s*['|"](.*)['|"]\s*--/)
|
100
|
+
if capture_data.nil? || capture_data.captures[0].nil?
|
101
|
+
raise Inspec::Exceptions::ResourceFailed "Failed to extract menuentry name from #{line}"
|
102
|
+
end
|
103
|
+
|
104
|
+
entry['name'] = capture_data.captures[0]
|
105
|
+
|
106
|
+
# Begin processing from index forward until a `}` line is met
|
107
|
+
lines.drop(index+1).each do |mline|
|
108
|
+
break if mline =~ /^\s*}\s*$/
|
109
|
+
case mline
|
110
|
+
when /(?:^|\s*)initrd.*/
|
111
|
+
entry['initrd'] = mline.split(' ')[1]
|
112
|
+
when /(?:^|\s*)linux.*/
|
113
|
+
entry['kernel'] = mline.split
|
114
|
+
when /(?:^|\s*)set root=.*/
|
115
|
+
entry['root'] = mline.split('=')[1].tr('\'', '')
|
116
|
+
when /(?:^|\s*)insmod.*/
|
117
|
+
entry['insmod'] << mline.split(' ')[1]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
menu_entries << entry
|
122
|
+
end
|
123
|
+
|
124
|
+
menu_entries
|
125
|
+
end
|
126
|
+
|
127
|
+
def default_menu_entry(menu_entries, default)
|
128
|
+
# If the default entry isn't `saved` then a number is used as an index.
|
129
|
+
# By default this is `0`, which would be the first item in the list.
|
130
|
+
return menu_entries[default.to_i] unless default == 'saved'
|
131
|
+
|
132
|
+
grubenv_contents = inspec.file(@grubenv_path).content
|
133
|
+
|
134
|
+
# The location of the grubenv file is not guaranteed. In the case that
|
135
|
+
# the file does not exist this will return the 0th entry. This will also
|
136
|
+
# return the 0th entry if InSpec lacks permission to read the file. Both
|
137
|
+
# of these reflect the default Grub2 behavior.
|
138
|
+
return menu_entries[0] if grubenv_contents.nil?
|
139
|
+
|
140
|
+
default_name = SimpleConfig.new(grubenv_contents).params['saved_entry']
|
141
|
+
default_entry = menu_entries.select { |k| k['name'] == default_name }[0]
|
142
|
+
return default_entry unless default_entry.nil?
|
143
|
+
|
144
|
+
# It is possible for the saved entry to not be valid . For example, grubenv
|
145
|
+
# not being up to date. If so, the 0th entry is the default.
|
146
|
+
menu_entries[0]
|
147
|
+
end
|
148
|
+
|
149
|
+
###################################################################
|
150
|
+
# Grub1 aka legacy-grub config. Primarily used by Centos/Rhel 6.x #
|
151
|
+
###################################################################
|
152
|
+
|
153
|
+
def parse_kernel_lines(content, conf)
|
154
|
+
# Find all "title" lines and then parse them into arrays
|
155
|
+
menu_entry = 0
|
156
|
+
lines = content.split("\n")
|
157
|
+
kernel_opts = {}
|
158
|
+
lines.each_with_index do |file_line, index|
|
159
|
+
next unless file_line =~ /^title.*/
|
160
|
+
current_kernel = file_line.split(' ', 2)[1]
|
161
|
+
lines.drop(index+1).each do |kernel_line|
|
162
|
+
if kernel_line =~ /^\s.*/
|
163
|
+
option_type = kernel_line.split(' ')[0]
|
164
|
+
line_options = kernel_line.split(' ').drop(1)
|
165
|
+
if (menu_entry == conf['default'].to_i && @kernel == 'default') || current_kernel == @kernel
|
166
|
+
if option_type == 'kernel'
|
167
|
+
kernel_opts['kernel'] = line_options
|
168
|
+
else
|
169
|
+
kernel_opts[option_type] = line_options[0]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
else
|
173
|
+
menu_entry += 1
|
174
|
+
break
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
kernel_opts
|
179
|
+
end
|
180
|
+
|
181
|
+
def read_file(config_file)
|
182
|
+
read_file_content(config_file)
|
183
|
+
end
|
184
|
+
|
185
|
+
def read_params
|
186
|
+
return @params if defined?(@params)
|
187
|
+
|
188
|
+
content = read_file(@conf_path)
|
189
|
+
|
190
|
+
if @version == 'legacy'
|
191
|
+
# parse the file
|
192
|
+
conf = SimpleConfig.new(
|
193
|
+
content,
|
194
|
+
multiple_values: true,
|
195
|
+
).params
|
196
|
+
# convert single entry arrays into strings
|
197
|
+
conf.each do |key, value|
|
198
|
+
if value.size == 1
|
199
|
+
conf[key] = conf[key][0].to_s
|
200
|
+
end
|
201
|
+
end
|
202
|
+
kernel_opts = parse_kernel_lines(content, conf)
|
203
|
+
@params = conf.merge(kernel_opts)
|
204
|
+
end
|
205
|
+
|
206
|
+
if @version == 'grub2'
|
207
|
+
# read defaults
|
208
|
+
defaults = read_file(@defaults_path)
|
209
|
+
|
210
|
+
conf = SimpleConfig.new(
|
211
|
+
defaults,
|
212
|
+
multiple_values: true,
|
213
|
+
).params
|
214
|
+
|
215
|
+
# convert single entry arrays into strings
|
216
|
+
conf.each do |key, value|
|
217
|
+
if value.size == 1
|
218
|
+
conf[key] = conf[key][0].to_s
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
kernel_opts = grub2_parse_kernel_lines(content, conf)
|
223
|
+
@params = conf.merge(kernel_opts)
|
224
|
+
end
|
225
|
+
@params
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,306 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Usage:
|
4
|
+
# describe host('example.com') do
|
5
|
+
# it { should be_resolvable }
|
6
|
+
# it { should be_reachable }
|
7
|
+
# its('ipaddress') { should include '93.184.216.34' }
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# To verify a hostname with protocol and port
|
11
|
+
# describe host('example.com', port: 443, protocol: 'tcp') do
|
12
|
+
# it { should be_reachable }
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# We do not support the following serverspec syntax:
|
16
|
+
# describe host('example.com') do
|
17
|
+
# it { should be_reachable.with( :port => 22 ) }
|
18
|
+
# it { should be_reachable.with( :port => 22, :proto => 'tcp' ) }
|
19
|
+
# it { should be_reachable.with( :port => 53, :proto => 'udp' ) }
|
20
|
+
#
|
21
|
+
# it { should be_resolvable.by('hosts') }
|
22
|
+
# it { should be_resolvable.by('dns') }
|
23
|
+
# end
|
24
|
+
|
25
|
+
require 'resolv'
|
26
|
+
|
27
|
+
module Inspec::Resources
|
28
|
+
class Host < Inspec.resource(1)
|
29
|
+
name 'host'
|
30
|
+
supports platform: 'unix'
|
31
|
+
supports platform: 'windows'
|
32
|
+
desc 'Use the host InSpec audit resource to test the name used to refer to a specific host and its availability, including the Internet protocols and ports over which that host name should be available.'
|
33
|
+
example "
|
34
|
+
describe host('example.com') do
|
35
|
+
it { should be_reachable }
|
36
|
+
it { should be_resolvable }
|
37
|
+
its('ipaddress') { should include '12.34.56.78' }
|
38
|
+
end
|
39
|
+
|
40
|
+
describe host('example.com', port: '80', protocol: 'tcp') do
|
41
|
+
it { should be_reachable }
|
42
|
+
end
|
43
|
+
"
|
44
|
+
|
45
|
+
attr_reader :hostname, :port, :protocol
|
46
|
+
|
47
|
+
def initialize(hostname, params = {})
|
48
|
+
@hostname = hostname
|
49
|
+
@port = params[:port]
|
50
|
+
|
51
|
+
if params[:proto]
|
52
|
+
warn '[DEPRECATION] The `proto` parameter is deprecated. Use `protocol` instead.'
|
53
|
+
@protocol = params[:proto]
|
54
|
+
else
|
55
|
+
@protocol = params.fetch(:protocol, 'icmp')
|
56
|
+
end
|
57
|
+
|
58
|
+
@host_provider = nil
|
59
|
+
if inspec.os.linux?
|
60
|
+
@host_provider = LinuxHostProvider.new(inspec)
|
61
|
+
elsif inspec.os.windows?
|
62
|
+
return skip_resource 'Invalid protocol: only `tcp` and `icmp` protocols are support for the `host` resource on your OS.' unless
|
63
|
+
%w{icmp tcp}.include?(@protocol)
|
64
|
+
|
65
|
+
@host_provider = WindowsHostProvider.new(inspec)
|
66
|
+
elsif inspec.os.darwin?
|
67
|
+
@host_provider = DarwinHostProvider.new(inspec)
|
68
|
+
else
|
69
|
+
return skip_resource 'The `host` resource is not supported on your OS yet.'
|
70
|
+
end
|
71
|
+
|
72
|
+
missing_requirements = @host_provider.missing_requirements(protocol)
|
73
|
+
return skip_resource 'The following requirements are not met for this resource: ' \
|
74
|
+
"#{missing_requirements.join(', ')}" unless missing_requirements.empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
def proto
|
78
|
+
warn '[DEPRECATION] The `proto` method is deprecated. Use `protocol` instead.'
|
79
|
+
protocol
|
80
|
+
end
|
81
|
+
|
82
|
+
# if we get the IP address, the host is resolvable
|
83
|
+
def resolvable?(type = nil)
|
84
|
+
warn "The `host` resource ignores #{type} parameters. Continue to resolve host." if !type.nil?
|
85
|
+
resolve.nil? || resolve.empty? ? false : true
|
86
|
+
end
|
87
|
+
|
88
|
+
def reachable?
|
89
|
+
# ping checks do not require port or protocol
|
90
|
+
return ping.fetch(:success, false) if protocol == 'icmp'
|
91
|
+
|
92
|
+
# if either port or protocol are specified but not both, we cannot proceed.
|
93
|
+
if port.nil? || protocol.nil?
|
94
|
+
raise "Protocol required with port. Use `host` resource with host('#{hostname}', port: 1234, proto: 'tcp') parameters." if port.nil? || protocol.nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
# perform the protocol-specific reachability test
|
98
|
+
ping.fetch(:success, false)
|
99
|
+
end
|
100
|
+
|
101
|
+
def connection
|
102
|
+
ping[:connection]
|
103
|
+
end
|
104
|
+
|
105
|
+
def socket
|
106
|
+
ping[:socket]
|
107
|
+
end
|
108
|
+
|
109
|
+
# returns all A records of the IP address, will return an array
|
110
|
+
def ipaddress
|
111
|
+
resolve.nil? || resolve.empty? ? nil : resolve
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_s
|
115
|
+
resource_name = "Host #{hostname}"
|
116
|
+
resource_name += " port #{port} proto #{protocol}" if port
|
117
|
+
|
118
|
+
resource_name
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def ping
|
124
|
+
return @ping_cache if defined?(@ping_cache)
|
125
|
+
return {} if @host_provider.nil?
|
126
|
+
|
127
|
+
@ping_cache = @host_provider.ping(hostname, port, protocol)
|
128
|
+
end
|
129
|
+
|
130
|
+
def resolve
|
131
|
+
return @ip_cache if defined?(@ip_cache)
|
132
|
+
@ip_cache = @host_provider.resolve(hostname) if !@host_provider.nil?
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class HostProvider
|
137
|
+
attr_reader :inspec
|
138
|
+
def initialize(inspec)
|
139
|
+
@inspec = inspec
|
140
|
+
end
|
141
|
+
|
142
|
+
def missing_requirements(_protocol)
|
143
|
+
# each provider can return an array of missing requirements that can
|
144
|
+
# be enumerated in a skip_resource message
|
145
|
+
[]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class UnixHostProvider < HostProvider
|
150
|
+
def initialize(inspec)
|
151
|
+
super
|
152
|
+
|
153
|
+
@has_nc = inspec.command('nc').exist?
|
154
|
+
@has_ncat = inspec.command('ncat').exist?
|
155
|
+
@has_net_redirections = inspec.command("strings `which bash` | grep -qE '/dev/(tcp|udp)/'").exit_status == 0
|
156
|
+
end
|
157
|
+
|
158
|
+
def missing_requirements(protocol)
|
159
|
+
missing = []
|
160
|
+
|
161
|
+
if %w{tcp udp}.include?(protocol) && !@has_nc && !@has_ncat
|
162
|
+
if @has_net_redirections
|
163
|
+
missing << "#{timeout} (part of coreutils) or netcat must be installed" unless inspec.command(timeout).exist?
|
164
|
+
else
|
165
|
+
missing << 'netcat must be installed'
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
missing
|
170
|
+
end
|
171
|
+
|
172
|
+
def ping(hostname, port, protocol)
|
173
|
+
if %w{tcp udp}.include?(protocol)
|
174
|
+
if @has_nc || @has_ncat
|
175
|
+
resp = inspec.command(netcat_check_command(hostname, port, protocol))
|
176
|
+
else
|
177
|
+
resp = inspec.command("#{timeout} 1 bash -c \"< /dev/#{protocol}/#{hostname}/#{port}\"")
|
178
|
+
end
|
179
|
+
else
|
180
|
+
# fall back to ping, but we can only test ICMP packages with ping
|
181
|
+
resp = inspec.command("ping -w 1 -c 1 #{hostname}")
|
182
|
+
end
|
183
|
+
|
184
|
+
{
|
185
|
+
success: resp.exit_status.to_i.zero?,
|
186
|
+
connection: resp.stderr,
|
187
|
+
socket: resp.stdout,
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
def netcat_check_command(hostname, port, protocol)
|
192
|
+
if @has_nc
|
193
|
+
base_cmd = 'nc'
|
194
|
+
elsif @has_ncat
|
195
|
+
base_cmd = 'ncat'
|
196
|
+
else
|
197
|
+
return
|
198
|
+
end
|
199
|
+
|
200
|
+
if protocol == 'udp'
|
201
|
+
extra_flags = '-u'
|
202
|
+
else
|
203
|
+
extra_flags = ''
|
204
|
+
end
|
205
|
+
|
206
|
+
"echo | #{base_cmd} -v -w 1 #{extra_flags} #{hostname} #{port}"
|
207
|
+
end
|
208
|
+
|
209
|
+
def timeout
|
210
|
+
'timeout'
|
211
|
+
end
|
212
|
+
|
213
|
+
def resolve_with_dig(hostname)
|
214
|
+
addresses = []
|
215
|
+
|
216
|
+
# look for IPv4 addresses
|
217
|
+
cmd = inspec.command("dig +short A #{hostname}")
|
218
|
+
cmd.stdout.lines.each do |line|
|
219
|
+
matched = line.chomp.match(Resolv::IPv4::Regex)
|
220
|
+
addresses << matched.to_s unless matched.nil?
|
221
|
+
end
|
222
|
+
|
223
|
+
# look for IPv6 addresses
|
224
|
+
cmd = inspec.command("dig +short AAAA #{hostname}")
|
225
|
+
cmd.stdout.lines.each do |line|
|
226
|
+
matched = line.chomp.match(Resolv::IPv6::Regex)
|
227
|
+
addresses << matched.to_s unless matched.nil?
|
228
|
+
end
|
229
|
+
|
230
|
+
addresses.empty? ? nil : addresses
|
231
|
+
end
|
232
|
+
|
233
|
+
def resolve_with_getent(hostname)
|
234
|
+
cmd = inspec.command("getent ahosts #{hostname}")
|
235
|
+
return nil unless cmd.exit_status.to_i.zero?
|
236
|
+
|
237
|
+
# getent ahosts output is formatted like so:
|
238
|
+
# $ getent ahosts www.google.com
|
239
|
+
# 172.217.8.4 STREAM www.google.com
|
240
|
+
# 172.217.8.4 DGRAM
|
241
|
+
# 172.217.8.4 RAW
|
242
|
+
# 2607:f8b0:4004:803::2004 STREAM
|
243
|
+
# 2607:f8b0:4004:803::2004 DGRAM
|
244
|
+
# 2607:f8b0:4004:803::2004 RAW
|
245
|
+
addresses = []
|
246
|
+
cmd.stdout.lines.each do |line|
|
247
|
+
ip, = line.split(/\s+/, 2)
|
248
|
+
next unless ip.match(Resolv::IPv4::Regex) || ip.match(Resolv::IPv6::Regex)
|
249
|
+
addresses << ip unless addresses.include?(ip)
|
250
|
+
end
|
251
|
+
|
252
|
+
addresses
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
class DarwinHostProvider < UnixHostProvider
|
257
|
+
def timeout
|
258
|
+
'gtimeout'
|
259
|
+
end
|
260
|
+
|
261
|
+
def resolve(hostname)
|
262
|
+
resolve_with_dig(hostname)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class LinuxHostProvider < UnixHostProvider
|
267
|
+
def resolve(hostname)
|
268
|
+
resolve_with_getent(hostname)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# Windows
|
273
|
+
# TODO: UDP is not supported yey, we need a custom ps1 script to add udp support
|
274
|
+
# @see http://blogs.technet.com/b/josebda/archive/2015/04/18/windows-powershell-equivalents-for-common-networking-commands-ipconfig-ping-nslookup.aspx
|
275
|
+
# @see http://blogs.technet.com/b/heyscriptingguy/archive/2014/03/19/creating-a-port-scanner-with-windows-powershell.aspx
|
276
|
+
class WindowsHostProvider < HostProvider
|
277
|
+
def ping(hostname, port = nil, _proto = nil)
|
278
|
+
# ICMP: Test-NetConnection www.microsoft.com
|
279
|
+
# TCP and port: Test-NetConnection -ComputerName www.microsoft.com -RemotePort 80
|
280
|
+
request = "Test-NetConnection -ComputerName #{hostname} -WarningAction SilentlyContinue"
|
281
|
+
request += " -RemotePort #{port}" unless port.nil?
|
282
|
+
request += '| Select-Object -Property ComputerName, TcpTestSucceeded, PingSucceeded | ConvertTo-Json'
|
283
|
+
cmd = inspec.command(request)
|
284
|
+
|
285
|
+
begin
|
286
|
+
ping = JSON.parse(cmd.stdout)
|
287
|
+
rescue JSON::ParserError => _e
|
288
|
+
return {}
|
289
|
+
end
|
290
|
+
|
291
|
+
{ success: port.nil? ? ping['PingSucceeded'] : ping['TcpTestSucceeded'] }
|
292
|
+
end
|
293
|
+
|
294
|
+
def resolve(hostname)
|
295
|
+
cmd = inspec.command("Resolve-DnsName –Type A #{hostname} | ConvertTo-Json")
|
296
|
+
begin
|
297
|
+
resolv = JSON.parse(cmd.stdout)
|
298
|
+
rescue JSON::ParserError => _e
|
299
|
+
return nil
|
300
|
+
end
|
301
|
+
|
302
|
+
resolv = [resolv] unless resolv.is_a?(Array)
|
303
|
+
resolv.map { |entry| entry['IPAddress'] }
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|