I run a cPanel server. This server was recently compromised and spam was being sent, so I would like to keep track of every email that Exim sends.

Would it be possible to make Exim run a script before putting the email in the queue?

I want to make Exim send the "From: " header to a Python script. This script will keep track of how many emails that domain has sent in 1 hour, and either let the email be sent, or block the cPanel account.

I have tried doing this with transport_filter and system_filter, but I couldn't successfully do it.

How can I make Exim send outgoing email to a Python script for processing?


The easiest way is to craft some router that check the headers of the submitted message. If there is NO some special header there (like X-Spam-My-Approval) the message is routed to the transport with pipe attached to it. The script on the other side of pipe will do all the magic and add the secret header to the message, then submit it again. Now routers are pass it to the transport with SMTP driver.

begin routers
  driver    = accept
  transport = myscript
  domains   = !+local_domains
  condition = ${if ! eq{$header_X-Spam-My-Approval:}{YES}} # header is absent or not "YES"

  driver    = accept
  transport = relay
  domains   = !+local_domains
  condition = ${if eq{$header_X-Spam-My-Approval:}{YES}}

Appropriate transports should be like that:

begin transports
  driver  = pipe
  command = /path/to/script --option1 --option2

  driver  = smtp
  headers_remove = X-Spam-My-Approval
  . . . . . .

Keep in mind that exim should have enough privileges to run the script and script should have an appropriate EUID listed in the exim's trusted_users config line to be able to submit a message as arbitrary sender.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.