# Harden Shared cPanel Server: Secure CageFS and ModSecurity Setup

Source: https://srvscripts.com/guides/harden-shared-cpanel-server/
Updated: 2026-10-03
Publisher: srvScripts (https://srvscripts.com/)

On a shared server every account is a potential entry point, and the 2026 CVE series showed how quickly a compromised customer account becomes a root problem. Three layers keep a single bad site from taking the whole box: filesystem isolation (CageFS), request filtering at the web server (ModSecurity), and detection of what gets through (Imunify or ClamAV). Each layer catches things the others miss, and none of them is a substitute for keeping cPanel and the kernel patched.

In short: Install CageFS on CloudLinux and enable it for every account so users cannot see each other’s files, deploy ModSecurity with the OWASP Core Rule Set through EasyApache 4 starting in DetectionOnly and moving to blocking once false positives…

**Short answer:** Install CageFS on CloudLinux and enable it for every account so users cannot see each other’s files, deploy ModSecurity with the OWASP Core Rule Set through EasyApache 4 starting in DetectionOnly and moving to blocking once false positives are excluded per domain, and add Imunify360, ImunifyAV or ClamAV to catch what gets through. Keep cPanel auto-updates on and apply the 2026 kernel mitigations so none of the layers can be escaped.

## Isolate accounts with CageFS

CageFS is a CloudLinux feature, so this section applies to CloudLinux 8, 9 or 10. On plain AlmaLinux you get partial isolation from cPanel’s jailshell and `mod_ruid2`/`mod_suexec`, but not the virtualised filesystem that stops one user from reading `/etc/passwd`, `/proc` entries for other users, or another account’s world-readable `wp-config.php`.

Install and enable it for all users:

```
yum install cagefs -y
/usr/sbin/cagefsctl --init
/usr/sbin/cagefsctl --enable-all
```

After that, every new account is caged automatically. Check with `cagefsctl --list-enabled`. Pair it with PHP Selector (`lvemanager`) so users run PHP inside the cage, and with LVE limits so a runaway site is throttled rather than starving its neighbours.

Two pitfalls: cron jobs and shell scripts that expect access to system paths outside the skeleton will break, and you must run `cagefsctl --force-update` after installing new system packages that users need (ImageMagick, a new PHP module) so the skeleton picks them up. When a customer reports “command not found” for something that clearly exists, the cage is usually the reason.

## Deploy ModSecurity with the OWASP Core Rule Set

cPanel ships ModSecurity through EasyApache 4 as `ea-modsec2-rules-owasp-crs` (or the ModSecurity 3 connector on newer profiles). Install it from **WHM » Software » EasyApache 4**, or from the shell:

```
dnf install ea-modsec2-rules-owasp-crs -y
/scripts/restartsrv_httpd
```

Then enable the vendor under **WHM » Security Center » ModSecurity Vendors** and confirm the rule set is loaded. Start in detection-only mode for a week so you can see what would be blocked without breaking customer sites:

```
whmapi1 modsec_set_setting setting_id=1 state=DetectionOnly
```

Review hits under **WHM » Security Center » ModSecurity Tools » Hits List**. The rules that fire most on legitimate traffic are typically the request-body and SQL-injection anomalies triggered by WordPress page builders and WooCommerce checkouts. Disable individual rules per domain rather than globally: **ModSecurity Tools » Rules List » Disable** with a domain scope writes the exclusion to the vhost include, not to the global config.

Once the false-positive rate is acceptable, switch to blocking:

```
whmapi1 modsec_set_setting setting_id=1 state=On
```

If you run LiteSpeed Enterprise, the same rules load through its ModSecurity-compatible engine; check the LiteSpeed cPanel plugin version is at least 2.4.8 to be clear of CVE-2026-48172.

## Choose a scanner: Imunify360, ImunifyAV or ClamAV

The scanning layer detects what the WAF let through: webshells uploaded through a vulnerable plugin, injected JavaScript, and cron-based persistence. There are three realistic options.

- **Imunify360** is the full product: WAF with a WordPress-specific rule set enabled by default since August 2026, proactive defence for PHP, an L7 rate limiter, and the “Under Attack Mode” WebShield feature. It costs per server but folds the WAF and IDS work into one agent, and on CloudLinux it integrates with CageFS and LVE. Install with the vendor script after adding your licence key, then check `imunify360-agent rstatus`.

- **ImunifyAV** is the scanner-only product. The free tier detects; the paid ImunifyAV+ tier cleans. It is the sensible choice on AlmaLinux without CloudLinux where you already have ModSecurity and the cPanel CSF fork.

- **ClamAV** ships as a cPanel plugin (**WHM » cPanel » Manage Plugins » ClamAV Scanner**). Its default signatures are weak for PHP malware, so add a community webshell signature set and schedule scans yourself. It is free and better than nothing, but do not rely on it alone.

Whatever you pick, schedule a full scan of `/home` weekly and an on-access or inotify scan of upload directories if the product supports it. Make sure the scanner runs inside the LVE limits or outside business hours; a full-disk scan on a busy server at noon is a self-inflicted outage.

## Close the remaining gaps

Hardening the web layer is pointless if mail or the kernel is the weak point. Alongside the three layers above:

- Keep cPanel auto-updates on and confirm the build each Monday with `whmapi1 version`.

- Apply the 2026 kernel mitigations or run KernelCare so Copy Fail and Dirty Frag cannot be used to escape CageFS.

- Disable the CSF Messenger service and remote URLGET lists if you run any CSF fork older than 16.31.

- Restrict outbound SMTP for the `nobody` user and set per-domain hourly mail limits, so a compromised site cannot become a spam source; our [outbound spam guide](/guides/find-source-of-outgoing-spam-cpanel/) covers the hunt when it happens anyway.

- Turn off `symlink protection` bypasses: make sure **WHM » Tweak Settings » Enable EXPERIMENTAL Jailshell** is not the only barrier and that Apache is built with the symlink-protection patch selected in EasyApache.

## Verify

Test each layer on a throwaway account. Create a file outside the account’s home from a caged shell and confirm it fails. Send a request containing an obvious payload such as `?id=1' UNION SELECT` to a site on the server and confirm a `403` with a matching entry in `/etc/apache2/logs/modsec_audit.log`. Upload the EICAR test string to `public_html` and confirm the scanner flags it within the scan interval. Run our [server security audit script](/scripts/server-security-audit/) afterwards and keep its output as the baseline you compare against next quarter.

## Harden shared cPanel server at a glance

**Official documentation:** [Imunify360 documentation](https://docs.imunify360.com/), [CloudLinux documentation](https://docs.cloudlinux.com/), [OWASP CRS documentation](https://coreruleset.org/docs/).

**Related guides:** [Fix Imunify360 missing from the WHM interface (enable-plugin and other causes)](https://srvscripts.com/guides/fix-imunify360-missing-from-whm/) · [Fix WordPress “cURL error 28: Failed to connect” caused by Imunify360 or CSF](https://srvscripts.com/guides/wordpress-curl-error-28-imunify360-csf/) · [Whitelist IPs and countries in Imunify360 from the CLI](https://srvscripts.com/guides/imunify360-whitelist-ip-cli/).

## Frequently asked questions

### Does CageFS work on AlmaLinux without CloudLinux?

No. CageFS is part of CloudLinux and needs its kernel and LVE stack; on plain AlmaLinux the closest equivalents are cPanel’s jailshell, `mod_ruid2` or suexec, and Apache symlink protection, which isolate processes but not the filesystem view.

### How long does enabling ModSecurity with the OWASP CRS take on cPanel?

Installing the rule set and restarting Apache takes a few minutes; the DetectionOnly review period before switching to blocking should last about a week so the hits list covers normal customer traffic, including admin activity and checkouts.

### Can I undo this?

Yes. `cagefsctl --disable-all` removes the cage from every account, ModSecurity can be set back to DetectionOnly or Off with `whmapi1 modsec_set_setting`, and the scanner packages can be uninstalled; none of the three layers changes customer data.
