Red Hat Training

A Red Hat training course is available for RHEL 8

Chapter 14. Blocking and allowing applications using fapolicyd

Setting and enforcing a policy that either allows or denies application execution based on a rule set efficiently prevents the execution of unknown and potentially malicious software.

14.1. Introduction to fapolicyd

The fapolicyd software framework controls the execution of applications based on a user-defined policy. This is one of the most efficient ways to prevent running untrusted and possibly malicious applications on the system.

The fapolicyd framework provides the following components:

  • fapolicyd service
  • fapolicyd command-line utilities
  • fapolicyd RPM plugin
  • fapolicyd rule language

The administrator can define the allow and deny execution rules for any application with the possibility of auditing based on a path, hash, MIME type, or trust.

The fapolicyd framework introduces the concept of trust. An application is trusted when it is properly installed by the system package manager, and therefore it is registered in the system RPM database. The fapolicyd daemon uses the RPM database as a list of trusted binaries and scripts. The fapolicyd RPM plugin registers any system update that is handled by either the YUM package manager or the RPM Package Manager. The plugin notifies the fapolicyd daemon about changes in this database. Other ways of adding applications require the creation of custom rules and restarting the fapolicyd service.

The fapolicyd service configuration is located in the /etc/fapolicyd/ directory with the following structure:

  • The fapolicyd.rules file contains allow and deny execution rules.
  • The fapolicyd.conf file contains daemon’s configuration options. This file is useful primarily for performance-tuning purposes.

You can use one of the ways for fapolicyd integrity checking:

  • file-size checking
  • comparing SHA-256 hashes
  • Integrity Measurement Architecture (IMA) subsystem

By default, fapolicyd does no integrity checking. Integrity checking based on the file size is fast, but an attacker can replace the content of the file and preserve its byte size. Computing and checking SHA-256 checksums is more secure, but it affects the performance of the system. The integrity = ima option in fapolicyd.conf requires support for files extended attributes (also known as xattr) on all file systems containing executable files.

Additional resources

14.2. Deploying fapolicyd

To deploy the fapolicyd framework in RHEL:

Procedure

  1. Install the fapolicyd package:

    # yum install fapolicyd
  2. Enable and start the fapolicyd service:

    # systemctl enable --now fapolicyd

Verification

  1. Verify that the fapolicyd service is running correctly:

    # systemctl status fapolicyd
    ● fapolicyd.service - File Access Policy Daemon
       Loaded: loaded (/usr/lib/systemd/system/fapolicyd.service; enabled; vendor p>
       Active: active (running) since Tue 2019-10-15 18:02:35 CEST; 55s ago
      Process: 8818 ExecStart=/usr/sbin/fapolicyd (code=exited, status=0/SUCCESS)
     Main PID: 8819 (fapolicyd)
        Tasks: 4 (limit: 11500)
       Memory: 78.2M
       CGroup: /system.slice/fapolicyd.service
               └─8819 /usr/sbin/fapolicyd
    
    Oct 15 18:02:35 localhost.localdomain systemd[1]: Starting File Access Policy D>
    Oct 15 18:02:35 localhost.localdomain fapolicyd[8819]: Initialization of the da>
    Oct 15 18:02:35 localhost.localdomain fapolicyd[8819]: Reading RPMDB into memory
    Oct 15 18:02:35 localhost.localdomain systemd[1]: Started File Access Policy Da>
    Oct 15 18:02:36 localhost.localdomain fapolicyd[8819]: Creating database
  2. Log in as a user without root privileges, and check that fapolicyd is working, for example:

    $ cp /bin/ls /tmp
    $ /tmp/ls
    bash: /tmp/ls: Operation not permitted

14.3. Marking files as trusted using an additional source of trust

You can use this procedure for using an additional source of trust for fapolicyd. Before RHEL 8.3, fapolicyd trusted only files contained in the RPM database. The fapolicyd framework now supports also use of the /etc/fapolicyd/fapolicyd.trust plain-text file as a source of trust. You can either modify fapolicyd.trust directly with a text editor or through fapolicyd CLI commands.

Note

Prefer marking files as trusted using fapolicyd.trust instead of writing custom fapolicyd rules.

Prerequisites

  • The fapolicyd framework is deployed on your system.

Procedure

  1. Copy your custom binary to the required directory, for example:

    $ cp /bin/ls /tmp
    $ /tmp/ls
    bash: /tmp/ls: Operation not permitted
  2. Mark your custom binary as trusted:

    # fapolicyd-cli --file add /tmp/ls

    Note that previous command add the corresponding line to /etc/fapolicyd/fapolicyd.trust.

  3. Update the fapolicyd database:

    # fapolicyd-cli --update
  4. Restart fapolicyd:

    # systemctl restart fapolicyd

Verification

  1. Check that your custom binary can be now executed, for example:

    $ /tmp/ls
    ls

Additional resources

  • fapolicyd.trust(5) man page.

14.4. Adding custom allow and deny rules for fapolicyd

The default set of rules in the fapolicyd package does not affect system functions. For custom scenarios, such as storing binaries and scripts in a non-standard directory or adding applications without the yum or rpm installers, you must modify existing or add new rules. The following steps demonstrate adding a new rule to allow a custom binary.

Prerequisites

  • The fapolicyd framework is deployed on your system.

Procedure

  1. Copy your custom binary to the required directory, for example:

    $ cp /bin/ls /tmp
    $ /tmp/ls
    bash: /tmp/ls: Operation not permitted
  2. Stop the fapolicyd service:

    # systemctl stop fapolicyd
  3. Use debug mode to identify a corresponding rule. Because the output of the fapolicyd --debug command is verbose and you can stop it only by pressing Ctrl+C or killing the corresponding process, redirect the error output to a file:

    # fapolicyd --debug 2> fapolicy.output &
    [1] 51341

    Alternatively, you can run fapolicyd debug mode in another terminal.

  4. Repeat the command that was not permitted:

    $ /tmp/ls
    bash: /tmp/ls: Operation not permitted
  5. Stop debug mode by resuming it in the foreground and pressing Ctrl+C:

    # fg
    fapolicyd --debug
    ^Cshutting down...
    Inter-thread max queue depth 1
    Allowed accesses: 2
    Denied accesses: 1
    [...]

    Alternatively, kill the process of fapolicyd debug mode:

    # kill 51341
  6. Find a rule that denies the execution of your application:

    # cat fapolicy.output
    [...]
    rule:9 dec=deny_audit perm=execute auid=1000 pid=51362 exe=/usr/bin/bash : file=/tmp/ls ftype=application/x-executable
    [...]
  7. Add a new allow rule before the rule that denied the execution of your custom binary in the /etc/fapolicyd/fapolicyd.rules file. The output of the previous command indicated that the rule is the rule number 9 in this example:

    allow perm=execute exe=/usr/bin/bash trust=1 : path=/tmp/ls ftype=application/x-executable trust=0

    Alternatively, you can allow executions of all binaries in the /tmp directory by adding the following rule in the /etc/fapolicyd/fapolicyd.rules file:

    allow perm=execute exe=/usr/bin/bash trust=1 : dir=/tmp/ all trust=0
  8. To prevent changes in the content of your custom binary, define the required rule using an SHA-256 checksum:

    $ sha256sum /tmp/ls
    780b75c90b2d41ea41679fcb358c892b1251b68d1927c80fbc0d9d148b25e836  ls

    Change the rule to the following definition:

    allow perm=execute exe=/usr/bin/bash trust=1 : sha256hash=780b75c90b2d41ea41679fcb358c892b1251b68d1927c80fbc0d9d148b25e836
  9. Start the fapolicyd service:

    # systemctl start fapolicyd

Verification

  1. Check that your custom binary can be now executed, for example:

    $ /tmp/ls
    ls

Additional resources

  • fapolicyd.trust(5) man page.

14.5. Enabling fapolicyd integrity checks

By default, fapolicyd does not perform integrity checking. You can configure fapolicyd to perform integrity checks by comparing either file sizes or SHA-256 hashes. You can also set integrity checks by using the Integrity Measurement Architecture (IMA) subsystem.

Prerequisites

  • The fapolicyd framework is deployed on your system.

Procedure

  1. Open the /etc/fapolicyd/fapolicyd.conf file in a text editor of your choice, for example:

    # vi /etc/fapolicyd/fapolicyd.conf
  2. Change the value of the integrity option from none to sha256, save the file, and exit the editor:

    integrity = sha256
  3. Restart the fapolicyd service:

    # systemctl restart fapolicyd

Verification

  1. Back up the file used for the verification:

    # cp /bin/more /bin/more.bak
  2. Change the content of the /bin/more binary:

    # cat /bin/less > /bin/more
  3. Use the changed binary as a regular user:

    # su example.user
    $ /bin/more /etc/redhat-release
    bash: /bin/more: Operation not permitted
  4. Revert the changes:

    # mv -f /bin/more.bak /bin/more

14.7. Additional resources

  • fapolicyd-related man pages listed by using the man -k fapolicyd command.
  • The FOSDEM 2020 fapolicyd presentation.