There are two approaches you can use:
We will not use this method:
# cd /usr/ports/mail/exim # vi Makefile (optional) # make # make install # make clean
It would install the binary as
/usr/sbin/exim and the
configuration file in
Although it is easy to do, you will be stuck with whatever version of exim the port uses, which may not be the latest version. Also, you won't get a choice as to which features get compiled in (although editing the Makefile does let you turn on some features); and you won't have an opportunity to apply any patches.
So instead, we will compile from source. This method is applicable to all Unix machines, not just FreeBSD.
First, we are going to create an 'exim' user. This is so that we can build exim to give up its 'root' privileges as soon as possible after starting up, which improves security. The following command creates a user and group 'exim' with uid and gid of 90, or you can use 'vipw' to edit the password file directly.
$ su # pw useradd exim -u 90 -d /usr/exim # exit
Next, unpack and apply any patches. You can do all this as a non-root user, i.e. just within your normal home directory
See exim-users archive
for a note on the exim-3.22 patch for a segfault when the
ignore_target_hosts feature is used.
$ tar -xvzf /path/to/file/exim-3.22.tar.gz $ cd exim-3.22 $ cat /path/to/file/exim-ignore_target_hosts.patch | patch -p1 ... Patching file src/host.c using Plan A... Hunk #1 succeeded at 1794. done.
Now set up files which tell exim how to build. Note - case sensitive - make sure you type Local and Makefile with an initial capital letter.
(we are still within the exim-3.22 directory) $ mkdir Local $ cp src/EDITME Local/Makefile $ vi Local/Makefile
There are various things you can change in Local/Makefile. For our exercise, please make the following changes. Search for each of the settings and adjust it accordingly.
COMPRESS_COMMAND=/usr/bin/gzip # change ZCAT_COMMAND=/usr/bin/zcat # change EXIM_UID=90 # uncomment + change EXIM_GID=90 # uncomment + change LOG_FILE_PATH=/var/log/exim/exim_%slog # uncomment + change LOOKUP_CDB=yes # uncomment PID_FILE_PATH=/var/spool/exim/exim%s.pid # uncomment + change SPOOL_DIRECTORY=/var/spool/exim # uncomment SUPPORT_MAILDIR=yes # uncomment
Note that because we have told exim to give up its root privileges, we need to specify directories where it can write its log files and pid file. These directories will be owned by user 'exim' so that it will have sufficient privileges to create these files. (Some of these settings can be overridden in the configuration file, but it makes life easier to compile in the values we need)
Note that we will keep the default locations for the exim
binaries and configure file, which are
The following lets 'eximon' be built (only if your system is running X11):
$ cp exim_monitor/EDITME Local/eximon.conf
Now build and install exim:
$ make ... >>> exim binary built $ su Password: <root password> # make install ... Exim installation complete
Still as root, we need to create a log directory owned by 'exim'. (We don't need to create /var/spool/exim because exim will do that itself the first time it is run)
# mkdir /var/log/exim # chown exim:exim /var/log/exim # exit
Now check that the exim binary and configuration file have been installed (a number of utilites are also installed)
$ ls -lR /usr/exim total 17 drwxr-xr-x 2 root wheel 512 Apr 18 11:30 bin -rw-r--r-- 1 root wheel 16294 Apr 18 11:30 configure <-- config file /usr/exim/bin: total 764 -rwxr-xr-x 1 root wheel 6859 Apr 18 11:30 exicyclog -rwxr-xr-x 1 root wheel 2554 Apr 18 11:30 exigrep -rwsr-xr-x 1 root wheel 505954 Apr 18 11:30 exim <-- main program -rwxr-xr-x 1 root wheel 8850 Apr 18 11:30 exim_dbmbuild -rwxr-xr-x 1 root wheel 24834 Apr 18 11:30 exim_dumpdb -rwxr-xr-x 1 root wheel 27124 Apr 18 11:30 exim_fixdb -rwxr-xr-x 1 root wheel 12509 Apr 18 11:30 exim_lock -rwxr-xr-x 1 root wheel 25475 Apr 18 11:30 exim_tidydb -rwxr-xr-x 1 root wheel 6764 Apr 18 11:30 eximon -rwxr-xr-x 1 root wheel 101392 Apr 18 11:30 eximon.bin -rwxr-xr-x 1 root wheel 21101 Apr 18 11:30 eximstats -rwxr-xr-x 1 root wheel 4431 Apr 18 11:30 exinext -rwxr-xr-x 1 root wheel 2886 Apr 18 11:30 exiqsumm -rwxr-xr-x 1 root wheel 2284 Apr 18 11:30 exiwhat
Exim's configuration file is /usr/exim/configure. A default file is installed which is suitable for a simple installation, e.g. a workstation. To make it work under FreeBSD, you need to make a minor change:
... local_delivery driver = appendfile file = /var/mail/$local_part delivery_date_add envelope_to_add return_path_add group = mail <-- UNCOMMENT THIS LINE # mode = 0660 ...
Now we will use this default config file to check that exim is installed properly.
Firstly, use exim's address testing mode, -bt. This will make all the delivery decisions for a given address but not actually perform a delivery. Try testing both remote and local delivery. Before testing local delivery, make sure you have a local account to deliver to - for security reasons, exim will not deliver to 'root'
# /usr/exim/bin/exim -bt email@example.com firstname.lastname@example.org deliver to email@example.com router = lookuphost, transport = remote_smtp host mxa2.pobox.com [22.214.171.124] MX=10 host mxa1.pobox.com [126.96.36.199] MX=10 host max3.pobox.com [188.8.131.52] MX=10 host mxa4.pobox.com [184.108.40.206] MX=10 host mxb.pobox.com [220.127.116.11] MX=30 # /usr/exim/bin/exim -bt brian firstname.lastname@example.org deliver to brian in domain pc1.t1.ws.afnog.org director = localuser, transport = local_delivery
Next, use the verbose delivery mode, -v to actually deliver a message. Again, try both local and remote.
# /usr/exim/bin/exim -v email@example.com From: firstname.lastname@example.org To: email@example.com Subject: test message Testing <Ctrl-D> ... you will see the delivery decision process and the SMTP exchange LOG: 0 MAIN Completed
If there is a problem and you need even more output, you can use '-d1' to '-d9' in addition to '-v' for debugging output.
Next check the log files. Normal deliveries are recorded in the file exim_mainlog; if there are serious configuration errors which cause exim to abort, you may also have an exim_paniclog
# cd /var/log/exim # ls # cat exim_mainlog
Changing mailer.conf will ensure that any local programs which try to invoke sendmail invoke exim instead. On systems without mailer.conf, you can rename /usr/sbin/sendmail to /usr/sbin/sendmail.old, and install a symlink from /usr/sbin/sendmail to /usr/exim/bin/exim. If you are using uucp, replace /bin/rmail with a symlink to /usr/exim/bin/exim too.
To make it obvious, we can also arrange that exim is started instead of sendmail at boot time (although actually this is not necessary, as once mailer.conf is changed, it will be exim that runs anyway)
# Execute exim rather than sendmail # sendmail /usr/exim/bin/exim send-mail /usr/exim/bin/exim mailq /usr/exim/bin/exim newaliases /usr/exim/bin/exim_dbmbuild /etc/mail/aliases /etc/mail/aliases.db
/usr/exim/bin/exim -bd -q30m
We need to ensure that log files are rotated daily, so we set up a crontab entry to do this. By default, 10 days of logs are kept. To change this, edit the exicyclog script and change 'keep=10'
0 0 * * * root /usr/exim/bin/exicyclog
/usr/exim/bin is not in the search path. One way to save us having to keep typing '/usr/exim/bin/exim' is to add a symlink into /usr/local/bin, which is already in the default search path.
# ln -s /usr/exim/bin/exim /usr/local/bin/exim
If you were doing this on a live machine which was already running
sendmail, then you would kill the sendmail daemon and start exim instead.
Check that there is no mail left in
/var/spool/mqueue. If there
is, then you should run /usr/libexec/sendmail/sendmail
-q from time to time until the queue is empty.
This shows the contents of Exim's mail spool, equivalent to 'mailq'
Force delivery of an individual message. With -v, delivery occurs in the foreground with verbose progress information. Without it, the delivery attempt occurs in the background.
Attempt another delivery to all destination addresses which contain string, for example:
# exim -R @hotmail.com -v
Force another delivery attempt on all queued messages, including those which are frozen.
Run a spoof SMTP session as if from IP address 18.104.22.168. This is useful for testing whether anti-relaying is configured properly.
# exim -bh 22.214.171.124 **** SMTP testing session as if from host 126.96.36.199 **** Not for real! 220 pc1.t1.ws.afnog.org ESMTP Exim 3.22 #1 Wed, 02 May 2001 16:42:36 +0000 helo wombat 250 pc1.t1.ws.afnog.org Hello wombat [188.8.131.52] mail from:<> 250 <> is syntactically correct rcpt to:<firstname.lastname@example.org> 550 relaying to <email@example.com> prohibited by administrator quit 221 pc1.t1.ws.afnog.org closing connection
If you need to enable relaying for certain blocks of IP addresses, see host_accept_relay in configure. Do not turn your machine into an open relay!
Scan through an exim logfile and generate statistics. You can set up a
cronjob to mail statistics to you every day; just make sure it runs a little
after exicyclog has run, which means that yesterday's logs will be in
exim_mainlog.01. This should be on a single line.
15 0 * * * root /usr/exim/bin/eximstats /var/log/exim/exim_mainlog.01 | mail -s "Exim stats" firstname.lastname@example.org
In this exercise, we will change our Exim installation so that it delivers mail into separate files under $HOME/Maildir/ rather than a single mbox file /var/mail/$USER
We will do this by creating a new configuration file, testing it without touching the live configuration file, and when we are happy that it is OK, installing it.
# cd /usr/exim # cp configure configure.new # vi configure.new
Find the local_delivery transport, and change it as follows:
local_delivery: driver = appendfile maildir_format create_directory directory = $home/Maildir/ delivery_date_add envelope_to_add return_path_add # with Maildir, we do not add a "From " line, and do not need to # convert "From " to ">From " prefix = suffix = check_string = escape_string =
Test routing to address using the new configure file. This should be sufficient to check the syntax of the file, and check that the mail routing is working. Check both local and remote delivery.
Actually perform a delivery using the new configure file. Do this for a number of different test addresses (e.g. local and remote) and check that the deliveries have completed. Use exim -bp to check that the messages have not remained in the queue, and check the log files too.
# exim -C /usr/exim/configurefile.new -v fred Subject: test message testing . # su - fred $ ls Maildir/new 988935301.3615.pc1.t1.ws.afnog.org $ cat Maildir/new/988935301.3615.pc1.t1.ws.afnog.org ... the message $ exit
(Note: with -C you need to be running as root, otherwise exim runs as the user who started exim. It is a good idea to give the full pathname to the configuration file; this is because exim re-execs itself to perform delivery, and the second exim process could have a different working directory)
It's a good idea to keep a copy of the old configuration before rolling the new one into place, so that you can back out in case of problems.
# cd /usr/exim # cp configure configure-20010509 # mv configure.new configure
The running exim daemon will still be using the old configuration file, so you need to send it a HUP signal (-1) to make it reread its configuration.
# cat /var/spool/exim/exim.pid 16379 # kill -HUP 16379
As a final check, make sure the exim daemon is still running. If it is configured to accept incoming mail, then check that it does so:
# telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 pc1.t1.ws.afnog.org ESMTP Exim 3.22 #1 Wed, 02 May 2001 17:59:56 +0000 Ctrl-] telnet> close Connection closed.
In this example, there is something else we need to do: change all Mail User Agents (MUAs) so that they look for mail in $HOME/Maildir/ rather than /var/mail/$USER. If you are using Mutt, edit /usr/local/etc/Muttrc and include the following line:
If people collect mail using pop3 then you will need a different pop3d which is capable of reading Maildir format messages. In the next exercise we will install qmail-pop3d for this.
This configuration can be used on a machine acting as a smarthost. It has absolutely no local delivery capability, and as a result it is configured to run without priviledges (i.e. it remains as user 'exim') which enhances security. A number of parameters have been altered to suit a large-scale server, and on a reasonable machine you should be able to handle several hundred thousand messages per day.
This configuration in turn reads two plaintext files which you need to create:
# Allow relaying from localhost 127.0.0.1 # AFNOG workshop address space 184.108.40.206/23
# List domains for which we have agreed to act as backup MX t1.ws.afnog.org
Because there is no capability for local delivery, it's important that you set up forwarding so that any error messages and postmaster mail are sent to a remote mailbox. This is done in /etc/mail/aliases:
root: email@example.com postmaster: root