Exim Cheat Sheet

Input Mode Control
Starting a daemon process

Start listening process

# exim -bd                # start an Exim daemon process on default port 25

# exim -bd -oX 1225       # start an Exim daemon process on port 1225

Interactive SMTP reception

SMTP on stdin and stdout, from local process or via inetd

# exim -bs

Batched SMTP

Batched SMTP from local process

# exim -bS

Extracting recipients from header lines

Message on standard input, recipients from header lines

# exim -t
From: paul.valle@datadisk.co.uk
To: complaints@datadisk.co.uk
Bcc: customerservice@datadisk.co.uk
...
.                           # finish with a single dot

Set SMTP timeout

Set SMTP timeout (overrides option smtp_receive_timeout)

# exim -os

Additional Message Data
sender address supplies the senders address overriding the address computed from the users login name

# exim -f angrycustomer@datadisk.co.uk compliants@datadisk.co.uk
Override the username

The gecos field is normally used to supply the username, but this can be overriden

# exim -F 'The Boss' paul.valle@datadisk.co.uk

Changing the characteristics for a message

There are a number of options starting with -oM that change the characteristics of a message

-oMa   sets the field that contains the IP address of the remote host
-oMaa  sets the field that contains the authenicator name, makes the message look like its authenicated
-oMai  sets the authenicated id value
-oMas  sets the authenicated sender value
-oMi   sets the fields that holds the IP address of the i/f on the local host that was used
-oMr   sets the protocol used to received the mesage (useful for logging)
-oMs   sets the field that holds the verified name of the remote host
-oMt   sets the field that holds the id string obtained by an RFC1413 callback to the sending host

Immediate Delivery Control
request background delivery

The accepting process automatically starts a delivery for each message received

# exim -odb

Wait until a delivery process has finished

Exim will create a new delivery process but will wait until it completes before proceeding

# exim -odf
# exim -odi

Place messages on the queue Exim normally tries to deliver the message ASAP, but you can place the message on the queue first

# exim -odq
Place SMTP on queues but deliver local ASAP You can place SMTP messages on a queue but send local deliveries ASAP

# exim -odqs
Error Reporting
Report an error by sending a message # exim -oem
Report an error by sending a message but different error code # exim -oee
Report error by writing a message to the standard error stream # exim -oep
Queue Runner Processes
start a queue runner process

Queue runner processes are normally started periodically by the daemon but you can do it manually

# exim -q

overriding retry times and freezing

Normally a queue runner process only unfrozen messages and addresses whose retry times have been reached but using the option below means all messages will be tried

# exim -qff

Local deliveries only

Process all unfrozen messages, and does local deliveries but skips remote deliveries

# exim -ql         # only local deliveries
# exim -qfl        # local and force for all addresses even if the retry limit has not been meet
# exim -qffl       # local, force and frozen messages (thawed)

Configuration Overrides
use specific configuration file # exim -C /etc/exim/test_exim_config
Override defined macros

# exim -D LOG_SELECTOR=+filter ...

Note: you can use upto 10 -D

Watching Exim
Display number of messages on the queue # exim -bpc
Display the complete queue # exim -bp
Message Control
Create a delivery process for specific message (basically deliver the message)

# exim -M 1G4K8N-0003uY-29

Note: the message will be delivered even if its frozen, retry time has been reached, etc

Freeze and thaw messages # exim -Mf 1G4K8N-0003uY-29          # Freeze message

# exim -Mt 1G4K8N-0003uY-29          # Thaw message
Abandon Messages # exim -Mg 1G4K8N-0003uY-29          # give up and generate a bounce message

# exim -Mrm 1G4K8N-0003uY-29         # give up but DO NOT generate a bounce message
Inspect a queued message # exim -Mvb 1G4K8N-0003uY-29         # view message body

# exim -Mvh 1G4K8N-0003uY-29         # view message header

# exim -Mvl 1G4K8N-0003uY-29         # view message log
Modify a queued message # exim -Mar 1G4K8N-0003uY-29 paul.valle@datadisk.co.uk        # Add recipient

# exim -Mes 1G4K8N-0003uY-29 paul.valle@datadisk.co.uk        # Edit sender

# exim -Mmad 1G4K8N-0003uY-29                                 # Mark all delivered

# exim -Mmd 1G4K8N-0003uY-29 paul.valle@datadisk.co.uk        # Mark delivered (just the address)
Testing
Testing the config settings

You can obtain lots of information using this command (version, authenicators, lookups, etc)

# exim -bV

Display specific options from the config file

# exim -bP router_list

Other options:

qualify_domain
hold_domains
configure_file
transport
local_delivery
authenticators
router_list
transport_list
authenticator_list
spool_directory

Testing routing

You get back information on what router, transport was used, type of lookup, etc

# exim -bt paul.valle@datadisk.co.uk

Verify an address

# exim -bv paul.valle@datadisk.co.uk

# exim -bvs paul.valle@datadisk.co.uk

Note: -bvs will only be different if option verify_sender and verify_recipient have been set

Start a fake SMTP connection # exim -bh 192.168.0.25              # starts a interactive SMTP session
Testing retry rules

# exim -brt datadisk.co.uk

Note: brush up on the syntax for the retry rules see delivery errors

Testing rewrite rules

# Rewrite rule
*@datadiskcorp.co.uk $1@datadisk.co.uk Ffrsbc

# exim -brw paul.valle@datadiskcorp.co.uk

sender:   paul.valle@datadisk.co.uk          ## changed because of the s flag
from:     paul.valle@datadisk.co.uk          ## changed because of the f flag
to:       paul.valle@datadiskcorp.co.uk      ## did not change because we did not use the t flag
cc:       paul.valle@datadisk.co.uk          ## changed because of the c flag
bcc:      paul.valle@datadisk.co.uk          ## changed because of the b flag
reply-to: paul.valle@datadisk.co.uk          ## changed because of the r flag
env-from: paul.valle@datadisk.co.uk          ## changed because of the F flag
env-to:   paul.valle@datadiskcorp.co.uk      ## did not change because we did not use the T flag

Note: more information can be seen at Address Rewriting

Testing filter files

# exim -bf new-filter < test-message
# exim -bvf new-filter < test-message                                ## adding verbose
# exim -bf new-filter -f paul.valle@datadisk.co.uk < test-message    ## specify the sender
# exim -bF system-filter < test-message                              ## test a system filter

Note: more information can be seen at Message Filtering

Testing string expansion # exim -be
> ${lookup {root} lsearch{/etc/passwd}}
x:0:1:Super User:/:/bin/sh
>

Debugging

Debugging

Start a interactive debugging session

# exim -d all+filter -f paul.valle@datadisk.co.uk complaints@datadisk.co.uk

Note: plus means add debug information for specific option minus means do not debug for that option (see options below)

Debugging Selectors
acl ACL interpretation
auth Authenication
deliver General delivery logic
dns DNS lookups
dnsbl DNS black list code
exec Arguments for exec()
expand Details of string expansion
filter Filter handling
hints_lookup Hints data lookup
host_lookup All types of name-to-IP address handling
ident ident lookups
interface Lists of local interfaces
lists Matching things in lists
load System load checks
local_scan Debugging in the local_scan() function
lookup General lookup code and all lookups
memory Memory handling
pid Add pid to debug lines
process_info Setting info for the process log
queue_run Queue runs
receive General message reception logic
resolver The DNS resolver's debugging output
retry Retry handling
rewrite Address rewriting
route Address routing
timestamp Timestamp debug lines
tls TLS logic
transport Transports
uid Change of uid/gid and looking up uid/gid
verify Address verification
all All of the above and also -v output

Expansion Conditions

!<condition> negate the result
<symbolic operator> {<string1>}{<string2>} =   equal to
== equal to
>   greater than
>= greater than equal to
<   less than
<=  less than equal to
crypteq {<string1>}{<string2>} The first string is encrypted and compared against the second, which must already be encrypted.
def:<variable name> The condition is true if the variable is NOT a empty string
def:header_<header_name>
def:h_<header_name>
true if a message is being processed and the named header exists in the message
eq {<string1>}{<string2>} true if both strings are identical
eqi {<string1>}{<string2>} same as above both case-independent
exists {<filename>} true if filename exists
first_delivery true during the first delivery attempt
ge {<string1>}{<string2>} true if the first resulting string is greater of equal to the second string
gei {<string1>}{<string2>} same as above but case-independent
gt {<string1>}{<string2>} true if the first resulting string is greater than the second string
gti {<string1>}{<string2>} same as above but case-independent
isip {<string>} true if the string is a IP address
isip4 true if the string is a IPv4 address
isip6 true if the string is a IPv6 address
ldapauth{<LDAP query>} true if LDAP authenciates
le {<string1>}{<string2>} true if the first resulting string is less than or equal to the second string
lei {<string1>}{<string2>} same as above but case-independent
lt {<string1>}{<string2>} true if the first resulting string is less than the second string
lti {<string1>}{<string2>} same as above but case-independent
match {<string1>}{<string2>} The second string is treated as a regular expression and applioed to the first, the condition is true if the match succeeds.
match_address {<string1>}{<string2>} The first string must be an email address and the second must be an address list against which the first is matched
match_domain {<string1>}{<string2>} The first string must be a domain and the second must be an domain list against which the first is matched
match_ip {<string1>}{<string2>} The first string must be a IP address and the second must be an IP address list against which the first is matched
match_local_part {<string1>}{<string2>} The first string must be a local part and the second must be an local part list against which the first is matched
pam {<string1>:<string2>:..} Use PAM to authenciate the user
pwcheck{<user:password>} Use Cyrus pwcheck daemon now has been replaced with saslauthd
queue_running true during delivery attempts that are initiated by queue runner processes
radius{<authenication string>} Use Radius to authenciate
saslauthd{<user>}{<password>}{<service>}{<realm>} Use Cyrus (saslauthd) to authenicate
Combining Conditions
and {{<cond1>}{<cond2>}...} The statement is valuated from left to right, the condition is true if all the statements are true
or {{<cond1>}{<cond2>}...} The statement is valuated from left to right, the condition is true if one of the statements are true

Expansion Variables

$0, $1, and so on When a matches expansion condition succeeds, these variables contain the captured substrings identified by the regular expression during subsequent processing of the success string of the containing if expansion item.
$acl_c.. The full-names are user defined, values are placed in these variables by the set modifer in an ACL, they persist throughout the lifetime of an SMTP connection.
$acl_m.. These variables are the same as above but are reset after each message
$acl_verify_message This variable contains the original failure message
$address_data This variable is set by means of the address_data option routers
$address_file The name of the .forward or aliases file if used.
$address_pipe This holds the pipe command when the transport is running
$auth1-$auth3 These variables are used in SMTP authenicators
$authenicated_id May preserve some of the authication information in the variable
$authenicated_sender uses the SMTP MAIL command to populate this variable
$authenicated_failed set to 1 if the authenication succeeds.
$body_linecount Holds the number of lines in the body of a message
$body_zerocount Holds the number of binary zeros in the body of a message
$bounce_recipient set to the recipient address of a bounced message while Exim is creating it.
$bounce_return_size_limit contains the value set in the bounce_return_size_limit option
$caller_gid holds the GID under which the process that called Exim was running
$caller_uid holds the UID under which the process that called Exim was running
$compile_date holds the date that Exim was compiled
$compile_number holds the count that Exim has been compiled
$dnslist_domain holds the domain that is blacklisted by a DNS blacklist, this variable is then used in the rejection messages.
$dnslist_text if the domain is on a DNS blacklist the contents of any associated TXT record are placed in this variable.
$dnslist_value if the domain is on a DNS blacklist the IP address from the resource record are placed in this variable.
$domain When an address is being routed or delivered this variable conatins the domain.
$domain_data This variable is used when a router has a domains condition, if a domain is matched then it is placed in this variable, the router will then use this variable for the remaining router options
$exim_gid the GID of Exim
$exim_path the path of the Exim binary
$home when the check_local_user option (routers) is used, the users home directory is placed in this variable, the transport may use this option.
$host if a router sets up a list of hosts when it accepts an address and assigns it to a transport, this variable contains the first host on that list.
$host_address the IP address of $host
$host_data If a hosts condition in an ACL is satisfied by means of a lookup, the result of the lookup is made available in this variable.
$host_lookup_deferred contains a 1 if there is a DNS problem i.e timeout
$host_lookup_failed

contains a 1 if DNS cannot resolve the hostname from its IP address

$inode used when expanding the directory_file option, it contains the inode number of the temporary file that is about to be renamed.
$ldap_dn conatins the last entry in the most recently successful LDAP lookup.
$load_average contains the system load average
$local_part this contains the local part of the address
$local_part_data If a local_parts condition in an ACL is satisfied by means of a lookup, the result of the lookup is made available in this variable.
$local_part_prefix this contains a specific prefix that has been removed from the local_part
$local_part_suffix this variable contains the specific suffix for the local part
$local_scan_data contains the text returned by the local_scan() function when a message is received
$local_user_gid set to the GID when the check_local_user router precondition succeeds
$local_user_uid set to the UID when the check_local_user router precondition succeeds
$localhost_number contains the value of the localhost_number option
$log_inodes contains the number of free inodes in the disk partition where Exim's log files are kept
$log_space contains the amount of free space in the disk partition where Exim's log files are kept
$malware_name this variable is available when Exim is compiled with the content-scanning extension, it is set to the name of the Virus that was found when the ACL malware condition is true.
$message_age contains the number of seconds since the message was received.
$message_body contains the initial portion of a message's body while it is being delivered
$message_body_end contains the final portion of a message's body while it is being delivered
$message_body_size contains the size of the body's size in bytes
$message_headers contains a concatenation of all the header lines when a message is being processed
$message_exim_id
$message_id
contains the unique message ID that is generated and used by Exim to identify the message
$message_linecount conatins the total number of lines in the header and body of the message
$message_size contains the size of the message in bytes
$mime_xxx a number of variables whose names start with $mime are set during MIME ACL
$n0 to $n9 are counters that can be incremented by the add command in filters
$original_domain this contains the original address when using .forward files, alias, filters
$original_local_part this is the same as above but contains the local part
$originator_gid this is the value of $caller_gid that was set when the message was received
$originator_uid this is the value of $caller_uid that was set when the message was received
$parent_domain conatins the domain of the immediately preceding parent address, used when using .forward files, aliasing, etc
$parent_local_part this is the same as above but contains the local part
$pid the current process ID
$pipe_address used by the pipe transport and transport filters, you cannot expanded this variable, provokes a "unknown variable"
$primary_hostname holds the value set in the config file or the value determined by running the uname() function
$prvscheck_xxx used when using the prvscheck expansion option
$qualify_domain holds the value set of this option in the config file
$qualify_recipient holds the value set of this option in the config file
$rcpt_count contains the number of SMTP RCPT commands received
$rcpt_defer_count contains the number of SMTP RCPT commands received that have been rejected by a temporary response
$rcpt_fail_count contains the number of SMTP RCPT commands received that have been rejected by a permanent response
$received_count conatins the number of Received: header lines
$received_for if there is only one recipient address this this variable contains that address
$received_ip_address contains the local IP address that received this message
$received_port contains the local port that received this message
$received_protocol contains the protocol that received this message
$received_time contains the date and time when the message was received
$recipient_data contains the data from the lookup when using ACL recipients condition
$recipient_verify_failure this contains the information when it fails in a ACL
$recipients contains a list of envelope recipients for a message
$recipients_count contains the number of envelope recipients that came with the message
$reply_address contains the Reply-To: header field
$return_path contains the return path, normally has the same as the $sender_address
$return_size_limit contains the value in return_size_limit option
$runrc contains the return code from a command that is run by the run expansion item
$self_hostname is set to the name of the local host that the original router encountered
$sender_address contains th senders address that was contained in the message's envelope
$sender_address_data if $address_data is set when the routers are called from an ACL to verify a sender address, the final value preserved in $sender_address_data to distingushed it from data from a recipient address.
$sender_address_domain holds the domain portion of $sender_address
$sender_address_local_part holds the domain portion of $sender_local_part
$sender_data If a senders condition in an ACL is satisfied by means of a lookup or in a senders router option , the result of the lookup is made available in this variable.
$sender_fullhost contains the IP address and hostname in a single string, which always ends with the IP address in square brackets
$sender_helo_name contains the first arguement from the SMTP HELO or EHLO command
$sender_host_address contains the clients IP address
$sender_host_authenicated conatins the name of the authenicated driver that successfully authenicated the client from which the message was received.
$sender_host_name contains the host name as obtained by looking up its IP address
$sender_host_port contains the port number that was used on the remote host
$sender_ident contains the identification received in response to an RFC 1413 request
$sender_rate_xxx a number of variables that are set as part of the ratelimit ACL condition
$sender_rcvhost used specifically in Received: header lines
$sender_verify_failure contains information about the failure of an ACL
$smtp_active_hostname contains the value of the active hostname, as specified by the smtp_active_hostname option
$smtp_command contains the entire SMTP command
$smtp_command_argument conatins the SMTP command arguments
$sn0 to $sn9 these variables are copies of values of the $n0 to $n9 accumulators that were current at the end of the system filter
$spam_xx variables whose name start with $spam are available when exim is compiled with the content-scanning extension and the spam ACL condition is used
$spool_directory holds the name of Exim's spool directory
$spool_inodes contains the number of free inodes in the disk partition where Exim's spool files are kept
$spool_space contains the amount of free space in the disk partition where Exim's spool files are kept
$thisaddress is only set during the processing of the foranyaddress command in an Exim filter
$tls_certificate_verified is set to 1 if the TLS certificate has been verified
$tls_cipher set to the name of the cipher used in a TLS connection
$tls_peerdn set to the value of the ditinguished name of the certificate
$tod_bsdinbox holds the date and time of the day in BSD style format
$tod_epoch the time and date as a number of seconds since the start of the Unix epoch
$tod_full holds a full version of the date and time
$tod_log holds the time and date in the format used for writing Exims log files
$tod_logfile contains the date in the format yyyymmdd
$tod_zone contains the numerical value of the local timezone
$tod_zulu contains the UTC data and time in "Zulu" format
$value contains the result of an expression lookup, extraction operation or external command
$version_number holds the version number of Exim
$warn_message_delay set only during the creation of a message warning about a delivery delay
$warn_message_recipients set only during the creation of a message warning about a delivery delay