mirror of
https://github.com/inspec/inspec
synced 2024-11-27 15:10:44 +00:00
Merge pull request #5458 from inspec/vasundhara/add_selinux_resource
Add selinux resource with basic feature support
This commit is contained in:
commit
8f4e69abec
7 changed files with 207 additions and 0 deletions
81
docs-chef-io/content/inspec/resources/selinux.md
Normal file
81
docs-chef-io/content/inspec/resources/selinux.md
Normal file
|
@ -0,0 +1,81 @@
|
|||
+++
|
||||
title = "selinux resource"
|
||||
draft = false
|
||||
gh_repo = "inspec"
|
||||
platform = "linux"
|
||||
|
||||
[menu]
|
||||
[menu.inspec]
|
||||
title = "selinux"
|
||||
identifier = "inspec/resources/os/selinux.md selinux resource"
|
||||
parent = "inspec/resources/os"
|
||||
+++
|
||||
|
||||
Use the `selinux` Chef InSpec audit resource to test the state and mode of SELinux policy.
|
||||
|
||||
The `selinux` resource extracts and exposes data reported by the `sestatus` command.
|
||||
|
||||
## Availability
|
||||
|
||||
### Installation
|
||||
|
||||
This resource is distributed along with Chef InSpec itself. You can use it automatically.
|
||||
|
||||
### Version
|
||||
|
||||
## Syntax
|
||||
|
||||
The `selinux` Chef InSpec resource block tests the state and mode of SELinux policy.
|
||||
|
||||
describe selinux do
|
||||
it { should be_installed }
|
||||
it { should_not be_disabled }
|
||||
it { should be_enforcing }
|
||||
it { should_not be_permissive }
|
||||
end
|
||||
|
||||
## Examples
|
||||
|
||||
The following examples show how to use this Chef InSpec selinux resource.
|
||||
|
||||
### Test if SELinux is installed and enabled
|
||||
|
||||
describe selinux do
|
||||
it { should be_installed }
|
||||
it { should_not be_disabled }
|
||||
end
|
||||
|
||||
### Test if SELinux is enabled and running in enforcing mode
|
||||
|
||||
describe selinux do
|
||||
it { should_not be_disabled }
|
||||
it { should be_enforcing }
|
||||
end
|
||||
|
||||
## Matchers
|
||||
|
||||
For a full list of available matchers, please visit our [matchers page](/inspec/matchers/).
|
||||
|
||||
### be_installed
|
||||
|
||||
The `be_installed` matcher tests if the SELinux is installed on the system:
|
||||
|
||||
it { should be_installed }
|
||||
|
||||
### be_disabled
|
||||
|
||||
The `be_disabled` matcher tests if the SELinux is disabled on the system:
|
||||
|
||||
it { should be_disabled }
|
||||
|
||||
### be_enforcing
|
||||
|
||||
The `be_enforcing` matcher tests if the SELinux mode is set to enforcing:
|
||||
|
||||
it { should be_enforcing }
|
||||
|
||||
### be_permissive
|
||||
|
||||
The `be_permissive` matcher tests if the SELinux mode is set to permissive:
|
||||
|
||||
it { should be_permissive }
|
|
@ -103,6 +103,7 @@ require "inspec/resources/rabbitmq_config"
|
|||
require "inspec/resources/registry_key"
|
||||
require "inspec/resources/security_identifier"
|
||||
require "inspec/resources/security_policy"
|
||||
require "inspec/resources/selinux"
|
||||
require "inspec/resources/service"
|
||||
require "inspec/resources/shadow"
|
||||
require "inspec/resources/ssh_config"
|
||||
|
|
53
lib/inspec/resources/selinux.rb
Normal file
53
lib/inspec/resources/selinux.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
require "inspec/resources/command"
|
||||
|
||||
module Inspec::Resources
|
||||
class Selinux < Inspec.resource(1)
|
||||
name "selinux"
|
||||
supports platform: "linux"
|
||||
|
||||
desc "Use selinux Inspec resource to test state/mode of the selinux policy."
|
||||
|
||||
example <<~EXAMPLE
|
||||
describe selinux do
|
||||
it { should be_installed }
|
||||
it { should be_disabled }
|
||||
it { should be_permissive }
|
||||
it { should be_enforcing }
|
||||
end
|
||||
EXAMPLE
|
||||
|
||||
def initialize(selinux_path = "/etc/selinux/config")
|
||||
@path = selinux_path
|
||||
cmd = inspec.command("sestatus")
|
||||
|
||||
if cmd.exit_status != 0
|
||||
# `sestatus` command not found error message comes in stdout so handling both here
|
||||
out = cmd.stdout + "\n" + cmd.stderr
|
||||
return skip_resource "Skipping resource: #{out}"
|
||||
end
|
||||
|
||||
result = cmd.stdout.delete(" ").gsub(/\n/, ",").gsub(/\r/, "").downcase
|
||||
@data = Hash[result.scan(/([^:]+):([^,]+)[,$]/)]
|
||||
end
|
||||
|
||||
def installed?
|
||||
inspec.file(@path).exist?
|
||||
end
|
||||
|
||||
def disabled?
|
||||
@data["selinuxstatus"] == "disabled"
|
||||
end
|
||||
|
||||
def enforcing?
|
||||
@data["currentmode"] == "enforcing"
|
||||
end
|
||||
|
||||
def permissive?
|
||||
@data["currentmode"] == "permissive"
|
||||
end
|
||||
|
||||
def to_s
|
||||
"SELinux"
|
||||
end
|
||||
end
|
||||
end
|
9
test/fixtures/cmd/sestatus
vendored
Normal file
9
test/fixtures/cmd/sestatus
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
SELinux status: enabled
|
||||
SELinuxfs mount: /sys/fs/selinux
|
||||
SELinux root directory: /etc/selinux
|
||||
Loaded policy name: targeted
|
||||
Current mode: enforcing
|
||||
Mode from config file: enforcing
|
||||
Policy MLS status: enabled
|
||||
Policy deny_unknown status: allowed
|
||||
Max kernel policy version: 31
|
11
test/fixtures/files/selinux_conf
vendored
Normal file
11
test/fixtures/files/selinux_conf
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# This file controls the state of SELinux on the system.
|
||||
# SELINUX= can take one of these three values:
|
||||
# enforcing - SELinux security policy is enforced.
|
||||
# permissive - SELinux prints warnings instead of enforcing.
|
||||
# disabled - No SELinux policy is loaded.
|
||||
SELINUX=enforcing
|
||||
# SELINUXTYPE= can take one of three values:
|
||||
# targeted - Targeted processes are protected,
|
||||
# minimum - Modification of targeted policy. Only selected processes are protected.
|
||||
# mls - Multi Level Security protection.
|
||||
SELINUXTYPE=targeted
|
|
@ -171,6 +171,7 @@ class MockLoader
|
|||
"/etc/cron.d/crondotd" => mockfile.call("crondotd"),
|
||||
"/etc/postfix/main.cf" => mockfile.call("main.cf"),
|
||||
"/etc/postfix/other.cf" => mockfile.call("other.cf"),
|
||||
"/etc/selinux/selinux_conf" => mockfile.call("selinux_conf"),
|
||||
}
|
||||
|
||||
# create all mock commands
|
||||
|
@ -556,8 +557,15 @@ class MockLoader
|
|||
|
||||
# filesystem command
|
||||
"2e7e0d4546342cee799748ec7e2b1c87ca00afbe590fa422a7c27371eefa88f0" => cmd.call("get-wmiobject-filesystem"),
|
||||
"sestatus" => cmd.call("sestatus"),
|
||||
}
|
||||
|
||||
if @platform && (@platform[:name] == "windows" || @platform[:name] == "freebsd")
|
||||
mock_cmds.merge!(
|
||||
"sestatus" => empty.call
|
||||
)
|
||||
end
|
||||
|
||||
# ports on linux
|
||||
# allow the ss and/or netstat commands to exist so the later mock is called
|
||||
if @platform && @platform[:name] == "alpine"
|
||||
|
|
44
test/unit/resources/selinux_test.rb
Normal file
44
test/unit/resources/selinux_test.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
require "helper"
|
||||
require "inspec/resource"
|
||||
require "inspec/resources/selinux"
|
||||
|
||||
describe "Inspec::Resources::Selinux" do
|
||||
it "verify selinux is installed" do
|
||||
resource = load_resource("selinux", "/etc/selinux/selinux_conf")
|
||||
_(resource.installed?).must_equal true
|
||||
end
|
||||
|
||||
it "verify selinux state - enforcing" do
|
||||
resource = load_resource("selinux")
|
||||
_(resource.enforcing?).must_equal true
|
||||
end
|
||||
|
||||
it "verify selinux state - permissive" do
|
||||
resource = load_resource("selinux")
|
||||
_(resource.permissive?).must_equal false
|
||||
end
|
||||
|
||||
it "verify selinux disabled " do
|
||||
resource = load_resource("selinux")
|
||||
_(resource.disabled?).must_equal false
|
||||
end
|
||||
|
||||
it "verify selinux on linux" do
|
||||
resource = MockLoader.new(:linux).load_resource("selinux")
|
||||
_(resource.enforcing?).must_equal true
|
||||
_(resource.permissive?).must_equal false
|
||||
_(resource.disabled?).must_equal false
|
||||
end
|
||||
|
||||
it "verify selinux on windows" do
|
||||
resource = MockLoader.new(:windows).load_resource("selinux")
|
||||
_(resource.installed?).must_equal false
|
||||
_(resource.enforcing?).must_equal false
|
||||
end
|
||||
|
||||
it "verify selinux on freebsd" do
|
||||
resource = MockLoader.new(:freebsd12).load_resource("selinux")
|
||||
_(resource.installed?).must_equal false
|
||||
_(resource.enforcing?).must_equal false
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue