Skip to content

Commit

Permalink
Import resources from selinux_policy (#79)
Browse files Browse the repository at this point in the history
* add resources + integration tests from selinux_policy
* Use inspec profiles instead of raw tests
* use native shell_out instead of execute resources in port resource
* use native shell_out instead of execute resources in fcontext resource
* Use shell_out! helper in permissive resource
* update documentation for new resources
* add spec tests for all resources
* appease yamllint
* fix module list on c7
* Standardize documentation format
* Review fixes
* fix tests
* appease mdl
* Fix test idempotency
* add missing header to resource
* add missing documentation links to README

Signed-off-by: Robert Detjens <[email protected]>
  • Loading branch information
detjensrobert authored Sep 2, 2021
1 parent 0bce2b7 commit b35112c
Show file tree
Hide file tree
Showing 57 changed files with 1,307 additions and 224 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ This file is used to list changes made in each version of the selinux cookbook.

## Unreleased

- Import `selinux_policy` resources into this cookbook (`_fcontext`, `_permissive`, and `_port`)
- `selinux_policy_module` not imported since it is a duplicate of `selinux_module`

### Deprecations

- `selinux_fcontext` action `addormodify` renamed to `manage`
- `selinux_port` action `addormodify` renamed to `manage`

## 5.1.1 - *2021-08-30*

- Standardise files with files in sous-chefs/repo-management
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ Disable SELinux only if you plan to not use it. Use `Permissive` mode if you jus
The following resources are provided:

- [selinux_boolean](documentation/selinux_boolean.md)
- [selinux_fcontext](documentation/selinux_fcontext.md)
- [selinux_install](documentation/selinux_install.md)
- [selinux_module](documentation/selinux_module.md)
- [selinux_permissive](documentation/selinux_permissive.md)
- [selinux_port](documentation/selinux_port.md)
- [selinux_state](documentation/selinux_state.md)

## Maintainers
Expand Down
14 changes: 8 additions & 6 deletions documentation/selinux_boolean.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ Introduced: v4.0.0

## Actions

- `:set`
| Action | Description |
| ------ | ---------------------------- |
| `:set` | Set the state of the boolean |

## Properties

| Name | Type | Default | Description | Allowed Values |
| ------------ | ---------------------------- | ------- | ----------------------------------------------- | -------------- |
| `boolean` | String | | SELinux boolean to set | |
| `value` | Integer, String, true, false | | SELinux boolean value | `on`, `off` |
| `persistent` | true, false | true | Set to true for value setting to survive reboot | |
| Name | Type | Default | Description |
| ------------ | -------------------------------- | ------------- | ----------------------------------------------- |
| `boolean` | String | Resource name | SELinux boolean to set |
| `value` | `true`, `false`, `'on'`, `'off'` | | SELinux boolean value |
| `persistent` | `true`, `false` | `true` | Set to true for value setting to survive reboot |

## Examples

Expand Down
48 changes: 48 additions & 0 deletions documentation/selinux_fcontext.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[Back to resource list](../README.md#resources)

# selinux_fcontext

Set the SELinux context of files with `semanage fcontext`.

## Actions

| Action | Description |
| --------- | ------------------------------------------------------------------------------- |
| `:manage` | *(Default)* Assigns the file to the right context regardless of previous state. |
| `:add` | Assigns the file context if not set.(`-a`) |
| `:modify` | Updates the file context if previously set.(`-m`) |
| `:delete` | Removes the file context if set. (`-d`) |

## Properties

| Name | Type | Default | Description |
| ----------- | ------ | --------------- | ---------------------------------------------------------------------------- |
| `file_spec` | String | Resource name | Path or regular expression to files to modify. |
| `secontext` | String | | The SELinux context to assign the file to. |
| `file_type` | String | `a` (all files) | Restrict the resource to only modifying specific file types. See list below. |

Supported file types:

- **`a`** - All files
- **`f`** - Regular files
- **`d`** - Directory
- **`c`** - Character device
- **`b`** - Block device
- **`s`** - Socket
- **`l`** - Symbolic link
- **`p`** - Named pipe

## Examples

```ruby
# Allow http servers (e.g. nginx/apache) to modify moodle files
selinux_policy_fcontext '/var/www/moodle(/.*)?' do
secontext 'httpd_sys_rw_content_t'
end

# Adapt a symbolic link
selinux_policy_fcontext '/var/www/symlink_to_webroot' do
secontext 'httpd_sys_rw_content_t'
file_type 'l'
end
```
27 changes: 13 additions & 14 deletions documentation/selinux_install.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,38 @@ Introduced: v4.0.0

## Actions

- `:install`
- `:upgrade`
- `:remove`
| Action | Description |
| ---------- | ------------------------------------- |
| `:install` | *(Default)* Install required packages |
| `:upgrade` | Upgrade required packages |
| `:remove` | Remove any SELinux-related packages |

## Properties

| Name | Type | Default | Description |
| ---------- | ------------- | -------------------------- | --------------------------- |
| `packages` | String, Array | `default_install_packages` | SELinux packages for system |
| Name | Type | Default | Description |
| ---------- | ------------- | --------------------------------------------------------- | --------------------------- |
| `packages` | String, Array | see [`default_install_packages`](../libraries/install.rb) | SELinux packages for system |

## Examples

### Default installation

```ruby
selinux_install '' do
action :install
end
selinux_install 'example'
```

### Install with excluded packages
### Install with custom packages

```ruby
selinux_install '' do
packages_exclude %w(policycoreutils selinux-policy selinux-policy-targeted )
action :install
selinux_install 'example' do
packages %w(policycoreutils selinux-policy selinux-policy-targeted)
end
```

### Uninstall

```ruby
selinux_install '' do
selinux_install 'example' do
action :remove
end
```
27 changes: 14 additions & 13 deletions documentation/selinux_module.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ Introduced: v4.0.0

## Actions

- `:create`
- `:delete`
- `:install`
- `:remove`
| Action | Description |
| ---------- | ---------------------------------------------------- |
| `:create` | *(Default)* Compile a module and install it |
| `:delete` | Remove module source files from `/etc/selinux/local` |
| `:install` | Install a compiled module into the system |
| `:remove` | Remove a module from the system |

## Properties

| Name | Type | Default | Description |
| ------------- | ------ | -------------------- | ----------------------------------------------- |
| `cookbook` | String | | Cookbook to source from module source file from |
| `module_name` | String | Resource name | Override the module name |
| `content` | String | | Module source as text |
| `source` | String | | Module source file name |
| `content` | String | `nil` | Module source as String |
| `base_dir` | String | `/etc/selinux/local` | Directory to create module source file in |
| `module_name` | String | `name` | Override the module name |
| `cookbook` | String | | Cookbook to source from module source file from |

## Examples

Expand All @@ -30,8 +32,7 @@ selinux_module 'test_create' do
cookbook 'selinux_test'
source 'test.te'
module_name 'test'

action :create
action :install
end
```

Expand All @@ -49,15 +50,15 @@ Consider the following steps to obtain a `.te` file, the rule description format

1. Add `selinux` to your `metadata.rb`, as for instance: `depends 'selinux', '>= 0.10.0'`;
2. Run your SELinux workflow, and add `.te` files on your cookbook files, preferably under `files/default/selinux` directory;
3. Write recipes using `selinux_module` provider;
3. Write recipes using `selinux_module` resource;

### SELinux `audit2allow` Workflow

This provider was written with the intention of matching the workflow of `audit2allow` (provided by package `policycoreutils`), which basically will be:
This resource was written with the intention of matching the workflow of `audit2allow` (provided by package `policycoreutils`), which basically will be:

1. Test application and inspect `/var/log/audit/audit.log` log-file with a command like this basic example: `grep AVC /var/log/audit/audit.log |audit2allow -M my_application`;
1. Test application and inspect `/var/log/audit/audit.log` log-file with a command like this basic example: `grep AVC /var/log/audit/audit.log | audit2allow -M my_application`;
2. Save `my_application.te` SELinux module source, copy into your cookbook under `files/default/selinux/my_application.te`;
3. Make use of `selinux` provider on a recipe, after adding it as a dependency;
3. Make use of `selinux` resource on a recipe, after adding it as a dependency;

For example, add the following on the recipe level:

Expand Down
29 changes: 29 additions & 0 deletions documentation/selinux_permissive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[Back to resource list](../README.md#resources)

# selinux_permissive

Allows some types to misbehave without stopping them. Not as good as specific policies, but better than disabling SELinux entirely.

> This does not set the SELinux state to permissive! Use [`selinux_state`](selinux_state.md) for that.
## Actions

| Action | Description |
| --------- | -------------------------------------------------- |
| `:add` | *(Default)* Adds a permissive, unless already set. |
| `:delete` | Removes a permissive, if set. |

## Properties

| Name | Type | Default | Description |
| --------- | ------ | ------------- | ------------------------------------------- |
| `context` | String | Resource name | Name of the context to disable SELinux for. |

## Examples

```ruby
# Disable enforcement on Apache
selinux_permissive 'httpd_t' do
notifies :restart, 'service[httpd]'
end
```
32 changes: 32 additions & 0 deletions documentation/selinux_port.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[Back to resource list](../README.md#resources)

# selinux_policy_port

Allows assigning a network port to a certain SELinux context, e.g. for running a webserver on a non-standard port.

## Actions

| Action | Description |
| --------- | ------------------------------------------------------------------------------- |
| `:manage` | *(Default)* Assigns the port to the right context regardless of previous state. |
| `:add` | Assigns the port context if not set.(`-a`) |
| `:modify` | Updates the port context if previously set.(`-m`) |
| `:delete` | Removes the port context if set. (`-d`) |

## Properties

| Name | Type | Default | Description |
| ----------- | ------ | ------------- | ------------------------------------------ |
| `port` | String | Resource name | The port in question. |
| `protocol` | String | | Either `tcp` or `udp`. |
| `secontext` | String | | The SELinux context to assign the port to. |

## Examples

```ruby
# Allow nginx/apache to bind to port 5678 by giving it the http_port_t context
selinux_policy_port '5678' do
protocol 'tcp'
secontext 'http_port_t'
end
```
21 changes: 13 additions & 8 deletions documentation/selinux_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,22 @@ Introduced: v4.0.0

## Actions

- `:disabled`
- `:enforcing`
- `:permissive`
| Action | Description |
| ------------- | ---------------------------------------------- |
| `:enforcing` | *(Default)* Set the SELinux state to enforcing |
| `:permissive` | Set the state to permissive |
| `:disabled` | Set the state to disabled |
`
> ⚠ Switching to or from `disabled` requires a reboot!
## Properties

| Name | Type | Default | Description |
| ------------- | ----------- | --------------------- | ------------------------------------------------------- |
| `config_file` | String | `/etc/selinux/config` | Path to SELinux config file on disk |
| `persistent` | true, false | `true` | Persist status update to the selinux configuration file |
| `policy` | String | `targeted` | SELinux policy type |
| Name | Type | Default | Description |
| ------------------ | ------------------- | --------------------- | ------------------------------------------------------------------ |
| `config_file` | String | `/etc/selinux/config` | Path to SELinux config file on disk |
| `persistent` | true, false | `true` | Persist status update to the selinux configuration file |
| `policy` | String | `targeted` | SELinux policy type |
| `automatic_reboot` | true, false, Symbol | `false` | Whether to automatically reboot the node if needed to change state |

## Examples

Expand Down
35 changes: 22 additions & 13 deletions kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ provisioner:
name: chef_zero
product_name: chef
chef_license: accept-no-persist
multiple_converge: 2
enforce_idempotency: true
deprecations_as_errors: true
product_version: <%= ENV['CHEF_VERSION'] || 'latest' %>
log_level: <%= ENV['CHEF_LOG_LEVEL'] || 'auto' %>
Expand Down Expand Up @@ -35,27 +37,34 @@ suites:
- recipe[selinux_test::enforcing]
- recipe[selinux_test::debian_enforcing_prepare]
- recipe[selinux_test::module_create]
- recipe[selinux_test::module_remove]
- recipe[selinux_test::boolean]
verifier:
inspec_tests:
- test/integration/common
- test/integration/enforcing
provisioner:
# not idempotent on debian/ubuntu due to debian_enforcing_prepare & module_create/remove
multiple_converge: 1
enforce_idempotency: false
- name: permissive
run_list:
- recipe[selinux_test::install]
- recipe[selinux::permissive]
- recipe[selinux_test::module_create]
- recipe[selinux_test::module_remove]
- recipe[selinux_test::boolean]
verifier:
inspec_tests:
- test/integration/common
- test/integration/permissive
- name: disabled
run_list:
- recipe[selinux_test::install]
- recipe[selinux::disabled]
verifier:
inspec_tests:
- test/integration/common
- test/integration/disabled
- name: port
run_list:
- recipe[selinux_test::install]
- recipe[selinux::permissive]
- recipe[selinux_test::port]
- name: fcontext
run_list:
- recipe[selinux_test::install]
- recipe[selinux::permissive]
- recipe[selinux_test::fcontext]
- name: permissive_resource
run_list:
- recipe[selinux_test::install]
- recipe[selinux::permissive]
- recipe[selinux_test::permissive_resource]
8 changes: 4 additions & 4 deletions libraries/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ module InstallHelpers
def default_install_packages
case node['platform_family']
when 'rhel', 'fedora', 'amazon'
%w(make policycoreutils selinux-policy selinux-policy-targeted selinux-policy-devel libselinux-utils)
%w(make policycoreutils selinux-policy selinux-policy-targeted selinux-policy-devel libselinux-utils setools-console)
when 'debian'
if node['platform'] == 'ubuntu'
if node['platform_version'].to_f == 18.04
%w(make policycoreutils selinux selinux-basics selinux-policy-default selinux-policy-dev auditd)
%w(make policycoreutils selinux selinux-basics selinux-policy-default selinux-policy-dev auditd setools)
else
%w(make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd)
%w(make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd setools)
end
else
%w(make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd)
%w(make policycoreutils selinux-basics selinux-policy-default selinux-policy-dev auditd setools)
end
end
end
Expand Down
Loading

0 comments on commit b35112c

Please sign in to comment.