One compromised PHP script shouldn't take down your entire server. On most hosting panels, it can. Here's how Panelica makes that impossible — using five layers of kernel-level isolation that wrap every single user, on every single plan.
Why Isolation Matters More Than You Think
Shared hosting has a fundamental problem: multiple users, multiple applications, one machine. When isolation fails, one bad actor — or one vulnerable plugin — can compromise everyone on that server.
This isn't theoretical. In October 2024, CyberPanel CVE-2024-51567 was exploited in the wild. A single unauthenticated command injection vulnerability allowed attackers to compromise the entire host. The PSAUX ransomware campaign infected over 22,000 servers in days. On each of those servers, every customer's data was accessible because there was no meaningful isolation between users.
Most panels respond to this with basic Unix file permissions and hope. If you're running cPanel without CloudLinux, HestiaCP, ISPConfig, or CyberPanel — your users are sharing a PHP process pool, possibly a single PHP-FPM socket, and have visibility into each other's process trees.
Panelica was built differently. Five layers of kernel-enforced isolation, active on every server, for every user, at no extra cost.
In this post, we'll walk through each layer: what it does, why it exists, and exactly what it protects against.
The Big Picture: Request Flow Through All 5 Layers
Before diving into each layer, here's how a web request travels through Panelica's security stack — and where isolation is enforced at each step.
Layer 0: Network Perimeter — WAF, Firewall, and Intrusion Prevention
Before a request even reaches your application, it passes through Panelica's network perimeter layer. This is the outermost defense, and it's designed to stop known threats before they cost any server resources.
nftables Firewall
Panelica uses nftables — the modern replacement for iptables in Linux kernels 3.13+. Unlike iptables, nftables processes rules in a single pass through a kernel-native virtual machine, reducing overhead significantly on busy servers. The panel manages rules directly: open ports, blocked IPs, country-based blocks, and rate limiting are all configured through the UI and written atomically to nftables.
ModSecurity + OWASP Core Rule Set
ModSecurity runs as a dynamic module in Nginx (the panel proxy layer), inspecting every HTTP request against the OWASP Core Rule Set (CRS). The CRS protects against the full OWASP Top 10: SQL injection, XSS, remote file inclusion, path traversal, and command injection. This is the layer that would have stopped CyberPanel CVE-2024-51567 at the network level.
Panelica manages per-domain ModSecurity rules from the panel — you can whitelist false positives, adjust sensitivity levels, or disable specific rules for specific domains without touching config files.
Fail2ban Integration
Fail2ban monitors log files for repeated failure patterns and automatically adds IP bans via nftables. Panelica configures jails for SSH, Nginx authentication endpoints, WordPress login pages, and the panel's own login. Default ban threshold is 5 failures in 10 minutes; default ban duration is 1 hour — all configurable per-jail from the panel.
Malicious traffic is blocked before it reaches your application code. SQL injection attempts, brute-force login attempts, and known attack patterns are stopped at the server edge — not after they've already consumed PHP worker time and database connections.
Layer 1: Nginx Request Router — Smart Traffic Distribution
Every domain hosted on Panelica gets its own Nginx server block, generated automatically when the domain is provisioned. This isn't a wildcard catch-all — each domain has explicitly defined routing rules.
The Decision Tree
When a request arrives for a PHP file, Nginx evaluates the domain's configuration and routes to the correct PHP-FPM socket based on the domain's assigned PHP version and user. Static files (images, CSS, JS) are served directly from disk without touching PHP at all. This alone eliminates a significant attack surface — static files don't execute code.
Nginx-Only vs Nginx+Apache Mode
Panelica supports two web server configurations per domain:
- Nginx-only mode: Pure Nginx for maximum performance. All URL rewriting handled in Nginx config. Best for Laravel, WordPress (with Nginx rules), and modern PHP apps.
- Nginx+Apache mode: Nginx handles SSL termination and static files; dynamic requests are reverse-proxied to Apache running on port 7080. This enables full
.htaccesssupport — critical for legacy applications, CodeIgniter, or any app relying on Apache-specific directives.
In both modes, Nginx acts as the front router. Apache never directly faces the internet.
Each domain's traffic is independently routed. A misconfiguration in one domain's server block cannot affect another domain. Static assets bypass PHP entirely, reducing attack surface. The routing layer is fully managed — you never edit nginx config manually.
Layer 2: Per-Domain Unix Sockets — The Isolation Gateway
This is where cross-domain isolation begins at the transport level. Every domain gets its own Unix domain socket for communicating with PHP-FPM.
Socket Naming Convention
# Socket path pattern:
/opt/panelica/var/run/php-{version}-{username}_{domain}.sock
# Examples:
/opt/panelica/var/run/php-8.3-alice_example.com.sock
/opt/panelica/var/run/php-8.1-alice_legacy-app.com.sock
/opt/panelica/var/run/php-8.4-bob_newsite.org.sock
Socket permissions are set to 0660 with ownership www-data:www-data. The Nginx worker (running as www-data) can communicate with the socket; no other user can. Even if User B's PHP code attempts to send a request to User A's socket — the kernel rejects it at the file permission level before any data is transmitted.
Per-Domain PHP Version Selection
Because each domain gets its own socket pointing to its own PHP-FPM pool, different domains can run different PHP versions simultaneously. User A can run example.com on PHP 8.4 and legacy-app.com on PHP 8.1, with no interference between them. Changing PHP version for one domain restarts only that domain's FPM pool — zero impact on other domains.
Domain Restart Isolation
Per-domain sockets mean per-domain restartability. When a PHP-FPM pool is restarted (after a config change, after an OOM event, after a crash), only that specific domain's socket is affected. Other users' sites continue serving requests through their own sockets, completely unaware anything happened.
Your domains are completely independent at the transport layer. A crashing PHP pool on another user's domain doesn't affect your socket. You can run different PHP versions per domain. Domain restarts are surgical — other customers don't feel a thing.
Layer 3: PHP-FPM Per-User Per-Version Pools — Process-Level Isolation
This is the layer where most competing panels cut corners. Panelica runs a dedicated PHP-FPM pool per user per PHP version — not a shared global pool, not a per-site pool that reuses a global config. A fully independent FPM service, isolated by kernel boundaries.
Systemd Service Per User Per Version
Each user + PHP version combination gets a dedicated systemd service unit:
# Service unit naming:
panelica-php-fpm-{version}-user@{username}.service
# Examples:
[email protected]
[email protected] # Alice's legacy PHP
[email protected]
# Pool config location:
/opt/panelica/etc/php-fpm-users/{username}/{version}/pool.d/pool.conf
The master PHP-FPM process starts as root (required to bind sockets with correct permissions), then immediately drops privileges: worker processes run as the user's actual UID and GID. This means every PHP process executing Alice's code runs as Alice — not as www-data, not as nobody, not as a shared service account.
open_basedir Enforcement
Each pool has its own open_basedir configuration, pointing exclusively to that user's home directory. When Alice's PHP code attempts to open a file outside /home/alice/, the kernel rejects the open() syscall — not because of a PHP check, not because of Nginx rules, but because the filesystem ACL says no.
# In Alice's pool.conf:
php_admin_value[open_basedir] = /home/alice/:/tmp/alice/:/opt/panelica/services/php/8.3/
# Bob cannot access /home/alice/ — his open_basedir points to /home/bob/
php_admin_value[open_basedir] = /home/bob/:/tmp/bob/:/opt/panelica/services/php/8.3/
disable_functions Per Pool
Dangerous PHP functions (shell execution, process spawning, system calls) can be disabled per pool. The panel provides a security profile per user — relaxed for developers who need exec(), strict for untrusted users, locked-down for shared hosting customers.
ondemand Process Manager
Pools use PHP-FPM's ondemand process manager: worker processes spawn when a request arrives and are killed after a configurable idle timeout. This means idle users consume zero CPU and minimal memory — the pool exists in configuration but costs nothing until a request is served.
On CyberPanel, HestiaCP (default config), and ISPConfig — all users' PHP code runs through a shared global PHP-FPM pool. There's no per-user process isolation. A shell script uploaded by User B, if executed via PHP, can traverse to User A's directory if file permissions are misconfigured anywhere. Panelica's per-user per-version pools make this class of attack impossible by design.
Your PHP code runs in its own process, as your own Linux user, with its own filesystem boundaries. Other users' PHP code cannot reach your files. You choose your PHP version independently. If your application exhausts PHP workers, only your pool is affected — other users continue serving requests normally.
Layer 4: Cgroups v2 — Kernel-Enforced Resource Limits
Cgroups (Control Groups) version 2 is a Linux kernel feature that enforces resource quotas at the process level. There is no way for a process to exceed a cgroup limit from userspace — the kernel enforces it unconditionally.
Per-User Systemd Slice
Every Panelica user gets a dedicated systemd slice:
# Slice path in cgroup hierarchy:
/sys/fs/cgroup/panelica.slice/panelica-user.slice/panelica-user-{username}.slice/
# Controllers active:
cpu → cpu.max (e.g., "100000 100000" = 1 core max)
memory → memory.max (e.g., "536870912" = 512MB hard limit)
io → io.max (disk read/write bytes per second)
pids → pids.max (maximum process count — fork bomb protection)
All of Alice's processes — PHP-FPM workers, SSH sessions, FTP connections, Docker containers — are placed under Alice's slice. The kernel accounts for the total across all of them. If Alice's crypto miner spawns 100 forked processes, they all count toward her PID limit and CPU quota.
What "Kernel-Enforced" Actually Means
When a process in Alice's slice attempts to use more CPU than allowed, the kernel's CFS scheduler throttles it. There's no user-mode agent, no polling check, no grace period. The throttling happens at the scheduler level, microsecond by microsecond. Alice can run a while(true) {} loop and it will never steal CPU from Bob because the kernel distributes CPU time according to cgroup weights before any scheduler tick is assigned.
Memory limits work via OOM (Out Of Memory) killer integration. When a process in Alice's cgroup exceeds memory.max, the kernel sends SIGKILL to the largest process in that cgroup — Alice's runaway PHP script dies, not Bob's database server.
Watcher Daemons
Panelica runs three dedicated watcher daemons that ensure new processes are always placed in the correct cgroup:
- ssh_cgroup_watcher: Monitors new SSH connections and assigns them to the connecting user's slice
- phpfpm_cgroup_watcher: Assigns newly spawned PHP-FPM worker processes to their user's slice
- ftp_cgroup_watcher: Handles ProFTPD session processes
Guaranteed resources. If a neighbor's application is hammering the CPU, your PHP processes still get their allocated share — the kernel guarantees it. A runaway script, a crypto miner, a fork bomb — none of these can starve other users because the kernel enforces limits before any process gets to run. This is something money can't buy on cPanel without a CloudLinux license.
Layer 5: Linux Namespaces + Unix Permissions — Complete Invisibility
The final layer separates what users can see — not just what they can access. Even with all previous layers in place, a user could potentially run ps aux and see other users' process names and arguments. Namespaces eliminate even that.
PID Namespace Isolation
Each Panelica user operates in their own PID namespace. When Alice runs ps aux in her shell session, she sees only her own processes — PHP-FPM workers, her SSH session, any cron jobs she's running. Bob's processes are literally invisible in her namespace. This is not access control — it's namespace-level invisibility enforced by the kernel's clone(CLONE_NEWPID) call.
This matters because process listing reveals information: running application names, port bindings in arguments, database credentials passed via command line. In a shared environment without PID namespaces, any user can enumerate the entire server's process tree.
Mount Namespace Isolation
Mount namespaces give each user a private view of the filesystem. Panelica implements a CageFS-equivalent approach: each user's namespace includes their home directory, required system libraries, and PHP binaries — but not other users' home directories, not /proc entries for other users' processes, not sensitive system paths.
This is implemented natively via Linux namespaces (clone(CLONE_NEWNS)) — no kernel patches, no third-party modules. Pure upstream Linux.
SSH Chroot Jail
Two SSH access modes, both chroot-based:
- sshjailed mode: SFTP access only, no shell. The user's view of the filesystem is limited to their home directory. Standard
sftpcommands work; shell execution is impossible. - sshfull mode: Full bash shell, but inside a chroot environment. Users get a working shell but cannot navigate above their chroot root. System directories, other users' homes, sensitive configuration — all invisible.
Unix Permissions Foundation
Every user gets a dedicated UID and GID on the Linux system. Home directories are created with permission 700 (owner only). All files written by the panel on behalf of a user — web files, config files, database dumps — are written using the user's UID via sudo with a whitelist-based sudoers configuration. The panel never writes files as root into user home directories.
Other users are invisible to you, and you are invisible to them. You cannot see their processes, their files, or their running applications. Your home directory is private at the kernel level — not just by convention. SSH access is scoped to exactly what you need, nothing more.
Real-World Scenario: What Happens When User A Gets Hacked?
🔍 Incident: WordPress Plugin Exploit → PHP Shell Upload
Setup: Server has 20 users. Alice runs a WordPress site with a vulnerable contact form plugin. Bob, Carol, and 17 others run unrelated PHP applications.
The attack: An attacker exploits a remote file upload vulnerability in Alice's plugin and uploads a PHP webshell to Alice's WordPress uploads directory. They access it via the browser and have a PHP command execution environment.
On a panel without isolation (e.g., CyberPanel without hardening):
- PHP shell runs as www-data (shared by all users)
- Attacker navigates to
/home/bob/— readable - Steals Bob's database credentials from
wp-config.php - Reads all users' email account passwords from config files
- Launches crypto miner — consumes 100% CPU, all 20 users' sites slow to a crawl
- Reads SSH private keys from other users'
.ssh/directories - Pivots to root via kernel exploit or misconfigured sudo
- Entire server compromised. All 20 customers affected.
On Panelica:
- PHP shell runs as Alice's UID (e.g., uid=1001) — not www-data
- Attacker tries
file_get_contents('/home/bob/public_html/wp-config.php')→ Permission denied (open_basedir: Layer 3) - Attacker tries
exec('ls /home/')→ sees only/home/alice/, other directories empty in mount namespace (Layer 5) - Attacker spawns a crypto miner → CPU throttled to Alice's cgroup quota (Layer 4), Bob's site unaffected
- Attacker tries to fork-bomb the server → hits
pids.max, process creation fails (Layer 4) - Attacker runs
ps aux→ sees only Alice's processes, PID namespace is isolated (Layer 5) - Attacker tries to read
/etc/passwdvia shell → chroot jail prevents filesystem traversal (Layer 5) - ModSecurity logged the initial upload attempt as suspicious (Layer 0)
- Fail2ban is watching for repeated exploit attempts (Layer 0)
- Damage is contained entirely within Alice's account. Bob, Carol, and all 17 others: unaffected.
This is the practical difference between "security features" and "security architecture." Panelica's layers work together — each one limits a different attack vector, and together they make lateral movement between users effectively impossible.
How Other Panels Compare
Most panels have some isolation — the question is how much, and whether you need to pay extra for it.
| Isolation Layer | cPanel/WHM | HestiaCP | CyberPanel | ISPConfig | Panelica |
|---|---|---|---|---|---|
| Cgroups v2 | CloudLinux only (paid) | No | No | No | Yes — all plans |
| PID/Mount Namespaces | CloudLinux only (paid) | No | No | No | Yes — all plans |
| SSH Chroot Jail | CageFS (paid add-on) | Basic | No | Manual config | Yes — all plans |
| Per-User PHP-FPM | Yes (EasyApache, paid) | Basic | No | Basic | Per-user + per-version + per-domain |
| Per-Domain Socket | No | No | No | No | Yes — per domain |
| WAF (ModSecurity) | Paid add-on | No | Limited | Manual | Panel-managed — all plans |
| Kernel Resource Limits | CloudLinux only (paid) | No | No | No | Kernel-enforced — all plans |
The important caveat on cPanel: the features marked "CloudLinux only" work very well — when you're running CloudLinux. But CloudLinux is a separate operating system license, billed per-server per-month on top of your cPanel license. On a typical shared hosting server, you're looking at $40-60/month in licensing before you've paid for the hardware. Panelica includes equivalent isolation (and in some cases deeper) as part of the standard license.
Technical Specifications
Five Layers. Zero Compromises. Every Plan.
Most panels treat security isolation as a premium feature — something you unlock by paying more or by switching to a different operating system. CloudLinux exists precisely because cPanel's base installation lacks the kernel-level isolation that production shared hosting requires.
Panelica's position is different: kernel-level isolation is not a feature you should have to pay extra for. It's the correct architecture for any server with multiple users. We built the isolation layer first, then built the panel around it.
The five layers work together and they work independently. Each layer stops a different class of attack. Together, they contain a compromise to the user it started with — leaving every other user on your server unaffected.
One compromised PHP script shouldn't take down your entire server. With Panelica, it won't.
See It Running on Your Server
Install Panelica in under 3 minutes. All five isolation layers active from the first user created. No CloudLinux license required. No premium add-ons.