DEV Community

우병수
우병수

Posted on • Originally published at techdigestor.com

cPanel/WHM Is Down — Here's What I Actually Use to Manage Shared and VPS Hosting Without Paying for a Panel

TL;DR: The thing that actually broke my cPanel loyalty wasn't a better alternative appearing — it was the October 2019 licensing change. Before that, cPanel/WHM ran on a flat per-server model.

📖 Reading time: ~31 min

What's in this article

  1. Why I Stopped Relying on cPanel/WHM for New Projects
  2. The Actual Problem You're Probably Here to Solve
  3. Recovering Access to a Locked cPanel/WHM Box (Before You Nuke It)
  4. The Free Panels I've Actually Deployed in Production
  5. HestiaCP Setup Walkthrough — From Zero to Hosting Multiple Sites
  6. CyberPanel vs HestiaCP vs Webmin/Virtualmin — When to Pick Which
  7. Migrating Off cPanel Without Losing Your Clients' Data
  8. Hardening Your Panel Install — Stuff the Docs Skip

Why I Stopped Relying on cPanel/WHM for New Projects

The thing that actually broke my cPanel loyalty wasn't a better alternative appearing — it was the October 2019 licensing change. Before that, cPanel/WHM ran on a flat per-server model. After? They switched to per-account billing, and the cheapest tier jumped to around $15/month for up to 5 accounts, scaling to $40+/month for anything resembling a real agency setup. I was running 30+ client sites on a single VPS. The math went from "affordable infrastructure cost" to "this is now my second-biggest business expense overnight."

Here's something I want to address directly: a huge chunk of people searching for "cPanel WHM auth bypass PoC" are not script kiddies targeting someone else's box. They're developers who got locked out of their own server — maybe a client changed the WHM root password before a contract ended, maybe a VPS migration corrupted the session tokens, maybe they inherited a server from a freelancer who's now unreachable. The desperation behind that search is real and completely legitimate. You built something, you pay for the hardware, and now a UI layer is holding your own infrastructure hostage.

What I cover here is the practical exit ramp: free and open-source control panels that give you back real ownership. SSH access you control, DNS management you can actually script against, email server config that doesn't require clicking through 14 nested menus, and multi-site/multi-domain management that doesn't charge you per account. Every tool I mention you can install on a fresh Ubuntu 22.04 or Debian 12 VPS in under 30 minutes, and none of them will send you a revised invoice because you added a subdomain.

If your dependency problem goes beyond hosting panels — you're stuck on expensive SaaS tools across the board — the Essential SaaS Tools for Small Business in 2026 guide is worth reading alongside this. The pattern repeats itself: vendor locks in a workflow, raises prices, and suddenly "switching cost" becomes the product they're actually selling you.

The Actual Problem You're Probably Here to Solve

The keyword that brought you here is a magnet for two very different audiences: people who've genuinely locked themselves out of a server they own, and people looking for exploit code. I'm writing for the first group. If you're the second group, close the tab — CVE exploit PoCs for cPanel/WHM auth bypass vulnerabilities are not something I'll be covering, and running them against systems you don't own is a federal crime in most jurisdictions.

The most common scenario I've seen play out: you inherit a VPS from a previous sysadmin, the WHM root password isn't in the handoff docs, and the cPanel account passwords are equally useless for getting back into WHM itself. The legitimate recovery path depends entirely on your VPS provider. Every major provider gives you an out-of-band console that bypasses the OS entirely:

  • Linode (Akamai Cloud): Dashboard → your Linode → "Launch LISH Console" → reboot into rescue mode. You get a Finnix-based live environment where you can mount your disk and chroot into it, then run passwd root.
  • DigitalOcean: Droplet → Recovery → "Boot from Recovery ISO". Same idea — you get console access before the OS boots, mount /dev/vda1 or whatever your root partition is, and reset credentials from there.
  • Vultr: Server → Settings → "ISO" tab lets you boot a custom ISO, or use their built-in recovery mode. Their console is under "View Console" directly on the server page.

If you're on a dedicated box or a provider without rescue mode (some budget hosts skip this), the GRUB single-user method is your fallback. At boot, interrupt GRUB, find your kernel line, and append init=/bin/bash or single depending on your distro. On AlmaLinux/CloudLinux (which cPanel requires), it looks like this:

# At GRUB menu, press 'e' to edit the boot entry
# Find the line starting with 'linux' or 'linux16'
# Append to end of that line:
rd.break enforcing=0

# Then Ctrl+X to boot — you land in initramfs shell
mount -o remount,rw /sysroot
chroot /sysroot
passwd root
# Type new password twice
touch /.autorelabel   # Required on SELinux systems or you'll get locked out again
exit
reboot
Enter fullscreen mode Exit fullscreen mode

The touch /.autorelabel line is the one people skip and then spend an hour confused about why SSH still rejects them. SELinux on CloudLinux/AlmaLinux will flag the changed /etc/shadow context and block the login until a relabel happens. First reboot after this takes several minutes — that's normal, not a hang.

The second scenario is actually where this article gets more useful: you're not locked out, you're just questioning whether renewing cPanel at $45–$200+/month (their current tier pricing, depending on account count) makes sense for your setup. If you're managing fewer than 5 domains on a single VPS, the honest answer is probably no. Tools like HestiaCP, Webmin/Virtualmin, and CyberPanel cover 90% of what a solo developer or small agency actually does — SSL certs, virtual hosts, DNS, MySQL databases, email — without the licensing overhead. The third scenario is essentially the same question asked from the other direction: you want to resell or manage multi-tenant hosting and you need WHM-style account isolation without paying WHM prices. That's a completely solvable problem, and the rest of this piece covers exactly which tools map to which situations.

Recovering Access to a Locked cPanel/WHM Box (Before You Nuke It)

The most overlooked tool in this situation is your VPS provider's web console — and I mean this literally. Before you panic and open a support ticket, open your Vultr, Linode (now Akamai Cloud), or Hetzner dashboard and find the "View Console" button. This gives you a noVNC or serial console session that completely bypasses SSH, firewall rules, and fail2ban. It doesn't matter that you locked yourself out over port 22 or that CSF dropped all your IPs. The console talks directly to the hypervisor. I've recovered three servers this way that I was 100% convinced were gone.

If the OS won't boot, or root's password is genuinely unknown, you go rescue mode. Hetzner's rescue system is particularly clean — you reboot into a minimal Linux environment and your original disk is sitting at /dev/sda (or /dev/nvme0n1 on newer boxes). Mount it, chroot in, reset the password:

# Hetzner rescue shell — adapt device path to your actual disk
mount /dev/sda1 /mnt
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
chroot /mnt

# Now you're inside your original OS
passwd root
# Type new password twice, then:
exit
reboot
Enter fullscreen mode Exit fullscreen mode

Linode calls this "Rescue Mode" and Vultr calls it "Boot from ISO" — same idea, different labels. On CentOS 7/AlmaLinux 8 systems (which is most cPanel installs), your root partition might be LVM. If mount /dev/sda1 /mnt gives you nothing useful, run lvscan, then vgchange -ay, and your actual volume will show up under /dev/mapper/.

If you can get a root shell but specifically lost the WHM password — the OS is fine, you can SSH in as root — don't go near the database manually. cPanel ships a script for exactly this:

# Resets the WHM/reseller password for any cPanel account
/usr/local/cpanel/scripts/resetpass

# Or for a specific cPanel user account password from WHM API:
whmapi1 passwd user=myusername password='N3wSecureP@ss'
Enter fullscreen mode Exit fullscreen mode

resetpass is interactive and walks you through it. The whmapi1 command is the one I reach for when a client is locked out of their individual hosting account but WHM itself is fine — it goes straight through cPanel's own auth layer and doesn't touch MySQL directly. Both require you to be root on the box.

When none of the above works — the disk is corrupted, the system won't chroot cleanly, or something in cPanel's internal state is genuinely broken — stop trying to fix it live. Take a snapshot first. Every major provider has a one-click snapshot from the dashboard or API. Then provision a fresh VPS, reinstall AlmaLinux 8 + cPanel (the cPanel install script hasn't changed much in years: cd /home && curl -o latest -L https://securedownloads.cpanel.net/latest && sh latest), and restore from backup. This is where not having off-server backups will genuinely ruin your day. cPanel's built-in backup destination should be an S3 bucket or Backblaze B2 — not a directory on the same server. B2 costs $0.006/GB/month and the cPanel transport plugin supports it natively via S3-compatible API. If your backups lived on /backup on the same disk that just died, you've learned this lesson the expensive way.

The Free Panels I've Actually Deployed in Production

The thing that caught me off guard when I moved away from cPanel was how dramatically different these panels are under the hood — this isn't just a UI preference decision. Each one makes real architectural choices that affect your server's stack, performance ceiling, and failure modes. I've run all four of the panels below on live boxes, some for years. Here's what actually matters about each.

HestiaCP

HestiaCP is what VestaCP should have become before the original maintainers went dark around 2019. The fork picked up active development and it shows — the panel is polished, the Git history is alive, and security patches actually ship. Install on a fresh Ubuntu 22.04 LTS box looks like this:

# Download the installer — review it before you pipe to bash, seriously
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh

# Minimal production install: Apache + Nginx (Nginx as reverse proxy), Exim, Dovecot, BIND
bash hst-install.sh --apache yes --nginx yes --phpfpm yes --multiphp yes \
  --vsftpd yes --proftpd no --named yes --mysql yes --postgresql no \
  --exim yes --dovecot yes --sieve yes --clamav no --spamassassin no \
  --iptables yes --fail2ban yes --quota yes --interactive no \
  --hostname mail.yourdomain.com --email admin@yourdomain.com --password yourpassword
Enter fullscreen mode Exit fullscreen mode

The --multiphp yes flag is the one you want if you're managing multiple clients — it lets you assign PHP 7.4 through 8.3 per-domain without fighting the system PHP. ClamAV and SpamAssassin I leave off by default on anything under 4GB RAM; you can add them later and the panel handles it cleanly. Nginx sits in front of Apache here, which means you get static file performance from Nginx while Apache handles .htaccess — important if you're migrating WordPress sites that rely on mod_rewrite rules.

CyberPanel

If your workload is primarily WordPress and you care about raw page load speed, CyberPanel is the honest answer. It runs OpenLiteSpeed instead of Apache, and on identical hardware I've seen TTFB drop from 280ms to 90ms after migrating a mid-traffic WooCommerce store. The one-click WordPress installer actually configures LiteSpeed Cache automatically — you're not hunting for a plugin and manually configuring server-level caching like you would elsewhere.

# Requires a fresh CentOS 7/8, AlmaLinux 8/9, Ubuntu 20.04/22.04
sh <(curl https://cyberpanel.net/install.sh || wget -O - https://cyberpanel.net/install.sh)

# During install, select:
# 1 - Install CyberPanel with OpenLiteSpeed (free, not enterprise LiteSpeed)
# 1 - Full installation
# Y - Poweredby LiteSpeed (leave on)
# Y - Remote MySQL (only if you have a separate DB node)
Enter fullscreen mode Exit fullscreen mode

The trade-off is real: mail is handled by Postfix + Dovecot but the mail interface is basic, and if you need serious DNS cluster control or heavy email filtering, you'll hit walls fast. Also, CyberPanel's upgrade path has burned me twice — always snapshot before running cyberpanel upgrade. The Docker-based upgrade mechanism is clever in theory but I've had it fail mid-upgrade and leave the panel in a broken state that required a manual fix to the Python environment.

Webmin + Virtualmin

Ugly? Absolutely. But I've never hit an edge case that Virtualmin couldn't handle with some digging, which I genuinely cannot say about the others. It's been in production somewhere since the early 2000s and the docs reflect actual server behavior rather than marketing copy. When I needed to manage a server running Debian 11 with a non-standard mail setup involving both Postfix and a smarthost relay to a third-party spam filter, Virtualmin had a UI toggle for it. HestiaCP would've required template edits.

# Official install script — works on Debian 10/11/12, Ubuntu 20.04/22.04, RHEL/AlmaLinux 8/9
wget -O virtualmin-install.sh https://software.virtualmin.com/gpl/scripts/virtualmin-install.sh
chmod +x virtualmin-install.sh

# --bundle LAMP or LEMP depending on your preference
sudo ./virtualmin-install.sh --hostname yourdomain.com --bundle LAMP
Enter fullscreen mode Exit fullscreen mode

The free GPL version handles most use cases. Virtualmin Pro (paid) adds nicer backup integrations and a few convenience features, but I've run GPL in production for years without feeling like I was missing anything critical. The interface looks like it was designed in 2008 because parts of it were, but every option you need is there if you know where to look.

ISPConfig

ISPConfig is the only panel on this list designed from the ground up for multi-server setups. You get one master control panel that talks to multiple slave nodes — separate web servers, mail servers, and DNS servers — over a MySQL replication channel. I've used this for a small hosting operation where we needed to split mail and web onto different physical boxes for compliance reasons. Nothing else in the free tier does this cleanly.

# Multi-server setup requires the "expert" install mode
# Run on master first, then on each slave pointing back to master's DB
wget -O - https://get.ispconfig.org | sh -s -- --use-ftp-ports=40110-40210 \
  --use-unattended-setup --lang=en

# Slave node install — connect to existing master
wget -O - https://get.ispconfig.org | sh -s -- --use-expert-setup
# During setup: choose "Join existing ISPConfig multiserver setup"
# Provide master DB host, port 3306, ispconfig DB credentials
Enter fullscreen mode Exit fullscreen mode

The learning curve is steeper than HestiaCP and the UI is somewhere between Virtualmin and modern. But for true infrastructure separation, it's the only free option that doesn't involve duct tape.

What I Stopped Using and Why

  • VestaCP — abandoned upstream, unpatched CVEs sitting in the codebase, HestiaCP is a direct migration path anyway.
  • Ajenti — the UI is genuinely the nicest of any panel listed here, but half the plugins are broken or unmaintained and I found myself fixing Python dependency conflicts more than managing servers.
  • DirectAdmin — solid panel, but starts at $29/month per server. Not free, doesn't belong on this list regardless of how good it is.

HestiaCP Setup Walkthrough — From Zero to Hosting Multiple Sites

The thing that surprised me most about HestiaCP is how opinionated the installer is — and that's actually a good thing. You get one shot to configure it correctly, because retrofitting components after install is painful. The install command is long, but every flag matters. Before you run anything, make sure you're on a fresh Ubuntu 22.04 LTS VPS with at least 1GB RAM (2GB is more comfortable), and your domain's A record is already pointing at the server IP. DNS propagation needs to have settled — the installer will attempt hostname resolution.

Disable UFW before you touch the installer. HestiaCP ships with its own iptables + fail2ban stack, and if UFW is already running, you'll get silent port conflicts that are annoying to debug. Run this first:

# Kill UFW completely — HestiaCP manages firewall rules itself
systemctl stop ufw && systemctl disable ufw
Enter fullscreen mode Exit fullscreen mode

Then grab and run the installer. Here's the full command I use for small client VPS setups — notice ClamAV is explicitly off:

wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh

bash hst-install.sh \
  --apache yes \
  --phpfpm yes \
  --multiphp yes \
  --vsftpd no \
  --proftpd no \
  --named yes \
  --mysql yes \
  --postgresql no \
  --exim yes \
  --dovecot yes \
  --sieve yes \
  --clamav no \       # critical on 1GB RAM — ClamAV alone wants ~500MB
  --spamassassin no \
  --iptables yes \
  --fail2ban yes \
  --quota no \
  --api yes \
  --lang en \
  --hostname mail.yourdomain.com \
  --email admin@yourdomain.com \
  --password YourStrongPass \
  --force
Enter fullscreen mode Exit fullscreen mode

ClamAV is the gotcha that bites people hardest. I watched a client's 1GB VPS become completely unresponsive 20 minutes after a fresh install because ClamAV's freshclam process was doing its initial signature download while the rest of the stack was starting up. Disabling it post-install technically works, but the service still initializes during boot before you can kill it. Just skip it at install time with --clamav no. If you genuinely need malware scanning later, add it to a bigger VPS.

After the installer finishes (expect 10–15 minutes), you'll hit the web UI at https://yourserver:8083. Adding your first domain through the UI is straightforward — Web → Add Web Domain — but I always end up using the CLI anyway because it's scriptable:

# Add domain via CLI (runs as root or with sudo)
v-add-domain admin yourdomain.com

# Then provision Let's Encrypt SSL — include www if you want both covered
v-add-letsencrypt-domain admin yourdomain.com www.yourdomain.com
Enter fullscreen mode Exit fullscreen mode

For WordPress specifically: create the domain, then drop your files into /home/admin/web/yourdomain.com/public_html/. HestiaCP creates a per-user directory structure with separate document roots, logs, and config — it's cleaner than most cPanel layouts I've worked with. The database gets created via Web → phpMyAdmin or with v-add-database admin dbname dbuser dbpass mysql.

The multi-PHP feature is the actual reason I recommend HestiaCP for client work over anything else at this price point (free). Switching a domain from PHP 7.4 to PHP 8.2 is literally a dropdown in the domain's Edit screen — three clicks, no nginx config editing, no pool file juggling. I maintain a handful of legacy WordPress sites that can't run on 8.x yet alongside newer projects on 8.2, all on the same VPS. With cPanel that story involves WHM's EasyApache, which is fine but overkill when you don't own the license. The HestiaCP implementation just works, and the switch takes effect immediately without restarting anything manually.

CyberPanel vs HestiaCP vs Webmin/Virtualmin — When to Pick Which

CyberPanel vs HestiaCP vs Webmin/Virtualmin — The Actual Decision Matrix

The thing that trips most people up is assuming these panels are interchangeable with different UIs. They're not. Each one made a fundamentally different architectural bet, and that bet affects every decision downstream — from which PHP versions you can run per domain to whether your email deliverability will be a constant headache or just occasionally annoying.

Panel

Web Server

Email Stack

One-Click Apps

Clustering

RAM Floor

OS Support

Maintenance

HestiaCP

Nginx + Apache (reverse proxy)

Exim + Dovecot

WordPress via CLI

No

~512MB usable

Ubuntu 20.04/22.04, Debian 10/11/12

Active — frequent releases

CyberPanel

OpenLiteSpeed (or LiteSpeed Enterprise)

Postfix + Dovecot

WordPress, Joomla, Prestashop

Yes (LiteSpeed)

~1GB recommended

Ubuntu 20.04/22.04, AlmaLinux 8/9, CentOS 7

Active, but issues linger

Webmin/Virtualmin

Apache (Nginx optional)

Postfix + Dovecot or Sendmail

WordPress via script

No

~256MB (Webmin alone)

RHEL/Alma/Rocky/CentOS, Ubuntu, Debian

Active — Webmin has been around since 1997

ISPConfig

Apache or Nginx (your choice)

Postfix + Dovecot + Rspamd/Amavis

None built-in

Yes — multi-server

~512MB

Debian, Ubuntu, AlmaLinux, Rocky

Active, conservative release pace

Pick HestiaCP if you're migrating cPanel clients and need the workflow to feel familiar without paying WHM licensing fees. The multi-PHP-per-domain setup is straightforward — you can run PHP 7.4, 8.1, and 8.3 simultaneously across different accounts using PHP-FPM pools, and the Nginx+Apache reverse proxy mode means your .htaccess\ files keep working without any translation layer. I've migrated a 40-account shared hosting box from cPanel to Hestia and the client-facing panel felt close enough that nobody filed a support ticket about the UI. The install is also genuinely one command:

# On a clean Ubuntu 22.04 VPS — run as root
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
bash hst-install.sh --apache yes --phpfpm yes --multiphp yes --vsftpd yes --proftpd no \
  --named yes --mysql yes --postgresql no --exim yes --dovecot yes \
  --spamassassin yes --clamav no --softaculous no --port 8083 --lang en
Enter fullscreen mode Exit fullscreen mode

Pick CyberPanel specifically when you're running WordPress-heavy hosting and want OpenLiteSpeed's cache layer doing the heavy lifting at the web server level rather than through a plugin. LSCache at the OLS layer is genuinely fast — I've seen TTFB drop from 400ms to under 60ms on mid-traffic WordPress sites just from the cache configuration, with no code changes. The honest caveat: .htaccess\ compatibility is about 85-90% there. Rules for basic redirects and password protection work fine. Complex mod_rewrite chains, especially anything relying on RewriteBase\ behavior inherited from Apache, occasionally behave differently. Test before you migrate. Also, CyberPanel's bug tracker has issues that sit open for months — the panel works well enough in practice, but don't expect rapid fixes if you hit an edge case.

Pick Webmin/Virtualmin if you're on CentOS/AlmaLinux, need actual BIND DNS control (zone file editing, DNSSEC, split-horizon setups), or you're managing a server that's been running for three years and you're not touching the OS. This is the only panel where I'd feel comfortable adding it to an existing production server without reinstalling, because Virtualmin installs on top of your existing stack rather than assuming it owns the machine. The BIND integration is the best of the four — you get per-zone controls, record-level TTL overrides, and view configuration from the UI, which matters when you're supporting clients who've customized their DNS in ways no migration tool will correctly detect.

Pick ISPConfig if the problem you're solving is managing multiple physical servers from one interface. Everything else is a reasonable panel; ISPConfig's multi-server setup is its actual superpower. You can have a dedicated mail server, a web server, and a DNS server all managed from one ISPConfig master installation, with per-service role assignment. The setup doc is long and the UI feels like it was designed in 2009 because it mostly was, but for a small hosting operation with physically separate infrastructure it's the only free option that handles this natively.

Don't install any panel if you're running a single application on a VPS. A WordPress site, a Node.js API, a Django app — none of these need a control panel. Every panel you install adds open ports, a login endpoint, cron jobs running as root, and software that needs its own patching schedule. The attack surface is real and the benefit is zero. Configure Nginx directly, get your cert with Certbot, and call it done:

# Everything you actually need for a single-app VPS
apt install nginx certbot python3-certbot-nginx -y
certbot --nginx -d yourdomain.com --non-interactive --agree-tos -m you@yourdomain.com

# Harden Nginx — disable server tokens, set reasonable timeouts
# /etc/nginx/nginx.conf
server_tokens off;
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
Enter fullscreen mode Exit fullscreen mode

The auth bypass CVEs that hit cPanel/WHM historically — and the ones that have surfaced in open-source panels too — almost always target the panel's own authentication layer, not your application. No panel means no panel vulnerabilities. That's not paranoia, that's just reducing the thing that can be exploited to the things that actually need to be there.

Migrating Off cPanel Without Losing Your Clients' Data

The part that trips people up isn't the migration itself — it's discovering halfway through that your new panel imported the files and databases but silently dropped the cron jobs, the custom php.ini overrides, and three years of client email. I've seen agencies lose client trust over exactly this. The fix is treating migration as a multi-step checklist rather than a one-click import.

What's Actually Inside a cPanel Backup

A cPanel full backup is a .tar.gz with a predictable internal structure. Once you extract it, you know exactly where everything lives:

# Extract and inspect without fully unpacking first
tar -tzf backup-username.tar.gz | head -60

# When you're ready to extract
tar -xzf backup-username.tar.gz -C /tmp/cpanel_restore/

# Internal layout you'll find:
# homedir/          → the user's public_html, mail, etc.
# mysql/            → .sql dumps of each database
# mysql.sql         → user/permission grants
# cp/               → cPanel-specific metadata (cron, email accounts, etc.)
# userdata/         → vhost config per domain
# ssl/              → certificates if any were active
Enter fullscreen mode Exit fullscreen mode

The cp/ directory has your cron jobs in a file literally called cron — plain text, one job per line. Your custom PHP settings live scattered across per-directory .htaccess or php.ini files inside homedir/. Nothing imports those automatically. Before you run any migration script, grep through the backup manually: find /tmp/cpanel_restore -name "php.ini" -o -name ".user.ini" — collect what you find and re-apply them by hand on the destination.

HestiaCP's Migration Script: What It Gets Right and Wrong

HestiaCP ships a restore command that handles the heavy lifting for file and database content. The command is straightforward:

# Run as root on the destination HestiaCP server
v-restore-user admin /path/to/backup-username.tar.gz

# Watch the restore log in real time
tail -f /var/log/hestia/system.log
Enter fullscreen mode Exit fullscreen mode

It correctly restores web files, creates the MySQL databases and users, and sets up the domain vhosts. What it does not restore: cron jobs (the cp/cron file is ignored), custom PHP ini directives, SSL certificates from the backup (you'll need to re-issue via Let's Encrypt), and email forwarders. Go back to the extracted backup, open cp/cron, and manually add each job through HestiaCP's cron UI or via v-add-cron-job. It takes ten minutes and saves you an angry client email at 3am when their scheduled invoice script stops firing.

Database Migration: Skip phpMyAdmin for Anything Over 50MB

phpMyAdmin's export will time out or silently truncate on large databases — the default PHP execution limits on shared hosts kill the request mid-export. Use SSH and mysqldump directly from the source server:

# On the SOURCE (cPanel) server via SSH
mysqldump -u dbuser -p --single-transaction --routines --triggers \
  --hex-blob database_name > /home/username/db_export.sql

# Compress it before transferring — large DBs compress 70-80%
gzip db_export.sql

# SCP to destination (run this from your local machine or destination)
scp user@oldserver.com:/home/username/db_export.sql.gz /tmp/

# Import on destination
gunzip -c /tmp/db_export.sql.gz | mysql -u newdbuser -p new_database_name
Enter fullscreen mode Exit fullscreen mode

The --single-transaction flag is critical if you're dumping InnoDB tables on a live site — it takes a consistent snapshot without locking tables, so the site stays up during export. --routines and --triggers are easy to forget and will break any app that relies on stored procedures. Always verify row counts after import: SELECT COUNT(*) FROM critical_table; on both servers before you flip DNS.

DNS Cutover Without the 24-Hour Anxiety Window

Lower your TTL to 300 seconds (5 minutes) at least 24 hours before you plan to switch — this is the step most people skip and then wonder why propagation takes forever. Once old resolvers flush their cache of your previous 14400-second TTL, your actual switchover window drops to about 10 minutes instead of 4+ hours.

# Check current TTL before you start
dig yourdomain.com A +noall +answer

# After switching nameservers or A record, trace propagation
dig +trace yourdomain.com

# Check from multiple resolver perspectives
dig @8.8.8.8 yourdomain.com A
dig @1.1.1.1 yourdomain.com A
dig @9.9.9.9 yourdomain.com A
Enter fullscreen mode Exit fullscreen mode

Keep the old server live and responding for a full 48 hours after the DNS switch. Stragglers — mostly corporate networks with aggressive local DNS caching — will still hit the old IP. If you shut it down immediately, those users see a dead site. Set a calendar reminder to decommission, not an impulse shutdown. During those 48 hours, keep both servers synced for any databases getting writes — a quick rsync or manual DB export every few hours covers you.

Email Migration: The Part That Actually Costs You Clients

Files and databases are easy to verify. Email is invisible until a client notices their 2019 project correspondence is gone. imapsync is the right tool — it connects to both IMAP servers simultaneously and copies messages folder-by-folder, preserving read/unread state and folder structure.

# Install on any Linux box (can run from your local machine)
apt install imapsync   # Debian/Ubuntu
# or: cpan Mail::IMAPClient (if installing via CPAN)

# Basic sync — run BEFORE DNS cutover while both servers are live
imapsync \
  --host1 oldserver.com --user1 client@domain.com --password1 'oldpass' \
  --host2 newserver.com --user2 client@domain.com --password2 'newpass' \
  --ssl1 --ssl2 \
  --automap \
  --exclude "Trash|Junk|Spam"

# Run it again after DNS cutover to catch the delta (emails received during migration)
# The --addheader flag prevents duplicate detection issues with some mail servers
imapsync ... --addheader
Enter fullscreen mode Exit fullscreen mode

Run imapsync twice: once a day or two before cutover to do the bulk transfer, then again immediately after DNS propagates to sync the delta. The second run is fast because imapsync skips already-transferred messages by comparing message IDs. One gotcha: cPanel's mail storage uses Maildir under homedir/mail/, so if IMAP isn't responding on the old server for some reason, you can also copy those Maildir folders directly to the new server's mail directory and HestiaCP will pick them up — the format is compatible.

Hardening Your Panel Install — Stuff the Docs Skip

The thing that catches most people off guard: the default ports for these panels are public knowledge, actively catalogued in Shodan, and get hammered within hours of a VPS spinning up. I've watched auth logs on fresh installs fill up with brute-force attempts against port 8083 before I'd even finished setting up DNS. Moving the port isn't security theater — it eliminates 99% of automated scanning noise immediately.

Move the Panel Off Its Default Port First

HestiaCP ships on 8083, CyberPanel on 8090. Every script kiddie scanner knows this. For HestiaCP, there's a built-in command that handles the nginx config, firewall rules, and service restart all at once — don't just change it in the config file manually or you'll break things:

# Pick something non-obvious — not 2087, that's cPanel's port and also scanned
v-change-sys-port 2087

# Verify the service restarted cleanly
systemctl status hestia

# Confirm the port is actually bound
ss -tlnp | grep hestia
Enter fullscreen mode Exit fullscreen mode

For CyberPanel there's no equivalent one-liner, so you're editing /usr/local/lsws/conf/httpd_config.xml and updating the admin listener port, then restarting OpenLiteSpeed. More annoying, but same principle.

Lock the Panel Port Down to Your IP Only

Port obscurity slows down scanners. IP whitelisting stops everyone else cold. The order of these iptables rules matters — the DROP rule has to sit above any blanket ACCEPT rules or it won't fire:

# Block everyone except your IP from reaching the panel port
iptables -I INPUT -p tcp --dport YOUR_PORT ! -s YOUR.IP.HERE -j DROP

# Make it survive reboots (Debian/Ubuntu)
apt install iptables-persistent -y
netfilter-persistent save

# If you're on a dynamic IP, use your hosting provider's firewall UI instead
# — iptables rules don't update themselves when your home IP changes
Enter fullscreen mode Exit fullscreen mode

The gotcha here: if you have multiple admins or you're on a VPN that rotates IPs, this gets painful fast. In that case, put the panel behind a WireGuard tunnel and only allow the WireGuard interface. More setup upfront, zero headaches after.

Fail2ban Is Installed but Probably Not Watching the Panel

Most panel installers drop Fail2ban on the system but leave the panel-specific jails in a disabled state. Check yours right now:

cat /etc/fail2ban/jail.local | grep -A5 hestia

# If that's empty, check what jails actually exist
ls /etc/fail2ban/filter.d/ | grep hestia

# Enable the jail by adding this to jail.local
[hestia-iptables]
enabled = true
filter = hestia-iptables
action = iptables-multiport[name=hestia, port="YOUR_PORT", protocol=tcp]
logpath = /var/log/hestia/auth.log
maxretry = 5
bantime = 3600

systemctl restart fail2ban
fail2ban-client status hestia-iptables
Enter fullscreen mode Exit fullscreen mode

The maxretry = 5 with a 1-hour ban is reasonable for a panel. Some people go lower on retries, but 3 attempts will lock out your own junior devs constantly. Five is the practical floor.

TOTP on the Admin Account — Before You Add Any Sites

HestiaCP added TOTP support in v1.6 and it's genuinely well-implemented. Go to Admin → Edit User → Two-Factor Authentication, scan the QR code into Authy or any TOTP app, and save your backup codes somewhere that isn't the same server. I mean it about doing this first — before you add domains, before you create hosting accounts. A compromised admin account on a panel with 20 sites under it is a disaster; on a fresh install it's just an embarrassment.

CyberPanel's 2FA story is weaker — it exists but has had implementation bugs in past releases. Check the version you're running against their changelog before trusting it blindly.

Offsite Backups to B2 — the Config the Docs Bury

Backblaze B2 is genuinely the cheapest S3-compatible storage for this use case — $0.006/GB/month as of their current pricing, with free egress to Cloudflare-fronted destinations. HestiaCP's backup system supports it natively. The config lives in /usr/local/hestia/conf/hestia.conf:

# Add or update these lines in hestia.conf
BACKUP_SYSTEM='b2'
BACKUP_B2_BUCKET='your-bucket-name'
BACKUP_B2_KEYID='your-application-key-id'
BACKUP_B2_KEY='your-application-key'

# Restart hestia to pick up the changes
systemctl restart hestia

# Trigger a manual backup to verify it actually works
v-backup-user admin
Enter fullscreen mode Exit fullscreen mode

The part that burns people: B2 application keys are scoped. Create a key that's restricted to the specific bucket only — don't use your master key. If the server is ever compromised, a bucket-scoped key limits the blast radius to your backups, not your entire B2 account. Also set a lifecycle rule on the bucket to delete backups older than 30 days, otherwise costs creep up silently.

Honest Rough Edges — Where These Free Panels Still Fall Short

The thing that trips up most people first is email. Every panel I tested — HestiaCP, CyberPanel, AAPanel — will generate DKIM keys and sign outgoing mail automatically. That part works. What none of them do is push those DNS records anywhere. You get a text box showing your DKIM TXT record, and then you're on your own. DMARC is completely absent from all of them. No UI, no wizard, nothing. You're manually adding _dmarc.yourdomain.com TXT records and hoping you got the policy syntax right. For one or two domains that's fine. For twenty client domains it becomes a spreadsheet problem you have to manage yourself.

Reseller billing is the gap that actually matters if you're trying to run a business. None of these panels ship with invoicing. Not even a basic "charge $X per account per month" workflow. If clients are paying you, you're bolting on WHMCS (starts around $15.95/month on their shared license) or Blesta (one-time ~$99 plus renewals) and wiring it up manually via their APIs. HestiaCP has a WHMCS module maintained by the community — it works, but you're debugging provisioning failures yourself when it doesn't. Compare that to cPanel's WHM, where the reseller billing integration is at least documented and has paid support behind it.

The 2am failure scenario is where community support really shows its limits. I've been in the position of a Postfix queue backing up at midnight, searching HestiaCP's forum, and landing on a thread from 2021 where three people disagreed on the fix and none of them marked anything as resolved. GitHub issues are better for reproducible bugs but useless for "my mail stopped working after an OS update." CyberPanel has a slightly more active community because it's backed by a commercial company with a paid tier, so their forums get faster responses — but "faster" is relative when you're comparing hours to minutes.

PHP-FPM per-client isolation is the one that catches power users off guard. The panels will set up separate pools per domain, which is good. But the UI exposes almost nothing beyond enabling/disabling PHP-FPM and picking a version. If a client's WordPress site is memory-leaking and you need to tune pm.max_children or set request_terminate_timeout, you're doing this:

# HestiaCP stores pool configs here on Ubuntu 22.04
sudo nano /etc/php/8.2/fpm/pool.d/domain.conf

# Add or override these at the bottom — don't touch the generated header
pm.max_children = 10
pm.max_requests = 500
request_terminate_timeout = 60s

# Then reload, don't restart — restart drops active connections
sudo systemctl reload php8.2-fpm
Enter fullscreen mode Exit fullscreen mode

The panel will overwrite parts of that file on certain config changes, so you need to know which sections are safe to edit. There's no documentation on this. You find out by losing your edits once and then reading the panel's source code on GitHub to understand the templating logic.

The honest verdict breaks down cleanly by scale. Under roughly 15–20 client sites where you're also doing the dev work, these free panels are genuinely superior to paying $20–$45/month per server for cPanel licensing — you get cleaner defaults, faster servers without the cPanel overhead, and enough control to do real work. Past that threshold, especially if clients are non-technical and will email you when something breaks, the economics shift. cPanel and Plesk charge what they charge partly because their support chain exists — you can escalate, there are vendors who specialize in it, and your client's host probably already knows how to use WHM. That institutional familiarity has real value when you're managing 50+ accounts and can't personally debug every mail delivery failure at 2am.


Disclaimer: This article is for informational purposes only. The views and opinions expressed are those of the author(s) and do not necessarily reflect the official policy or position of Sonic Rocket or its affiliates. Always consult with a certified professional before making any financial or technical decisions based on this content.


Originally published on techdigestor.com. Follow for more developer-focused tooling reviews and productivity guides.

Top comments (0)