ProactiveDefense is the part of Imunify360 most operators leave on the default setting because they do not understand what it actually does. It is not the ModSecurity WAF and it is not the on-access AV scanner. It is a PHP execution hook that watches each request inside the PHP interpreter and kills the process when a request matches an attack-behaviour signature — eval() on a base64-decoded payload, system() invoked from inside a WordPress wp-includes path, an uploaded image opening an outbound socket.
The default in fresh Imunify360 installs is KILL mode globally. On a shared cPanel host with a couple of hundred WordPress sites that almost certainly breaks something on day one — usually a cache plugin's pre-compiled template loader or a legacy file manager. The fix is not "disable ProactiveDefense"; that gives up the most useful PHP-layer defence the product ships with. The fix is a one-week LOG-mode audit, targeted whitelists for the offenders, and a per-user opt-out for the handful of customers who insist on running plugins that fingerprint as malware.
Where ProactiveDefense fits in the Imunify stack
There are three independent engines, and they fail differently. Knowing which one blocked a request saves an hour every time.
- ModSecurity WAF — inspects the HTTP request before PHP starts. Blocks at the Apache/LiteSpeed level with a 406 or 403. If the user got a "Not Acceptable" page, it is the WAF. Tuning is covered in tune Imunify360 WAF false positives.
- Malware scanner — runs on-access (via inotify) and on a schedule. Quarantines files on disk. If a file vanished into
/var/imunify360/files/, it is the scanner. - ProactiveDefense — runs inside the PHP request after the WAF has passed it. Terminates the script mid-execution. The visible symptom is a blank page or a 500 with no PHP error log entry — the interpreter was killed before it could flush output.
A blank page that returns nothing to the user and leaves no trace in the site's own error log is the ProactiveDefense fingerprint. Confirm with tail -f /var/log/imunify360/proactive_defense.log while reproducing the request.
The three modes
DISABLED → engine loads but does nothing
LOG → engine evaluates each request and logs hits, lets PHP continue
KILL → engine terminates PHP requests that match a critical signature
Imunify360 also exposes a blamer sub-option that writes the full PHP call stack to the log when a script is killed. Always enable it — without blamer, the kill log just says "rule 12345 fired on /index.php" and you have no idea which plugin made the offending call.
| Mode | When to use |
|---|---|
| DISABLED | Never on production. The CPU cost of LOG mode is under 1% per request. |
| LOG | First week after install. New servers. After any major ruleset bump. |
| KILL | Steady state. Once the log is clean for 48 hours. |
Enable LOG mode first
On a brand-new install, flip to LOG mode immediately and let it sit for a week:
imunify360-agent config update '{"PROACTIVE_DEFENSE": {"mode": "LOG", "blamer": true}}'
imunify360-agent config show | grep -A4 PROACTIVE_DEFENSE
On servers running KILL mode by default and breaking sites you cannot identify, the same command downgrades immediately — no restart, no PHP reload. Customers get their sites back inside a minute.
Watch the log over the next few days:
tail -f /var/log/imunify360/proactive_defense.log
Each entry contains the user, the script path, the matched rule ID, and the call stack if blamer is on. After 5–7 days you have an enumeration of what would have been killed. Group by rule ID:
awk -F'rule_id=' '{print $2}' /var/log/imunify360/proactive_defense.log \
| awk '{print $1}' | sort | uniq -c | sort -rn | head -20
The top 10 rules account for almost all the noise. Each one falls into one of three buckets — legitimate plugin pattern, customer running shady scripts, or actual compromise. The actions differ.
Whitelist legitimate patterns
ProactiveDefense whitelists live in /etc/imunify360/whitelist/proactive/. Each file in the directory is a list of SHA256 hashes of PHP files that should bypass the engine entirely. The hash matches the file as it exists on disk; if the file changes, the whitelist no longer applies — which is the point, since malware likes to inject into known-good plugin paths.
To whitelist a single file:
sha256sum /home/acmecorp/public_html/wp-content/plugins/wp-rocket/inc/loader.php
# 7a3f... /home/acmecorp/public_html/wp-content/plugins/wp-rocket/inc/loader.php
echo "7a3f..." > /etc/imunify360/whitelist/proactive/wp-rocket-loader.txt
imunify360-agent config update '{"PROACTIVE_DEFENSE": {"mode": "KILL"}}'
For a vendor-wide whitelist (every file under a plugin directory), use the bulk tool:
find /home/acmecorp/public_html/wp-content/plugins/wp-rocket -name '*.php' \
-exec sha256sum {} \; | awk '{print $1}' \
> /etc/imunify360/whitelist/proactive/wp-rocket-all.txt
Per-user opt-out
Some customers run software that is indistinguishable from malware at the behavioural level — legacy file managers, custom upload portals, anything that calls system() from a web request. Whitelisting every file is not workable. Disable ProactiveDefense for the single user instead:
imunify360-agent ignore-list user add acmecorp --component proactive
imunify360-agent ignore-list user list
The user's WAF and AV remain active; only the in-PHP ProactiveDefense hook is bypassed. Document the exception — when the customer renews next year, the ignore entry is still there, and a sysadmin three jobs from now will want to know why.
For shared servers where you do not want to bear that risk per customer, charge for it. The opt-out is a real reduction in defence posture and is a reasonable add-on line on the invoice.
Promote to KILL mode
After 48 hours of clean logs (or only logs you have explicitly whitelisted), flip the switch:
imunify360-agent config update '{"PROACTIVE_DEFENSE": {"mode": "KILL", "blamer": true}}'
Keep blamer on permanently. The log is the only forensics record after a kill — if you turn blamer off to save disk, the next time a customer complains about a "blank page" you will be guessing.
Rotate the log aggressively. proactive_defense.log grows quickly on a busy server; the default Imunify logrotate keeps 4 weeks at 100 MB each. That is fine for most fleets. For very large hosts, ship it to a central log store and let it rotate daily.
Common false positives and what to do about them
| Symptom | Likely cause | Action |
|---|---|---|
| WP Rocket cache rebuild kills | Pre-compiled template eval | Hash-whitelist the WP Rocket loader files |
| WP-CLI cron killed mid-run | wp cron event run triggers eval() heuristic | Add wp-cli PHP CLI binary to ignore list, not the web request |
| Elementor preview blank | Builder uses dynamic include() from POST data | Whitelist wp-content/plugins/elementor/core/files/ |
| Site Health "loopback" failures | Local HTTP request from PHP looks like SSRF | Whitelist wp-admin/includes/class-wp-site-health.php |
| WHMCS admin scripts killed | Smarty template engine, base64-encoded blobs | Hash-whitelist the WHMCS install directory |
When a legitimate-looking pattern is killed and the offending file genuinely is what it appears to be, get the hash into the whitelist and move on. Reporting it to TuxCare via the Imunify false-positive reporting flow is worthwhile for the long-tail fix but does not unblock your customer today.
What is Imunify360 ProactiveDefense?+
How is ProactiveDefense different from the Imunify360 malware scanner?+
Should I run ProactiveDefense in KILL or LOG mode?+
Why are my sites returning blank pages after enabling Imunify360?+
Can I disable ProactiveDefense for one customer without weakening other accounts?+
Does ProactiveDefense work without CloudLinux installed?+
Next steps
- Activate or renew your protection with an Imunify360 license.
- Run the WAF false-positive tuning playbook before you tune ProactiveDefense — clearing the WAF log first makes the PD log easier to read.
- Compare PD's coverage against the alternatives in Imunify360 vs Patchman for shared hosting.
- For the on-disk side of malware defence, walk through installing Imunify360 on cPanel and the per-server scan settings it lays down.