Skip to content

Commit

Permalink
refactor: several role improvements
Browse files Browse the repository at this point in the history
When adding files to the trustdb, wait until the server recognizes
that the trustdb is updated before returning.

Do not use compiled C programs for testing trust, just use
executable shell scripts.

Set vars such as __fapolicyd_trust_supported et. al. based on
os family and version rather than using distribution version.
One reason is that CentOS Stream was excluded from many features
but it should be included.

Clean up after tests

Other minor improvements

Signed-off-by: Rich Megginson <[email protected]>
  • Loading branch information
richm committed Nov 29, 2023
1 parent 0ca409d commit 90e3949
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 117 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ ansible-galaxy collection install -vv -r meta/collection-requirements.yml

### fapolicyd_setup_enable_service

Default `false` - if set to `true` the variable makes the service started
and enabled fapolicyd service after successful deployment.
Default `true` - if set to `false` the variable makes the service stopped
and disabled.

### fapolicyd_setup_trust

Expand Down
2 changes: 1 addition & 1 deletion defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Enable or disable service after configuration
# to allow testing and verification before use.
# NB. See ima_evm_setup if planning to use IMA.
fapolicyd_setup_enable_service: false
fapolicyd_setup_enable_service: true

# trust list for fapolicyd configuration file
# default "rpmdb,file"
Expand Down
1 change: 0 additions & 1 deletion examples/simple.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
- name: Example fapolicyd role invocation
hosts: all
vars:
fapolicyd_setup_enable_service: true
fapolicyd_setup_integrity: sha256
fapolicyd_setup_trust: rpmdb,file
fapolicyd_add_trusted_file:
Expand Down
105 changes: 72 additions & 33 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
- Only Enterprise Linux >= 8.1 and Fedora are supported
- System - {{ ansible_facts.os_family }}
- Version - {{ ansible_facts.distribution_version }}
when: (ansible_facts.os_family != "RedHat") or
(ansible_facts.distribution_version is version("8.1", "<"))
when: not __fapolicyd_supported

- name: Check trust compatibility
fail:
Expand All @@ -19,7 +18,7 @@
ignore_errors: true
when:
- fapolicyd_setup_trust | length > 0
- ansible_facts.distribution_version is version("8.2", "<=")
- not __fapolicyd_trust_supported
register: __failed_check_trust

- name: Check integrity compatibility
Expand All @@ -30,7 +29,7 @@
ignore_errors: true
when:
- fapolicyd_setup_integrity | length > 0
- ansible_facts.distribution_version is version("8.3", "<=")
- not __fapolicyd_integrity_supported
register: __failed_check_integrity

- name: Check trust files compatibility
Expand All @@ -41,7 +40,7 @@
ignore_errors: true
when:
- fapolicyd_add_trusted_file | length > 0
- ansible_facts.distribution_version is version("8.3", "<=")
- not __fapolicyd_trustfiles_supported
register: __failed_check_trusted_file

- name: Check failed conditions
Expand All @@ -52,18 +51,13 @@

- name: Install fapolicyd packages
package:
name: "{{ __fapolicyd_packages }}"
name: "{{ __pkgs }}"
state: present
use: "{{ (__fapolicyd_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"

- name: Install fapolicyd-selinux packages
package:
name: "{{ __fapolicyd_selinux_packages }}"
state: present
use: "{{ (__fapolicyd_is_ostree | d(false)) |
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
when: ansible_facts.distribution_version is version("8.3", ">=")
vars:
__pkgs: "{{ __fapolicyd_packages + (__fapolicyd_selinux_packages
if __fapolicyd_selinux_supported else []) }}"

- name: Copy fapolicyd configuration file
template:
Expand All @@ -79,39 +73,84 @@
check_mode: false
changed_when: false
when:
- ansible_facts.distribution_version is version("8.6", ">=")
- __fapolicyd_configcheck_supported | bool
- __fapolicy_conf is changed

- name: Trustdb cleanup
command: fapolicyd-cli --file delete /
when: ansible_facts.distribution_version is version("8.3", ">=")
changed_when: true
failed_when: false

- name: Add file to trustdb
command: fapolicyd-cli --file add {{ item | quote }}
loop: "{{ (fapolicyd_add_trusted_file is string) |
ternary([fapolicyd_add_trusted_file], fapolicyd_add_trusted_file) }}"
when:
- fapolicyd_add_trusted_file | length > 0
- ansible_facts.distribution_version is version("8.3", ">=")
changed_when: true

- name: Start fapolicyd service
service:
name: "{{ __fapolicyd_services }}"
state: restarted
state: started
enabled: true
when: fapolicyd_setup_enable_service | bool
ignore_errors: true
register: __fapolicyd_start

- name: Restart fapolicyd service
service:
name: "{{ __fapolicyd_services }}"
state: restarted
enabled: true
when:
- fapolicyd_setup_enable_service | bool
- __fapolicy_conf is changed
ignore_errors: true
register: __fapolicyd_restart

- name: Check fapolicyd logs
command: journalctl -n5 -u {{ __fapolicyd_services | quote }}
register: __fapolicyd_results
changed_when: false
when: __fapolicyd_restart is failed
failed_when: __fapolicyd_restart is failed
when: __fapolicyd_start is failed or __fapolicyd_restart is failed
failed_when: __fapolicyd_start is failed or __fapolicyd_restart is failed

- name: Trustdb cleanup
command: fapolicyd-cli --file delete /
changed_when: true
failed_when: false

- name: Add file to trustdb
command: fapolicyd-cli --file add {{ item | quote }}
loop: "{{ (fapolicyd_add_trusted_file is string) |
ternary([fapolicyd_add_trusted_file], fapolicyd_add_trusted_file) }}"
changed_when: true

# The problem is that there is a race condition between calling
# fapolicyd-cli --update and when fapolicyd will actually enforce
# the policyd - so we have to look for the 'Updated' message in
# the fapolicyd logs. Also - I don't think we can move this into
# a script, because that script might be excluded by policy!
- name: Update fapolicyd db
when: fapolicyd_setup_enable_service | bool
shell:
cmd: |
set -euxo pipefail
# get current journal cursor
cursor=""
while [ -z "$cursor" ]; do
sleep 1
cursor="$(journalctl -u fapolicyd -n 0 --show-cursor |
awk '/^-- cursor:/ {print $3}')" || :
done
# update trustdb
fapolicyd-cli --update
# wait until we see the message 'Updated' - wait up to 30 seconds
starttime="$(date +%s)"
waittime=30 # seconds
endtime="$(expr "$starttime" + "$waittime")"
set +o pipefail # the read will always return a failure code at EOF
journalctl -u fapolicyd --no-tail -f --after-cursor "$cursor" | \
while read -r line; do
if [[ "$line" =~ fapolicyd[^:\ ]*:\ Updated$ ]]; then
echo SUCCESS: trustdb is updated
exit 0
fi
curtime="$(date +%s)"
if [ "$curtime" -gt "$endtime" ]; then
echo ERROR: trustdb not updated after "$waittime" seconds - exiting
exit 1
fi
done
changed_when: true

- name: Making sure fapolicyd does not run if it was set so
service:
Expand Down
32 changes: 32 additions & 0 deletions tasks/set_vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,35 @@
vars:
__vars_file: "{{ role_path }}/vars/{{ item }}"
when: __vars_file is file

# fapolicyd only supported on EL
# NOTE - some RedHat os_family like CentOS stream and Fedora
# only have major version - in that case, assume the version is
# compatible with the highest released minor version of the
# major version e.g. CentOS stream 8 is the same as EL 8.9
# or higher
- name: Set fapolicyd feature facts for OS versions
vars:
# use temp vars for readability
__major_ver: "{{ ansible_facts['distribution_major_version'] }}"
__ver: "{{ ansible_facts['distribution_version'] }}"
__distro_ver: "{{ (__major_ver == __ver) |
ternary(__major_ver ~ '.9999', __ver) }}"
__is_redhat: "{{ ansible_facts['os_family'] == 'RedHat' }}"
set_fact:
__fapolicyd_supported: "{{ __is_redhat and
__distro_ver is version('8.1', '>=') }}"
__fapolicyd_trust_supported: "{{ __is_redhat and
__distro_ver is version('8.3', '>=') }}"
__fapolicyd_integrity_supported: "{{ __is_redhat and
__distro_ver is version('8.4', '>=') }}"
__fapolicyd_trustfiles_supported: "{{ __is_redhat and
__distro_ver is version('8.4', '>=') }}"
__fapolicyd_selinux_supported: "{{ __is_redhat and
__distro_ver is version('8.3', '>=') }}"
__fapolicyd_configcheck_supported: "{{ __is_redhat and
__distro_ver is version('8.6', '>=') }}"
__fapolicyd_watch_fs_supported: "{{ __is_redhat and
__distro_ver is version('8.2', '>=') }}"
__fapolicyd_syslog_format_supported: "{{ __is_redhat and
__distro_ver is version('8.3', '>=') }}"
4 changes: 2 additions & 2 deletions templates/fapolicyd.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ detailed_report = 1
db_max_size = 50
subj_cache_size = 1549
obj_cache_size = 8191
{% if ansible_facts.distribution_version is version("8.2", ">=") %}
{% if __fapolicyd_watch_fs_supported %}
watch_fs = ext2,ext3,ext4,tmpfs,xfs,vfat,iso9660,btrfs
{% endif %}

{% if fapolicyd_setup_trust | length > 0 %}
trust = {{ fapolicyd_setup_trust }}
{% endif %}

{% if ansible_facts.distribution_version is version("8.3", ">=") %}
{% if __fapolicyd_syslog_format_supported %}
syslog_format = rule,dec,perm,auid,pid,exe,:,path,ftype,trust
{% endif %}

Expand Down
Loading

0 comments on commit 90e3949

Please sign in to comment.