The file /etc/fapolicyd/fapolicyd.conf contains
configuration information for the application whitelisting daemon
configuration. This file allows the admin to tune the performance and
actions of the fapolicyd during runtime. This file contains one
configuration keyword per line, an equal sign, and then followed by
appropriate configuration information. All option names and values are case
insensitive. The keywords recognized are listed and described below. Each
line should be limited to 160 characters or the line will be skipped. You
may add comments to the file by starting the line with a '#' character.
- permissive
- This option is either a 0 to mean send policy decisions to the kernel for
enforcement. Or it can be a 1 to mean always allow the access even if
policy would block it. This should only be used for policy testing and
debug. The default value is 0.
- nice_val
- This option gives fapolicyd a scheduler boost. The number can be from 0 to
20. The default value is 10.
- q_size
- This option is used to control how big of an internal queue that fapolicyd
will use. If requests come in faster than fapolicyd can answer, the queue
holds the pending requests. If the do_stat_report is enabled, when
fapolicyd shutsdown it will provide some statistics which includes maximum
queue depth used. This information can be used to help tune performance.
The default value is 800. Also note, this value means that fapolicyd gets
a file descriptor for that entry. There is an rlimit cap controlled by
systemd's LimitNOFILE setting for the service. You may also need to adjust
it if the q_size exceeds its value.
When decision_threads is greater than 1, this value is
applied to each decision worker. The total userspace queue capacity and
approximate fanotify permission file descriptor budget are therefore
decision_threads multiplied by q_size, plus the daemon's
other descriptors.
- decision_threads
- This option controls how many decision worker threads fapolicyd is
configured to use. The default value is 1. The value must be at least 1,
no larger than the number of online CPU cores, and no larger than the
daemon's supported maximum. Startup validation also checks that the
configured worker count fits the LMDB reader-slot reservation, estimated
fixed worker memory budget, and file descriptor budget implied by
q_size. Each decision worker owns its own event queue, subject
cache, object cache, and subject-slot defer array. Increasing this value
can reduce queueing when decision processing is CPU-bound, but it also
increases the fixed memory and file descriptor footprint of those
per-worker resources. The trust database map is shared, but each worker
still needs an LMDB reader slot. This setting is applied when the daemon
starts; restart fapolicyd after changing it.
- uid
- This can be a number or an account name which fapolicyd should switch to
during startup. The default value is 0 because it is guaranteed to exist.
But it is recommended to use the fapolicyd account if that exists.
- gid
- This can be a number or an group name which fapolicyd should switch to
during startup. The default value is 0 because it is guaranteed to exist.
But it is recommended to use the fapolicyd group if that exists.
- do_stat_report
- This option controls whether (1) or not (0) fapolicyd should create a
usage statistics report on shutdown. The report is written to
/var/log/fapolicyd-access.log. This report gives information about number
of allowed accesses and denials. Then for both the subject and object
cache, it dumps information about size, hits, misses, and evictions. The
default value is 1 which means create the report.
- detailed_report
- This option controls whether (1) or not (0) fapolicyd should add subject
and object information to the usage statistics report. This would be
information about the exact process or file path in the cache from most
recently used to last recently used. This can be useful for forensics if
an incident had occurred. But if the file names are sensitive then you may
want to turn this off. The default value is 1 meaning add the details.
- db_max_size
- This option controls how many megabytes to allow the trust database to
grow to. If you have lots of packages installed, then you want to make it
bigger. The default value is "auto", which tells the daemon to
size the trust database based on current utilization whenever it starts or
rebuilds the database. Auto sizing starts from a 100 megabyte baseline,
targets roughly 75% active database usage, keeps lower-utilization reload
headroom for the current trust database generation and the candidate
generation being built, grows when needed, and shrinks conservatively when
utilization is low.
Manual numeric values are never changed by the daemon. If a
manual value is too small for a safe reload, fapolicyd logs a warning
with the current size and a recommended minimum. Set db_max_size
to at least that recommendation, or use db_max_size = auto so the
daemon can resize the LMDB map as package sets change.
- subj_cache_size
- This option controls how many entries the subject cache holds. You want
the size to be big enough that you are not getting too many evictions
compared to hits. But you don't want to waste memory. Whenever there is an
eviction, fapolicyd has to regenerate information about the subject and
this slows performance. There are only 64k processes allowed at any time,
so this would be the upper limit. The default value is 4099. With multiple
decision_threads , this value is per worker. Leaving it unchanged
increases total subject cache capacity and memory. Reducing it to keep the
memory footprint stable can increase subject collisions, early subject
cache evictions, and subject defer fallbacks.
- obj_cache_size
- This option controls how many entries the object cache holds. You want the
size to be big enough that you are not getting too many evictions compared
to hits. But you don't want to waste memory. Whenever there is an
eviction, fapolicyd has to regenerate information about the object and
this slows performance. The default value is 8191. With multiple
decision_threads , this value is per worker. Leaving it unchanged
increases total object cache capacity and memory. Reducing it to keep the
memory footprint stable can increase object cache misses, collisions, and
evictions.
- watch_fs
- This is a comma separated list of file systems that should be watched for
access permission. No attempt is made to validate the file systems names.
They should exactly match the name presented in the first column of
/proc/mounts. If this is not configured, it will default to watching ext4,
xfs, and tmpfs.
- ignore_mounts
- ignore_mounts A comma-separated list of mount points that fapolicyd
must not watch, even when their filesystem type matches watch_fs.
Entries must be absolute paths exactly as shown in the second column of
/proc/mounts; whitespace around commas is ignored. Each listed
mount must be mounted with the noexec option; otherwise the
daemon warns and monitors the mount point instead. The root filesystem
/ is always monitored. This option cannot be combined with
allow_filesystem_mark=1. See the discussion in SECURITY
CONSIDERATIONS FOR ignore_mounts.
- trust
- This is a comma separated list of trust back-ends. If this is not
configured, 'rpmdb,file' is default. Fapolicyd supports file
back-end that reads content of /etc/fapolicyd/fapolicyd.trust and use it
as a list of trusted files. The second option is rpmdb backend that
generates list of trusted files from rpmdb.
- integrity
- This option tells fapolicyd which integrity strategy it should use. It can
be one of 4 values:
- none
- This is the default and does no integrity checking.
- size
- Selecting this option will compare the size of the file with what it was
knows to be. This is better than nothing and very fast since fapolicyd
already collects size information during normal processing. However, an
attacker could replace the file and as long as the size matches, it will
not be detected.
- ima
- Selecting this option will use a hash that the IMA subsystem places in a
file's extended attributes in addition to the size check. IMA measurements
can be SHA256 or SHA512 depending on kernel policy. When the IMA digest
and trust metadata disagree, fapolicyd recomputes the IMA hash for a
single retry before logging rate-limited warnings. The recomputation adds
hashing overhead on the first mismatch and there is currently no
configuration knob to disable these warnings. This means that all file
systems holding executable code must support extended attributes.
- sha256
- Selecting this option will calculate a SHA256 hash by cryptographic means.
A size check will also be performed.
- syslog_format
- This option controls how the output from the access decision is formatted.
The format is a comma separated list of subject and object names from the
rules. It does not allow the keyword "all". It also allows for
rule, dec, and perm. The format must include a semi-colon to delineate
subject from object keywords. The typical use is to place information
about the access decision, then subject information, a colon, and the
object information. Also note that the more things being logged, the more
it will impact system performance. Also, the event written is limited to
512 bytes.
Example:
syslog_format = rule,dec,perm,auid,pid,exe,:,path,ftype,trust
- rpm_sha256_only
- When this option is set to 1, it will force RPM trust entries to use
SHA256 or larger hashes. This is useful on systems where the integrity is
set to SHA256 or IMA and some rpms were originally built with e.g. SHA1.
The daemon will ignore these SHA1 entries when the RPM backend imports
trust data. Hash integrity lookups also reject SHA1/MD5 records that are
already present in the active trust database, so stale weak RPM entries do
not remain trusted after a configuration reload enables this option. If
set to 0 the daemon stores and uses SHA1/MD5 from RPM trust data as well.
This is compatible with older behavior which works with the integrity set
to NONE and SIZE. The NONE or SIZE integrity setting considers the files
installed via rpm as trusted and it does not care about their hashes at
all. The default value is 0.
- allow_filesystem_mark
- When this option is set to 1, it allows fapolicyd to monitor file access
events on the underlying file system when they are bind mounted or are
overlayed (e.g. the overlayfs). Normally they block fapolicyd from seeing
events on the underlying file systems. This may or may not be desirable.
For example, you might start seeing containers accessing things outside of
the container but there is no source of trust for the container. In that
case you probably do not want to see access from the container. Or maybe
you do not use containers but want to control anything run by systemd-run
when dynamic users are allowed. In that case you probably want to turn it
on. Not all kernel's support this option. Therefore the default value is
0. This option cannot be used when ignore_mounts lists one or more
paths. Filesystem marks extend monitoring beneath bind or overlay mounts
in a way that prevents individual mount points from being ignored. When
both options appear in the configuration the daemon terminates with an
error so the conflict can be corrected before startup.
- report_interval
- This option specifies a reporting interval, measured in seconds, which
fapolicyd uses to schedule recurring dumps of daemon state to
fapolicyd.state and runtime metrics to fapolicyd.metrics.
See fapolicyd.state(5) and fapolicyd.metrics(5) for the
report fields. The default value of 0 disables interval reporting.
- reset_strategy
- This option controls whether runtime metric counters are reset as part of
metrics report generation. The default value is never, which
preserves the historical behavior where metrics grow for the lifetime of
the daemon. Use auto when interval reports should describe only the
activity since the previous timer-based report. Use manual when
counters should reset only after a signal-based report carries reset
intent, such as fapolicyd-cli --reset-metrics. Plain
fapolicyd-cli --check-status and fapolicyd-cli
--check-metrics reports do not reset counters. Signal-based reports do
not reset counters when this option is set to auto, and interval
timer reports do not reset counters when it is set to manual. Set
this option to never when continuously growing counters are
required, and to auto or manual when reports should
atomically snapshot the current metrics and start the next reporting
interval with fresh counters. Rule hit counters are naturally scoped to
the active ruleset generation and reset when a new ruleset is loaded;
metric resets also clear them after reporting so the existing rules can be
tested from a fresh counter window. In all reset modes, configuration and
state identity values such as cache sizes, queue size, trust database
size, integrity mode, permissive mode, watched mounts, and ruleset
generation are not reset.
- timing_collection
- This option controls whether privileged manual decision timing windows are
allowed. The default value is off, which ignores timing start and
stop requests. Set it to manual to allow root to use
fapolicyd-cli --timing-start and fapolicyd-cli --timing-stop
for bounded diagnostic timing runs. While a run is active, the daemon
records fixed aggregate latency metrics for each decision worker and
stage. When the run is stopped, the daemon writes
/run/fapolicyd/fapolicyd.timing. Normal state reports include only
timing control state, not the timing histograms. See
fapolicyd.timing(5) for the timing report fields.
Do not treat decision_threads as only a CPU setting. A
higher value creates more decision workers, and each worker preallocates its
own queue, subject cache, object cache, and subject-slot defer array. The
subject defer array is sized from subj_cache_size with a fixed
minimum, so increasing workers also increases total defer capacity and
memory.
Increase decision_threads when metrics show that decision
work is backing up, such as high queue wait, high Inter-thread max queue
depth relative to q_size, or non-zero Inter-thread queue full
count. After changing it, compare fapolicyd-cli(8) status or
metrics reports before and after the restart. Watch queue depth, queue full
count, subject and object cache collisions and evictions, subject defer
fallbacks, and the reported glibc heap usage.
On systems with enough memory, keep q_size,
subj_cache_size, and obj_cache_size unchanged when adding
workers so total queue and cache capacity grows with the available decision
parallelism. On memory-constrained systems, reduce those per-worker values
only after estimating the total footprint. Reducing cache sizes can keep
memory more stable, but it may increase cache misses, collisions, evictions,
and subject defer fallbacks. Any sustained non-zero subject defer fallback
count means the subject cache and derived defer array are too small for the
workload.
On SIGHUP, fapolicyd parses fapolicyd.conf,
publishes a new immutable decision configuration generation, reloads the
filter configuration, and asks the normal rule and trust database owners to
reload their state. A decision that has already started keeps using the
decision configuration generation it pinned at the beginning of the
decision. New decisions use the most recently published generation.
The following fapolicyd.conf settings are live after a
successful reload:
- permissive, integrity, and the lookup-side
rpm_sha256_only digest floor are decision-used fields and are
published together as one immutable generation.
- nice_val, do_stat_report, detailed_report,
reset_strategy, and timing_collection are applied directly
by the reload path.
- syslog_format is used by the next successfully published
ruleset.
- trust and the rpm_sha256_only RPM ingestion filter are used
by the next trust database reload.
The fapolicyd-filter.conf file is also reloaded on
SIGHUP before the trust database reload is requested. The filter is
consulted when trust source entries are imported or rebuilt; it is not
consulted directly by normal access decisions.
The following settings require a daemon restart because they are
consumed when long-lived runtime objects are created:
- q_size, decision_threads, subj_cache_size, and
obj_cache_size size the per-worker event queues, worker count,
caches, and subject defer arrays.
- uid and gid control the daemon identity selected during
startup.
- watch_fs, ignore_mounts, and allow_filesystem_mark
determine the fanotify mark set installed during startup.
- db_max_size and the special auto database sizing mode
determine the LMDB map size policy used when the trust database is opened
or rebuilt. Changing this setting in the file does not replace the active
database sizing policy until restart.
- report_interval starts the interval report timer used by the
decision thread.
Ignoring a mount removes fanotify visibility for that tree.
fapolicyd will not evaluate reads/opens that occur on the ignored
mount, which reduces load but creates blind spots in policy enforcement.
- Interpreters and plugins: Even with noexec, trusted
interpreters (shell, Python, Java, Node.js, etc.) and applications that
load plugins, bytecode, or data-driven modules may read and act on files
from the ignored mount. Those accesses bypass fapolicyd because no
fanotify mark is placed there.
- Policy blind spots: Content copied into the ignored tree is not
evaluated while it resides there. Risk may surface only after the content
moves to a monitored location.
- Coverage of system paths: The root filesystem / is always
monitored so core paths (e.g., /usr) remain protected. Do not rely
on ignore_mounts to work around denials for native ELF binaries; it
is a performance control, not a permissive toggle.
Before adding entries to ignore_mounts, administrators
should:
Matching is by mount point path as shown in /proc/mounts;
trailing slashes are normalized. Bind/overlay/NFS/FUSE mounts are matched by
their mount point path (not device identifiers). When
allow_filesystem_mark=1 is set together with ignore_mounts,
the daemon refuses the configuration to avoid conflicting semantics.