If you’re like most businesses, you rely on email to keep your communication flowing. But with the ever-growing number of spam emails, it’s important to take steps to protect yourself and your email system. In this article, we’ll show you how to route incoming email with Exim, a powerful mail server software. When it comes to spam prevention, there are a few things you can do. First and foremost, make sure that your email address is properly registered with the major providers (Gmail, Yahoo!, etc.). Also make sure that your domain is whitelisted by your provider (this will stop most automated spam submissions from reaching your inbox). But even if all of those measures fail, there are still ways to protect yourself from spam. One way is to use filters on your email client (like Outlook or Thunderbird) to block certain senders or messages. Another is to use an anti-spam service like Spamhaus or Mailguard. And finally, you can use a mail server like Exim to route all of your incoming email through a secure server. By using these various methods and tools, you can help protect yourself from the growing number of spam emails in today’s world. ..


We’ll assume you’ve already got a functioning Exim server that’s able to receive email. The official wiki provides informative guidance if you’re starting from scratch with a fresh installation.

Managing Exim Configuration

Available configuration approaches vary by operating system distribution. An Exim installation built from source will use src/configure.default as its config file.

The file for Exim installed from a package manager is typically /etc/exim/config or /etc/exim.conf. You can find the path that’s currently used by running exim -bP configure_file.

Debian-based operating systems have a slightly more complicated system. There are two possible configuration methods: a single file, /etc/exim4/exim4.conf.template, or split config files within /etc/exim4/conf.d. You need to run update-exim4.conf after you make changes. This creates a single merged file that’s actually read by Exim.

Exim should be restarted each time you change its configuration. Run service exim4 restart to apply your changes.

Creating a Router

The first step in getting email to your application is defining a custom router. Routers match incoming emails against a set of conditions to determine the delivery mechanism to use.

Routers are processed in the sequential order they’re found in the configuration file. Any routers above yours in the file could match incoming emails first.

Add your router to your configuration file within the ROUTERS CONFIGURATION section. If you’re using the split Debian configuration, you can create a new file in /etc/exim4/conf.d/routers instead. Routers will be combined in alphabetical order when you use this approach.

Here’s an example router:

This is a basic router which matches any email sent to example.com. When a match is processed, Exim will accept the message and deliver it using the example_transport transport. We’ll create this next.

Creating a Transport

Once an email has been accepted by a router, it’s delivered by a transport. Transports are responsible for implementing the message delivery routine. Different drivers can send over the internet using SMTP, transfer to a local Unix user, or write to a file.

Creating a custom transport based on a built-in driver lets you deliver matching emails to your own application. You can then deal with each email individually, outside of Exim.

Unlike routers the order of transports does not matter. Each incoming email will match to the single transport specified by the router that accepts it. Add your transport anywhere in the TRANSPORTS CONFIGURATION section of your Exim file. Debian users with split configuration enabled can create a file in /etc/exim4/conf.d/transports.

Here’s a transport that invokes a PHP script:

When combined with the example router from above, any email sent to @example.com will be delivered to handle_incoming_email.php. Exim supplies the entire email in RFC-compliant format as the command’s standard input for you to read in your programming language.

The transport is configured with the pipe driver. This uses a Unix pipe to supply the incoming email to your command. The command will be executed as the user and group you specify.

Using Environment Variables

Exim will set several environment variables before executing your command. These can be used to access information about the message without having to parse the full email format.

Available variables include:

DOMAIN – The domain the incoming email was sent to. MESSAGE_ID – Exim’s internal ID representing the email. RECIPIENT – The email address which the message was sent to. SENDER – The email address which the message originated from.

You can add additional variables to the command’s environment by setting the environment option in your transport. This accepts a comma-separated list of key-value pairs:

Return Values

Your command should exit with a 0 status code to confirm a successful delivery. A non-zero exit code will be interpreted as a failed delivery. The sender will receive a bounce message.

This behavior is disabled by setting the ignore_status option in your transport. Exim will then treat non-zero status codes as successful.

In addition, you can use the temp_errors option to define script exit codes which indicate an error was encountered but is expected to be temporary. When Exim sees one of these status codes, message delivery will be deferred and retried later on.

The content of bounce messages can be customized with the return_fail_output option. When this is set to true, Exim will include the contents of your script’s standard output in its bounce email. The mechanism facilitates use of your application code to deliver personalized bounce responses to senders.

Command Invocation

Exim usually invokes your command directly from the transport. If you set the use_shell option, it will pass the command to /bin/sh instead. This can be useful in scenarios where your script requires a full shell environment to be available.

Command execution times out after one hour with the default configuration. A timeout is treated as a delivery error. The command will be terminated and a bounce message returned to the sender. The timeout can be customized with the timeout setting. Additionally setting the timeout_defer option will cause timeouts to be treated as temporary errors, allowing another delivery attempt after a delay.

You should also consider that your script might be executed concurrently if multiple emails arrive at the same time. Your application should be able to withstand this possibility. Locking systems that allow only one instance to run simultaneously should be disabled for your email handling script.

Conclusion

Exim is easily configured to route incoming email to your own application. A simple setup that directs all received messages can be achieved with a basic router coupled to a transport using the pipe driver.

You need to provide a binary that accepts an email on standard input as part of your application. The binary will be invoked by Exim whenever a new message is received. You should then parse the email in a standards-compliant manner to pull out the body content and message headers relevant to your system.