Panellicense

Route cPanel outbound mail via SES, SendGrid, or Mailgun

Configure a smart host in Exim so every outbound message from cPanel is relayed through SES, SendGrid, or Mailgun — with per-domain overrides and the gotchas that bite resellers.

8 min readUpdated 2026-05-17exim · smarthost · deliverability · ses
schema: HowToschema: FAQPage

Once a shared cPanel server has been listed on Spamhaus or UCEPROTECT enough times, removing the listings stops working — the IP's reputation is sunk and you are better off routing outbound mail through a service that owns clean address space. Amazon SES, SendGrid, and Mailgun all do this; the configuration on the cPanel side is the same shape for each.

This walks through adding a smart host to Exim via WHM's Advanced Editor, authenticating to the provider, restricting which domains use the relay, and the queue inspection that tells you whether mail is actually leaving the box the way you intended. If your problem is volume rather than reputation, start with the Exim outbound throttling guide — that fixes the cause and this article fixes the symptom.

When a smart host is the right answer

SituationSmart host?
Your /24 is on PBL or SBL and delistings keep coming backYes
Datacentre IP that AOL, Microsoft, and Yahoo silently dropYes
One compromised account is filling the queueNo — fix limits and scan outbound first
You want DKIM signing centralised across many domainsYes — providers sign on their own keys
You run a transactional product and need bounce webhooksYes
You need to keep From: matching your own DKIM key on hundreds of customer domainsMaybe — see the per-domain section below

A smart host doesn't fix abuse — it just moves whose abuse desk hears about it. Keep your per-account hourly cap and outbound SpamAssassin pass in place; SES will suspend your sending identity within hours if you start relaying spam through them, and that is a worse outage than a Spamhaus listing.

Pick the credentials before touching Exim

Each provider's smart host endpoint and SMTP credentials:

ProviderHostPortUsernamePassword
Amazon SESemail-smtp.<region>.amazonaws.com587SMTP-specific IAM access keySMTP-specific secret
SendGridsmtp.sendgrid.net587the literal string apikeyAPI key (SG.xxx…)
Mailgunsmtp.<region>.mailgun.org587SMTP login from the domain pageSMTP password

Generate these in the provider's console first. For SES, the IAM SMTP credentials are not your regular IAM access keys — use the Create SMTP Credentials button in the SES console, which derives a Sigv4 password from a fresh IAM user. Note the region; SES endpoints are regional and us-east-1 credentials will not authenticate against eu-west-1.

You also need at least one verified sending identity at the provider — either a domain (DKIM-verified via DNS, the right answer for a hosting fleet) or each individual From: address. Without that, the smart host will accept the SMTP session and then reject the MAIL FROM line, which surfaces in your queue as host email-smtp.… refused MAIL FROM.

Add the smart host in WHM

WHM → Service Configuration → Exim Configuration Manager → Advanced Editor. There are three sections to edit; everything else stays untouched.

1. Authenticator (AUTH section)

Add inside the Auths Configuration block, under the existing auth_relay_hosts section if there is one:

smarthost_login:
  driver = plaintext
  public_name = LOGIN
  hide client_send = : SMTP_USERNAME : SMTP_PASSWORD

The leading colon is intentional — it sends an empty AUTH ID and then username, password. hide keeps the credentials out of the exim debug log. Substitute the real values from the table above; for SendGrid the username is literally apikey.

2. Smart host router (PREROUTERS)

In Routers Configuration → PREROUTERS, add:

send_via_smarthost:
  driver = manualroute
  domains = ! +local_domains
  ignore_target_hosts = 127.0.0.0/8
  transport = smarthost_smtp
  route_list = * email-smtp.eu-west-1.amazonaws.com::587
  no_more

domains = ! +local_domains means "every domain except those hosted on this box" — local mail still routes locally, only outbound goes through the smart host. The no_more prevents Exim from falling back to direct MX delivery if the smart host fails, which is usually what you want (a queued retry through the smart host is safer than punching out to the wider internet).

3. Transport (POSTTRANSPORTS)

In Transports Configuration → POSTTRANSPORTS:

smarthost_smtp:
  driver = smtp
  hosts_require_auth = *
  hosts_require_tls = *
  port = 587
  helo_data = $primary_hostname

hosts_require_tls enforces STARTTLS — SES, SendGrid, and Mailgun all require it and will fail the session otherwise. helo_data sends your real hostname; some providers log it for abuse correlation.

Save. WHM validates the config and restarts Exim. If the parser complains, the most common cause is indentation — Exim configs are whitespace-sensitive and tabs vs spaces matter inside option blocks.

Verify the routing

Send a test from the command line as a real user, not root:

su - cpaneluser
echo "smart host test $(date)" | mail -s "smarthost test" you@external.example.com
exit
exim -bp

exim -bp should be empty within a second or two. If the message stayed in the queue, run it with debug enabled and watch what happens:

exim -d+all -M $(exim -bp | awk '{print $3; exit}')

The router section should show send_via_smarthost: domains matching, and the SMTP conversation should show EHLO, STARTTLS, then AUTH LOGIN — if it skips AUTH the provider will reject with 530 Authentication required.

The provider-side check is fastest: SES, SendGrid, and Mailgun all show the message in their dashboard within seconds of accepting it, with the cPanel server IP under "via".

Per-domain overrides

A reseller running customer domains often wants their own marketing domains on SES while leaving customer mail going out direct (because the customer's DKIM is signed on the local keypair and the smart host would break alignment).

Replace the router with two routers, ordered:

smarthost_my_domains:
  driver = manualroute
  domains = lsearch;/etc/exim/smarthost_domains
  transport = smarthost_smtp
  route_list = * email-smtp.eu-west-1.amazonaws.com::587
  no_more

send_via_smarthost:
  # leave disabled or remove entirely

Populate /etc/exim/smarthost_domains with one domain per line. Only those domains route through SES; everything else uses the normal cPanel outbound path. The DKIM keypair the provider expects must be the one in the provider's dashboard, not the cPanel-generated one in /var/cpanel/domain_keys.

What to check after a week

Three things, in order:

  1. Bounce rate at the provider. SES will throttle and then suspend the sending identity above 5%. Pull the suppression list weekly and feed addresses back to the cPanel accounts that generated them.
  2. /var/log/exim_mainlog for R=send_via_smarthost. Every outbound delivery should show that router. If you see R=lookuphost or R=dnslookup for non-local domains, the smart host router didn't match — usually a typo in domains =.
  3. Queue depth. exim -bpc should sit near zero. A growing queue with frozen messages means the provider is rejecting auth or your sending identity isn't verified.

For abuse follow-up, the Exim outbound throttling guide covers the per-account caps and outbound SpamAssassin scan that keep one compromised account from getting your provider account suspended.

Does using a smart host fix a Spamhaus listing?+
It bypasses it for new mail because outbound traffic now leaves from the provider's IPs, not yours. The listing on your IP remains — request delisting separately, and keep sending volume off that IP for at least 30 days so the listing ages out.
Can I route only outbound and keep inbound mail on the cPanel server?+
Yes — the smart host config above only affects outbound. Inbound MX records stay pointed at your server, and Exim still receives and stores mail locally.
What's the difference between using Amazon SES SMTP and the SES API?+
The SMTP interface is what Exim speaks natively, so it's a drop-in. The API gives you bounce and complaint webhooks, request signing, and slightly higher throughput, but you need an extra service to relay through it. For most cPanel hosts the SMTP path is enough.
Will my customers' DKIM signatures still validate after routing through a smart host?+
Only if the provider has the matching private key. Either move DKIM signing to the provider (publish their DNS record, disable local signing for that domain) or limit the smart host to your own domains via the per-domain override.
Why is mail still going out direct after I added the smart host?+
Check that the router is in PREROUTERS (so it runs before dnslookup) and that `domains = ! +local_domains` matches the outbound destination. Run `exim -d+all -M <id>` on a queued message to see which router fires.

Next steps

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.