Panellicense

Tune WHM cPHulk brute force protection without lockouts

A working cPHulk configuration for shared cPanel servers — whitelist, thresholds, country blocking, notifications, and the CLI commands that get you back in when you lock yourself out.

6 min readUpdated 2026-05-16cpanel · whm · cphulk · security
schema: HowToschema: FAQPageschema: BreadcrumbList

cPHulk is the brute-force protection built into WHM. It watches SSH, WHM, cPanel, Webmail, FTP, POP3, IMAP, and SMTP for repeated authentication failures and blocks the source IP or account. The defaults are too lenient for a public-facing server and the first time you crank them up you will almost certainly lock yourself out — usually from a hotel Wi-Fi at the worst possible moment.

This is the configuration that survives a real shared-hosting workload: tight enough that SSH password sprays die in under a minute, loose enough that a customer mistyping their mail password three times doesn't generate a support ticket.

Step 0 — Whitelist before you touch anything else

The single most common cPHulk mistake is tightening the thresholds first and adding a whitelist second. Do this in the opposite order. Under WHM → Security Center → cPHulk Brute Force Protection → History Reports / Whitelist Management, add:

  • Your office or VPN egress IP
  • Your monitoring system's IP
  • Any IPs that run automated WHM API calls (Blesta, WHMCS, billing automation)
  • The server's own primary IP — surprisingly easy to lock out via loopback under some configs

Or from the shell:

whmapi1 create_cphulk_record list_name=white ip=203.0.113.42
whmapi1 create_cphulk_record list_name=white ip=198.51.100.0/24

CIDR notation works. Whitelisted IPs bypass all cPHulk checks, so do not whitelist shared-hosting customer IPs — only your own administrative ranges.

If you provision new servers from a single bastion, bake the whitelist into your cPanel VPS install playbook so a fresh build is never wide open.

Step 1 — Pick the right detection windows

cPHulk has two trigger pairs that map to different threat models:

SettingDefaultsWhat it catches
IP-based: failures + minutes9 in 5Single attacker pounding from one IP
Username-based: failures + minutes15 in 5Distributed attack across many IPs on one account

For a public server, drop the IP-based pair to 5 failures in 5 minutes and leave the username-based pair at the default. Going below 5 produces too many false positives from mail clients with stale passwords; going above 10 lets a slow brute-force run for hours.

The One-Day Block values matter more than the short-window ones — a one-day block should require a sustained attack, not a single bad afternoon. Set:

  • One-Day Block period: 24 hours
  • Failures before one-day block (IP): 40
  • Failures before one-day block (username): 80

The cPHulk database is checked on every login attempt and grows fast on a busy server. Keep Command to run when an IP triggers a one-day block empty unless you actually shovel events into a SIEM — running a shell hook on every block adds measurable CPU under attack.

Step 2 — Choose IP-based blocking, not just account-based

In Configuration Settings, two toggles change the behaviour materially:

  • Block IP addresses at the firewall level for failed logins. Turn this on. Without it, cPHulk only inserts records into its MySQL table and checks them application-side — fine for SSH, useless for protecting an exposed mail port from a 10k-IP botnet. With it on, cPHulk drops blocked IPs into iptables and the kernel rejects them before any daemon sees the connection.
  • Notify on brute force. On. Send to a real, monitored inbox — not the catch-all that no one reads.

The iptables chain cPHulk uses is cphulk, and rules are flushed and rebuilt by cphulkd on every config reload. Do not hand-edit it; use the whitelist UI or create_cphulk_record.

Step 3 — Country blocking is a 70% solution

Under Country Management, you can deny or allow logins from entire country codes. Useful, but with caveats:

  • The GeoIP database lags real allocations by weeks. A new VPS range in a "blocked" country may not be blocked.
  • Customers travel. A blanket block on countries you don't sell to will eventually deny a legitimate login from someone on holiday.
  • Tor exit nodes and residential proxies route around it trivially.

The right use: block at the firewall, not at the application. Keep the list short — the worst three or four offenders for your specific workload — and pair it with Imunify360's brute-force module for actual coverage. If you run both, disable one of them so they don't double-count failures.

Step 4 — Get back in when you lock yourself out

You will. When it happens, you have three options.

From an already-open SSH session (or your KVM/console):

# Confirm you are blocked
whmapi1 get_cphulk_status

# Remove the block on your IP
whmapi1 flush_cphulk_login_history_for_ips ip=203.0.113.42

# Or wipe the whole login history if you also need account unlock
whmapi1 flush_cphulk_login_history

If cPHulk is locked out and refusing all logins (the database can corrupt under heavy attack):

/usr/local/cpanel/bin/cphulkdwhitelist 203.0.113.42
/usr/local/cpanel/etc/init/stopcphulkd
/usr/local/cpanel/etc/init/startcphulkd

As an absolute last resort, disable cPHulk entirely from the console:

whmapi1 disable_cphulk

The setting persists across reboots. Re-enable as soon as you've added a whitelist entry via the API:

whmapi1 enable_cphulk

Step 5 — Monitor what's actually happening

The signal you want isn't "cPHulk is enabled" — it's "cPHulk is blocking faster than the attackers can find new IPs." Two things to watch:

  1. cPHulk's own log: /usr/local/cpanel/logs/cphulkd.loggrep BLOCK shows real-time blocks, useful as a tail in a tmux pane during an attack.
  2. The dashboard's History Reports: sorted by Number of Brutes, this surfaces the /16 ranges that need to go on the deny list. If you see the same /24 generate 800 failures across 200 IPs in an hour, deny the /16 in Whitelist/Blacklist Management.

The /blacklist API is symmetric to the whitelist:

whmapi1 create_cphulk_record list_name=black ip=192.0.2.0/24

Next steps

Does cPHulk protect WordPress logins?+
No. cPHulk only watches the cPanel-managed services (SSH, WHM, cPanel, Webmail, mail protocols). WordPress wp-login.php attacks reach Apache directly. Use ModSecurity with the OWASP CRS, Imunify360's WAF, or a plugin like Wordfence for that layer.
Should I use cPHulk or CSF/LFD?+
Pick one for brute-force protection. cPHulk is integrated with WHM and aware of cPanel users; CSF/LFD is more flexible and adds firewall management features cPHulk lacks. Running both means failures get counted twice and blocks fire earlier than your thresholds suggest.
Why is cPHulk blocking my own server's IP?+
Internal scripts that authenticate over the public IP (rather than 127.0.0.1) count against the same thresholds as outside attackers. Whitelist the server's primary IP, and switch automation to use the loopback or unix sockets where possible.
How do I clear all cPHulk blocks at once?+
Run whmapi1 flush_cphulk_login_history. This drops every block and every failure record. Only do this when you're sure no active attack is in progress — otherwise you've just handed every attacker a fresh quota of attempts.
Does country blocking work for SSH on a non-standard port?+
Yes. cPHulk applies its blocks at the iptables level (when firewall-level blocking is enabled), so the port your SSH daemon listens on doesn't matter. The block is by source IP, not destination port.
Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.