In short
When a mail account on your server starts sending spam, the Exim queue jumps and the IP lands on blocklists within hours. You stop it in four steps: identify the account or script in /var/log/exim_mainlog, change the password and suspend sending, remove the spam from the queue, and close the cause, which is almost always a password stolen by phishing or guessed by brute force.
Signs an account is compromised
- The mail queue goes from dozens to thousands of messages (
exim -bpc). - Hundreds of bounces ("Mail delivery failed") arrive at an account that normally sends little.
- Gmail or Outlook start rejecting or junking mail from the whole server.
- The server IP appears on Spamhaus, SpamCop or Barracuda.
- A customer reports that their contacts got odd emails "from them".
- The server blocks a domain for exceeding its hourly sending limit.
Step 1: identify who is sending
Outbound spam has two possible sources, and the Exim log shows which one it is:
| Source | How it shows in exim_mainlog | Typical cause |
|---|---|---|
| Mail account | A=dovecot_login:user@domain.com | Password stolen by phishing, guessed or leaked |
| Website script | cwd=/home/user/public_html/... with no authentication | Unprotected form, vulnerable plugin or malware on the site |
These commands show the day's top senders. Run them as root:
# Queue size
exim -bpc
# Queue summary by destination domain
exim -bp | exiqsumm | sort -rn | head -20
# Authenticated accounts that sent the most mail
grep "A=dovecot_login" /var/log/exim_mainlog | grep -o "A=dovecot_login:[^ ]*" | sort | uniq -c | sort -rn | head
# Directories scripts sent mail from
grep "cwd=/home" /var/log/exim_mainlog | grep -o "cwd=[^ ]*" | sort | uniq -c | sort -rn | headTo confirm, open one of the queued messages: exim -Mvh ID shows the headers and exim -Mvb ID the body. If Track email origin via X-Source is on in Tweak Settings, the X-Source and X-Source-Dir headers point to the exact script.
Without shell access, WHM › Email › View Relayers and View Sent Summary show the same information graphically.
Step 2: stop the sending
Work in this order. The goal is to cut off sending first and clean up afterwards:
- Change the account password in cPanel › Email › Email Accounts › Manage. That also ends any webmail sessions the attacker has open.
- Suspend outgoing mail for that account from the same screen, or from the shell with UAPI.
- If the source is a script, suspend outgoing mail for the whole cPanel account with the WHM API while you clean the site.
- Check forwarders and filters in cPanel › Email › Forwarders and Email Filters. Attackers often add rules that forward all mail to an outside address, or delete replies so the owner doesn't notice.
# Suspend outgoing mail for one mail account
uapi --user=CPUSER Email suspend_outgoing email=user@domain.com
# Suspend outgoing mail for a whole cPanel account
whmapi1 suspend_outgoing_email user=CPUSER
# Re-enable once it's fixed
uapi --user=CPUSER Email unsuspend_outgoing email=user@domain.com
whmapi1 unsuspend_outgoing_email user=CPUSERStep 3: clean the queue
Spam still in the queue keeps retrying delivery and keeps hurting your reputation. Remove it by sender:
# How many messages from that sender
exiqgrep -c -f user@domain.com
# Remove them
exiqgrep -i -f user@domain.com | xargs exim -Mrm
# Remove the frozen bounces a campaign usually leaves behind
exiqgrep -z -i | xargs exim -MrmCheck the list before you delete: exiqgrep -f user@domain.com without -i shows the messages. A sloppy filter can delete legitimate mail from other customers.
Step 4: find and close the cause
| Cause | How to confirm it | What to do |
|---|---|---|
| Password stolen by phishing | The user remembers "verifying their account" on some page | Change any passwords they reused and read credential phishing |
| Brute force or password spraying | Lots of "auth failed" in /var/log/maillog before the first send | Tune cPHulk and follow this guide |
| Password leaked from another site | The address shows up in public breaches | A unique password and a password manager |
| Malware on the user's computer | Authenticated sends from the user's office or home IP | Clean the computer before changing the password |
| Vulnerable script | Sends with cwd=/home/... and an X-PHP-Script header | Update or remove the plugin and scan the site with ImunifyAV or ClamAV |
Step 5: recover your reputation
With sending stopped, check whether the IP or domains ended up on blocklists, and request removal only after the cause is fixed. If you ask earlier, you get relisted, and some lists take longer to accept a second request. Step by step in how to get your server IP off a blocklist.
If the mailbox held personal data
An attacker with access to a mailbox could read and download everything in it. In the European Union, the GDPR requires notifying the supervisory authority within 72 hours when a breach poses a risk to people (in Spain, the AEPD; in Ireland, the DPC, and so on). In Chile, Law 21.719 requires reporting security breaches to the Personal Data Protection Agency once it is fully in force in December 2026. Write down what happened, when, and what you did: you will need it.
How to keep it from happening again
- Hourly sending and bounce limits in Tweak Settings, so the next incident cuts itself off.
- cPHulk and mandatory strong passwords, so guessing passwords isn't practical.
- Alerts: a cron job that warns you when
exim -bpcgoes over a set number. - Filter inbound phishing. Most compromised accounts start with an email that leads to a fake login page. Clisec inspects links and their destination pages before delivering mail and blocks that phishing across the whole server.
The full server review is in the cPanel email security guide.
Frequently asked questions
How do I find which account is sending spam on my cPanel server?
Search /var/log/exim_mainlog for lines with A=dovecot_login and count how often each user appears. If a script is the source, look for lines with cwd=/home. WHM › View Relayers shows the same without a shell.
Is changing the password enough?
Not always. Also check forwarders and filters the attacker may have created, clean the queue, and find out how they got the password. If you don't close the cause, it happens again.
How long does it take to get off a blocklist?
It depends on the list: SpamCop and some others expire on their own within hours or days once reports stop; Spamhaus usually accepts removal within a day or two if the problem is fixed.
Does Clisec block outbound spam?
No. Clisec filters inbound mail. It helps prevent compromised accounts by blocking the phishing that steals passwords, but sending is controlled with the Exim and WHM limits described in this guide.
Protect inbound email on your whole server
Most compromised accounts start with a phishing email. Clisec blocks it before it reaches the inbox, across your whole cPanel server.