6. The Exim runtime 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 6 - The Exim runtime configuration file

Exim uses a single runtime configuration file that is read whenever an Exim binary is executed. Note that in normal operation, this happens frequently, because Exim is designed to operate in a distributed manner, without central control.

If a syntax error is detected while reading the configuration file, Exim writes a message on the standard error, and exits with a non-zero return code. The message is also written to the panic log. Note: Only simple syntax errors can be detected at this time. The values of any expanded options are not checked until the expansion happens, even when the expansion does not actually alter the string.

The name of the configuration file is compiled into the binary for security reasons, and is specified by the CONFIGURE_FILE compilation option. In most configurations, this specifies a single file. However, it is permitted to give a colon-separated list of filenames, in which case Exim uses the first existing file in the list.

The runtime configuration file must be owned by root or by the user that is specified at compile time by the CONFIGURE_OWNER option (if set). The configuration file must not be world-writeable, or group-writeable unless its group is the root group or the one specified at compile time by the CONFIGURE_GROUP option.

Warning: In a conventional configuration, where the Exim binary is setuid to root, anybody who is able to edit the runtime configuration file has an easy way to run commands as root. If you specify a user or group in the CONFIGURE_OWNER or CONFIGURE_GROUP options, then that user and/or any users who are members of that group will trivially be able to obtain root privileges.

Up to Exim version 4.72, the runtime configuration file was also permitted to be writeable by the Exim user and/or group. That has been changed in Exim 4.73 since it offered a simple privilege escalation for any attacker who managed to compromise the Exim user account.

A default configuration file, which will work correctly in simple situations, is provided in the file src/configure.default. If CONFIGURE_FILE defines just one filename, the installation process copies the default configuration to a new file of that name if it did not previously exist. If CONFIGURE_FILE is a list, no default is automatically installed. Chapter 7 is a “walk-through” discussion of the default configuration.

### 1. Using a different configuration file

A one-off alternate configuration can be specified by the -C command line option, which may specify a single file or a list of files. However, when -C is used, Exim gives up its root privilege, unless called by root (or unless the argument for -C is identical to the built-in value from CONFIGURE_FILE), or is listed in the TRUSTED_CONFIG_LIST file and the caller is the Exim user or the user specified in the CONFIGURE_OWNER setting. -C is useful mainly for checking the syntax of configuration files before installing them. No owner or group checks are done on a configuration file specified by -C, if root privilege has been dropped.

Even the Exim user is not trusted to specify an arbitrary configuration file with the -C option to be used with root privileges, unless that file is listed in the TRUSTED_CONFIG_LIST file. This locks out the possibility of testing a configuration using -C right through message reception and delivery, even if the caller is root. The reception works, but by that time, Exim is running as the Exim user, so when it re-execs to regain privilege for the delivery, the use of -C causes privilege to be lost. However, root can test reception and delivery using two separate commands (one to put a message in the queue, using -odq, and another to do the delivery, using -M).

If ALT_CONFIG_PREFIX is defined in Local/Makefile, it specifies a prefix string with which any file named in a -C command line option must start. In addition, the filename must not contain the sequence “`/../`”. There is no default setting for ALT_CONFIG_PREFIX; when it is unset, any filename can be used with -C.

One-off changes to a configuration can be specified by the -D command line option, which defines and overrides values for macros used inside the configuration file. However, like -C, the use of this option by a non-privileged user causes Exim to discard its root privilege. If DISABLE_D_OPTION is defined in Local/Makefile, the use of -D is completely disabled, and its use causes an immediate error exit.

The WHITELIST_D_MACROS option in Local/Makefile permits the binary builder to declare certain macro names trusted, such that root privilege will not necessarily be discarded. WHITELIST_D_MACROS defines a colon-separated list of macros which are considered safe and, if -D only supplies macros from this list, and the values are acceptable, then Exim will not give up root privilege if the caller is root, the Exim run-time user, or the CONFIGURE_OWNER, if set. This is a transition mechanism and is expected to be removed in the future. Acceptable values for the macros satisfy the regexp: `^[A-Za-z0-9_/.-]*$`

Some sites may wish to use the same Exim binary on different machines that share a file system, but to use different configuration files on each machine. If CONFIGURE_FILE_USE_NODE is defined in Local/Makefile, Exim first looks for a file whose name is the configuration filename followed by a dot and the machine’s node name, as obtained from the uname() function. If this file does not exist, the standard name is tried. This processing occurs for each filename in the list given by CONFIGURE_FILE or -C.

In some esoteric situations different versions of Exim may be run under different effective uids and the CONFIGURE_FILE_USE_EUID is defined to help with this. See the comments in src/EDITME for details.

### 2. Configuration file format

Exim’s configuration file is divided into a number of different parts. General option settings must always appear at the start of the file. The other parts are all optional, and may appear in any order. Each part other than the first is introduced by the word “begin” followed by at least one literal space, and the name of the part. The optional parts are:

- ACL: Access control lists for controlling incoming SMTP mail (see chapter 44).

- authenticators: Configuration settings for the authenticator drivers. These are concerned with the SMTP AUTH command (see chapter 33).

- routers: Configuration settings for the router drivers. Routers process addresses and determine how the message is to be delivered (see chapters 15–22).

- transports: Configuration settings for the transport drivers. Transports define mechanisms for copying messages to destinations (see chapters 24–30).

- retry: Retry rules, for use when a message cannot be delivered immediately. If there is no retry section, or if it is empty (that is, no retry rules are defined), Exim will not retry deliveries. In this situation, temporary errors are treated the same as permanent errors. Retry rules are discussed in chapter 32.

- rewrite: Global address rewriting rules, for use when a message arrives and when new addresses are generated during delivery. Rewriting is discussed in chapter 31.

- local_scan: Private options for the local_scan() function. If you want to use this feature, you must set

      LOCAL_SCAN_HAS_OPTIONS=yes

  in Local/Makefile before building Exim. Details of the local_scan() facility are given in chapter 46.

Leading and trailing white space in configuration lines is always ignored.

Blank lines in the file, and lines starting with a # character (ignoring leading white space) are treated as comments and are ignored. Note: A # character other than at the beginning of a line is not treated specially, and does not introduce a comment.

Any non-comment line can be continued by ending it with a backslash. Note that the general rule for white space means that trailing white space after the backslash and leading white space at the start of continuation lines is ignored. Comment lines beginning with # (but not empty lines) may appear in the middle of a sequence of continuation lines.

A convenient way to create a configuration file is to start from the default, which is supplied in src/configure.default, and add, delete, or change settings as required.

The ACLs, retry rules, and rewriting rules have their own syntax which is described in chapters 44, 32, and 31, respectively. The other parts of the configuration file have some syntactic items in common, and these are described below, from section 6.11 onwards. Before that, the inclusion, macro, and conditional facilities are described.

### 3. File inclusions in the configuration file

You can include other files inside Exim’s runtime configuration file by using this syntax:

    .include <filename>
    .include_if_exists <filename>

on a line by itself. Double quotes round the filename are optional. If you use the first form, a configuration error occurs if the file does not exist; the second form does nothing for non-existent files. The first form allows a relative name. It is resolved relative to the directory of the including file. For the second form an absolute filename is required.

Includes may be nested to any depth, but remember that Exim reads its configuration file often, so it is a good idea to keep them to a minimum. If you change the contents of an included file, you must HUP the daemon, because an included file is read only when the configuration itself is read.

The processing of inclusions happens early, at a physical line level, so, like comment lines, an inclusion can be used in the middle of an option setting, for example:

    hosts_lookup = a.b.c \
                   .include /some/file

Include processing happens after macro processing (see below). Its effect is to process the lines of the included file as if they occurred inline where the inclusion appears.

### 4. Macros in the configuration file

If a line in the main part of the configuration (that is, before the first “begin” line) begins with an upper case letter, it is taken as a macro definition, and must be of the form

    <name> = <rest of line>

The name must consist of letters, digits, and underscores, and need not all be in upper case, though that is recommended. The rest of the line, including any continuations, is the replacement text, and has leading and trailing white space removed. Quotes are not removed. The replacement text can never end with a backslash character, but this doesn’t seem to be a serious limitation.

Macros may also be defined between router, transport, authenticator, or ACL definitions. They may not, however, be defined within an individual driver or ACL, or in the local_scan, retry, or rewrite sections of the configuration.

### 5. Macro substitution

Once a macro is defined, all subsequent lines in the file (and any included files) are scanned for the macro name; if there are several macros, the line is scanned for each, in turn, in the order in which the macros are defined. The replacement text is not re-scanned for the current macro, though it is scanned for subsequently defined macros. For this reason, a macro name may not contain the name of a previously defined macro as a substring. You could, for example, define

    ABCD_XYZ = <something>
    ABCD = <something else>

but putting the definitions in the opposite order would provoke a configuration error. Macro expansion is applied to individual physical lines from the file, before checking for line continuation or file inclusion (see above). If a line consists solely of a macro name, and the expansion of the macro is empty, the line is ignored. A macro at the start of a line may turn the line into a comment line or a `.include` line.

### 6. Redefining macros

Once defined, the value of a macro can be redefined later in the configuration (or in an included file). Redefinition is specified by using == instead of =. For example:

    MAC =  initial value
    ...
    MAC == updated value

Redefinition does not alter the order in which the macros are applied to the subsequent lines of the configuration file. It is still the same order in which the macros were originally defined. All that changes is the macro’s value. Redefinition makes it possible to accumulate values. For example:

    MAC =  initial value
    ...
    MAC == MAC and something added

This can be helpful in situations where the configuration file is built from a number of other files.

### 7. Overriding macro values

The values set for macros in the configuration file can be overridden by the -D command line option, but Exim gives up its root privilege when -D is used, unless called by root or the Exim user. A definition on the command line using the -D option causes all definitions and redefinitions within the file to be ignored.

### 8. Example of macro usage

As an example of macro usage, consider a configuration where aliases are looked up in a MySQL database. It helps to keep the file less cluttered if long strings such as SQL statements are defined separately as macros, for example:

    ALIAS_QUERY = select mailbox from user where \
                  login='${quote_mysql:$local_part}';

This can then be used in a redirect router setting like this:

    data = ${lookup mysql{ALIAS_QUERY}}

In earlier versions of Exim macros were sometimes used for domain, host, or address lists. In Exim version 4 these are handled better by named lists – see section 10.4.

### 9. Builtin macros

Exim defines some macros depending on facilities available, which may differ due to build-time definitions and from one release to another. All of these macros start with an underscore. They can be used to conditionally include parts of a configuration (see below).

The following classes of macros are defined:

     _HAVE_*                      build-time defines
     _DRIVER_ROUTER_*             router drivers
     _DRIVER_TRANSPORT_*          transport drivers
     _DRIVER_AUTHENTICATOR_*      authenticator drivers
     _EXP_COND_*                  expansion conditions
     _EXP_ITEM_*                  expansion items
     _EXP_OP_*                    expansion operators
     _EXP_VAR_*                   expansion variables
     _LOG_*                       log_selector values
     _OPT_MAIN_*                  main config options
     _OPT_ROUTERS_*               generic router options
     _OPT_TRANSPORTS_*            generic transport options
     _OPT_AUTHENTICATORS_*        generic authenticator options
     _OPT_ROUTER_*_*              private router options
     _OPT_TRANSPORT_*_*           private transport options
     _OPT_AUTHENTICATOR_*_*       private authenticator options

Use an “exim -bP macros” command to get the list of macros.

### 10. Conditional skips in the configuration file

You can use the directives `.ifdef`, `.ifndef`, `.elifdef`, `.elifndef`, `.else`, and `.endif` to dynamically include or exclude portions of the configuration file. The processing happens whenever the file is read (that is, when an Exim binary starts to run).

The implementation is very simple. Instances of the first four directives must be followed by text that includes the names of one or macros. The condition that is tested is whether or not any macro substitution has taken place in the line. Thus:

    .ifdef AAA
    message_size_limit = 50M
    .else
    message_size_limit = 100M
    .endif

sets a message size limit of 50M if the macro `AAA` is defined (or `A` or `AA`), and 100M otherwise. If there is more than one macro named on the line, the condition is true if any of them are defined. That is, it is an “or” condition. To obtain an “and” condition, you need to use nested `.ifdef`s.

Although you can use a macro expansion to generate one of these directives, it is not very useful, because the condition “there was a macro substitution in this line” will always be true.

Text following `.else` and `.endif` is ignored, and can be used as comment to clarify complicated nestings.

### 11. Common option syntax

For the main set of options, driver options, and local_scan() options, each setting is on a line by itself, and starts with a name consisting of lower-case letters and underscores. Many options require a data value, and in these cases the name must be followed by an equals sign (with optional white space) and then the value. For example:

    qualify_domain = mydomain.example.com

Some option settings may contain sensitive data, for example, passwords for accessing databases. To stop non-admin users from using the -bP command line option to read these values, you can precede the option settings with the word “hide”. For example:

    hide mysql_servers = localhost/users/admin/secret-password

For non-admin users, such options are displayed like this:

    mysql_servers = <value not displayable>

If “hide” is used on a driver option, it hides the value of that option on all instances of the same driver.

The following sections describe the syntax used for the different data types that are found in option settings.

### 12. Boolean options

Options whose type is given as boolean are on/off switches. There are two different ways of specifying such options: with and without a data value. If the option name is specified on its own without data, the switch is turned on; if it is preceded by “no_” or “not_” the switch is turned off. However, boolean options may be followed by an equals sign and one of the words “true”, “false”, “yes”, or “no”, as an alternative syntax. For example, the following two settings have exactly the same effect:

    queue_only
    queue_only = true

The following two lines also have the same (opposite) effect:

    no_queue_only
    queue_only = false

You can use whichever syntax you prefer.

### 13. Integer values

If an option’s type is given as “integer”, the value can be given in decimal, hexadecimal, or octal. If it starts with a digit greater than zero, a decimal number is assumed. Otherwise, it is treated as an octal number unless it starts with the characters “0x”, in which case the remainder is interpreted as a hexadecimal number.

If an integer value is followed by the letter K, it is multiplied by 1024; if it is followed by the letter M, it is multiplied by 1024x1024; if by the letter G, 1024x1024x1024. When the values of integer option settings are output, values which are an exact multiple of 1024 or 1024x1024 are sometimes, but not always, printed using the letters K and M. The printing style is independent of the actual input format that was used.

### 14. Octal integer values

If an option’s type is given as “octal integer”, its value is always interpreted as an octal number, whether or not it starts with the digit zero. Such options are always output in octal.

### 15. Fixed point numbers

If an option’s type is given as “fixed-point”, its value must be a decimal integer, optionally followed by a decimal point and up to three further digits.

### 16. Time intervals

A time interval is specified as a sequence of numbers, each followed by one of the following letters, with no intervening white space:

s | seconds
m | minutes
h | hours
d | days
w | weeks

For example, “3h50m” specifies 3 hours and 50 minutes. The values of time intervals are output in the same format. Exim does not restrict the values; it is perfectly acceptable, for example, to specify “90m” instead of “1h30m”.

### 17. String values

If an option’s type is specified as “string”, the value can be specified with or without double-quotes. If it does not start with a double-quote, the value consists of the remainder of the line plus any continuation lines, starting at the first character after any leading white space, with trailing white space removed, and with no interpretation of the characters in the string. Because Exim removes comment lines (those beginning with #) at an early stage, they can appear in the middle of a multi-line string. The following two settings are therefore equivalent:

    trusted_users = uucp:mail
    trusted_users = uucp:\
                    # This comment line is ignored
                    mail

If a string does start with a double-quote, it must end with a closing double-quote, and any backslash characters other than those used for line continuation are interpreted as escape characters, as follows:

`\\` | single backslash
`\n` | newline
`\r` | carriage return
`\t` | tab
`\`<octal digits> | up to 3 octal digits specify one character
`\x`<hex digits> | up to 2 hexadecimal digits specify one character

If a backslash is followed by some other character, including a double-quote character, that character replaces the pair.

Quoting is necessary only if you want to make use of the backslash escapes to insert special characters, or if you need to specify a value with leading or trailing spaces. These cases are rare, so quoting is almost never needed in current versions of Exim. In versions of Exim before 3.14, quoting was required in order to continue lines, so you may come across older configuration files and examples that apparently quote unnecessarily.

### 18. Expanded strings

Some strings in the configuration file are subjected to string expansion, by which means various parts of the string may be changed according to the circumstances (see chapter 11). The input syntax for such strings is as just described; in particular, the handling of backslashes in quoted strings is done as part of the input process, before expansion takes place. However, backslash is also an escape character for the expander, so any backslashes that are required for that reason must be doubled if they are within a quoted configuration string.

### 19. User and group names

User and group names are specified as strings, using the syntax described above, but the strings are interpreted specially. A user or group name must either consist entirely of digits, or be a name that can be looked up using the getpwnam() or getgrnam() function, as appropriate.

### 20. List construction

The data for some configuration options is a list of items, with colon as the default separator. Many of these options are shown with type “string list” in the descriptions later in this document. Others are listed as “domain list”, “host list”, “address list”, or “local part list”. Syntactically, they are all the same; however, those other than “string list” are subject to particular kinds of interpretation, as described in chapter 10.

In all these cases, the entire list is treated as a single string as far as the input syntax is concerned. The trusted_users setting in section 6.17 above is an example. If a colon is actually needed in an item in a list, it must be entered as two colons. Leading and trailing white space on each item in a list is ignored. This makes it possible to include items that start with a colon, and in particular, certain forms of IPv6 address. For example, the list

    local_interfaces = 127.0.0.1 : ::::1

contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address ::1.

Note: Although leading and trailing white space is ignored in individual list items, it is not ignored when parsing the list. The spaces around the first colon in the example above are necessary. If they were not there, the list would be interpreted as the two items 127.0.0.1:: and 1.

#### 20.1. Changing list separators

Doubling colons in IPv6 addresses is an unwelcome chore, so a mechanism was introduced to allow the separator character to be changed. If a list begins with a left angle bracket, followed by any punctuation character, that character is used instead of colon as the list separator. For example, the list above can be rewritten to use a semicolon separator like this:

    local_interfaces = <; 127.0.0.1 ; ::1

This facility applies to all lists, with the exception of the list in log_file_path. It is recommended that the use of non-colon separators be confined to circumstances where they really are needed.

It is also possible to use newline and other control characters (those with code values less than 32, plus DEL) as separators in lists. Such separators must be provided literally at the time the list is processed. For options that are string-expanded, you can write the separator using a normal escape sequence. This will be processed by the expander before the string is interpreted as a list. For example, if a newline-separated list of domains is generated by a lookup, you can process it directly by a line such as this:

    domains = <\n ${lookup mysql{.....}}

This avoids having to change the list separator in such data. You are unlikely to want to use a control character as a separator in an option that is not expanded, because the value is literal text. However, it can be done by giving the value in quotes. For example:

    local_interfaces = "<\n 127.0.0.1 \n ::1"

Unlike printing character separators, which can be included in list items by doubling, it is not possible to include a control character as data when it is set as the separator. Two such characters in succession are interpreted as enclosing an empty list item.

#### 20.2. Empty items in lists

An empty item at the end of a list is always ignored. In other words, trailing separator characters are ignored. Thus, the list in

    senders = user@domain :

contains only a single item. If you want to include an empty string as one item in a list, it must not be the last item. For example, this list contains three items, the second of which is empty:

    senders = user1@domain : : user2@domain

Note: There must be white space between the two colons, as otherwise they are interpreted as representing a single colon data character (and the list would then contain just one item). If you want to specify a list that contains just one, empty item, you can do it as in this example:

    senders = :

In this case, the first item is empty, and the second is discarded because it is at the end of the list.

### 21. Format of driver configurations

There are separate parts in the configuration for defining routers, transports, and authenticators. In each part, you are defining a number of driver instances, each with its own set of options. Each driver instance is defined by a sequence of lines like this:

    <instance name>:
      <option>
      ...
      <option>

In the following example, the instance name is localuser, and it is followed by three options settings:

    localuser:
      driver = accept
      check_local_user
      transport = local_delivery

For each driver instance, you specify which Exim code module it uses – by the setting of the driver option – and (optionally) some configuration settings. For example, in the case of transports, if you want a transport to deliver with SMTP you would use the smtp driver; if you want to deliver to a local file you would use the appendfile driver. Each of the drivers is described in detail in its own separate chapter later in this manual.

You can have several routers, transports, or authenticators that are based on the same underlying driver (each must have a different instance name).

The order in which routers are defined is important, because addresses are passed to individual routers one by one, in order. The order in which transports are defined does not matter at all. The order in which authenticators are defined is used only when Exim, as a client, is searching them to find one that matches an authentication mechanism offered by the server.

Within a driver instance definition, there are two kinds of option: generic and private. The generic options are those that apply to all drivers of the same type (that is, all routers, all transports or all authenticators). The driver option is a generic option that must appear in every definition. The private options are special for each driver, and none need appear, because they all have default values.

The options may appear in any order, except that the driver option must precede any private options, since these depend on the particular driver. For this reason, it is recommended that driver always be the first option.

Driver instance names, which are used for reference in log entries and elsewhere, can be any sequence of letters, digits, and underscores (starting with a letter) and must be unique among drivers of the same type. A router and a transport (for example) can each have the same name, but no two router instances can have the same name. The name of a driver instance should not be confused with the name of the underlying driver module. For example, the configuration lines:

    remote_smtp:
      driver = smtp

create an instance of the smtp transport driver whose name is remote_smtp. The same driver code can be used more than once, with different instance names and different option settings each time. A second instance of the smtp transport, with different options, might be defined thus:

    special_smtp:
      driver = smtp
      port = 1234
      command_timeout = 10s

The names remote_smtp and special_smtp would be used to reference these transport instances from routers, and these names would appear in log lines.

Comment lines may be present in the middle of driver specifications. The full list of option settings for any particular driver instance, including all the defaulted values, can be extracted by making use of the -bP command line option.

<-previous Table of Contents next->