Security
Security in OPanel is built from stock Debian primitives — systemd sandboxing, cgroups, nftables, mTLS — rather than a third-party kernel module. This page covers the pieces operators configure and watch.
Per-site isolation
Section titled “Per-site isolation”Every site gets, without any configuration:
| Layer | How |
|---|---|
| Identity | Its own Unix user and group, with a cluster-unique ID so sites move between servers without chown |
| Filesystem | Its own home directory, mode 0710, invisible to every other tenant |
| Processes | A systemd sandbox for every process it runs — PHP-FPM, cron, SSH/SFTP, WP-CLI, file manager operations |
| Resources | A cgroup v2 slice with its own CPU quota, memory limit, task limit and I/O weight |
| PHP | Its own PHP-FPM master and its own OPcache — no cross-tenant cache poisoning |
| Cache | Its own Valkey instance or key-prefix-restricted ACL user |
| Database | Its own MariaDB users, with grants only on its own databases |
A site’s code cannot see another tenant’s files, processes or PHP cache. This is what CloudLinux and CageFS sell as a paid add-on to cPanel; here it’s the default for every site on stock Debian.
Web application firewall
Section titled “Web application firewall”Each site has a firewall mode: off, detect (matches are logged, nothing blocked) or block (matching requests get a branded 403). It’s Coraza running the OWASP Core Rule Set, inspecting the request line, headers and up to 13 MiB of the body.
If the firewall itself fails to load, block-mode sites are served a 503 rather than left
unprotected; detect-mode sites keep serving uninspected. The affected server shows a
waf_unavailable problem in the console until it recovers.
Cluster-wide IP blocking
Section titled “Cluster-wide IP blocking”A built-in fail2ban for the whole platform. The controller, SSH gateways and edges each count abuse signals per client address and report them centrally:
| Signal | Reported by | Default threshold |
|---|---|---|
panel_login |
Controller | 20 failed sign-ins in 15 minutes |
ssh_auth |
SSH gateways | 15 refused attempts in 10 minutes |
wp_login |
Edges | 20 failed WordPress logins in 10 minutes |
xmlrpc |
Edges | 60 requests to xmlrpc.php in 5 minutes |
waf |
Edges | 20 blocked requests in 10 minutes |
flood |
Edges | 300 requests over the 100/s burst limit in 1 minute |
An address that crosses a threshold is blocked on every server within seconds: 10 minutes the first time, 1 hour the second, 24 hours from the third within a rolling 7-day window. Loopback, private ranges, cluster node addresses, your admin networks and a staff allowlist are never blocked, and a block never closes an operator’s open SSH session.
Manage it under Admin → Security → IP blocking, or /api/v1/ip-blocks,
/api/v1/ip-allowlist and /api/v1/ip-blocking/settings. If a site sits behind a CDN you don’t
otherwise trust, add the CDN’s networks to edgeTrustedProxies — otherwise every visitor behind it
shares the CDN’s address and the CDN itself gets blocked.
Malware scanning
Section titled “Malware scanning”Every site is scanned on the server that holds its files: changed files every six hours, a full scan weekly, each site at its own time within the window. Three layers run, cheapest first:
- WordPress checksums —
wp core verify-checksumsand plugin checksums against WordPress.org, without loading any plugin or theme code. - The built-in scanner — reads every file (never executes any), compares hashes against a
known-bad list, and runs lexical rules for PHP web malware: obfuscated
eval/base64_decodechains, web shell markers, disguised uploaders, PHP hidden in upload or image folders, and more. - ClamAV and YARA, if you install them on a server — scans pick them up automatically from the next run.
Findings are quarantined into the server’s trash (recoverable until the retention window passes),
or resolved, or marked as a false positive. Site owners are notified by email on new high or
critical findings. See Admin → Security → Malware or /api/v1/sites/{id}/malware.
Sign-in security
Section titled “Sign-in security”- Staff must have a second factor — an authenticator app or a passkey — before they can do anything but set one up. This applies to platform staff and reseller brand staff alike.
- Passkeys, TOTP and recovery codes are available to every account. Ten recovery codes are issued when a second factor is first set up.
- Sessions are listed and individually revocable, with idle and absolute timeouts.
- API tokens never act on the account that created them — a leaked token can act on customers and sites within its scopes, but cannot change a password, read second factors, or add an SSH key. See API reference.
Regain access to a locked-out installation from the command line, as the opanel service account:
runuser -u opanel -- opanel admin reset-password --email person@example.comrunuser -u opanel -- opanel admin reset-password --email person@example.com --clear-mfamTLS between components
Section titled “mTLS between components”Every internal connection — controller, agents, edges, SSH gateways — is mutual TLS on the cluster’s own certificate authority. Certificates last 90 days and renew themselves automatically. Retiring a server, or removing a role from it, withdraws its certificates immediately, in both directions, rather than letting them run out naturally — a retired or demoted server cannot keep talking to the cluster, and the cluster stops answering it. Every client also pins the specific server it means to reach, not just its role, so a certificate cannot be reused to impersonate a different node.
Audit log
Section titled “Audit log”Every mutating action anywhere in OPanel — by staff, by customers, by the system itself — is
recorded with its actor, IP address, the affected object and what changed. Staff can filter it by
actor, action, subject and time range under Admin → Audit log or GET /api/v1/audit.