I Audited a Production WHM/cPanel Server. Here's What I Found (and How to Check Yours)
Source: Dev.to
Last month I ran a security audit on a production WHM/cPanel server. It belonged to a web agency hosting a couple dozen client sites — WordPress, WooCommerce, the usual stack. The server had been running for years without anyone really looking at it. Sites were up, clients were happy, nobody touched anything. Sound familiar? Here’s what I found: OpenSSH vulnerable to a critical CVE** (remote code execution class — the kind you patch the day it’s announced, not years later) SSH open to the world on port 22, root login enabled, password authentication on No brute-force protection beyond cPHulk’s defaults PHP versions EOL’d long ago, still serving production sites “Backups configured” — but never test-restored. Two were silently failing No firewall rules beyond the defaults. Every service exposed None of this is exotic. This is what most long-running cPanel servers look like when nobody owns them. So here’s the audit checklist I use — run it on your own server this week. It takes about an hour.
- Are you running vulnerable services? The single highest-impact check. Start with SSH, since it’s the front door: ssh -V
Compare against the OpenSSH release notes and check the version against known CVEs. If you’re on a years-old version, assume it’s vulnerable. On AlmaLinux/CloudLinux/RHEL-family (which is what cPanel runs on), check what security updates are pending: yum updateinfo list security all
If that list is long, that’s your priority for the week. Don’t cherry-pick — patch. Edit /etc/ssh/sshd_config:
Move off the default port (reduces noise, not a security measure by itself)
Port 2222
No root over SSH. Ever. Use a sudo user.
PermitRootLogin no
Keys only. Passwords get brute-forced.
PasswordAuthentication no PubkeyAuthentication yes
Limit who can even try
AllowUsers youradminuser
Then restart: systemctl restart sshd — but test the new connection in a second terminal before closing your current session. Locking yourself out of a production server is a rite of passage you can skip. Better yet: restrict SSH access to your IP at the firewall level, so the rest of the internet can’t even reach the port. cPanel servers should be running CSF/LFD (ConfigServer Security & Firewall). It’s free and integrates directly into WHM: cd /usr/src wget https://download.configserver.com/csf.tgz tar -xzf csf.tgz cd csf && sh install.sh
The defaults are decent, but the minimum to configure: TESTING = “0” once you’ve confirmed you’re not locked out Close every port you don’t use. A typical cPanel server needs far fewer open ports than the default Enable LFD login failure detection for SSH, FTP, mail, and cPanel itself Set LF_PERMBLOCK = “1” for repeat offenders Run this in WHM → MultiPHP Manager, or from the shell: whmapi1 php_get_installed_versions
Anything EOL (check php.net/supported-versions) is unpatched attack surface — and on a shared server, one compromised site is a problem for every site. Move accounts off EOL versions. If a client’s site “needs” PHP 7.4 in 2026, that’s a conversation about updating the site, not a reason to keep the server vulnerable. A backup you’ve never restored is a hope, not a backup. Whatever you use — cPanel’s native backups, JetBackup, rsync scripts — do this: Pick one account Restore it to a test location (JetBackup can restore to an alternate account) Verify: files there? Database imports? Emails intact? The agency server I audited had backups “running” for months. Two accounts were silently failing on a database dump error. Nobody knew, because nobody had ever restored one. While you’re at it, check the 3-2-1 basics: are backups stored off the server? A backup on the same disk as production protects you from nothing that matters.
Who has shell access?
grep -v ‘/sbin/nologin|/bin/false’ /etc/passwd
Who’s in the wheel/sudo group?
grep wheel /etc/group
Any resellers with root-level WHM privileges they don’t need?
In WHM → Edit Reseller Nameservers and Privileges, audit reseller ACLs. “All features” granted years ago for convenience is privilege escalation waiting to happen. Symlink protection — enable it in WHM (EasyApache → Apache symlink protection) so one compromised account can’t read other accounts’ files ModSecurity — should be on, with the OWASP CRS or Comodo ruleset cPHulk — enabled, with country-level blocking if your users are geographically predictable Disable unused services — systemctl list-units —type=service —state=running and ask yourself why each one is there /tmp mounted with noexec,nosuid — classic and still effective None of these steps are hard. The problem is never the difficulty — it’s that nobody owns the server. Sites get built, deployed, and forgotten. The server hums along until the day it doesn’t, and that day is expensive: downtime, blacklisted IPs, compromised client data, weekend recovery marathons. If you’re a developer or agency running your own WHM/cPanel box: block one hour, run this checklist, and write down what you find. Worst case, you confirm you’re in good shape. Best case, you find the thing before someone else does. I’ve spent 15+ years managing Linux and WHM/cPanel infrastructure, and these days I help web agencies keep their client-hosting servers secure and online through SysBalance. Questions about anything in this checklist? Drop them in the comments — happy to go deeper on any of these.