Exim Overview

Most mail messages are delivered immediate, this is way most MTAs are very simple, there is no need for elaborate queuing mechanisms through which all messages pass. Exim basically tries to delivery a message as soon as it arrives, but on occations a message will fail to be delivered, in such events messages wait on Exims queue and are delivered later.

All this is performed by a single binary, which operators in different ways depending on the arguments with which it was called. Sendmail can be replaced by Exim by creating a symbolic link from /usr/lib/sendmail or /usr/sbin/sendmail to the Exim binary.

Exim's Queue

In Exim there is just one single queue which is an unordered collection of messages waiting to be delivered much like a "pool", you can use the exim binary to list the messages, Messages that are not delivered first time are picked up later by the queue runner processes that scan the entire queue and start a delivery process for each message in turn.

Display the Message Queue # exim -bp

Receiving and Delivering Messages

Message reception and message delivery are two seperate operations in Exim, Receiving a message consists or writing it to local spool files ("putting on the queue") and checking that the files have been successfully written before acknowledging receipt to the sending host or local process.There is only one copy of the message however many recipients there are which is spooled to the only one single queue.

Exim does alias, forwarding and mailing list expansion for local addresses and domain lookup for remote addresses every time it handles a message. It does not retain previous alias, forwarding and mail list expansion from one delivery to the next. However there is a one_time option for mailing lists, the lists addresses are added to the original list of recipients at the first delivery attempt, and no re-expansion occurs at subsequent attempts.

Exim Processes

Exim requires process to perform two actions

In a normal configuration a single daemon process runs which deals with the above actions, however you can also configure Exim to run from inetd which will listen on port 25 and use then cron to start the queue runner processes, but it is better just to run the Exim damon which can limit load on your system.

How is Exim Configured

Configuration information supplied by the administrator, is used at two different times, one configuration files is used when building the Exim binary and another is read when whenever the binary is run.

Exim is controlled by a single text file, often called something like /usr/exim/configure or /etc/exim.conf, you can use the Exim binary to tell you where it is

Display Exims controlfile # exim -bP configure_file

Whenever Exim is started it reads it configuration which can contain many parameters, but normally only a few are configured. This file is loaded into memory where Exim will use it from, for this reason if you change the file you must get the Eximdaemon to reload it.

Read the configuration file # kill -HUP <exim process id>

How Exim Delivers Messages

There are many ways an address can be processed, DNS, local part in an alias file, there are sperate blocks of code in Exim for doing different kinds of processing and each is seperately and independently configurable. The word driver is used as the general term for one of these blocks of code, when you specify that a particular driver is to be used, you need only to give one or two parameters for it, some have many options whose values can be changed to vary the drivers behaviour.

There are three different kinds of driver

Routers The job of routers is to process addresses and delivering messages and decide what deliveries are to take place
Transports Transports are componenets of Exim that actually deliver messages by writing them to files or to pipes ot over SMTP connections
Authentication this driver handles SMTP authentication

For an example in a typical configuration a message that is addressed bug_reports@exim.example, where exim.example is a local domain would be handled

  1. The first router in the configuration is a dnslookup router that handles addresses that are not in a local domain by looking up MX records in DNS, as this a local domain this step is skipped
  2. The next router handles system aliases, this tells Exim to check /etc/aliases file, here it finds that the local part bug_reports is indeed an alias, and that it resolves to two other addresses, the local address debugger1@exim.example and a remote address debugger2@datadisk.co.uk. Exim adds these two new addressesto the list of recipients that it is routing, it is now finshed with the original address
  3. The two new address are taken in turn, for the first address debugger1@exim.example the first router is skipped because the domain is local. This time the second router does not find an alias so the address is passed on to the following routers. One of them is a router that recognizes local users and arranges for Exim to run a transport called appendfile, which adds a copy of the message to debugger1 mailbox. The acutal delivery does not take place until after Exim has worked how to handle all the addresses
  4. For the other recipient, because the domain datadisk.co.uk is not local, the first router is run, it looks up the domain in DNS and finds its IP address of the remote host to which the message should be sent. It then arranges for Exim to run the smtp transport to carry oyut the delivery.

Here is a list of the drivers

Driver Name
Driver Type
Description
accept
Router
A router that accepts any address that is passed to it, normally it is used as a "catchall" router
appendfile
Transport
A transport that writes messages to local files
autoreply
Transport
A transport that generates automatic replies to messages
dnslookup
Router
A router that looksup domains in the DNS and does MX processing
ipliteral
Router
A router that handles "IP literal" addresse such as paul.valle@192.168.0.1 (not used any more)
lmtp
Transport
A transport that delivers messages to external processes using LMTP (Local Mail Transfer Protocol), which is a variation of SMTP that is designed for passing messages between local processes
manualroute
Router
A router that routes domains using locally supplied information such as a list of domains and corresponding hosts
pipe
Transport
A transport that passes messages to external processes via pipes
queryprogram
Router
A router that runs an external program in order to route an address
redirect
Router
A router that handles several different kinds of redirection, including alias files, users .forward files, and Exim or Sieve filters. It can also explicity fource failure of an address
smtp
Transport
A transport that writes messages to other hosts over TCP/IP connections, using SMTP or LMTP

The configuration may refer to the same driver more than once, but with different options, thus allowing for multiple instances of the same driver type. Each driver instance is given an identifying name in the configuration file, for use in the logging and for reference from other drivers.

Processing an Address

When routing an address, Exim offers it to each configured router in turn, until one of them is able to deal with it, so the order of the routers are import in the configuration file. Conditions can be placed on the routers such as certains domains, restricting them to certains times of the day. A router that successfully handles an address may assign it to a transport. If a router cannot handle an address it declines it and passes it onto the next router for processing, if all routers decline the address then the delivery fails. An router can give five possible returns

accept Accept the address and pass it to a transport
decline Decline the address and pass it onto the next router
defer the router may be able to handle the address but cannot do so at the present time (DNS may not be working)
fail The roputer recognizes the address and knows that routing should fail, for example you could keep a list of ex-employees and make them fail with a special message.
pass The router recognizes the address, but cannot handle it itself. It requests that the address be passed to a lter router, overrriding a flase setting of more.

Complete example

Below is a simple Exim configuration file, in the file are 7 routers which all do different things, I have explained what each one does, but will go into more details at a later date and you find links to this information.

Config Example

notlocal:                            ## Name of the router instance
   driver = dnslookup                ## The kind router, DNS lookup in this case
   domains = !simple.example         ## Means the domain must not be simple.example (note the !)
   transport = remote_smtp           ## The transport that will handle accepted addresses
   no_more

system_aliases:
   driver = redirect                                     ## implement redirection
   data = ${lookup{$local_part}lsearch{/etc/aliases}}    ## search the /etc/aliases file to find aliases
                                                         ## see string expansion for more details

userforward:
   driver = redirect                  ## implement redirection
   check_local_user                   ## check the local_part corresponds to a login name on local host
   file $home/.forward                ## if a forwarding file exists add to the list adresses to be
                                      ## routed

localuser:
   driver = accept                    ## just accept the address if the below check_local_user suceeds
   check_local_user                   ## check the local_part corresponds to a login name on local host
   transport = local_delivery         ## use the local_delivery transport to deliver the message

notlocal:
   driver = dnslookup                 ## obtain remote hosts via DNS (using MX and address records)
   domain = ! simple.example          ## ignore the simple.example domain (because its local)
   transport = remote_smtp            ## use this router to deliver the message
   no_more                            ## if this fails don't run any more routers

local_delivery:
   driver = appendfile                ## add a copy of the message to the end of the mailbox file
   file = /var/mail/$local_part       ## the is the file we are appending
   delivery_date_add                  ## add a header that records the date and time of delivery
   envelope_to_add                    ## add a header that records the original recipient address
   return_path_add                    ## add a header that records the senders from the message envelope

remote_smtp:
  driver = smtp                       ## use SMTP to deliver the message

Complications

There are a number of common problems that can go wrong

Exim has a retry hints database to keep track of all failed messages, this is how it knows to resend messages.

Use of Transports by Routers

Some routers only change the delivery address which means that they do not require transport, but any router that sets up the message for delivery require a transport. A transport can use a pipe or append to a file, both of which use external files to specify what alias or file to use.