Chapter 11. Configuring and managing application whitelists

Application whitelisting efficiently prevents the execution of unknown and potentially malicious software.

11.1. Application whitelisting in RHEL

The fapolicyd software framework introduces a form of application whitelisting and blacklisting based on a user-defined policy. The application whitelisting feature provides 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 YUM 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.

Application whitelisting 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 YUM plugin registers any system update that is handled by the YUM package manager. The plugin notifies the fapolicyd daemon about changes in this database.

An installation using the rpm utility requires a manual refresh of the database, and 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.mounts file contains a list of watched mount points.
  • The fapolicyd.conf file contains daemon’s configuration options. This file is useful primarily for performance-tuning purposes.

Additional resources

  • See the fapolicyd(8), fapolicyd.rules(7), and fapolicyd.conf(5) man pages for more information.

11.2. Deploying application whitelisting

To deploy the fapolicyd framework in RHEL:

Procedure

  1. Install the fapolicyd package:

    # yum install fapolicyd
  2. Generate an initial list of mount points for your system, for example:

    # mount | egrep '^tmpfs| ext4| ext3| xfs' | awk '{ printf "%s\n", $3 }' >> /etc/fapolicyd/fapolicyd.mounts
  3. Enable and start the fapolicyd service:

    # systemctl enable --now fapolicyd

Verification steps

  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. Check that application whitelisting is working, for example:

    # cp /bin/ls /opt
    # cd /opt
    # ./ls
    -bash: ./ls: Operation not permitted

11.3. Adding custom rules for application whitelisting

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 whitelist 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 /opt
    # cd /opt
    # ./ls
    -bash: ./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] 16026

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

  4. Repeat the command that was not permitted:

    # cd /opt
    # ./ls
    -bash: ./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 16026
  6. Find a rule that denies the execution of your application:

    # cat fapolicy.output
    [...]
    rule:8 dec=deny_audit auid=1000 pid=29425 exe=/usr/bin/bash file=/opt/ls
    [...]
  7. Add a new allow rule before the rule that denied the execution of your custom binary in the /etc/fapolicyd/fapolicyd.rules file:

    allow all path=/opt/ls

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

    allow all dir=/opt/
  8. To prevent changes in the content of your custom binary, define the required rule using an SHA-256 checksum:

    $ sha256sum /opt/ls
    780b75c90b2d41ea41679fcb358c892b1251b68d1927c80fbc0d9d148b25e836  ls

    Change the rule in the previous step to the following definition:

    allow all sha256hash=780b75c90b2d41ea41679fcb358c892b1251b68d1927c80fbc0d9d148b25e836
  9. Start the fapolicyd service:

    # systemctl start fapolicyd

Verification steps

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

    # ./ls
    ls

Additional resources

  • See the fapolicyd.rules(7) man page for more information.

11.4. Troubleshooting RHEL application whitelisting

The following section provides tips for basic troubleshooting of the fapolicyd application whitelisting framework and guidance for adding application using the rpm command.

Installing applications using rpm

  • If you install an application using the rpm command, you have to perform a manual refresh of the fapolicyd RPM database:

    1. Install your application:

      # rpm -i application.rpm
    2. Refresh the database:

      # fapolicyd-cli --update

      If you skip this step, the system can freeze and must be restarted.

Service status

  • If fapolicyd does not work correctly, check the service status:

    # systemctl status fapolicyd

Debug mode

  • Debug mode provides detailed information about matched rules, database status, and more. To switch fapolicyd to debug mode:

    1. Stop the fapolicyd service:

      # systemctl stop fapolicyd
    2. Use debug mode to identify a corresponding rule:

      # fapolicyd --debug

      Because the output of the fapolicyd --debug command is verbose, you can redirect the error output to a file:

      # fapolicyd --debug 2> fapolicy.output

Removing the fapolicyd database

  • To solve problems related to the fapolicyd database, try to remove the database file:

    # systemctl stop fapolicyd
    # rm -f /var/lib/fapolicyd/*
    Warning

    Do not remove the /var/lib/fapolicyd/ directory. The fapolicyd framework automatically restores only the database file in this directory.

Application pipe

  • In rare cases, removing the fapolicyd pipe file can solve a lockup:

    # rm -f /var/run/fapolicyd/fapolicyd.fifo

Additional resources

  • See the fapolicyd-cli(1) man page for more information.

11.5. Additional resources

  • See the fapolicyd-related man pages listed using the man -k fapolicyd command for more information.