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.conf file contains daemon’s configuration options. This file is useful primarily for performance-tuning purposes.

Additional resources

  • See the fapolicyd(8), fapolicyd.rules(5), 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. 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. Log in as a user without root privileges, and check that application whitelisting is working, for example:

    $ cp /bin/ls /tmp
    $ /tmp/ls
    bash: /tmp/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 /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 steps

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

    $ /tmp/ls
    ls

Additional resources

  • See the fapolicyd.rules(5) 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