Skip to content

Commit

Permalink
Allow users to ignore errors when removing built-in policy
Browse files Browse the repository at this point in the history
If you attempt to remove built-in policy, you will get an error like this:
```
Port tcp/NNNN is defined in policy, cannot be deleted
```
If you want to have the role ignore errors like this, use
`selinux_ignore_builtin_removal: true`
  • Loading branch information
richm committed Aug 27, 2022
1 parent db49725 commit b673553
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 4 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ i.e. on the oldest system.

**Note:** Module priorities are ignored in Red Hat Enterprise Linux 6

#### Ignore errors when attempting to remove built-in policy

If you attempt to remove built-in policy, you will get an error like this:
```
include_role:
name: linux-system-roles.selinux
vars:
selinux_ports:
- { ports: '20514', proto: 'tcp', setype: 'syslogd_port_t',
state: 'absent' }
...
Port tcp/20514 is defined in policy, cannot be deleted
```
If you want the role to ignore errors like this, use `selinux_ignore_builtin_removal: true`
```
include_role:
name: linux-system-roles.selinux
vars:
selinux_ignore_builtin_removal: true
selinux_ports:
- { ports: '20514', proto: 'tcp', setype: 'syslogd_port_t',
state: 'absent' }
...
ok
```
The default value is `false`.

## Ansible Facts

### selinux\_reboot\_required
Expand Down
4 changes: 4 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ selinux_booleans_purge: no
selinux_fcontexts_purge: no
selinux_ports_purge: no
selinux_logins_purge: no

# If this is set, ignore errors when attempting
# to remove built-in policy
selinux_ignore_builtin_removal: false
56 changes: 55 additions & 1 deletion tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,67 @@
check_mode: no
when: ansible_check_mode

- name: Get local modifications - port - to check for built-in policy
command: /usr/sbin/semanage port -l -n -C
changed_when: false
register: __selinux_port_local
when:
- selinux_ignore_builtin_removal | bool
- selinux_ports | selectattr("state", "defined") |
selectattr("state", "match", "^absent$") | list | length > 0

- name: Set an SELinux label on a port
seport:
ports: "{{ item.ports }}"
proto: "{{ item.proto | default('tcp') }}"
setype: "{{ item.setype }}"
state: "{{ item.state | default('present') }}"
with_items: "{{ selinux_ports }}"
with_items: "{{ __selinux_ports }}"
vars:
__selinux_local_items: |
{% set items = [] %}
{% for line in __selinux_port_local.stdout_lines | d([]) %}
{% set ary = line.split(maxsplit=2) %}
{% set ports = ary[2].split(", ") %}
{% for port in ports %}
{% set entry = {"state": "absent", "ports": port,
"setype": ary[0], "proto": ary[1]} %}
{% set _ = items.append(entry) %}
{% set intport = port | int %}
{# port can be specified as a string "22" or int 22 #}
{% if intport != 0 %}
{% set entry = {"state": "absent", "ports": intport,
"setype": ary[0], "proto": ary[1]} %}
{% set _ = items.append(entry) %}
{% endif %}
{# if proto is omitted, defaults to tcp #}
{% if ary[1] == "tcp" %}
{% set entry = {"state": "absent", "ports": port,
"setype": ary[0]} %}
{% set _ = items.append(entry) %}
{% if intport != 0 %}
{% set entry = {"state": "absent", "ports": intport,
"setype": ary[0]} %}
{% set _ = items.append(entry) %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
{{ items }}
__selinux_ports: |
{% if selinux_ignore_builtin_removal %}
{% set items = [] %}
{% for item in selinux_ports %}
{% if item.get("state", "present") == "present"
or item in __selinux_local_items %}
{% set _ = items.append(item) %}
{# else do not remove built-in policy #}
{% endif %}
{% endfor %}
{{ items }}
{% else %}
{{ selinux_ports }}
{% endif %}
- name: Set linux user to SELinux user mapping
selogin:
Expand Down
62 changes: 59 additions & 3 deletions tests/tests_port.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
selinux_ports:
- { ports: '22100', proto: 'tcp', setype: 'ssh_port_t',
state: 'present' }
- { ports: 22101, setype: 'http_port_t' }
- { ports: '2049', proto: 'tcp', setype: 'nfs_port_t',
state: 'present' }

- name: include test variables
import_tasks: set_selinux_variables.yml
Expand All @@ -23,6 +26,9 @@
assert:
that: port_before | length > 0

- name: Show all port policy
command: semanage port -l

- name: subsequent changes
include_role:
name: linux-system-roles.selinux
Expand All @@ -31,6 +37,9 @@
selinux_ports:
- { ports: '22022', proto: 'tcp', setype: 'ssh_port_t',
state: 'present' }
- { ports: 22102, setype: 'http_port_t' }
- { ports: '2049', proto: 'tcp', setype: 'nfs_port_t',
state: 'present' }

- name: include test variables
import_tasks: set_selinux_variables.yml
Expand All @@ -41,15 +50,17 @@

- name: Check if there are SELinux port mapping changes
assert:
that: "{{ port_before != port_after }}"
that: port_before != port_after

- name: revert subsequent changes
include_role:
name: linux-system-roles.selinux
vars:
selinux_ports_purge: false
selinux_ports:
- { ports: '22022', proto: 'tcp', setype: 'ssh_port_t',
- { ports: 22022, setype: 'ssh_port_t',
state: 'absent' }
- { ports: '22102', proto: 'tcp', setype: 'http_port_t',
state: 'absent' }

- name: include test variables
Expand All @@ -61,7 +72,52 @@

- name: Check if SELinux port mapping is as before
assert:
that: "{{ port_before == port_after }}"
that: port_before == port_after

- name: Catch error when removing built-in policy
block:
- name: Try to remove a built-in port policy
include_role:
name: linux-system-roles.selinux
vars:
selinux_ports:
- { ports: 2049, setype: 'nfs_port_t',
state: 'absent' }
- { ports: '22022', proto: 'tcp', setype: 'ssh_port_t',
state: 'absent' }
- { ports: 22102, setype: 'http_port_t' }

- name: Unreachable task
fail:
msg: UNREACHABLE
rescue:
- name: Check the error
assert:
that: ansible_failed_result.results | selectattr('msg', 'defined') |
map(attribute='msg') | select('search', __pat) | list | length > 0
vars:
__pat: Port tcp/2049 is defined in policy, cannot be deleted

- name: Ignore errors when removing built-in policy
include_role:
name: linux-system-roles.selinux
vars:
selinux_ports:
- { ports: 2049, setype: 'nfs_port_t',
state: 'absent' }
- { ports: '22022', proto: 'tcp', setype: 'ssh_port_t',
state: 'absent' }
- { ports: 22102, setype: 'http_port_t' }
selinux_ignore_builtin_removal: true

- name: include test variables
import_tasks: set_selinux_variables.yml

- name: Verify that the http port was added
assert:
that: selinux_role_port.stdout_lines |
select('match', '^http_port_t .* tcp .*22102.*') |
list | length > 0

- include_role:
name: linux-system-roles.selinux
Expand Down

0 comments on commit b673553

Please sign in to comment.