How to Fix CSF/LFD “Excessive Resource Usage” Floods for PHP-FPM and dbus on AlmaLinux 9

Rate this post

If you have recently migrated to AlmaLinux 9 (or any RHEL 9 derivative) and run ConfigServer Security & Firewall (CSF) with Login Failure Daemon (LFD), you have probably noticed your inbox filling up with alerts like these:

Time:    Wed Feb 19 03:14:22 2025
Account: root
Resource: Virtual Memory Size
Exceeded: 384 > 256 (MB)
Executable: /usr/sbin/php-fpm
Command Line: php-fpm: pool example.com
Time:    Wed Feb 19 03:14:23 2025
Account: dbus
Resource: Virtual Memory Size
Exceeded: 312 > 256 (MB)
Executable: /usr/bin/dbus-broker
Command Line: dbus-broker --log 4 --controller 9 ...

These alerts fire constantly, sometimes dozens per hour, and they are almost always false positives. The problem is not that your server is under attack or that your applications are misbehaving. The problem is that CSF’s default memory threshold has not kept up with modern software.

In this article, we will break down why this happens, how to raise the threshold to a sensible value, and (critically) how to use the correct csf.pignore syntax to whitelist PHP-FPM pools, because the syntax you need is effectively undocumented.

Why the Default PT_USERMEM Threshold Is Too Low

CSF’s process tracking feature (PT_USERMEM) sets a ceiling on virtual memory usage per process. When any process exceeds this value, LFD sends an alert. The default value is 256 MB.

That was a reasonable default in 2012. It is not reasonable in 2025.

Here is what changed:

PHP-FPM on AlmaLinux 9 ships with PHP 8.x, which has a significantly larger memory footprint than PHP 5.x did. Each FPM worker process routinely maps 300 to 500 MB of virtual address space, even when actual resident memory usage (RSS) is a fraction of that. Virtual memory includes shared libraries, memory-mapped files, and reserved (but unused) address space. A server running 20 FPM pools will have dozens of workers exceeding 256 MB in virtual size at any given moment.

dbus-broker, the default D-Bus implementation on RHEL 9 and its derivatives, replaces the older dbus-daemon. It is more efficient in terms of CPU and throughput, but it maps more virtual memory at startup. Values of 280 to 400 MB are completely normal and expected. Since dbus-broker runs as the dbus user, LFD flags it repeatedly.

The key distinction that CSF’s alerts obscure is the difference between virtual memory (address space reserved by the kernel) and resident memory (physical RAM actually in use). A PHP-FPM worker showing 400 MB virtual may only be consuming 40 to 80 MB of actual RAM. The alerts are technically accurate but practically meaningless for these processes.

Step 1: Raise PT_USERMEM to a Modern Value

Open csf.conf:

nano /etc/csf/csf.conf

Find the PT_USERMEM directive. The default looks like this:

PT_USERMEM = "256"

Raise it to at least 512 MB. On servers running multiple PHP-FPM pools, WordPress with WooCommerce, or any Java/Node.js workloads alongside PHP, 768 MB or even 1024 MB is more appropriate:

PT_USERMEM = "512"

Save the file and restart CSF and LFD:

csf -ra

This single change will eliminate the vast majority of false positive alerts. However, if you want to be more surgical about it (keeping a lower threshold for everything else while specifically excluding known-safe processes), you will want to use csf.pignore.

Step 2: Whitelist PHP-FPM and dbus-broker in csf.pignore

The file /etc/csf/csf.pignore tells LFD to skip specific processes during its tracking sweeps. This is where things get frustrating, because the syntax you need for PHP-FPM is not well documented in CSF’s official materials.

The pignore Syntax Options

csf.pignore supports several matching methods:

Prefix What It Matches
exe: The full path of the binary executable as shown in /proc/PID/exe
cmd: A substring match against the full command line as shown in /proc/PID/cmdline
user: All processes owned by a specific username
pexe: Perl regex match against the executable path
pcmd: Perl regex match against the command line

Why exe: Does Not Work for PHP-FPM

Your first instinct will probably be to add this:

exe:/usr/sbin/php-fpm

This works for the master process. But it will not reliably match the child worker processes that are actually triggering the alerts. Here is why.

When PHP-FPM spawns child workers, the command line changes to something like:

php-fpm: pool example.com

The executable path in /proc/PID/exe still points to /usr/sbin/php-fpm, so you would think exe: should work. In practice, LFD’s process matching can behave inconsistently with forked workers, and many administrators report that exe: alone does not suppress the alerts for child pools.

The reliable solution is to use cmd: to match against the command line string.

The Working csf.pignore Entries

Open the file:

nano /etc/csf/csf.pignore

Add the following lines:

# PHP-FPM master and worker processes
cmd:php-fpm

# dbus-broker on AlmaLinux 9 / RHEL 9
exe:/usr/bin/dbus-broker

Let us break down why these entries work:

cmd:php-fpm performs a substring match against the command line of every process. This catches both the master process (php-fpm: master process (/etc/php-fpm.conf)) and every child worker (php-fpm: pool example.com, php-fpm: pool mysite.net, and so on). A single line covers all pools on the server.

exe:/usr/bin/dbus-broker works fine here because dbus-broker does not change its command line the way PHP-FPM does. The executable path is stable and consistent across all its processes.

Save the file and restart LFD:

csf -lf

Or restart both CSF and LFD:

csf -ra

Matching Specific Pools (Optional)

If you only want to whitelist specific PHP-FPM pools rather than all of them, use pcmd: with a regex:

# Only ignore the "example.com" pool
pcmd:php-fpm:\s+pool\s+example\.com

This gives you granular control if you want LFD to keep monitoring certain pools while ignoring others.

Step 3: Verify the Fix

After restarting, confirm that LFD is no longer flagging these processes. The quickest way is to watch the LFD log:

tail -f /var/log/lfd.log

You can also check which processes would currently exceed the threshold by running:

ps aux --sort=-%mem | awk '$6 > 262144 {print $1, $6/1024, "MB", $11, $12, $13}'

This shows processes using more than 256 MB of virtual memory. You should see PHP-FPM workers and possibly dbus-broker in the output, but they should no longer generate LFD alerts.

For a more thorough check, temporarily set LFD to testing mode by enabling PT_ALL_USERS in csf.conf and watching for any remaining alerts over 24 hours:

grep "Excessive resource" /var/log/lfd.log | tail -20

If the output is clean (or only shows genuinely suspicious processes), you are done.

Why Not Just Use user: to Ignore Everything?

You might be tempted to add broad exclusions like:

user:root
user:dbus

Do not do this. The user: directive ignores all processes for that user, which completely defeats the purpose of process tracking. If a compromised script starts consuming excessive memory under the root user, you want to know about it. Whitelisting by command line or executable path is far safer because it only exempts the specific processes you have identified as safe.

Recommended Configuration Summary

Here is the complete set of changes for a typical AlmaLinux 9 server running cPanel or DirectAdmin with PHP-FPM:

In /etc/csf/csf.conf:

PT_USERMEM = "512"

In /etc/csf/csf.pignore:

# PHP-FPM - use cmd: to match master and all child pool workers
cmd:php-fpm

# dbus-broker (RHEL 9 / AlmaLinux 9 default)
exe:/usr/bin/dbus-broker

Then apply:

csf -ra

Final Thoughts

The combination of AlmaLinux 9’s updated software stack and CSF’s aging defaults creates a perfect storm of alert fatigue. The fix is straightforward once you know the two pieces: raise PT_USERMEM to reflect modern memory usage patterns, and use cmd: (not exe:) in csf.pignore to properly match PHP-FPM worker processes.

The cmd: vs exe: distinction is the part that trips up most administrators. CSF’s documentation focuses heavily on exe: examples, and if you search online forums, you will find countless threads from people who added exe:/usr/sbin/php-fpm and could not figure out why the alerts kept coming. Now you know: PHP-FPM workers need command line matching, and cmd:php-fpm is the one-liner that solves it.

If you are still seeing alerts after applying these changes, double-check that you restarted LFD (not just CSF) and verify the syntax in csf.pignore has no trailing whitespace or invisible characters. A quick cat -A /etc/csf/csf.pignore will reveal any hidden issues.

 

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top