Chapter 11. 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.
11.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
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.
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
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 containsallow
anddeny
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)
, andfapolicyd.conf(5)
man pages for more information.
11.2. Deploying fapolicyd
To deploy the fapolicyd
framework in RHEL:
Procedure
Install the
fapolicyd
package:# yum install fapolicyd
Enable and start the
fapolicyd
service:# systemctl enable --now fapolicyd
Verification steps
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
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
11.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.
Prefer marking files as trusted using fapolicyd.trust
instead of writing custom fapolicyd
rules.
Prerequisites
-
The
fapolicyd
framework is deployed on your system.
Procedure
Copy your custom binary to the required directory, for example:
$ cp /bin/ls /tmp $ /tmp/ls bash: /tmp/ls: Operation not permitted
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
.Restart
fapolicyd
:# systemctl restart fapolicyd
Verification steps
Check that your custom binary can be now executed, for example:
$ /tmp/ls ls
Additional resources
-
See the
fapolicyd.trust(5)
man page for more information.
11.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
Copy your custom binary to the required directory, for example:
$ cp /bin/ls /tmp $ /tmp/ls bash: /tmp/ls: Operation not permitted
Stop the
fapolicyd
service:# systemctl stop fapolicyd
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.Repeat the command that was not permitted:
$ /tmp/ls bash: /tmp/ls: Operation not permitted
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
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 [...]
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
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
Start the
fapolicyd
service:# systemctl start fapolicyd
Verification steps
Check that your custom binary can be now executed, for example:
$ /tmp/ls ls
Additional resources
-
See the
fapolicyd.trust(5)
man page for more information.
11.6. Additional resources
-
See the
fapolicyd
-related man pages listed using theman -k fapolicyd
command for more information. -
The FOSDEM 2020 fapolicyd presentation provides several examples of adding custom
fapolicyd
rules.