7. The default configuration file
Author: The Exim Project. <https://www.exim.org/>
Description: Exim is a message transfer agent (MTA) developed at the University of Cambridge for use on Unix systems connected to the Internet.
Keywords: exim,smtp,mta,email

# Exim Internet Mailer

<-previous next->

## Chapter 7 - The default configuration file

The default configuration file supplied with Exim as src/configure.default is sufficient for a host with simple mail requirements. As an introduction to the way Exim is configured, this chapter “walks through” the default configuration, giving brief explanations of the settings. Detailed descriptions of the options are given in subsequent chapters. The default configuration file itself contains extensive comments about ways you might want to modify the initial settings. However, note that there are many options that are not mentioned at all in the default configuration.

### 1. Macros

All macros should be defined before any options.

One macro is specified, but commented out, in the default configuration:

    # ROUTER_SMARTHOST=MAIL.HOSTNAME.FOR.CENTRAL.SERVER.EXAMPLE

If all off-site mail is expected to be delivered to a "smarthost", then set the hostname here and uncomment the macro. This will affect which router is used later on. If this is left commented out, then Exim will perform direct-to-MX deliveries using a dnslookup router.

In addition to macros defined here, Exim includes a number of built-in macros to enable configuration to be guarded by a binary built with support for a given feature. See section 6.9 for more details.

### 2. Main configuration settings

The main (global) configuration option settings section must always come first in the file, after the macros. The first thing you’ll see in the file, after some initial comments, is the line

    # primary_hostname =

This is a commented-out setting of the primary_hostname option. Exim needs to know the official, fully qualified name of your host, and this is where you can specify it. However, in most cases you do not need to set this option. When it is unset, Exim uses the uname() system function to obtain the host name.

The first three non-comment configuration lines are as follows:

    domainlist local_domains    = @
    domainlist relay_to_domains =
    hostlist   relay_from_hosts = 127.0.0.1

These are not, in fact, option settings. They are definitions of two named domain lists and one named host list. Exim allows you to give names to lists of domains, hosts, and email addresses, in order to make it easier to manage the configuration file (see section 10.4).

The first line defines a domain list called local_domains; this is used later in the configuration to identify domains that are to be delivered on the local host.

There is just one item in this list, the string “@”. This is a special form of entry which means “the name of the local host”. Thus, if the local host is called a.host.example, mail to any.user@a.host.example is expected to be delivered locally. Because the local host’s name is referenced indirectly, the same configuration file can be used on different hosts.

The second line defines a domain list called relay_to_domains, but the list itself is empty. Later in the configuration we will come to the part that controls mail relaying through the local host; it allows relaying to any domains in this list. By default, therefore, no relaying on the basis of a mail domain is permitted.

The third line defines a host list called relay_from_hosts. This list is used later in the configuration to permit relaying from any host or IP address that matches the list. The default contains just the IP address of the IPv4 loopback interface, which means that processes on the local host are able to submit mail for relaying by sending it over TCP/IP to that interface. No other hosts are permitted to submit messages for relaying.

Just to be sure there’s no misunderstanding: at this point in the configuration we aren’t actually setting up any controls. We are just defining some domains and hosts that will be used in the controls that are specified later.

The next two configuration lines are genuine option settings:

    acl_smtp_rcpt = acl_check_rcpt
    acl_smtp_data = acl_check_data

These options specify Access Control Lists (ACLs) that are to be used during an incoming SMTP session for every recipient of a message (every RCPT command), and after the contents of the message have been received, respectively. The names of the lists are acl_check_rcpt and acl_check_data, and we will come to their definitions below, in the ACL section of the configuration. The RCPT ACL controls which recipients are accepted for an incoming message – if a configuration does not provide an ACL to check recipients, no SMTP mail can be accepted. The DATA ACL allows the contents of a message to be checked.

Two commented-out option settings are next:

    # av_scanner = clamd:/tmp/clamd
    # spamd_address = 127.0.0.1 783

These are example settings that can be used when Exim is compiled with the content-scanning extension. The first specifies the interface to the virus scanner, and the second specifies the interface to SpamAssassin. Further details are given in chapter 45.

Three more commented-out option settings follow:

    # tls_advertise_hosts = *
    # tls_certificate = /etc/ssl/exim.crt
    # tls_privatekey = /etc/ssl/exim.pem

These are example settings that can be used when Exim is compiled with support for TLS (aka SSL) as described in section 4.7. The first one specifies the list of clients that are allowed to use TLS when connecting to this server; in this case, the wildcard means all clients. The other options specify where Exim should find its TLS certificate and private key, which together prove the server’s identity to any clients that connect. More details are given in chapter 43.

Another two commented-out option settings follow:

    # daemon_smtp_ports = 25 : 465 : 587
    # tls_on_connect_ports = 465

These options provide better support for roaming users who wish to use this server for message submission. They are not much use unless you have turned on TLS (as described in the previous paragraph) and authentication (about which more in section 7.8). Mail submission from mail clients (MUAs) should be separate from inbound mail to your domain (MX delivery) for various good reasons (eg, ability to impose much saner TLS protocol and ciphersuite requirements without unintended consequences). RFC 6409 (previously 4409) specifies use of port 587 for SMTP Submission, which uses STARTTLS, so this is the “submission” port. RFC 8314 specifies use of port 465 as the “submissions” protocol, which should be used in preference to 587. You should also consider deploying SRV records to help clients find these ports. Older names for “submissions” are “smtps” and “ssmtp”.

Two more commented-out options settings follow:

    # qualify_domain =
    # qualify_recipient =

The first of these specifies a domain that Exim uses when it constructs a complete email address from a local login name. This is often needed when Exim receives a message from a local process. If you do not set qualify_domain, the value of primary_hostname is used. If you set both of these options, you can have different qualification domains for sender and recipient addresses. If you set only the first one, its value is used in both cases.

The following line must be uncommented if you want Exim to recognize addresses of the form user@[10.11.12.13] that is, with a “domain literal” (an IP address within square brackets) instead of a named domain.

    # allow_domain_literals

The RFCs still require this form, but many people think that in the modern Internet it makes little sense to permit mail to be sent to specific hosts by quoting their IP addresses. This ancient format has been used by people who try to abuse hosts by using them for unwanted relaying. However, some people believe there are circumstances (for example, messages addressed to postmaster) where domain literals are still useful.

The next configuration line is a kind of trigger guard:

    never_users = root

It specifies that no delivery must ever be run as the root user. The normal convention is to set up root as an alias for the system administrator. This setting is a guard against slips in the configuration. The list of users specified by never_users is not, however, the complete list; the build-time configuration in Local/Makefile has an option called FIXED_NEVER_USERS specifying a list that cannot be overridden. The contents of never_users are added to this list. By default FIXED_NEVER_USERS also specifies root.

When a remote host connects to Exim in order to send mail, the only information Exim has about the host’s identity is its IP address. The next configuration line,

    host_lookup = *

specifies that Exim should do a reverse DNS lookup on all incoming connections, in order to get a host name. This improves the quality of the logging information, but if you feel it is too expensive, you can remove it entirely, or restrict the lookup to hosts on “nearby” networks. Note that it is not always possible to find a host name from an IP address, because not all DNS reverse zones are maintained, and sometimes DNS servers are unreachable.

The next two lines are concerned with ident callbacks, as defined by RFC 1413 (hence their names):

    rfc1413_hosts = *
    rfc1413_query_timeout = 0s

These settings cause Exim to avoid ident callbacks for all incoming SMTP calls. Few hosts offer RFC1413 service these days; calls have to be terminated by a timeout and this needlessly delays the startup of an incoming SMTP connection. If you have hosts for which you trust RFC1413 and need this information, you can change this.

This line enables an efficiency SMTP option. It is negotiated by clients and not expected to cause problems but can be disabled if needed.

    prdr_enable = true

When Exim receives messages over SMTP connections, it expects all addresses to be fully qualified with a domain, as required by the SMTP definition. However, if you are running a server to which simple clients submit messages, you may find that they send unqualified addresses. The two commented-out options:

    # sender_unqualified_hosts =
    # recipient_unqualified_hosts =

show how you can specify hosts that are permitted to send unqualified sender and recipient addresses, respectively.

The log_selector option is used to increase the detail of logging over the default:

    log_selector = +smtp_protocol_error +smtp_syntax_error \
                   +tls_certificate_verified

The percent_hack_domains option is also commented out:

    # percent_hack_domains =

It provides a list of domains for which the “percent hack” is to operate. This is an almost obsolete form of explicit email routing. If you do not know anything about it, you can safely ignore this topic.

The next two settings in the main part of the default configuration are concerned with messages that have been “frozen” on Exim’s queue. When a message is frozen, Exim no longer continues to try to deliver it. Freezing occurs when a bounce message encounters a permanent failure because the sender address of the original message that caused the bounce is invalid, so the bounce cannot be delivered. This is probably the most common case, but there are also other conditions that cause freezing, and frozen messages are not always bounce messages.

    ignore_bounce_errors_after = 2d
    timeout_frozen_after = 7d

The first of these options specifies that failing bounce messages are to be discarded after 2 days in the queue. The second specifies that any frozen message (whether a bounce message or not) is to be timed out (and discarded) after a week. In this configuration, the first setting ensures that no failing bounce message ever lasts a week.

Exim queues it’s messages in a spool directory. If you expect to have large queues, you may consider using this option. It splits the spool directory into subdirectories to avoid file system degradation from many files in a single directory, resulting in better performance. Manual manipulation of queued messages becomes more complex (though fortunately not often needed).

    # split_spool_directory = true

In an ideal world everybody follows the standards. For non-ASCII messages RFC 2047 is a standard, allowing a maximum line length of 76 characters. Exim adheres that standard and won’t process messages which violate this standard. (Even ${rfc2047:...} expansions will fail.) In particular, the Exim maintainers have had multiple reports of problems from Russian administrators of issues until they disable this check, because of some popular, yet buggy, mail composition software.

    # check_rfc2047_length = false

If you need to be strictly RFC compliant you may wish to disable the 8BITMIME advertisement. Use this, if you exchange mails with systems that are not 8-bit clean.

    # accept_8bitmime = false

Libraries you use may depend on specific environment settings. This imposes a security risk (e.g. PATH). There are two lists: keep_environment for the variables to import as they are, and add_environment for variables we want to set to a fixed value. Note that TZ is handled separately, by the timezone runtime option and by the TIMEZONE_DEFAULT buildtime option.

    # keep_environment = ^LDAP
    # add_environment = PATH=/usr/bin::/bin

### 3. ACL configuration

In the default configuration, the ACL section follows the main configuration. It starts with the line

    begin acl

and it contains the definitions of two ACLs, called acl_check_rcpt and acl_check_data, that were referenced in the settings of acl_smtp_rcpt and acl_smtp_data above.

The first ACL is used for every RCPT command in an incoming SMTP message. Each RCPT command specifies one of the message’s recipients. The ACL statements are considered in order, until the recipient address is either accepted or rejected. The RCPT command is then accepted or rejected, according to the result of the ACL processing.

    acl_check_rcpt:

This line, consisting of a name terminated by a colon, marks the start of the ACL, and names it.

    accept  hosts = :

This ACL statement accepts the recipient if the sending host matches the list. But what does that strange list mean? It doesn’t actually contain any host names or IP addresses. The presence of the colon puts an empty item in the list; Exim matches this only if the incoming message did not come from a remote host, because in that case, the remote hostname is empty. The colon is important. Without it, the list itself is empty, and can never match anything.

What this statement is doing is to accept unconditionally all recipients in messages that are submitted by SMTP from local processes using the standard input and output (that is, not using TCP/IP). A number of MUAs operate in this manner.

    deny    domains       = +local_domains
            local_parts   = ^[.] : ^.*[@%!/|]
            message       = Restricted characters in address

    deny    domains       = !+local_domains
            local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
            message       = Restricted characters in address

These statements are concerned with local parts that contain any of the characters “@”, “%”, “!”, “/”, “|”, or dots in unusual places. Although these characters are entirely legal in local parts (in the case of “@” and leading dots, only if correctly quoted), they do not commonly occur in Internet mail addresses.

The first three have in the past been associated with explicitly routed addresses (percent is still sometimes used – see the percent_hack_domains option). Addresses containing these characters are regularly tried by spammers in an attempt to bypass relaying restrictions, and also by open relay testing programs. Unless you really need them it is safest to reject these characters at this early stage. This configuration is heavy-handed in rejecting these characters for all messages it accepts from remote hosts. This is a deliberate policy of being as safe as possible.

The first rule above is stricter, and is applied to messages that are addressed to one of the local domains handled by this host. This is implemented by the first condition, which restricts it to domains that are listed in the local_domains domain list. The “+” character is used to indicate a reference to a named list. In this configuration, there is just one domain in local_domains, but in general there may be many.

The second condition on the first statement uses two regular expressions to block local parts that begin with a dot or contain “@”, “%”, “!”, “/”, or “|”. If you have local accounts that include these characters, you will have to modify this rule.

Empty components (two dots in a row) are not valid in RFC 2822, but Exim allows them because they have been encountered in practice. (Consider the common convention of local parts constructed as “first-initial.second-initial.family-name” when applied to someone like the author of Exim, who has no second initial.) However, a local part starting with a dot or containing “/../” can cause trouble if it is used as part of a filename (for example, for a mailing list). This is also true for local parts that contain slashes. A pipe symbol can also be troublesome if the local part is incorporated unthinkingly into a shell command line.

The second rule above applies to all other domains, and is less strict. This allows your own users to send outgoing messages to sites that use slashes and vertical bars in their local parts. It blocks local parts that begin with a dot, slash, or vertical bar, but allows these characters within the local part. However, the sequence “/../” is barred. The use of “@”, “%”, and “!” is blocked, as before. The motivation here is to prevent your users (or your users’ viruses) from mounting certain kinds of attack on remote sites.

    accept  local_parts   = postmaster
            domains       = +local_domains

This statement, which has two conditions, accepts an incoming address if the local part is postmaster and the domain is one of those listed in the local_domains domain list. The “+” character is used to indicate a reference to a named list. In this configuration, there is just one domain in local_domains, but in general there may be many.

The presence of this statement means that mail to postmaster is never blocked by any of the subsequent tests. This can be helpful while sorting out problems in cases where the subsequent tests are incorrectly denying access.

    require verify        = sender

This statement requires the sender address to be verified before any subsequent ACL statement can be used. If verification fails, the incoming recipient address is refused. Verification consists of trying to route the address, to see if a bounce message could be delivered to it. In the case of remote addresses, basic verification checks only the domain, but callouts can be used for more verification if required. Section 44.21 discusses the details of address verification.

    accept  hosts         = +relay_from_hosts
            control       = submission

This statement accepts the address if the message is coming from one of the hosts that are defined as being allowed to relay through this host. Recipient verification is omitted here, because in many cases the clients are dumb MUAs that do not cope well with SMTP error responses. For the same reason, the second line specifies “submission mode” for messages that are accepted. This is described in detail in section 48.1; it causes Exim to fix messages that are deficient in some way, for example, because they lack a Date: header line. If you are actually relaying out from MTAs, you should probably add recipient verification here, and disable submission mode.

    accept  authenticated = *
            control       = submission

This statement accepts the address if the client host has authenticated itself. Submission mode is again specified, on the grounds that such messages are most likely to come from MUAs. The default configuration does not define any authenticators, though it does include some nearly complete commented-out examples described in 7.8. This means that no client can in fact authenticate until you complete the authenticator definitions.

    require message = relay not permitted
            domains = +local_domains : +relay_to_domains

This statement rejects the address if its domain is neither a local domain nor one of the domains for which this host is a relay.

    require verify = recipient

This statement requires the recipient address to be verified; if verification fails, the address is rejected.

    # deny    dnslists    = black.list.example
    #         message     = rejected because $sender_host_address \
    #                       is in a black list at $dnslist_domain\n\
    #                       $dnslist_text
    #
    # warn    dnslists    = black.list.example
    #         add_header  = X-Warning: $sender_host_address is in \
    #                       a black list at $dnslist_domain
    #         log_message = found in $dnslist_domain

These commented-out lines are examples of how you could configure Exim to check sending hosts against a DNS black list. The first statement rejects messages from blacklisted hosts, whereas the second just inserts a warning header line.

    # require verify = csa

This commented-out line is an example of how you could turn on client SMTP authorization (CSA) checking. Such checks do DNS lookups for special SRV records.

    accept

The final statement in the first ACL unconditionally accepts any recipient address that has successfully passed all the previous tests.

    acl_check_data:

This line marks the start of the second ACL, and names it. Most of the contents of this ACL are commented out:

    # deny    malware   = *
    #         message   = This message contains a virus \
    #                     ($malware_name).

These lines are examples of how to arrange for messages to be scanned for viruses when Exim has been compiled with the content-scanning extension, and a suitable virus scanner is installed. If the message is found to contain a virus, it is rejected with the given custom error message.

    # warn    spam      = nobody
    #         message   = X-Spam_score: $spam_score\n\
    #                     X-Spam_score_int: $spam_score_int\n\
    #                     X-Spam_bar: $spam_bar\n\
    #                     X-Spam_report: $spam_report

These lines are an example of how to arrange for messages to be scanned by SpamAssassin when Exim has been compiled with the content-scanning extension, and SpamAssassin has been installed. The SpamAssassin check is run with `nobody` as its user parameter, and the results are added to the message as a series of extra header line. In this case, the message is not rejected, whatever the spam score.

    accept

This final line in the DATA ACL accepts the message unconditionally.

### 4. Router configuration

The router configuration comes next in the default configuration, introduced by the line

    begin routers

Routers are the modules in Exim that make decisions about where to send messages. An address is passed to each router, in turn, until it is either accepted, or failed. This means that the order in which you define the routers matters. Each router is fully described in its own chapter later in this manual. Here we give only brief overviews.

    # domain_literal:
    #   driver = ipliteral
    #   domains = !+local_domains
    #   transport = remote_smtp

This router is commented out because the majority of sites do not want to support domain literal addresses (those of the form user@[10.9.8.7]). If you uncomment this router, you also need to uncomment the setting of allow_domain_literals in the main part of the configuration.

Which router is used next depends upon whether or not the ROUTER_SMARTHOST macro has been defined, per

    .ifdef ROUTER_SMARTHOST
    smarthost:
    #...
    .else
    dnslookup:
    #...
    .endif

If ROUTER_SMARTHOST has been defined, either at the top of the file or on the command-line, then we route all non-local mail to that smarthost; otherwise, we’ll perform DNS lookups for direct-to-MX lookup. Any mail which is to a local domain will skip these routers because of the domains option.

    smarthost:
      driver = manualroute
      domains = ! +local_domains
      transport = smarthost_smtp
      route_data = ROUTER_SMARTHOST
      ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1
      no_more

This router only handles mail which is not to any local domains; this is specified by the line

    domains = ! +local_domains

The domains option lists the domains to which this router applies, but the exclamation mark is a negation sign, so the router is used only for domains that are not in the domain list called local_domains (which was defined at the start of the configuration). The plus sign before local_domains indicates that it is referring to a named list. Addresses in other domains are passed on to the following routers.

The name of the router driver is manualroute because we are manually specifying how mail should be routed onwards, instead of using DNS MX. While the name of this router instance is arbitrary, the driver option must be one of the driver modules that is in the Exim binary.

With no pre-conditions other than domains, all mail for non-local domains will be handled by this router, and the no_more setting will ensure that no other routers will be used for messages matching the pre-conditions. See 3.12 for more on how the pre-conditions apply. For messages which are handled by this router, we provide a hostname to deliver to in route_data and the macro supplies the value; the address is then queued for the smarthost_smtp transport.

    dnslookup:
      driver = dnslookup
      domains = ! +local_domains
      transport = remote_smtp
      ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
      no_more

The domains option behaves as per smarthost, above.

The name of the router driver is dnslookup, and is specified by the driver option. Do not be confused by the fact that the name of this router instance is the same as the name of the driver. The instance name is arbitrary, but the name set in the driver option must be one of the driver modules that is in the Exim binary.

The dnslookup router routes addresses by looking up their domains in the DNS in order to obtain a list of hosts to which the address is routed. If the router succeeds, the address is queued for the remote_smtp transport, as specified by the transport option. If the router does not find the domain in the DNS, no further routers are tried because of the no_more setting, so the address fails and is bounced.

The ignore_target_hosts option specifies a list of IP addresses that are to be entirely ignored. This option is present because a number of cases have been encountered where MX records in the DNS point to host names whose IP addresses are 0.0.0.0 or are in the 127 subnet (typically 127.0.0.1). Completely ignoring these IP addresses causes Exim to fail to route the email address, so it bounces. Otherwise, Exim would log a routing problem, and continue to try to deliver the message periodically until the address timed out.

    system_aliases:
      driver = redirect
      allow_fail
      allow_defer
      data = ${lookup{$local_part}lsearch{/etc/aliases}}
    # user = exim
      file_transport = address_file
      pipe_transport = address_pipe

Control reaches this and subsequent routers only for addresses in the local domains. This router checks to see whether the local part is defined as an alias in the /etc/aliases file, and if so, redirects it according to the data that it looks up from that file. If no data is found for the local part, the value of the data option is empty, causing the address to be passed to the next router.

/etc/aliases is a conventional name for the system aliases file that is often used. That is why it is referenced by from the default configuration file. However, you can change this by setting SYSTEM_ALIASES_FILE in Local/Makefile before building Exim.

    userforward:
      driver = redirect
      check_local_user
    # local_part_suffix = +* : -*
    # local_part_suffix_optional
      file = $home/.forward
    # allow_filter
      no_verify
      no_expn
      check_ancestor
      file_transport = address_file
      pipe_transport = address_pipe
      reply_transport = address_reply

This is the most complicated router in the default configuration. It is another redirection router, but this time it is looking for forwarding data set up by individual users. The check_local_user setting specifies a check that the local part of the address is the login name of a local user. If it is not, the router is skipped. The two commented options that follow check_local_user, namely:

    # local_part_suffix = +* : -*
    # local_part_suffix_optional

show how you can specify the recognition of local part suffixes. If the first is uncommented, a suffix beginning with either a plus or a minus sign, followed by any sequence of characters, is removed from the local part and placed in the variable $local_part_suffix. The second suffix option specifies that the presence of a suffix in the local part is optional. When a suffix is present, the check for a local login uses the local part with the suffix removed.

When a local user account is found, the file called .forward in the user’s home directory is consulted. If it does not exist, or is empty, the router declines. Otherwise, the contents of .forward are interpreted as redirection data (see chapter 22 for more details).

Traditional .forward files contain just a list of addresses, pipes, or files. Exim supports this by default. However, if allow_filter is set (it is commented out by default), the contents of the file are interpreted as a set of Exim or Sieve filtering instructions, provided the file begins with “#Exim filter” or “#Sieve filter”, respectively. User filtering is discussed in the separate document entitled Exim’s interfaces to mail filtering.

The no_verify and no_expn options mean that this router is skipped when verifying addresses, or when running as a consequence of an SMTP EXPN command. There are two reasons for doing this:

1. Whether or not a local user has a .forward file is not really relevant when checking an address for validity; it makes sense not to waste resources doing unnecessary work.

2. More importantly, when Exim is verifying addresses or handling an EXPN command during an SMTP session, it is running as the Exim user, not as root. The group is the Exim group, and no additional groups are set up. It may therefore not be possible for Exim to read users’ .forward files at this time.

The setting of check_ancestor prevents the router from generating a new address that is the same as any previous address that was redirected. (This works round a problem concerning a bad interaction between aliasing and forwarding – see section 22.5).

The final three option settings specify the transports that are to be used when forwarding generates a direct delivery to a file, or to a pipe, or sets up an auto-reply, respectively. For example, if a .forward file contains

    a.nother@elsewhere.example, /home/spqr/archive

the delivery to /home/spqr/archive is done by running the address_file transport.

    localuser:
      driver = accept
      check_local_user
    # local_part_suffix = +* : -*
    # local_part_suffix_optional
      transport = local_delivery

The final router sets up delivery into local mailboxes, provided that the local part is the name of a local login, by accepting the address and assigning it to the local_delivery transport. Otherwise, we have reached the end of the routers, so the address is bounced. The commented suffix settings fulfil the same purpose as they do for the userforward router.

### 5. Transport configuration

Transports define mechanisms for actually delivering messages. They operate only when referenced from routers, so the order in which they are defined does not matter. The transports section of the configuration starts with

    begin transports

Two remote transports and four local transports are defined.

    remote_smtp:
      driver = smtp
      message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
    .ifdef _HAVE_PRDR
      hosts_try_prdr = *
    .endif

This transport is used for delivering messages over SMTP connections. The list of remote hosts comes from the router. The message_size_limit usage is a hack to avoid sending on messages with over-long lines.

The hosts_try_prdr option enables an efficiency SMTP option. It is negotiated between client and server and not expected to cause problems but can be disabled if needed. The built-in macro _HAVE_PRDR guards the use of the hosts_try_prdr configuration option.

The other remote transport is used when delivering to a specific smarthost with whom there must be some kind of existing relationship, instead of the usual federated system.

    smarthost_smtp:
      driver = smtp
      message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
      multi_domain
      #
    .ifdef _HAVE_TLS
      # Comment out any of these which you have to, then file a Support
      # request with your smarthost provider to get things fixed:
      hosts_require_tls = *
      tls_verify_hosts = *
      # As long as tls_verify_hosts is enabled, this this will have no effect,
      # but if you have to comment it out then this will at least log whether
      # you succeed or not:
      tls_try_verify_hosts = *
      #
      # The SNI name should match the name which we'll expect to verify;
      # many mail systems don't use SNI and this doesn't matter, but if it does,
      # we need to send a name which the remote site will recognize.
      # This _should_ be the name which the smarthost operators specified as
      # the hostname for sending your mail to.
      tls_sni = ROUTER_SMARTHOST
      #
    .ifdef _HAVE_OPENSSL
      tls_require_ciphers = HIGH:!aNULL:@STRENGTH
    .endif
    .ifdef _HAVE_GNUTLS
      tls_require_ciphers = SECURE192:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1
    .endif
    .endif
    .ifdef _HAVE_PRDR
      hosts_try_prdr = *
    .endif

After the same message_size_limit hack, we then specify that this Transport can handle messages to multiple domains in one run. The assumption here is that you’re routing all non-local mail to the same place and that place is happy to take all messages from you as quickly as possible. All other options depend upon built-in macros; if Exim was built without TLS support then no other options are defined. If TLS is available, then we configure "stronger than default" TLS ciphersuites and versions using the tls_require_ciphers option, where the value to be used depends upon the library providing TLS. Beyond that, the options adopt the stance that you should have TLS support available from your smarthost on today’s Internet, so we turn on requiring TLS for the mail to be delivered, and requiring that the certificate be valid, and match the expected hostname. The tls_sni option can be used by service providers to select an appropriate certificate to present to you and here we re-use the ROUTER_SMARTHOST macro, because that is unaffected by CNAMEs present in DNS. You want to specify the hostname which you’ll expect to validate for, and that should not be subject to insecure tampering via DNS results.

For the hosts_try_prdr option see the previous transport.

All other options are defaulted.

    local_delivery:
      driver = appendfile
      file = /var/mail/$local_part_data
      delivery_date_add
      envelope_to_add
      return_path_add
    # group = mail
    # mode = 0660

This appendfile transport is used for local delivery to user mailboxes in traditional BSD mailbox format.

We prefer to avoid using $local_part directly to define the mailbox filename, as it is provided by a potential bad actor. Instead we use $local_part_data, the result of looking up $local_part in the user database (done by using check_local_user in the the router).

By default appendfile runs under the uid and gid of the local user, which requires the sticky bit to be set on the /var/mail directory. Some systems use the alternative approach of running mail deliveries under a particular group instead of using the sticky bit. The commented options show how this can be done.

Exim adds three headers to the message as it delivers it: Delivery-date:, Envelope-to: and Return-path:. This action is requested by the three similarly-named options above.

    address_pipe:
      driver = pipe
      return_output

This transport is used for handling deliveries to pipes that are generated by redirection (aliasing or users’ .forward files). The return_output option specifies that any output on stdout or stderr generated by the pipe is to be returned to the sender.

    address_file:
      driver = appendfile
      delivery_date_add
      envelope_to_add
      return_path_add

This transport is used for handling deliveries to files that are generated by redirection. The name of the file is not specified in this instance of appendfile, because it comes from the redirect router.

    address_reply:
      driver = autoreply

This transport is used for handling automatic replies generated by users’ filter files.

### 6. Default retry rule

The retry section of the configuration file contains rules which affect the way Exim retries deliveries that cannot be completed at the first attempt. It is introduced by the line

    begin retry

In the default configuration, there is just one rule, which applies to all errors:

    *   *   F,2h,15m; G,16h,1h,1.5; F,4d,6h

This causes any temporarily failing address to be retried every 15 minutes for 2 hours, then at intervals starting at one hour and increasing by a factor of 1.5 until 16 hours have passed, then every 6 hours up to 4 days. If an address is not delivered after 4 days of temporary failure, it is bounced. The time is measured from first failure, not from the time the message was received.

If the retry section is removed from the configuration, or is empty (that is, if no retry rules are defined), Exim will not retry deliveries. This turns temporary errors into permanent errors.

### 7. Rewriting configuration

The rewriting section of the configuration, introduced by

    begin rewrite

contains rules for rewriting addresses in messages as they arrive. There are no rewriting rules in the default configuration file.

### 8. Authenticators configuration

The authenticators section of the configuration, introduced by

    begin authenticators

defines mechanisms for the use of the SMTP AUTH command. The default configuration file contains two commented-out example authenticators which support plaintext username/password authentication using the standard PLAIN mechanism and the traditional but non-standard LOGIN mechanism, with Exim acting as the server. PLAIN and LOGIN are enough to support most MUA software.

The example PLAIN authenticator looks like this:

    #PLAIN:
    #  driver                  = plaintext
    #  server_set_id           = $auth2
    #  server_prompts          = :
    #  server_condition        = Authentication is not yet configured
    #  server_advertise_condition = ${if def:tls_in_cipher }

And the example LOGIN authenticator looks like this:

    #LOGIN:
    #  driver                  = plaintext
    #  server_set_id           = $auth1
    #  server_prompts          = <| Username: | Password:
    #  server_condition        = Authentication is not yet configured
    #  server_advertise_condition = ${if def:tls_in_cipher }

The server_set_id option makes Exim remember the authenticated username in $authenticated_id, which can be used later in ACLs or routers. The server_prompts option configures the plaintext authenticator so that it implements the details of the specific authentication mechanism, i.e. PLAIN or LOGIN. The server_advertise_condition setting controls when Exim offers authentication to clients; in the examples, this is only when TLS or SSL has been started, so to enable the authenticators you also need to add support for TLS as described in section 7.2.

The server_condition setting defines how to verify that the username and password are correct. In the examples it just produces an error message. To make the authenticators work, you can use a string expansion expression like one of the examples in chapter 34.

Beware that the sequence of the parameters to PLAIN and LOGIN differ; the usercode and password are in different positions. Chapter 34 covers both.

<-previous Table of Contents next->