Creating Policy Rules
You might need to create custom policy rules if the default policy is too restrictive and is
preventing applications from running. You can also create custom policy rules to further
restrict access to applications and files. Rules can be added to the
/etc/fapolicyd/rules.d
directory following the conventions described in
About Policy Rules and in the
fapolicyd.rules(5)
manual page.
Rules have the following general format:
decision perm subject : object
- decision
-
Whether to allow or deny an event and whether to log that action. Values can be
allow
,deny
,allow_audit
,deny_audit
,allow_syslog
,deny_syslog
,allow_log
, ordeny_log
. - perm
-
The type of permission applied to the file, such as whether to trigger when the object is opened, run, or for any activity on the object. Values can be
open
,execute
, orany
. If no permission is specified, the default value isopen
. - subject
-
The actor performing the action on the object that the permission and decision applies to. This value can be set to
all
for every actor, but can also be limited to a particular UID or GID or another executable file. Values can beall
,auid
,uid
,gid
,sessionid
,pid
,ppid
,trust
,comm
,exe
,dir
,device
, orpattern
. See thefapolicyd.rules(5)
manual page for more detail. - object
-
The files or applications that the decision applies to. This value can be specified in various ways, such as by providing the path to a particular file, the MIME type of the file or for file matches in the trust database. Values can be
all
,path
,dir
,device
,ftype
,trust
, orsha256hash
. See thefapolicyd.rules(5)
manual page for more detail.
You can specify several subject and object directives for a single rule. For example, you can match the file path, MIME type, and file size as the object for a rule.
Rules can also be created to generate macros, or sets, that consist of a key and a set of values in the form of integers or strings in a comma-separated list. Set rules are prefixed with the percentage (%) symbol, and the set can be referenced when creating a rule by specifying the key prefixed with the percentage (%) symbol. The format of a set rule is as follows:
%key=value1,value2
You can see an example of a set rule in
/etc/fapolicyd/rules.d/10-languages.rules
.
The following example rules can be used to help guide you when creating custom rules for an environment.
Example 4-1 Create a rule to let a group of trusted users to run files matching the defined languages in their home directories
-
Create a system group and add trusted users to that group, or select an existing group of trusted users. In this example, we use the
adm
group for system administrators. -
Create a policy rule file at
/etc/fapolicyd/rules.d/50-adm-home-trust.rules
and add the following content:allow perm=any gid=adm : ftype=%languages dir=/home deny_log perm=any all : ftype=%languages dir=/home
Two rules are defined:-
Grant all users in the group
adm
all permissions on any files, in the/home
directory, of the type described in thelanguages
set in/etc/fapolicyd/rules.d/10-languages.rules
. -
Deny all users any permissions on any files, in the
/home
directory, of the type described in thelanguages
macro. Thedeny_log
rule causes the event to be added to both the audit log and to the system log.
-
-
Compile and load the new rules.
sudo fagenrules --load
See Checking and Loading Policy Rules for more information.
-
Verify that the rule is in effect.
-
As a user in the
adm
group, create a test executable file in$HOME/test_fapolicyd.py
with the following content:#/usr/bin/python3 print("Test succeeded")
-
Set the file mode to executable:
chmod +x $HOME/test_fapolicyd.py
-
Run the file:
$HOME/test_fapolicyd.py
The following output is displayed:
Test succeeded
-
As a user that isn't in the
adm
group, repeat the same steps. When you run the test script, the following output is displayed:bash: ./test_fapolicyd.py: Operation not permitted
If you have auditing configured, you can check for entries in the audit log as follows:
sudo ausearch --start today -m fanotify
Output similar to the following is displayed:
... time->date time type=PROCTITLE msg=audit(1704456339.181:406): proctitle="bash" type=PATH msg=audit(1704456339.181:406): item=0 name="./test_fapolicyd.py" inode=68153551 dev=fc:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0 type=CWD msg=audit(1704456339.181:406): cwd="/home/guest" type=SYSCALL msg=audit(1704456339.181:406): arch=c000003e syscall=257 success=no exit=-1 a0=ffffff9c a1=555d4b74e050 a2=0 a3=0 items=1 ppid=46725 pid=46765 auid=1000 uid=1001 gid=1001 euid=1001 suid=1001 fsuid=1001 egid=1001 sgid=1001 fsgid=1001 tty=pts0 ses=3 comm="bash" exe="/usr/bin/bash" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) type=FANOTIFY msg=audit(1704456339.181:406): resp=2
-
Example 4-2 Create a rule to let users to run a trusted application
Note that creating rules to let particular applications run is less efficient than adding the application to the trust database. See Adding Files to the Trust File Database for more information. Only add rules for specific files if you need to provide more explicit controls over file accesses. In this example, a rule is created controlling the ability to run a particular binary application that can only be run by using the trusted bash shell binary.
-
Create a policy rule file at
/etc/fapolicyd/rules.d/80-trustapp.rules
and add the following content:allow_log perm=execute exe=/usr/bin/bash trust=1 : path=/opt/external/app.bin ftype=application/x-executable trust=0
The rule states that if the trusted bash shell tries to run the untrusted application at the path
/opt/external/app.bin
, where that file is of MIME typeapplication/x-executable
, the action is allowed. Note that the decision is set toallow_log
so that the action is logged to help verify that the rule is working. After you have verified the rule, you can change the decision toallow
.Tip:
To check the mime type of a file when writing rules, run the following command:
fapolicyd-cli --ftype /path-to-file
Note that by specifying the MIME type for the file and the way in which the file can be loaded, the rule is reasonably restrictive. You can optionally create a more restrictive rule based on the SHA-256 hash of the file, which would prevent the rule from applying if the file is changed:
-
Obtain the SHA-256 hash for the file.
sha256sum /opt/external/app.bin|awk '{print $1}'
-
Use the SHA-256 hash to rewrite the rule as follows:
allow perm=execute exe=/usr/bin/bash trust=1 : sha256hash=hash
Set the value of
sha256hash
to the value that you obtained from running the previous command.
-
-
Compile and load the new rule.
sudo fagenrules --load
See Checking and Loading Policy Rules for more information.
-
Verify that the rule is in effect.
When you try to run
/opt/external/app.bin
as a standard user from the Bash shell, it runs correctly. Because the decision in the rule isallow_log
, you can view the fapolicyd log to see the rule in action. For example, run:sudo journalctl -S today -u fapolicyd|tail
The output displays that the rule is being enforced, for example:
datetime ro-ansible-ol8 fapolicyd[45792]: rule=13 dec=allow_log perm=execute auid=1000 pid=50439 exe=/usr/bin/bash : path=/opt/app.bin ftype=application/x-executable trust=0