Questo contenuto non è disponibile nella lingua selezionata.
Chapter 10. Blocking and allowing applications by using fapolicyd
Use the fapolicyd framework to implement an application allowlist solution that helps increase system security. 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.
10.1. The fapolicyd framework structure Copia collegamentoCollegamento copiato negli appunti!
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.
- Components and trust
The
fapolicydframework provides the following components:-
fapolicydservice -
fapolicydcommand-line utilities, such as thefapolicyd-clicommand and thefagenrulesscript -
fapolicydRPM plugin
The administrator can define
allowanddenyexecution rules for any application with the option to audit based on a path, hash, MIME type, or trust.The
fapolicydframework introduces the concept of trust. An application is trusted when the system package manager correctly installs it and therefore registered in the system RPM database. Thefapolicyddaemon uses the RPM database as a list of trusted binaries and scripts.The
fapolicydRPM plugin registers any system update that is handled by either the DNF or RPM package manager. The plugin notifies thefapolicyddaemon about changes in this database. Other ways of adding applications require the creation of custom rules and restarting thefapolicydservice.For more information, see the
fapolicyd-related man pages listed by using theman -k fapolicydcommand on your system.-
- Configuration files and directories
The
fapolicydservice configuration is located in the/etc/fapolicyd/directory with the following structure:-
The
/etc/fapolicyd/fapolicyd.trustfile contains a list of trusted files. You can also use multiple trust files in the/etc/fapolicyd/trust.d/directory. -
The
/etc/fapolicyd/rules.d/directory contains files withallowanddenyexecution rules. Thefagenrulesscript merges these component rules files to the/etc/fapolicyd/compiled.rulesfile. -
The
fapolicyd.conffile contains the daemon’s configuration options. This file is useful primarily for performance-tuning purposes.
-
The
- Rules
Rules in
/etc/fapolicyd/rules.d/are organized in several files, each representing a different policy goal. The numbers at the beginning of the corresponding file names determine the order in/etc/fapolicyd/compiled.rules:Expand 10
language rules
20
Dracut-related rules
21
rules for updaters
30
patterns
40
ELF rules
41
shared objects rules
42
trusted ELF rules
70
trusted language rules
72
shell rules
90
deny execute rules
95
allow open rules
For more information and examples, see the documentation installed with the
fapolicydpackage in the/usr/share/doc/fapolicyd/directory, the/usr/share/fapolicyd/sample-rules/README-rulesfile, and thefapolicyd.rules(5)andfagenrules(8)man pages on your system.- Integrity checking
You can use one of the following ways for
fapolicydintegrity checking:- File-size checking
- Comparing SHA-256 hashes
- Integrity Measurement Architecture (IMA) subsystem
By default,
fapolicyddoes 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. Theintegrity = imaoption infapolicyd.confrequires support for files' extended attributes (also known asxattr) on all file systems containing executable files.
10.2. Deploying fapolicyd Copia collegamentoCollegamento copiato negli appunti!
When deploying the fapolicyd application allowlisting framework, you can either try your configuration in permissive mode first or directly enable the service in the default configuration.
Procedure
Install the
fapolicydpackage:# dnf install fapolicydSet the Audit subsystem for recording
fapolicydevents:# auditctl -w /etc/fapolicyd/ -p wa -k fapolicyd_changes # service try-restart auditdOptional: To try your configuration first, change mode to permissive.
Open the
/etc/fapolicyd/fapolicyd.conffile in a text editor of your choice, for example:# vi /etc/fapolicyd/fapolicyd.confChange the value of the
permissiveoption from0to1, save the file, and exit the editor:permissive = 1Alternatively, you can debug your configuration by using the
fapolicyd --debug-deny --permissivecommand before you start the service. See the Troubleshooting problems related to fapolicyd section for more information.
Enable and start the
fapolicydservice:# systemctl enable --now fapolicydIf you enabled permissive mode through
/etc/fapolicyd/fapolicyd.conf:- Use your applications.
Check Audit logs for
fanotifydenials, for example:# ausearch -ts recent -m fanotifyWhen debugged, disable permissive mode by changing the corresponding value back to
permissive = 0, and restart the service:# systemctl restart fapolicyd
Verification
Verify that the
fapolicydservice is running correctly:# systemctl status fapolicyd ● fapolicyd.service - File Access Policy Daemon Loaded: loaded (/usr/lib/systemd/system/fapolicyd.service; enabled; preset: disabled) Active: active (running) since Tue 2024-10-08 05:53:50 EDT; 11s ago … Oct 08 05:53:51 machine1.example.com fapolicyd[4974]: Loading trust data from rpmdb backend Oct 08 05:53:51 machine1.example.com fapolicyd[4974]: Loading trust data from file backend Oct 08 05:53:51 machine1.example.com fapolicyd[4974]: Starting to listen for eventsLog in as a user without root privileges, and check that
fapolicydis working, for example:$ cp /bin/ls /tmp $ /tmp/ls bash: /tmp/ls: Operation not permitted
10.3. Marking files as trusted using an additional source of trust Copia collegamentoCollegamento copiato negli appunti!
The fapolicyd framework trusts files contained in the RPM database. You can mark additional files as trusted by modifying sources of trust.
You can modify the /etc/fapolicyd/fapolicyd.trust plain text file or files in the /etc/fapolicyd/trust.d directory, either directly using a text editor or through fapolicyd-cli commands. See the fapolicyd.trust(13) and fapolicyd-cli(8) man pages on your system for more details.
For performance reasons, mark files as trusted using fapolicyd.trust or trust.d/ rather than write custom fapolicyd rules.
Prerequisites
-
The
fapolicydframework 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 permittedMark your custom binary as trusted, and store the corresponding entry to the
myappfile in/etc/fapolicyd/trust.d/:# fapolicyd-cli --file add /tmp/ls --trust-file myapp-
If you skip the
--trust-fileoption, then the previous command adds the corresponding line to/etc/fapolicyd/fapolicyd.trust. To mark all existing files in a directory as trusted, provide the directory path as an argument of the
--fileoption, for example:# fapolicyd-cli --file add /tmp/my_bin_dir/ --trust-file myapp
-
If you skip the
Update the
fapolicyddatabase:# fapolicyd-cli --updateNoteChanging the content of a trusted file or directory changes its checksum, and therefore,
fapolicydno longer considers it trusted.To restore trust in the new content, refresh the file trust database by using the
fapolicyd-cli --file updatecommand. If you do not provide any argument, the entire database refreshes. Alternatively, you can specify a path to a specific file or directory. Then, update the database by usingfapolicyd-cli --update.
Verification
Check that you can execute your custom binary, for example:
$ /tmp/ls ls
10.4. Adding custom allow and deny rules for fapolicyd Copia collegamentoCollegamento copiato negli appunti!
The default set of fapolicyd rules does not affect system functions. For custom scenarios, such as storing binaries and scripts in a non-standard directory or adding applications without the DNF or RPM installers, you must either mark additional files as trusted or add new custom rules.
For basic scenarios, see Marking files as trusted using an additional source of trust. In more advanced scenarios such as allowing to execute a custom binary only for specific user and group identifiers, add new custom rules to the /etc/fapolicyd/rules.d/ directory.
The following steps demonstrate adding a new rule to allow a custom binary.
For more information and examples, see the documentation installed with the fapolicyd package in the /usr/share/doc/fapolicyd/ directory, the /usr/share/fapolicyd/sample-rules/README-rules file, and the fapolicyd.rules(5) and fagenrules(8) man pages on your system.
Prerequisites
-
The
fapolicydframework 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 permittedStop the
fapolicydservice:# systemctl stop fapolicydUse debug mode to identify a corresponding rule. Because the output of the
fapolicyd --debugcommand is verbose and you can stop it only by pressing Ctrl+C or killing the corresponding process, redirect the error output to a file. In this case, you can limit the output only to access denials by using the--debug-denyoption instead of--debug:# fapolicyd --debug-deny 2> fapolicy.output & [1] 51341Alternatively, you can run
fapolicyddebug mode in another terminal.Repeat the command that
fapolicyddenied:$ /tmp/ls bash: /tmp/ls: Operation not permittedStop debug mode by resuming it in the foreground and pressing Ctrl+C:
# fg fapolicyd --debug 2> fapolicy.output ^C …Alternatively, kill the process of
fapolicyddebug mode:# kill 51341Find a rule that denies the execution of your application:
# cat fapolicy.output | grep 'deny_audit' … rule=13 dec=deny_audit perm=execute auid=0 pid=6855 exe=/usr/bin/bash : path=/tmp/ls ftype=application/x-executable trust=0Locate the file that contains a rule that denies the execution of your custom binary. In this case, the
deny_audit perm=executerule belongs to the90-deny-execute.rulesfile:# ls /etc/fapolicyd/rules.d/ 10-languages.rules 40-bad-elf.rules 72-shell.rules 20-dracut.rules 41-shared-obj.rules 90-deny-execute.rules 21-updaters.rules 42-trusted-elf.rules 95-allow-open.rules 30-patterns.rules 70-trusted-lang.rules # cat /etc/fapolicyd/rules.d/90-deny-execute.rules # Deny execution for anything untrusted deny_audit perm=execute all : allAdd a new
allowrule to a file that lexically precedes the rule file that contains the rule that denied the execution of your custom binary in the/etc/fapolicyd/rules.d/directory.Create the rule file and open it in a text editor of your choice, for example:
# touch /etc/fapolicyd/rules.d/80-myapps.rules # vi /etc/fapolicyd/rules.d/80-myapps.rulesInsert the following rule to the
80-myapps.rulesfile:allow perm=execute exe=/usr/bin/bash trust=1 : path=/tmp/ls ftype=application/x-executable trust=0Alternatively, you can allow executions of all binaries in the
/tmpdirectory by adding the following rule to the rule file in/etc/fapolicyd/rules.d/:allow perm=execute exe=/usr/bin/bash trust=1 : dir=/tmp/ trust=0ImportantTo make a rule effective recursively on all directories under the specified directory, add a trailing slash to the value of the
dir=parameter in the rule (/tmp/in the previous example).
Prevent changes in the content of your custom binary
Define the required rule using an SHA-256 checksum:
$ sha256sum /tmp/ls 780b75c90b2d41ea41679fcb358c892b1251b68d1927c80fbc0d9d148b25e836 lsChange the rule to the following definition:
allow perm=execute exe=/usr/bin/bash trust=1 : sha256hash=780b75c90b2d41ea41679fcb358c892b1251b68d1927c80fbc0d9d148b25e836
Check that the list of compiled rules differs from the rule set in
/etc/fapolicyd/rules.d/:# fagenrules --check /usr/sbin/fagenrules: Rules have changed and should be updatedUpdate the list, which is stored in the
/etc/fapolicyd/compiled.rulesfile:# fagenrules --loadCheck that your custom rule is in the list of
fapolicydrules before the rule that denied the execution:# fapolicyd-cli --list ... 13. allow perm=execute exe=/usr/bin/bash trust=1 : path=/tmp/ls ftype=application/x-executable trust=0 14. deny_audit perm=execute all : all …Start the
fapolicydservice:# systemctl start fapolicyd
Verification
Check that your custom binary can be now executed, for example:
$ /tmp/ls ls
10.5. Enabling fapolicyd integrity checks Copia collegamentoCollegamento copiato negli appunti!
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
fapolicydframework is deployed on your system.
Procedure
Open the
/etc/fapolicyd/fapolicyd.conffile in a text editor of your choice, for example:# vi /etc/fapolicyd/fapolicyd.confChange the value of the
integrityoption fromnonetosha256, save the file, and exit the editor:integrity = sha256Restart the
fapolicydservice:# systemctl restart fapolicyd
Verification
Back up the file used for the verification:
# cp /bin/more /bin/more.bakChange the content of the
/bin/morebinary:# cat /bin/less > /bin/moreAttempt to use the changed binary as a regular user and verify
fapolicyddenies the operation:# su example.user $ /bin/more /etc/redhat-release bash: /bin/more: Operation not permittedRevert the changes:
# mv -f /bin/more.bak /bin/more
10.7. Preventing users from executing untrustworthy code by using the fapolicyd RHEL system role Copia collegamentoCollegamento copiato negli appunti!
You can automate the installation and configuration of the fapolicyd service by using the fapolicyd RHEL system role.
With this role, you can remotely configure the service to allow users to execute only trusted applications, for example, the ones which are listed in the RPM database and in an allow list. Additionally, the service can perform integrity checks before it executes an allowed application.
Prerequisites
- You have prepared the control node and the managed nodes.
- You are logged in to the control node as a user who can run playbooks on the managed nodes.
-
The account you use to connect to the managed nodes has
sudopermissions for these nodes.
Procedure
Create a playbook file, for example,
~/playbook.yml, with the following content:--- - name: Configuring fapolicyd hosts: managed-node-01.example.com tasks: - name: Allow only executables installed from RPM database and specific files ansible.builtin.include_role: name: redhat.rhel_system_roles.fapolicyd vars: fapolicyd_setup_permissive: false fapolicyd_setup_integrity: sha256 fapolicyd_setup_trust: rpmdb,file fapolicyd_add_trusted_file: - <path_to_allowed_command> - <path_to_allowed_service>The settings specified in the example playbook include the following:
fapolicyd_setup_permissive: <true|false>-
Enables or disables sending policy decisions to the kernel for enforcement. Set this variable for debugging and testing purposes to
false. fapolicyd_setup_integrity: <type_type>Defines the integrity checking method. You can set one of the following values:
-
none(default): Disables integrity checking. -
size: The service compares only the file sizes of allowed applications. -
ima: The service checks the SHA-256 hash that the kernel’s Integrity Measurement Architecture (IMA) stored in a file’s extended attribute. Additionally, the service performs a size check. Note that the role does not configure the IMA kernel subsystem. To use this option, you must manually configure the IMA subsystem. -
sha256: The service compares the SHA-256 hash of allowed applications.
-
fapolicyd_setup_trust: <trust_backends>-
Defines the list of trust backends. If you include the
filebackend, specify the allowed executable files in thefapolicyd_add_trusted_filelist.
For details about all variables used in the playbook, see the
/usr/share/ansible/roles/rhel-system-roles.fapolicyd.README.mdfile on the control node.Validate the playbook syntax:
$ ansible-playbook ~/playbook.yml --syntax-checkNote that this command only validates the syntax and does not protect against a wrong but valid configuration.
Run the playbook:
$ ansible-playbook ~/playbook.yml
Verification
Execute a binary application that is not on the allow list as a user:
$ ansible managed-node-01.example.com -m command -a 'su -c "/bin/not_authorized_application " <user_name>' bash: line 1: /bin/not_authorized_application: Operation not permitted non-zero return code