Exim configuration file
Exim configuration file in details
Following is an example of the Exim configuration file on Debian. Activation fields spamassassassin, clamav, opendkim, postgrey:
SA_ENABLE = yes
VIRUS_SCAN = yes
DKIM_ENABLE = yes
POSTGREY_SOCKET = /var/run/postgrey.sock
the acl_check_rcpt section
If clamav is activated in the acl_check_rcpt section, make sure the domain is not added into the Clamav whitelist
.ifdef VIRUS_SCAN
warn set acl_m3 = no
warn
condition = ${lookup{$domain}lsearch{/etc/clamav.whitelist} {yes}{no}}
set acl_m3 = ok
.endif
Check the sender in whitelists and blacklists:
accept domains = +local_domains : +relay_to_domains
condition = ${lookup{$sender_address}wildlsearch{/etc/exim4/whitelist}{yes}{no}}
set acl_m6 = whitelisted
logwrite = Accepted from $sender_address to $local_part@$domain by whitelist.
accept domains = +local_domains : +relay_to_domains
hosts = net-lsearch;/etc/exim4/whitelist
set acl_m6 = whitelisted
logwrite = Accepted from $sender_address to $local_part@$domain by whitelist.
deny condition = ${lookup{$sender_address}wildlsearch{/etc/exim4/blacklist}{yes}{no}}
set acl_m6 = blacklisted
logwrite = Rejected from $sender_address to $local_part@$domain by blacklist.
deny hosts = net-lsearch;/etc/exim4/blacklist
set acl_m6 = blacklisted
logwrite = Rejected from $sender_address to $local_part@$domain by blacklist.
Check the sender by greylisting:
.ifdef POSTGREY_SOCKET
defer log_message = greylisted host $sender_host_address
set acl_m0 = request=smtpd_access_policy\nprotocol_state=RCPT\nprotocol_name=${uc:$received_protocol}\nhelo_name=$sender_helo_name\nclient_address=$sender_host_address\nclient_name=$sender_host_name\nsender=$sender_address\nrecipient=$local_part@$domain\ninstance=$sender_host_address/$sender_address/$local_part@$domain\n\n
set acl_m0 = ${sg{${readsocket{POSTGREY_SOCKET}{$acl_m0}{5s}{}{action=DUNNO}}}{action=}{}}
message = ${sg{$acl_m0}{^\\w+\\s*}{}}
condition = ${if eq{${uc:${substr{0}{5}{$acl_m0}}}}{DEFER}{true}{false}}
.endif
the acl_check_data section
in case of high load of the server, accept messages without checks:
accept
condition = ${if >{$load_average}{3000} {yes}{no}}
logwrite = Accept message without spamd and antivirus check because LA > 3.
this message is more than 1 KB and less than 2 MB, check it using clamav, acl_m3 contains no, if the domain is added into the clamav whitelist:
.ifdef VIRUS_SCAN
accept
condition = ${if or {\
{<{$message_body_size}{1K}} \
{>{$message_body_size}{2M}} \
} {yes}{no}}
logwrite = Accept message without antivirus check because body size $message_body_size not critical
warn
condition = ${if eq{$acl_m3}{ok} {yes}{no}}
add_header = X-Scanned-By: ${extract{1}{/}{${readsocket{/var/run/clamav/clamd.ctl}{VERSION}{1s}{} {unscanned}}}}; $tod_full\n
deny
message = This message contains virus ($malware_name)
hosts = *
demime = *
malware = *
log_message = Rejected: this message contains virus ($malware_name)
condition = ${if eq{$acl_m3}{ok}{yes}{no}}
.endif
Spamassassin check:
.ifdef SA_ENABLE
warn
!authenticated = *
hosts = !127.0.0.1/24
condition = ${if < {$message_size}{1K}}
spam = SA_SPAMD_USER:true
add_header = 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
warn
!authenticated = *
hosts = !+relay_from_hosts
spam = SA_SPAMD_USER:true/defer_ok
add_header = 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
set acl_m4 = $spam_score_int
condition = ${if and{{<{$message_size}{100K}}{<{$acl_m4}{SA_SCORE_REJECT}}} {yes}{no}}
logwrite = From $sender_address to $recipients X-Spam_score: $acl_m4.
deny
condition = ${if and{{!eq{$acl_m4}{}}{>{$acl_m4}{SA_SCORE_REJECT}}} {yes}{no}}
message = Content analisis tool detect spam (from $sender_address to $recipients). Contact SA_ABUSE_ADDR.
.endif
the acl_check_dkim section
If dkim is activated, check dkim headings
.ifdef DKIM_ENABLE
acl_check_dkim:
warn
dkim_status = fail
logwrite = DKIM test failed: $dkim_verify_reason
add_header = X-DKIM-FAIL: DKIM test failed: (address=$sender_address domain=$dkim_cur_signer), signature is bad.
warn
dkim_status = invalid
add_header = :at_start:Authentication-Results: $dkim_cur_signer ($dkim_verify_status); $dkim_verify_reason
logwrite = DKIM test passed (address=$sender_address domain=$dkim_cur_signer), but signature is invalid.
accept
dkim_status = pass
add_header = :at_start:Authentication-Results: dkim=$dkim_verify_status, header.i=@$dkim_cur_signer
logwrite = DKIM test passed (address=$sender_address domain=$dkim_cur_signer), good signature.
accept
.endif
routers sections
Check that the domain is not suspended:
disabled_domains:
driver = redirect
condition = ${extract{3}{:}{${lookup{$domain}lsearch{/etc/exim4/domains}}}}
allow_fail = yes
data = :fail: Domain disabled
no_more
Check that the domain owner is not suspended:
disabled_users:
driver = redirect
condition = ${extract{5}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/passwd}}}}
allow_fail = yes
data = :fail: User disabled
no_more
Check that this domain is created on the server:
local_domains:
driver = redirect
data = ${quote_local_part:$local_part}@${extract{1}{:}{${lookup{$domain}lsearch{/etc/exim4/domains}}}}
cannot_route_message = Unknown user
redirect_router = dnslookup
no_more
Check that the mailbox is an alias:
aliases:
driver = redirect
data = ${extract{1}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/aliases}}}}
condition = ${if exists{/etc/exim4/aliases} {yes} {no} }
redirect_router = dnslookup
pipe_transport = address_pipe
Deliver email into the mailbox, if it is specified in exim-passwd:
procmail:
no_verify
driver = accept
transport = dovecot_deliver_pipe
transport_home_directory = ${extract{4}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/passwd}}}}
Perform a default action specified for the domain, if that mailbox does not exist:
catchall_for_domains:
driver = redirect
headers_add = X-redirected: yes
data = ${extract{2}{:}{${lookup{$domain}lsearch{/etc/exim4/domains}}}}
file_transport = local_delivery
redirect_router = dnslookup
Or send a message specifying that the mailbox does not exist on the server:
unknown_users:
driver = redirect
allow_fail = yes
data = :fail: Unknown user
no_more
Enable mail subaddressing:
userforward:
local_part_suffix = +*
local_part_suffix_optional
Subaddressing allows you to automatically distribute incoming messages to user folders. To do this, the recipient address must indicate the combination "mailbox + folder name". For example, if user@example.com has a “bill” folder on the IMAP server, then messages for user+bill@example.com will be automatically placed in this folder.
Transport section
Delivery of an email message in maildir using dovecot-lda:
dovecot_deliver_pipe:
driver = pipe
environment = "HOME=$home"
command = "/usr/lib/dovecot/dovecot-lda -d $local_part@$domain -f $sender_address"
return_path_add
delivery_date_add
envelope_to_add
check_string = "From "
escape_string = ">From "
user = ${extract{1}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/passwd}}}}
group = ${extract{2}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/passwd}}}}
Authentication section
If authentication through dovecot was selected during installation:
auth_plain:
driver = dovecot
public_name = PLAIN
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth1
auth_login:
driver = dovecot
public_name = LOGIN
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth1
auth_cram_md5:
driver = dovecot
public_name = CRAM-MD5
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth1
In case of authentication through sasldb:
cram:
driver = cyrus_sasl
public_name = CRAM-MD5
server_set_id = $1
plain:
driver = cyrus_sasl
public_name = PLAIN
server_set_id = $1
login:
driver = cyrus_sasl
public_name = LOGIN
server_set_id = $1