Dev.to Security 🔐 Cybersecurity 👁 1 📖 7 min read

The cPanel Mail Server Hardening Checklist I Never Skip

You work hard for your business, and all the while leads are slipping away — leads that never reached you — because of how the email server was set up. And the greater irony? Nobody knows it’s happening. One of my clie

The cPanel Mail Server Hardening Checklist I Never Skip

You work hard for your business, and all the while leads are slipping away — leads that never reached you — because of how the email server was set up. And the greater irony? Nobody knows it’s happening.

One of my clients recently asked me to diagnose a problem. The message was short:

“Hi Daanial, we’re not receiving email sometimes from one particular sender. Can you please look into it and fix or diagnose what’s wrong?”

Simple enough. So I opened the mail logs — and my heart sank. More than 8,000 emails had been discarded at the SMTP level: refused at the front door before they ever reached a single inbox. The customer had no idea. As far as they could tell, those messages were simply never sent.

That is the quiet killer of email hosting. It isn’t a dramatic outage you can see — it’s a loss of revenue you never knew you had.

That afternoon is exactly why I built the checklist in this article. It’s a must-read for email hosting providers, and a good read for anyone who cares whether email actually gets delivered. Below is every step I now run on a cPanel mail server before it ever touches a customer’s domain — in plain language.

First, think in layers — not one magic switch

The biggest mistake I see is treating email security as a single setting. It isn’t. A hardened mail server checks every message at several points, like a building with a guest list, a metal detector, and a locked back door. If one layer misses something, the next one catches it.

Every incoming email passes through several checkpoints before it reaches the inbox.
Every incoming email passes through several checkpoints before it reaches the inbox.

Step 1 — Switch on the spam engine

The first thing I do is turn on Apache SpamAssassin for the whole server. Out of the box it’s often off, or only on for some accounts. I force it on globally so no mailbox is left unprotected. In WHM: Home › Email › Apache SpamAssassin → Forced Global ON.

WHM: turning Apache SpamAssassin on for the entire server.
WHM: turning Apache SpamAssassin on for the entire server.

Plain takeaway: this is the smoke detector for email.

Step 2 — Tune the spam score so you don’t lose real mail

A spam filter that’s too aggressive is worse than no filter, because it eats real email. In cPanel, under Spam Filters › Spam Threshold Score, set it to “Passive — Only Very Obvious Spam (10)”. The higher the number, the more lenient — a value of 10 means only the most blatantly spammy messages get flagged.

Setting the spam threshold to 10 so genuine mail is never lost to false positives.
Setting the spam threshold to 10 so genuine mail is never lost to false positives.

Plain takeaway: start lenient. You can always tighten later — but you can never un-lose a customer’s email.

Step 3 — Add the global “known bad sender” lists

Blocklists (RBLs) are shared, worldwide lists of IP addresses already caught sending spam. I switch on the two I trust most — Spamhaus and SpamCop — under Exim Configuration Manager › RBLs.

Enabling the Spamhaus and SpamCop blocklists in WHM.
Enabling the Spamhaus and SpamCop blocklists in WHM.

One catch that trips up almost everyone: Spamhaus refuses to answer if you query it through a public DNS like Google’s 8.8.8.8. The server must use its own local resolver:

# point the server at its own resolver
rm -f /etc/resolv.conf
echo "nameserver 127.0.0.1" > /etc/resolv.conf
chattr +i /etc/resolv.conf   # lock the file so nothing overwrites it

Then prove it works — this test query should return a result:

dig @127.0.0.1 2.0.0.127.zen.spamhaus.org +short

Plain takeaway: blocklists stop the worst senders for free — but only if your server asks them the right way.

Step 4 — Make the server verify DKIM on incoming mail

DKIM is a digital signature legitimate senders attach to their email. Verifying it on incoming mail confirms a message really came from who it claims. Find it in WHM under Exim Configuration Manager › Basic Editor.

Turning on DKIM verification for incoming mail in Exim.
Turning on DKIM verification for incoming mail in Exim.

Plain takeaway: this is how the server checks a sender’s ID card instead of taking their word for it.

Step 5 — Put a guard on attachments (antivirus)

Spam is annoying; a virus is a liability. Install an antivirus/anti-malware scanner (ClamAV) so every attachment is checked before it lands in a mailbox: Home › cPanel › Manage Plugins.

Installing the ClamAV antivirus scanner from WHM’s plugin manager.
Installing the ClamAV antivirus scanner from WHM’s plugin manager.

Plain takeaway: the metal detector for attachments.

Step 6 — Stop your own server from becoming the spammer

One mailbox password leaks, an attacker logs in, and the server sends tens of thousands of spam messages in an hour — that’s how servers get blocklisted. Three settings in WHM Tweak Settings do the heavy lifting:

  • Cap hourly emails per account. One hacked account can no longer blast the internet.
  • Reject mail instead of silently dropping it. Silent dropping means email vanishes and nobody knows why.
  • Fail immediately instead of queueing. Bad mail is refused on the spot.

Setting a maximum number of emails each account can send per hour.
Setting a maximum number of emails each account can send per hour.

Reject undeliverable mail and fail immediately, rather than discard or queue it.
Reject undeliverable mail and fail immediately, rather than discard or queue it.

Outbound rate-limiting and sender tracking to catch a compromised account early.
Outbound rate-limiting and sender tracking to catch a compromised account early.

Plain takeaway: a good host doesn’t just block incoming spam — it makes sure it can never be the SOURCE of spam.

Step 7 — Get the server’s identity right

Big mail providers are suspicious of servers that look anonymous. I always set:

  • A real hostname (e.g. your-host.example.com).
  • Matching reverse DNS (PTR) — ask your datacenter. Mismatched rDNS is an instant spam signal.
  • A fresh SSL certificate (cPanel › SSL).
  • The correct server time.
  • A complete DNS record set: A (root, www, mail, webmail), MX, and — most importantly — SPF, DKIM, and DMARC.

Those last three are the trust trio: SPF says which servers may send for your domain, DKIM signs your messages so they can’t be forged, and DMARC tells the world what to do if a message fails. Skip them and your mail lands in spam, full stop. One more Exim tweak: reject remote mail sent to the server’s own hostname.

Plain takeaway: a server with a clean, honest identity gets trusted.

Step 8 — Lock the doors (firewall rules)

Think of the firewall as a guest list for the building: visitors come in through their own doors, the control room opens only for staff, every other door stays locked.

The firewall guest list: who can reach which port on the server.
The firewall guest list: who can reach which port on the server.

  • Website traffic (80, 443): ideally only from Cloudflare’s IP ranges.
  • Email ports (25, 465, 587, 993, 995): open to all.
  • cPanel 2083 / WHM 2087 / SSH 22: restricted to the admin’s own IP only.
  • Everything else: denied by default; outbound allowed.

One more lock I never skip: turn on Two-Factor Authentication (MFA) for WHM under Home › Security Center › Two-Factor Authentication. Even if someone steals the password and is on an allowed IP, they still can’t get in without the code from your phone.

Plain takeaway: open the doors people need, lock the rest, add MFA on the admin door.

Step 9 — Make webmail fast and reliable

Security that makes email painfully slow won’t last. In Dovecot I disable IPv6 if unused, set spare auth processes to 10 / max to 100, tune LMTP concurrency and cache, and use balanced compression. I also raise PHP limits (execution 300s, memory 512 MB, upload/POST 100 MB), and on an email-only box I stop the cPanel PHP-FPM service for a lighter Roundcube.

Plain takeaway: a hardened server should still feel fast.

Step 10 — The gotcha that bites everyone: port 25

Remember the 8,000 emails my client lost? This is the kind of thing that causes it. Mail “just hangs” — no error, no bounce — and the server looks spotless. The datacenter’s network can quietly drop inbound connections on port 25 before they reach your server, so messages are discarded at the SMTP level and nobody is told. Ask your datacenter/NOC to whitelist inbound SMTP (port 25) for your server’s IP. Before you call, confirm what you’re seeing:

grep -i "data timeout" /var/log/exim_mainlog | tail -10

Lines like “SMTP data timeout (message abandoned)” mean mail reached you but got cut off mid-transfer — a network-path problem, not the mailbox.

Plain takeaway: sometimes the mail server is perfect and the network is the villain.

Step 11 — Prove it works, then keep it current

Force a full update so every component is patched:

/usr/local/cpanel/scripts/upcp --force

Then confirm the auto-update cron is scheduled:

grep -R "upcp" /etc/cron* /var/spool/cron* 2>/dev/null

Plain takeaway: hardening is not a one-time event.

The bottom line

None of these steps is hard on its own. The value is in doing all of them, every time, in the same order — so no server ever ships with the factory defaults still on.

📋 A printable PDF version of this entire checklist is available here.

Originally published at quabin.com.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.