Exim
Exim is a message transfer agent (MTA) under the GNU license.
Configuration
The configuration file should contain:
- Macros
- Main configuration option settings
- Sections for these sections in this order: acl, authenticators, rewrite, routers, transports, retry
Lines can be commented out using #.
Main configuration settings are values that are defined in the file as foo = bar.
Lists
There are named lists which are defined by the type of list followed by the name of the list and they come in the form of list-type list-name = list-values.
There are 4 types of named lists:
- domainlist
- hostlist
- addresslist
- localpartlist
Items in lists are separated with a colon : but can be changed by first defining a list with <FS, where FS is the field separator character. Items can be negated with an exclamation !. List values may refer to other named lists with a plus +.
Patterns that start with the name of a single-key lookup type followed by a semicolon must be followed by a filename suitable for the lookup type. For example, lsearch;/etc/trustedmailhosts will search for a key in the file /etc/trustedmailhosts which should contain data formatted as key: value.
Lists are checked from left to right. The first match or negation that is found is the result.
Embedded Perl
The Perl interpreter can be used as part of the string expansion process, allowing for the ability to write sophisticated string transformations. Exim should be compiled with EXIM_PERL = perl.o to support the perl interpreter.
When the perl_startup = do '/etc/exim.pl' is included in the configuration, it will be executed in the Perl interpreter. Subroutines defined there can then be referenced later in the form of ${perl{func}{argument1}{argument2}. Up to 8 arguments can be passed.
ACLs
Access Control Lists or ACLs. The ACL section of the configuration file starts with begin acl. All ACLs that were referenced in the main configuration section must be defined here.
For example, cPanel will define and use the following ACLs.
acl_not_smtp = acl_not_smtp
acl_smtp_connect = acl_smtp_connect
acl_smtp_data = acl_smtp_data
acl_smtp_helo = acl_smtp_helo
acl_smtp_mail = acl_smtp_mail
acl_smtp_notquit = acl_smtp_notquit
acl_smtp_quit = acl_smtp_quit
acl_smtp_rcpt = acl_smtp_rcpt
The ACL statements are considered in order, until the recipient address is either accepted or rejected.
cPanel has a ton of rules. However, this illustrates how a RCPT is denied if the user's $HOME/etc/$DOMAIN/.suspend_incoming file exists.
acl_check_rcpt:
accept hosts = :
# implemented for "suspend incoming email" feature
deny
domains = +local_domains
condition = ${if exists {${extract{5}{::}{${lookup passwd{${lookup{$domain}lsearch{/etc/userdomains}{$value}}}{$value}}}}/etc/\.$local_part\@$domain\.suspended_incoming}}
message = Mail to ${lc:$local_part@$domain} has been suspended
log_message = Mail to ${lc:$local_part@$domain} has been suspended
ACL settings
- acl_smtp_rcpt
- Used during an incoming SMTP session for every recipient of a message; on every RCPT command
- acl_smtp_data
- Used after the content of the message have been received
Security
You can define the TLS certificate and private key files based on the presence of whether a file exists or not. See cPanel's configs:
tls_certificate = ${if and \
{ \
{gt{$tls_in_sni}{}} \
{!match{$tls_in_sni}{/}} \
} \
{${if exists {/var/cpanel/ssl/domain_tls/$tls_in_sni/combined} \
{/var/cpanel/ssl/domain_tls/$tls_in_sni/combined} \
{${if exists {${sg{/var/cpanel/ssl/domain_tls/$tls_in_sni/combined}{(.+/)[^.]+(.+/combined)}{\$1*\$2}}} \
{${sg{/var/cpanel/ssl/domain_tls/$tls_in_sni/combined}{(.+/)[^.]+(.+/combined)}{\$1*\$2}}} \
{/etc/exim.crt} \
}} \
}} \
{/etc/exim.crt} \
}
tls_privatekey = ${if and \
{ \
{gt{$tls_in_sni}{}} \
{!match{$tls_in_sni}{/}} \
} \
{${if exists {/var/cpanel/ssl/domain_tls/$tls_in_sni/combined} \
{/var/cpanel/ssl/domain_tls/$tls_in_sni/combined} \
{${if exists {${sg{/var/cpanel/ssl/domain_tls/$tls_in_sni/combined}{(.+/)[^.]+(.+/combined)}{\$1*\$2}}} \
{${sg{/var/cpanel/ssl/domain_tls/$tls_in_sni/combined}{(.+/)[^.]+(.+/combined)}{\$1*\$2}}} \
{/etc/exim.key} \
}} \
}} \
{/etc/exim.key} \
}
tls_advertise_hosts = *
tls_on_connect_ports = 465
tls_require_ciphers = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
Common Settings
https://www.exim.org/exim-html-current/doc/html/spec_html/ch-option_index.html https://www.exim.org/exim-html-current/doc/html/spec_html/ch-main_configuration.html#SECTalomo
TODO: Define the meaning of the following configuration items
add_environment = PATH=/usr/local/sbin::/usr/local/bin::/sbin::/bin::/usr/sbin::/usr/bin::/sbin::/bin
keep_environment = X-SOURCE : X-SOURCE-ARGS : X-SOURCE-DIR
addresslist secondarymx = *@partial-lsearch;/etc/secondarymx
auto_thaw = 7d
callout_domain_negative_expire = 1h
callout_negative_expire = 1h
check_rfc2047_length = false
chunking_advertise_hosts = 198.51.100.1
daemon_smtp_ports = 25 : 465 : 587
tls_on_connect_ports = 465
never_users = root
deliver_queue_load_max = 3
helo_accept_junk_hosts = *
ignore_bounce_errors_after = 1d
timeout_frozen_after = 5d
split_spool_directory = yes
local_from_check = false
log_selector = +incoming_port +smtp_connection +all_parents +retry_defer +subject +arguments +received_recipients
message_body_newlines = true
message_body_visible = 5000
openssl_options = +no_sslv2 +no_sslv3 +no_tlsv1 +no_tlsv1_1
queue_only_load = 6
remote_max_parallel = 10
rfc1413_query_timeout = 0s
smtp_accept_max = 100
smtp_accept_queue_per_connection = 30
smtp_connect_backlog = 50
smtp_enforce_sync = false
smtp_receive_timeout = 165s
smtputf8_advertise_hosts = :
spamd_address = 127.0.0.1 783 retry=30s tmo=3m
system_filter = /etc/cpanel_exim_system_filter
system_filter_group = cpaneleximfilter
system_filter_user = cpaneleximfilter
timezone = America/Los_Angeles
tls_advertise_hosts = *
tls_require_ciphers = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
untrusted_set_sender = *
- add_environment
- Environment variables to set
- keep_environment
- Environment variables to import. eg.
^LDAP
- qualify_domain
- Used to construct a complete email address from local login names, for messages from local processes. Defaults to
primary_hostnameif not set. - primary_hostname
- The FQDN, otherwise if unset, Exim uses the uname system function to obtain the hostname
- allow_domain_literals
- To allow addresses of from
username@[10.1.1.1]rather than domain name. Typically disabled nowadays - never_users
- Local message deliveries are normally run in processes that are setuid to the recipient. This list of users define which deliveries should not run as. Users that are on this list will have their delivery deferred. Build option with
FIXED_NEVER_USERSalso defines a set of users that cannot be overridden.
- deliver_queue_load_max
- Defers delivery if system load exceeds the fixed point value.
- helo_accept_junk_hosts
- Accepts malformed HELO or ELHO commands for incoming SMTP mail to accomodate SMTP clients that send syntactic junk.
- ignore_bounce_errors_after
- Number of days until failing bounce messages are discarded
- timeout_frozen_after
- Number of days before any frozen messages (when a bouncing message encounters a permanent failure) are discarded.
- split_spool_directory
- Exim queues are stored in the spool directory. Large queues should have the directory split to avoid file system degradation from many files in one directory.
- check_rfc2047_length
- RFC 2047 allows for a line length of 76 characters. If set to true, any messages that violate this standard will fail. Set to false for better compatibility.
- rfc1413_hosts, rfc1413_query_timeout
- RFC 1413 deals with ident callbacks. Few hosts offer this service. Setting the timeout to 0 seconds will prevent ident callbacks for all incoming SMTP connections.
- domainlist local_domains = @
- identify domains that are to be delivered on the local host. The
@is a special form of entry which means "the name of the local host"
- domainlist relay_to_domains =
- Lists domains that allows this server to relay to. Default is empty and no relaying is permitted
- hostlist relay_from_hosts
- List of domains or IPs to permit relaying from. Default is the IP address of the loopback device.
Testing
String expansions can be tested with the -be option.
# exim -be '$tod_log'