我们有一台装有 Alma Linux 9.3 操作系统的服务器。默认情况下(以及所有当前类似 RHEL 的操作系统),它已fapolicyd
启用。该服务器上还运行着一个应用程序服务器(WildFly/JBoss/Java)。部署的应用程序处理一些数据文件(由用户提交),在标准情况下运行良好。
然而目前,有一段时间应用程序需要每分钟处理 1000 个文件。在这种情况下,开销fapolicyd
占用了大约 15% 的 CPU,我们认为这太多了。
我在互联网上找不到遇到类似问题的人。
fapolicyd
我也很惊讶ServerFault 上没有标签。
问题:
- 有没有办法优化
fapolicyd
配置,以便它可以更快地决定是否允许或拒绝文件访问?- 我想到的一件事是自定义规则的顺序。
- 也许使用通配符而不是使用文字规则。
- 有什么提示可以告诉我们如何评估它对
fapolicyd
我们有多重要吗?- 我们是否可以将其关闭,或者尽管开销巨大,但继续运行它是否真的是个好主意。
- 其他发行版是否也使用类似的东西
fapolicyd
,或者它是否“只是额外的安全性”就SELinux
足够了。(我知道它们不一样。)
资料来源:
答案1
允许列出已执行的程序是最有效的安全功能之一。如果没有它,受感染的用户帐户可能会执行任意有效负载。或者用户将不应该安装的程序安装到他们的主目录中。尽管这是一项可选功能,您可以决定是否启用。
检查所有这些文件系统调用都会影响性能。不过,可以通过优化规则和数据库来最大程度地减少开销。
从用户的角度衡量性能是否可接受。以响应时间为重点的目标(例如“99.9% 的应用程序 API 调用将在 1 秒内完成”)将检测出真正的问题,而不仅仅是资源利用率的趋势。
首先了解一下 fapolicyd 的背景,请注意来自自述文件:
表现
当程序打开文件或调用 execve 时,该线程必须等待 fapolicyd 做出决定。要做出决定,fapolicyd 必须查找有关进程和正在访问的文件的信息。fapolicyd 必须执行的每个系统调用都会减慢系统速度。
为了加快速度,fapolicyd 会缓存它查找的所有内容,以便后续访问使用缓存,而不是从头开始查找。但缓存只有这么大。不过,您可以控制它。您可以使主体和对象缓存都更大。当程序结束时,它会将一些性能统计数据输出到 /var/log/fapolicyd-access.log 或屏幕上,如下所示:
Permissive: false q_size: 640 Inter-thread max queue depth 7 Allowed accesses: 70397 Denied accesses: 4 Trust database max pages: 14848 Trust database pages in use: 10792 (72%) Subject cache size: 1549 Subject slots in use: 369 (23%) Subject hits: 70032 Subject misses: 455 Subject evictions: 86 (0%) Object cache size: 8191 Object slots in use: 6936 (84%) Object hits: 63465 Object misses: 17964 Object evictions: 11028 (17%)
在此报告中,您可以看到内部请求队列的最大数量为 7。这意味着守护进程最多有 7 个线程/进程在等待。这表明它有点积压,但处理请求的速度相当快。如果这个数字很大,比如超过 200,那么可能需要增加 q_size。请注意,如果超过 1015,那么可能需要告知 systemd 允许超过 1024 个描述符。在 fapolicyd.service 文件中,您需要添加 LimitNOFILE=16384 或大于队列的某个数字。
另一个值得关注的统计数据是命中与驱逐比率。当请求无处放置信息时,它必须驱逐某些内容以腾出空间。这是由 LRU 缓存完成的,它自然会确定哪些内容未被使用,并使其内存可供重复使用。
在上面的统计数据中,主题命中率为 95%。对象缓存就没那么幸运了。它的命中率为 79%。这仍然不错,但可以更好。这表明,对于该系统的工作负载,缓存可以稍微大一些。如果用于缓存大小的数字是质数,则与具有公分母的情况相比,由于冲突而导致的缓存流失会更少。您可以考虑将一些质数用作缓存大小:1021、1549、2039、4099、6143、8191、10243、12281、16381、20483、24571、28669、32687、40961、49157、57347、65353 等。
另外,应该提到的是,策略中的规则越多,它必须迭代的规则就越多,才能做出决定。至于系统性能影响,这非常依赖于工作负载。对于典型的桌面场景,您不会注意到它正在运行。在短时间内打开大量随机文件的系统将产生更大的影响。
另一个会影响性能的配置选项是完整性设置。如果将其设置为 sha256,则对象缓存中的每次未命中都会导致对正在访问的文件进行哈希计算。一种权衡是使用大小检查而不是 sha256。这不太安全,但如果性能有问题,这是一个选择。
do_stat_report = 1
在配置中启用统计报告,然后重新启动 fapolicyd(如果最近没有)。分析/var/log/fapolicyd-access.log
并记录哪些 PID 打开哪些文件的模式。
注意“命中”与“未命中”的比率。命中率越高越好,访问内存数据库比文件系统访问和处理速度快得多。将obj_cache_size
配置增加到系统一次拥有的文件数。可能的上限是数据文件系统中使用的 inode 数量,如输出所示df -i
。这可能过多,但如果您有内存,为什么不缓存几十万个条目呢。
检查 fapolicyd.conf 中的配置。integrity
除none
或之外的值size
将计算校验和并产生开销。特别是如果您在处理新文件时有很多未命中,这可能会占用大量 CPU。q_size
应该大于访问报告中的“最大队列深度”,但我怀疑队列大小是否需要增加。
查看 rules.d 中 compilation.rules 中的规则。RHEL 和 Fedora 从 rpm 填充受信任文件,不允许执行未知文件,不允许 ld.so 技巧,并允许大多数打开。如果您确实修改了规则,请考虑在打开系统调用等待时执行更多操作对性能的影响。
和往常一样,您可以在排除故障时分析到底发生了什么。 perf top
将打印 CPU 上的功能,并且在安装了 debuginfo 时效果会更好。bcc-tools 包有一些简洁的脚本:opensnoop 和 execsnoop 可以实时列出 open 和 exeve 调用。
最终,由您决定实施哪些控制措施以仅允许执行未经授权的程序。在 exec 调用中立即允许列出,如 fapolicyd,当然非常强大。一个不太全面的替代方案可能是限制 shell 访问:不允许人们交互式 shell,并锁定主目录的权限。或者,如果数据文件系统根本不应该有程序,请考虑将其安装为 noexec。良好的安全审计不会将清单视为不可变的,而是会列出替代控制措施及其原因。