In particular, running email tests as root is a bad idea, because root has privileges. You want to test that Exim is working when an ordinary, unprivileged user calls it.
We are going to install Exim from the generic distribution This way of doing it allows you to make your own choices at build time.
You do not need to be root to build Exim, and it is best practice if you are not. However, you do need to be root to install Exim. Reminder: In the sample commands below, the command prompt is shown as # for commands that must be run as root, and $ otherwise.
# ps auxw | grep sendmail # /etc/rc.d/init.d/sendmail stop # chkconfig --del sendmail
Create a user and group called exim. These will be used for running Exim when it does not need to be root.
# useradd -M -u 90 exim
You should also arrange for your personal (non-root) account to be in the exim group so that you can be an administrator for Exim.
# usermod -G exim username # grep exim /etc/group (To check)
# chmod 1777 /var/spool/mail(This is so that the default Exim configuration will work without having to be changed.)
# mkdir /usr/exim # chown yourname:yourname /usr/exim
You can now fetch and build Exim from your own account (not root).
$ cd /usr/exim $ ftp noc.taller.nsrc.orgLog in as anonymous.
ftp> cd /pub/software ftp> get exim-4.30.tar.bz2 ftp> get exim-html-4.30.tar.bz2 ftp> bye
$ cd /usr/exim $ bunzip2 exim-4.30.tar.bz2 $ tar -xvf exim-4.30.tar $ bunzip2 exim-html-4.30.tar.bz2 $ tar -xvf exim-html-4.30.tar
file:///usr/exim/exim-html-4.30/doc/html/index.htmlThere should also be a file called /usr/exim/exim-4.30/doc/spec.txt. It contains a copy of the manual in ASCII format which can be searched with a text editor.
$ cd /usr/exim/exim-4.30Copy the file src/EDITME to Local/Makefile and exim_monitor/EDITME to Local/eximon.conf. You then have to edit Local/Makefile, following the instructions inside it:
$ cp src/EDITME Local/Makefile $ cp exim_monitor/EDITME Local/eximon.conf $ vi Local/MakefileThere are lots of instructions inside the file, but you do not have to make many changes. You can leave almost all of the settings at the defaults, but you will need to set EXIM_USER to the user for running Exim. You also need to request `maildir' support for use later in the workshop. Find the lines that contain EXIM_USER and SUPPORT_MAILDIR, and change them to be like this:
EXIM_USER=exim SUPPORT_MAILDIR=yes
(Do not do this at the workshop.) When you build Exim on your own hosts back home, you may want to change BIN_DIRECTORY and CONFIGURE_FILE from their default values of /usr/exim/bin and /usr/exim/configure. For example, these settings are closer to what an RPM installation might use:
BIN_DIRECTORY=/usr/local/sbin CONFIGURE_FILE=/etc/exim/configureHowever, for this exercise, we assume that you didn't change the default values.
You don't need to edit Local/eximon.conf because the default settings will be OK.
$ makeYou should see a lot of output while Exim builds, ending with the line:
>>> exim binary builtWhen you see that line, you have successfully built Exim. Easy, wasn't it?
# cd /usr/exim/exim-4.30 # make installYou should end up with the Exim binaries in /usr/exim/bin/ and a default configuration file in /usr/exim/configure.
$ /usr/exim/bin/exim -bVwhich should tell you Exim's version number and some other information about which features are included.
We want programs to call exim rather than sendmail, but leave sendmail
installed so that if there is any existing mail in sendmail's queue, it can
be flushed later. Red Hat lets us choose a new MTA by setting a symlink in
the /etc/alternatives directory. We redirect the programs
'sendmail' and 'mailq' to point to exim.
# cd /etc/alternatives # rm mta # ln -s /usr/exim/bin/exim mta # rm mta-mailq # ln -s /usr/exim/bin/exim mta-mailq
$ /usr/sbin/sendmail -bVYou should get the same output as before, which shows that Exim is now being used instead of Sendmail.
$ export PATH=/usr/exim/bin:$PATH
Make sure you substitute a real local user name for localuser in what follows. Remember, you should not be root when running these tests.
$ exim -bt localuserThis tests the delivery routing for a local account. See what output you get.
$ exim -bt junkjunkjunk
$ exim -bt postmasterExim will not normally deliver mail to a root mailbox (for security reasons) so what people usually do is to make root an alias for the sysadmin. In Red Hat, all the default aliases point to root. Therefore, you should add a new alias to /etc/aliases. Add this line at the end:
# Person who should get root's mail root: yournameNow try this again:
$ exim -bt postmaster
$ exim -v -odf localuser This is a test message. .Note: the message is terminated by a line that just contains a dot. Be sure to type it! (Alternatively, you can send ``end of file'' by pressing CTRL-D.)
The -v option turns on user verification output, which shows you copies of Exim's log lines.
The -odf option requests `foreground' delivery, which means that the exim command won't return until the delivery is complete. (This avoids your shell prompt getting mixed up with Exim's output.)
$ cat /var/spool/exim/log/mainlog $ cat /var/spool/exim/log/paniclogThe panic log should normally be empty, and if nothing has ever been written to it, it will not even exist. Tip: On a live system it is helpful to set up a cron job that mails you a warning if it ever finds a non-empty panic log.
If you get a permission error, make sure that your username is in the 'exim' group, then logout and login again to become a member of that group.
If the delivery succeeded, you should see two lines in the main log, one containing <= for the message arriving, and one containing => for the delivery.
$ ls -l /var/spool/mail/localuser $ cat /var/spool/mail/localuserIf the delivery didn't succeed, you need to find out why. If the information in the log doesn't help, you can try the delivery again, with debugging turned on:
$ exim -d -odf localuser <there will be output from Exim here> This is another test message. .The -d option turns on debugging, which gives a lot more information than -v. You need to be an Exim administrator to use -d. If you get a `Permission denied' error, check that you are a member of the Exim group.
The next thing is to test whether Exim can send to a remote host. The speed of this may vary, depending on the state of the network connection. In what follows, replace user@remote.host with your home email address.
$ exim -bt user@remote.host
$ exim -v -odf user@remote.host This is a test message. .This time, the -v option causes Exim to display the SMTP dialogue as well as the log lines. If you can, check that the message arrived safely. If there are problems, see if you can figure out what went wrong and why.
$ /usr/exim/bin/exim -bd -q20mThe -bd option causes the daemon to listen for incoming SMTP calls, and the -q20m option causes it to start a queue runner process every 20 minutes. On a live system, starting the daemon should happen automatically on a reboot, by putting this command in /etc/rc.local .
$ telnet localhost 25You should see an Exim greeting message. Use QUIT to exit.
Start the monitor:
$ /usr/exim/bin/eximonThe upper window shows a `tail' of the main log; the lower window shows the messages that are waiting in the queue. Expect both to be empty to start with. Send a few messages and watch what the monitor displays.
To put a message on the queue without its being delivered, run
$ exim -odq address1 address2 ... Test message. .The message stays on the queue until a queue runner process notices it.
$ exim -bp
$ exim -v -q(Without -v you won't see any output at all on the terminal, but there will be entries in the log.)
$ telnet 127.0.0.1 25 ehlo localhost mail from:<localuser@pcnn.taller.nsrc.org> rcpt to:<localuser@pcnn.taller.nsrc.org> rcpt to:<user@some.remote.domain>You should get an OK response to all the SMTP commands. Type `quit' to end the SMTP session without actually sending a message.
$ telnet xx.xx.xx.nn 25 ehlo localhost mail from:<localuser@pcnn.taller.nsrc.org> rcpt to:<localuser@pcnn.taller.nsrc.org> rcpt to:<user@some.remote.domain>In this case, you should get the error message
550 relay not permittedfor the second RCPT command, which is the one that is trying to relay. The first RCPT command should be accepted, because it specifies a local delivery. You could also try telnetting from an external host and running the same check.
$ exigrep localuser /var/spool/exim/log/mainlogThat extracts all the log information for all messages that have any log line containing `localuser'. It's a Perl pattern match, so you can use Perl regular expressions.
To extract simple statistics from a log, run
$ eximstats /var/spool/exim/log/mainlog | moreThere are options for selecting which bits you don't want. Details are in the manual. If you have time, experiment with the options for outputting the statistics as HTML.
# cat /var/spool/exim/exim-daemon.pid # kill -HUP nnnnwhere nnnn is the pid from the previous line.
You can confirm that the daemon has restarted by checking the main log. You are going to be restarting Exim a lot, so make yourself a script to save typing. Use vi to create a file called /usr/local/bin/hupexim, containing these lines:
#!/bin/bash kill -HUP $(cat /var/spool/exim/exim-daemon.pid)Note that the # character in the first line is part of the file (it's not a prompt). Now make the new file into an executable script:
# chmod a+x /usr/local/bin/hupexim
If you are using the C-shell (csh) you must also run this command:
# rehashThis causes the internal hash table of the contents of the directories in the PATH variable to be recomputed. This is not necessary if you are using bash.
Now you can restart Exim just by running:
# hupexim
The following sections contain some suggestions for configuration modifications that you can try, just to get a feel for how the configuration file works. You do not have to stick rigidly to these examples; use different domain names or user names if you want to.
domainlist local_domains = @ : testnn.nsrc.orgwhere nn is the number of your host. Remember to HUP the daemon afterwards. Now you have a new local domain. Try sending it some mail:
$ mail yourname@testnn.afnog.orgCheck that it arrives in your mailbox.
Note: The domains that we are adding now can only be used from your own host, because there are no DNS records for them. When you are adding domains to a production host, you must of course also add MX records for them.
If you want to add a lot of domains, or if you want to keep changing them, it is easier to keep the list of domains in a file instead of in the Exim configuration. (You can also keep them in several different kinds of database, such as LDAP or MySQL, but we don't cover that in this workshop.) We are now going to add some domains like this, and then make them into virtual domains.
vdom1.nsrc.org vdom2.nsrc.org ...
domainlist local_domains = @ : testnn.nsrc.org : \ lsearch;/usr/exim/vdomainsNote: There is no space following the semicolon. This change makes all the new domains into local domains.
virtual_domains: driver = redirect domains = lsearch;/usr/exim/vdomains data = ${lookup{$local_part}lsearch{/usr/exim/aliases-$domain}} no_moreThere must be no space after the semicolon in the ``domains'' line. (Remember to HUP the daemon.)
brian: b.candler@pobox.com yourname: your email addressThe local parts brian and yourname should now be valid for the first virtual domain.
$ exim -bt philip@vdom1.afnog.orgPlease don't actually send test mail to that address -- I get too much junk already!
$ exim -bt unknown@vdom1.nsrc.org
Here is a sample router that does this job:
unknown_to_postmaster: driver = redirect data = postmaster
It should be placed last, after all the other routers. Test it by sending mail to an unknown user.
We are now going to remove this block by changing a line in the configuration
to let all the classroom hosts relay through your host. Change this line:
hostlist relay_from_hosts = 127.0.0.1to
hostlist relay_from_hosts = 127.0.0.1 : xx.xx.xx.xx/mmwhere xx.xx.xx.xx/mm is the classroom network. (Don't forget to HUP the daemon.) Then try the telnet test from section 2 again. This time it should accept the request to relay. Ask one of the other students to try relaying through your host -- it should work. If you can, telnet from a host outside the classroom network, and confirm that relaying is still blocked.
domainlist relay_to_domains =This defines domains to which your host will relay, wherever the message comes from. As you can see, the default list is empty, so no domains match.
Add some domains to this line. For example, add the domain of your home email.
In my case, this would be:
domainlist relay_to_domains = pobox.com
Now we need to test that Exim will indeed relay to those domains (but not to others) from a host that does not match relay_from_hosts. Exim has a testing facility that lets you simulate an SMTP call from a remote host. Run it like this:
$ exim -bh 192.168.1.1You will see some debugging output, and then an SMTP greeting line. Now type SMTP commands, waiting for a response between each one:
ehlo testhost mail from:<localuser@pcnn.taller.nsrc.org> rcpt to:<user@your.home.domain> rcpt to:<user@some.other.domain>You will see the tests that Exim is making as it runs the ACL after each RCPT command. Check that it allows relaying to the right domains, and not to any others. End the SMTP session with QUIT.
Edit the configuration, and change the remote_smtp transport to be
like this:
remote_smtp: driver = smtp port = 3456(Remember to HUP the daemon.) This makes Exim try port 3456 instead of the SMTP port (25) when delivering, causing the remote host to refuse the connection (assuming you've chosen an unused port!)
$ exim -qand see what happens and what gets logged. Have a look at the message's own msglog file, which you can do from the monitor or by using the -Mvl option. For example:
$ exim -Mvl 19EdUm-00016A-IA(That is an example message ID; you must use the real one for the message that is on your queue.)
$ exinext remote.domain
# Exim filter if $h_subject: is "spam" then save /dev/null endif
system_filter = /usr/exim/system.filter system_filter_file_transport = address_file
othernameotherdomain.com postmasteryour.domain
$ exim -brw othername@otherdomain.com