10 November 2021

cPanel servers use Exim as the Mail Transfer agent. The main Exim log file is (appropriately) named exim_mainlog. The entries in the log are terse but contain a wealth of information. If you are unfamiliar with the log, my article about Exim log files and exigrep is a good introduction.

In this article I want to look at some commands you can use if you suspect an account on your server is sending spam. You don’t need to fully understand Exim’s logs, but having at least some knowledge does help if you want to tweak the example commands. Similarly, it is useful to know the basics of grep.

Finding compromised mailboxes

There are two common reasons for spam issues: either a mailbox has been compromised or there is a malicious script in a website directory. For compromised mailboxes you can produce a count of email addresses that have sent emails. Any mailboxes that have sent a large number of emails can then be investigated further. This command shows the top 10 email addresses that have sent emails today (10 November 2021):

# grep ^"2021-11-10.*dovecot_login:" /var/log/exim_mainlog \
| awk -F 'A=dovecot_login:' 'split($2, addr, / /) { print addr[1] }' \
| sort | uniq -c | sort -nr | head
   2570 mail@example.com
     83 foo@bar
     69 bar@foo
...

The above command first retrieves all lines that start with the string “2021-11-10” and also contain the string dovecot_login:. It then uses some Awk magic to filter out the email addresses that logged in. The third line produces the sorted count.

The above output shows that mail@example.com has been sending a rather large number of emails. To check the emails that were sent from the address you can use a command like this:

# grep ^"2021-11-10.*dovecot_login:mail@example.com" /var/log/exim_mainlog \
| awk -v OFS='\t' -F 'A=dovecot_login:|T="' 'split($1, ts, / /) split($2, addr, / /) \
{ print ts[2], addr[1], $NF }'
17:44:13   mail@example.com   Online pharmacy!!!
17:44:13   mail@example.com   Online pharmacy!!!
17:44:13   mail@example.com   Online pharmacy!!!
...

The first line retrieves all today’s logins for mail@example.com. The output is then passed to an Awk command that prints the time, email address and email subject. Usually, that gives you enough information to determine whether or not the emails are legitimate.

Finding compromised websites

Compromised websites are often used to relay spam. Emails sent via scripts are also logged in exim_mainlog. The entries always include the string cwd= followed by the path to the directory from which the email was sent. Unfortunately, the log doesn’t tell you which script sent an email – it only shows you the script’s directory.

This command lists all directories from which emails were sent today:

# grep ^"2021-11-10.*cwd=" /var/log/exim_mainlog \
| grep -vE "cwd=/var/spool/exim|cwd=/etc/csf" \
| awk -F 'cwd=' 'split($2, dir, / /) { print dir[1] }' \
| sort | uniq -c | sort -nr | head
    344 /home/example/public_html
    141 /home/foo/public_html
    116 /home/bar/public_html
...

The second grep command excludes directories you don’t need to check, such as /var/spool/exim and /etc/csf. Normally, you are mostly interested in mail sent from user directories.

The log entries don’t contain a lot of information. You can get a full list of relay attempts, including the times, but that is as good as it gets. In particular, the log doesn’t include the recipients and email subjects:

# grep cwd=/home/example/public_html /var/log/exim_mainlog
2021-11-09 11:14:15 cwd=/home/example/public_html 3 args: /usr/sbin/sendmail -t -i
2021-11-09 11:14:15 cwd=/home/example/public_html 3 args: /usr/sbin/sendmail -t -i
2021-11-09 11:14:15 cwd=/home/example/public_html 3 args: /usr/sbin/sendmail -t -i
...

If the entries look suspicious then you can next check the access log for the domain. Often, the culprit is a contact form that is being abused by a spambot.